Filter とは
Filter と書きましたが,今回扱うのはその中でもSpatial Filter (空間処理フィルタ)です.
空間処理フィルタとは,生の画像データの特徴をより表現するために,取り扱う画像の画素値とその周辺の画素値を用いて,新たな画像を計算する方法です.
空間処理フィルタとは,生の画像データの特徴をより表現するために,取り扱う画像の画素値とその周辺の画素値を用いて,新たな画像を計算する方法です.
ノイズ除去フィルタ
撮影した画像は,必ず何らかのノイズが含まれています.例えば,真っ白の紙を写真で撮ったとしても,画素値が均一になっているとは限りません.光の当たり方であったりとか,そもそも紙が均一ではなかっただとか.
このようなノイズを最低限抑える,というのがこのノイズ除去フィルタです.
このようなノイズを最低限抑える,というのがこのノイズ除去フィルタです.
Original 画像と Noised 画像
輪郭抽出フィルタ
画像の特徴量(例えばある部分の面積,輪郭線の長さ,曲率など)は,主に画像の画素値の境界付近にあることが多いです.画像の画素値の境界がくっきりと区別される場合ならよいのですが,現実ではそういうことはありません.このようなときに,画素値境界を見つける方法の一つが輪郭抽出フィルタです.
Original 画像とEdge画像
Original 画像にEdge 抽出フィルタを施しています.花びらや草などのEdgeが白く表現されていることがわかります.
ImageJ -> Image -> Type -> 8 bit
で白黒にしたあと,
ImageJ -> Process -> Find Edges
によって処理をしています.
ImageJ -> Image -> Type -> 8 bit
で白黒にしたあと,
ImageJ -> Process -> Find Edges
によって処理をしています.
実装に関して
Filter を知るため,Python で実装を行っていきましょう.
まずは以下のようなRectangle 画像を読み込みます.
まずは以下のようなRectangle 画像を読み込みます.
import numpy as np import dateutil import cv2, matplotlib import matplotlib.pyplot as plt # import rectangle.jpg. img = cv2.imread('./picture/rectangle.jpg') img= cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) plt.imshow(img, cmap='gray')
sample.py
これにノイズを付与してみます.
## Add Noise pix = len(img) noise = 5*np.random.randn(pix,pix) img_n = img + noise plt.imshow(img_n,cmap='gray')
sample.py
平滑化 フィルタ
平滑化フィルタを施してみます.これはノイズ除去に頻繁に用いられるフィルタです.
周辺の画素を重み付きで足し合わせて,新しい画像の画素値を計算します.
早速やってみましょう.
周辺の画素を重み付きで足し合わせて,新しい画像の画素値を計算します.
早速やってみましょう.
#Gaussian filter g = np.array([[1.0/16,1.0/4,1.0/16],[1.0/4,1.0/2,1.0/4],[1.0/16,1.0/4,1.0/16]]) # convolution img_g = np.zeros([pix, pix]) for n in range(2,pix): for m in range(2,pix): for gn in range(len(g)): for gm in range(len(g)): img_g[n,m] = img_g[n,m] + g[gn,gm]*img_n[n - gn, m- gm ] plt.imshow(img_g, cmap='gray')
sample.py
どうでしょう.確かにノイズが滑らかになっていることが確認できると思います.
なお,このグラフはImageJで線を引いたあと,
Analyze -> Plot Profile (Cmd + K でもOK) によって表示することができます.便利ですね.
Analyze -> Plot Profile (Cmd + K でもOK) によって表示することができます.便利ですね.
Edge 抽出フィルタ
今度はEdge抽出のフィルタを試してみましょう.簡単のため,Horizontal の線を抽出するフィルタを考えます.
これは以下のような行列をたたみ込むことと同じです.なお,fはもともとの画像の画素値です.
これは以下のような行列をたたみ込むことと同じです.なお,fはもともとの画像の画素値です.
\begin{align}
h = \begin{pmatrix}
1 & 1& 1\\
0 & 0 & 0\\
-1 & -1 & -1
\end{pmatrix}
\end{align}
\begin{align}
(f*h)[n,m] = \sum_{i=0}^{N-1} \sum_{j=0}^{M-1} f[n-i,m-j] h[i,j]
\end{align}
## Simple image processing # Horizontal edge detection h = np.array([[1,1,1],[0,0,0],[-1,-1,-1]]) # convolution img_h = np.zeros([pix, pix]) for n in range(2,pix): for m in range(2,pix): for hn in range(len(h)): for hm in range(len(h)): img_h[n,m] = img_h[n,m] + h[hn,hm]*img[n - hn, m- hm ] plt.imshow(img_h, cmap='gray')
sample.py
この Filter をたたみ込むと,もともと画素値が変化していないところは0の値になります.
画素値が大きく変化しているところのみを取り出すことが出来るのがこのFilterです.
画素値が大きく変化しているところのみを取り出すことが出来るのがこのFilterです.
最後に
ImageJ には多数のフィルタが搭載されており,簡単に画像処理を行うことができます.
ただ,内部でこのようなことが行われている,というのを知ることは非常に大事です.
ただ,内部でこのようなことが行われている,というのを知ることは非常に大事です.
なお,ノイズに関しては
ImageJ -> Process -> Noise -> Add Noise
によって加えました.