Python入門トップページ


目次

  1. scikit-image のインストール
  2. Matplotlib による画像の表示
  3. 表示関数の定義
  4. RGBA から RGB への変換
  5. グレースケールをイメージする
  6. RGB からグレースケールへの変換
    1. RGB 平均
    2. ITU-R Rec BT.602
    3. Contemporary CRT phosphors (Rec 709)
    4. 3種類の比較
    5. scikit-image の rgb2gray 関数
  7. 平均化フィルタ
    1. 平均化フィルタの自作
    2. 平均化フィルタの一般化
    3. scikit-image の平均化フィルタ関数
  8. ガウシアンフィルタ
  9. バイラテラルフィルタ
  10. ランダムノイズとフィルタ
  11. ソーベルフィルタ
    1. ソーベルフィルタの自作
    2. scikit-image の sobel 関数
    3. 平均化/ガウシアンフィルタとソーベルフィルタの併用

画像フィルタの作成と利用

ソーベルフィルタ

ソーベルフィルタは画像から物体のエッジを検出するフィルタのひとつです.これは横方向および縦方向での色の変化に着目し,変化の強度がしきい値以上になる点をエッジと判断します.ソーベルフィルタのカーネルは次のようになります.

\begin{equation} \boldsymbol{F}_x = \left( \begin{array}{ccc} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{array} \right), \end{equation}
\begin{equation} \boldsymbol{F}_y = \left( \begin{array}{ccc} -1 & -2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1 \end{array} \right) \end{equation}

上のカーネル \(\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)
オリジナル
filters_20_gray.png

次に,ソーベルフィルタのカーネル関数を定義します.

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
filters_41_sobel_1x.png

同様に,グレースケール画像にカーネル \(\boldsymbol{F}_y\) を適用すると,次のようになります.

sobel_imgy = sobel_fy(gray_img)
show(sobel_imgy)
Fy
filters_41_sobel_2y.png

カーネル \(\boldsymbol{F}_x\) を適用した結果にさらに カーネル \(\boldsymbol{F}_y\) を適用すると,次のような結果になります.

sobel_img = sobel_fy(sobel_imgx)
show(sobel_img)
Fx*Fy
filters_41_sobel_3.png

上で得られた結果に対して,しきい値を 0.4 としてエッジ検出を行います.カーネル \(\boldsymbol{F}_x\) は横方向の色の変化に着目していることから,結果として縦向きのエッジが検出できています.

th = 0.4
show(sobel_imgx < th)
Fx
filters_41_sobel_4x.png

カーネル \(\boldsymbol{F}_y\) は縦方向の色の変化に着目しています.したがって,横向きのエッジが検出できています.

show(sobel_imgy < th)
Fy
filters_41_sobel_5y.png

ふたつのカーネル \(\boldsymbol{F}_x\), \(\boldsymbol{F}_y\) を組み合わせることでエッジを検出できていることがわかります.

show(sobel_img < th)
Fx*Fy
filters_41_sobel_6.png

目次に戻る