Programming Computer Vision with Python(学習ノート6)


エッジ検出(edge detection)は最も重要な画像処理技術の一つであり、画像エッジ検出はデータ量を大幅に減少させ、関連しないと考えられる情報を除去し、画像の重要な構造属性を保持し、後続の画像理解方法に基礎を提供する.
エッジ検出方法
視覚的に見ると、画像中のエッジの輝度は周囲より強く、例えば垂直方向のエッジに対しては、水平方向の画素輝度の1次微分(導関数)によって輝度変化を増強することができる.従って、エッジ検出は、画像水平方向と垂直方向の両方の輝度変化勾配を計算することによって、輝度変化の振幅と方向を得ることができる.
IxとIyはそれぞれ2方向の輝度勾配ベクトルであり、2つのベクトルのモードは勾配振幅である.
2つのベクトルの角度は変化方向です.
単純な輝度変化計算は、例えば水平方向のある画素について、その左右の隣接画素の差を輝度変化の推定とし、垂直方向類推を用いて画像のエッジを推定することもできる.エッジ補強画像と呼ばれるすべてのエッジ補強画素からなる新しい画像.エッジ増強画像は群演算により得ることができる.
クラスタ演算と演算子
原画像を画素演算して新しい画像を得る場合、新しい画像の各画素点は、原画像の周囲点からあるアルゴリズムに基づいて計算される必要があり、この演算を群演算と呼ぶ.群演算は通常、画像とテンプレートのボリューム形式で表され、ここでいうテンプレートは、周囲の画素がどのように総合的に計算されるかを決定するアルゴリズムであり、演算子とも呼ばれる.前回のノートで紹介したガウスファジイはガウス平均演算子を紹介し,演算子は対応する画素の重み値や係数を示す小さな行列の形で表された.次の図面は理解に役立ちます.
図中のconvolution maskはテンプレートまたは演算子を指し、移動するマスク層のように元の画像の上にマスクされ、マスク部分の各画素は、それぞれテンプレートに対応する位置の重み値に乗じ、最後にすべてテンプレートの中心点に対応する元の画像位置の新しい画素値として加算される.
ロバーツ交差演算子
上記差分法を用いて輝度変化勾配が実は1次微分の近似値であることを導いた.差分は、座標軸方向に沿った2つの画素を用いて計算してもよいし、対角画素を用いて計算してもよい.Roberts交差演算子はこの演算子に属し,最も古いエッジ検出演算子の一つである.Roberts交差演算子はエッジを正確に位置決めできるが,これらは輝度増強位置の基本演算子のみを検出し,ノイズに敏感であり,ノイズをエッジと誤認しやすい.
Prewitt演算子
輝度変化を計算する前に、周囲の画素を平均処理することでノイズを一定に抑制するが、エッジにぼやけが生じ、エッジの位置決めがRoberts演算子に及ばない.
Sobel演算子Sobelは比較的多くの演算子を適用しており,ノイズを抑制するために平均処理も考慮しているが,一方の軸でのみ平均処理を行い,他方の軸で重み値を大きくして輝度変化を計算するテクニックである.このようにして得られた効果は前の2つよりもっと良い.Sobel演算子を用いて得られるエッジはCanny演算子ほど正確ではないが,実際の応用ではCannyよりも効率が高く,多くの実際の応用の場合に第一選択となり,特に効率に対する要求が高く,細いテクスチャにあまり関心がない場合である.
PrewittとSobelは計算導関数法にいくつかの欠陥がある:フィルタのスケールは画像解像度の変化に伴って変化する必要がある.画像ノイズの面でより安定であり,任意のスケールで導関数を計算するためにGauss導関数フィルタを用いることができる.前のノートで使ったガウスファジイフィルタ:scipy.ndimage.filters.gaussian_filterはまた、orderパラメータによって指定された1次、2次、および3次導関数を計算するために使用することができ、orderは以下の値の組合せをとることができる.
  • 0:ガウス核を用いて畳み込む
  • を表す
  • 1:1次Gauss導関数
  • を用いる
  • 2:2次導関数
  • を用いる
  • 3:3次導関数
  • を用いる
    たとえばorder=(1,0)は,入力データの各次元に対して,まず1次導関数でボリューム化し,その後Gaussコアとボリューム化することを表す.
    scipy.ndimageはGaussフィルタに加えてPrewittフィルタとSobelフィルタも提供されており,以下ではこの3つの方法を用いてエッジ増強画像を生成する.
    from PIL import Image
    import numpy as np
    from scipy.ndimage import filters
    import matplotlib.pyplot as plt
    
    im = np.array(Image.open('Valve_original.png').convert('L'))
    
    #prewitt
    pwimx = np.zeros(im.shape)
    filters.prewitt(im, 1, pwimx)
    pwimy = np.zeros(im.shape)
    filters.prewitt(im, 0, pwimy)
    pwmagnitude = np.sqrt(pwimx ** 2 + pwimy ** 2) #        , :np.hypot(pwimx, pwimy)
    
    #sobel
    sbimx = np.zeros(im.shape)
    filters.sobel(im, 1, sbimx)
    sbimy = np.zeros(im.shape)
    filters.sobel(im, 0, sbimy)
    sbmagnitude = np.sqrt(sbimx ** 2 + sbimy ** 2)
    
    #gaussian
    gsimx = np.zeros(im.shape)
    filters.gaussian_filter(input = im, sigma = 1, order = (0,1), output = gsimx)
    gsimy = np.zeros(im.shape)
    filters.gaussian_filter(input = im, sigma = 1, order = (1,0), output = gsimy)
    gsmagnitude = np.sqrt(gsimx ** 2 + gsimy ** 2)
    
    plt.gray()
    
    index = 221
    plt.subplot(index)
    plt.imshow(im)
    plt.title('original')
    plt.axis('off')
    
    plt.subplot(index + 1)
    plt.imshow(pwmagnitude)
    plt.title("prewitt")
    plt.axis('off')
    
    plt.subplot(index + 2)
    plt.imshow(sbmagnitude)
    plt.title("sobel")
    plt.axis('off')
    
    plt.subplot(index + 3)
    plt.imshow(gsmagnitude)
    plt.title("gaussian")
    plt.axis('off')
    
    plt.show()

    効果図は以下の通りです.
    上の効果図だけではPrewittとSobelの違いがわかりにくく、ノイズの大きい画像で区別できるかもしれません.
    Canny演算子
    Cannyは現在最も厳密なエッジ検出アルゴリズムを定義しており、Cannelで計算したエッジは非常に細く、接続性がよく、ノイズに対する抵抗作用があり、同時に正確なエッジ位置決めを持っている.計算プロセスは、上記の方法に比べて複雑です.
  • まずGaussフィルタを使用して画像を平滑化し、いくつかのノイズを除去すると同時に、いくつかの極めて細いエッジも失われる.
  • 画像の輝度変化勾配
  • を算出する.
  • 非極大値抑制(non-maximum suppression)(エッジ微細化技術)を用いて勾配変化幅
  • を減少する.
  • 二重閾値検出エッジ
  • を用いる.
  • エッジ接続検出
  • 次の図はウィキペディアから見つかりました.エッジ効果は上よりずっと細いことがわかります.
    scipy.ndimageでは、Cannyフィルタは提供されていませんが、scikit-image(skimageと略称)という画像処理ライブラリには、Canny関数と例があります.
    以上紹介したのは1次微分演算子で、以下は2次微分演算子です.
    Laplacian演算子
    Laplacian演算子は2次微分のエッジ検出に基づいており,2次微分は1次微分よりもエッジが細く,2次微分処理は詳細に強い応答を示すため,Laplacianを適用して生成したエッジ増強画像は元の画像の多い背景詳細を保持している.従って、Laplacian演算子は、画像シャープ化処理およびスポット検出にも用いることができる.
    Log演算子
    これはGaussフィルタリングとLaplacianの2次導関数を結合した演算子である.なお,上述したCannyアルゴリズムもLoGを参照しており,エッジ検出の前に,まず元の画像にGaussフィルタリングを適用して画像を平滑化する.
    その他
    エッジ検出アルゴリズムは主に画像強度の1次と2次導関数に基づいているが,導関数の計算はノイズに敏感であるため,ノイズに関連するエッジ検出器の性能を改善するためにフィルタを用いなければならない.多くのフィルタはノイズを低減するとともに細いエッジの損失をもたらすことを指摘する必要があり、現在も異方性拡散と呼ばれる平滑化技術が存在し、平滑化がエッジに作用しないため、使用時に折衷選択が必要である.
    また、画素の輝度導関数を算出した後、次のステップは、エッジ位置がどこであるかを決定するための閾値を与えることである.閾値が低いほど検出可能なエッジ線が多くなり、結果としてピクチャノイズの影響を受けやすくなる.これに対して、高いしきい値では、細いまたは短いエッジセグメントが失われます.したがって,閾値の選択は実際の応用と結びつけて考えると検出結果がより良くなる.現在,背景に基づいて閾値を自動的に計算するアルゴリズムもある.
    小結
    次の節では、画像処理の形態学的基本演算について説明します.他のノートを見ることもできます.
    パラメータ資料
  • 画像処理常用エッジ検出演算子まとめ
  • A Comparison of various Edge Detection Techniques used in Image Processing
  • Image Filtering & Edge Detection