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. 平均化/ガウシアンフィルタとソーベルフィルタの併用

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

ソーベルフィルタ

平均化/ガウシアンフィルタとソーベルフィルタの併用

前のページではソーベルフィルタで画像のエッジを検出できることがわかりました.ここでは,平均化フィルタで処理したした画像をソーベルフィルタで処理したり,ガウシアンフィルタで処理した画像をソーベルフィルタで処理した場合にどのような結果になるかを確認しよう.これが分かれば畳み込みニューラルネットワークの中でどのような処理がされているかをイメージできるようになるでしょう.

まず,グレースケールに変換した画像を平均化フィルタで処理し,その後ソーベルフィルタで処理してみます.これによってソーベルフィルタだけでの処理結果よりも明確にエッジを検出できている様子が確認できるでしょう.この時,平均化フィルタのブロックサイズ (block_size) やソーベルフィルタの閾値を色々と変更して結果がどのように変わるかについて考察すると良いでしょう.

平均化フィルタとソーベルフィルタ
ink_img = plt.imread('ink.png') # RGBA形式の画像を読み込む
img = color.rgba2rgb(ink_img) # RGB形式に変換
gray_img = color.rgb2gray(img) # グレースケールに変換
mean_img = filters.threshold_local(gray_img, method='mean', block_size=9) # 平均化フィルタ
sobel_result = filters.sobel(mean_img) # ソーベルフィルタ
show(gray_img, file_name='ink_gray.png')
show(mean_img, file_name='mean_img.png')
show(sobel_result, file_name="mean_sobel_result.png")
show(sobel_result < 0.04, file_name='mean_sobel_edge.png')
グレースケール画像
filters_43_1_ink_gray.png
平均化フィルタ
filters_43_2_mean_img.png
ソーベルフィルタ
filters_43_3_mean_sobel_result.png
検出されたエッジ
filters_43_4_mean_sobel_edge.png

次は,グレースケールに変換した画像をガウシアンフィルタで処理し,その後ソーベルフィルタで処理してみます.ここでも,ガウシアンフィルタのシグマ (sigma) やソーベルフィルタの閾値を色々と変更して結果がどのように変わるかについて考察すると良いでしょう.

ガウシアンフィルタとソーベルフィルタ
ink_img = plt.imread('ink.png') # RGBA形式の画像を読み込む
img = color.rgba2rgb(ink_img) # RGB形式に変換
gray_img = color.rgb2gray(img) # グレースケールに変換
gauss_img = filters.gaussian(gray_img, sigma=3)# ガウシアンフィルタ
sobel_result = filters.sobel(gauss_img) # ソーベルフィルタ
show(gray_img, file_name='ink_gray.png')
show(gauss_img, file_name='gauss_img.png')
show(sobel_result, file_name="gauss_sobel_result.png")
show(sobel_result < 0.04, file_name='gauss_sobel_edge.png')
グレースケール画像
  filters_43_1_ink_gray.png
ガウシアンフィルタ
filters_43_5_gauss_img.png
ソーベルフィルタ
filters_43_6_gauss_sobel_result.png
検出されたエッジ
filters_43_7_gauss_sobel_edge.png

平均化フィルタのブロックサイズとソーベルフィルタの閾値を色々変更してどのような結果になるかグラフにまとめてみます.

平均化フィルタとソーベルフィルタ
ink_img = plt.imread('ink.png') # RGBA形式の画像を読み込む
img = color.rgba2rgb(ink_img) # RGB形式に変換
gray_img = color.rgb2gray(img) # グレースケールに変換
blocks = [11, 9, 7, 5]
thresholds = [0.010, 0.020, 0.030, 0.040, 0.050, 0.080]
rows = len(blocks)
cols = len(thresholds)
figsize = (12, 8)

fig, ax = plt.subplots(
    rows,
    cols,
    figsize=figsize,
    sharex=True, sharey=True,  # 軸を共有する
    constrained_layout=True, # Subplot 間の間隔を改善
)

for r, b in enumerate(blocks):
    for c, t in enumerate(thresholds):
        mean_img = filters.threshold_local(gray_img, method='mean', block_size=b) # 平均化フィルタ
        sobel_result = filters.sobel(mean_img) # ソーベルフィルタ
        ax[r][c].imshow(sobel_result<t, cmap=plt.cm.gray)
fig.supxlabel('threshold', fontsize='x-large') # 全体の横軸ラベル
fig.supylabel('block size', fontsize='x-large') # 全体の縦軸ラベル
plt.savefig('filters_block_threshold.png', dpi=300, facecolor='white')
plt.show()
平均化フィルタとソーベルフィルタ
filters_block_threshold.png

ガウシアンフィルタのシグマとソーベルフィルタの閾値を色々変更してどのような結果になるかグラフにまとめてみます.

ガウシアンフィルタとソーベルフィルタ
ink_img = plt.imread('ink.png') # RGBA形式の画像を読み込む
img = color.rgba2rgb(ink_img) # RGB形式に変換
gray_img = color.rgb2gray(img) # グレースケールに変換
sigmas = [6, 5, 4, 2]
thresholds = [0.010, 0.015, 0.020, 0.025, 0.030, 0.040]
rows = len(sigmas)
cols = len(thresholds)
figsize = (12, 8)

fig, ax = plt.subplots(
    rows,
    cols,
    figsize=figsize,
    sharex=True, sharey=True,  # 軸を共有する
    constrained_layout=True, # Subplot 間の間隔を改善
)

for r, s in enumerate(sigmas):
    for c, t in enumerate(thresholds):
        gauss_img = filters.gaussian(gray_img, sigma=s) # ガウシアンフィルタ
        sobel_result = filters.sobel(gauss_img) # ソーベルフィルタ
        ax[r][c].imshow(sobel_result<t, cmap=plt.cm.gray)
fig.supxlabel('threshold', fontsize='x-large') # 全体の横軸ラベル
fig.supylabel('sigma', fontsize='x-large') # 全体の縦軸ラベル
plt.savefig('filters_sigma_threshold.png', dpi=300, facecolor='white')
plt.show()
ガウシアンフィルタとソーベルフィルタ
filters_sigma_threshold.png

目次に戻る