ソーベルフィルタは画像から物体のエッジを検出するフィルタのひとつです.これは横方向および縦方向での色の変化に着目し,変化の強度がしきい値以上になる点をエッジと判断します.ソーベルフィルタのカーネルは次のようになります.
上のカーネル \(\boldsymbol{F}_x\) は横方向の色の変化に着目するカーネルで,\(\boldsymbol{F}_y\) は縦方向のカーネルです.
scikit-image で提供されるソーベルフィルタを利用する前に,自身でソーベルフィルタのコードを記述してみよう.まず,「表示関数の定義」ページを参照し,ライブラリのインポートと関数の定義を実行したあと,画像ファイルをグレースケールに変換して表示します.
ink_img = plt.imread('ink.png')
img = color.rgba2rgb(ink_img)
gray_img = color.rgb2gray(img)
show(gray_img)
オリジナル
次に,ソーベルフィルタのカーネル関数を定義します.
def sobel_fx(img):
h = gray_img.shape[0]
w = gray_img.shape[1]
filtered_img = np.copy(img)
for j in range(1, h-1):
for i in range(1, w-1):
sobelx = -1 * img[j-1, i-1]
sobelx += -2 * img[j, i-1]
sobelx += -1 * img[j+1, i-1]
sobelx += 1 * img[j-1, i+1]
sobelx += 2 * img[j, i+1]
sobelx += 1 * img[j+1, i+1]
filtered_img[j,i] =sobelx
return filtered_img
def sobel_fy(img):
h = gray_img.shape[0]
w = gray_img.shape[1]
filtered_img = np.copy(img)
for j in range(1, h-1):
for i in range(1, w-1):
sobely = -1 * img[j-1, i-1]
sobely += -2 * img[j-1, i]
sobely += -1 * img[j-1, i+1]
sobely += 1 * img[j+1, i-1]
sobely += 2 * img[j+1, i]
sobely += 1 * img[j+1, i+1]
filtered_img[j,i] =sobely
return filtered_img
グレースケール画像にカーネル \(\boldsymbol{F}_x\) を適用すると,次のような結果が得られます.
sobel_imgx = sobel_fx(gray_img)
show(sobel_imgx)
Fx
同様に,グレースケール画像にカーネル \(\boldsymbol{F}_y\) を適用すると,次のようになります.
sobel_imgy = sobel_fy(gray_img)
show(sobel_imgy)
Fy
カーネル \(\boldsymbol{F}_x\) を適用した結果にさらに カーネル \(\boldsymbol{F}_y\) を適用すると,次のような結果になります.
sobel_img = sobel_fy(sobel_imgx)
show(sobel_img)
Fx*Fy
上で得られた結果に対して,しきい値を 0.4 としてエッジ検出を行います.カーネル \(\boldsymbol{F}_x\) は横方向の色の変化に着目していることから,結果として縦向きのエッジが検出できています.
th = 0.4
show(sobel_imgx < th)
Fx
カーネル \(\boldsymbol{F}_y\) は縦方向の色の変化に着目しています.したがって,横向きのエッジが検出できています.
show(sobel_imgy < th)
Fy
ふたつのカーネル \(\boldsymbol{F}_x\), \(\boldsymbol{F}_y\) を組み合わせることでエッジを検出できていることがわかります.
show(sobel_img < th)
Fx*Fy