Python版OpenCVでラプラシアンフィルタを実装し、画像の輪郭を検出する方法をソースコード付きで解説します。
ラプラシアンフィルタで輪郭検出
ラプラシアンフィルタ(Laplacian filter)は、輪郭を検出できる空間フィルタです。
ラプラシアンフィルタの原理と計算式については下記事で紹介しています。

今回は、以下の3通りの方法でラプラシアンフィルタの処理を実装する方法について解説します。
方法①・・・cv2.Laplacianで実装
方法②・・・cv2.filter2Dで実装
方法③・・・NumPyでアルゴリズムを書いて実装(原理の理解を深めるため)
また、輪郭画像を大津の手法で2値化する方法や、前処理(ガウシアンフィルタでノイズ除去)を行う方法も紹介します。
解説動画
サンプルコード①cv2.Laplacianで実装
以下は、cv2.Laplacianで簡単に実装したときのサンプルプログラムです。
コード解説
cv2.Laplacianは、ラプラシアンフィルターで画像の輪郭検出をします。
dst = cv2.Laplacian(src, ddepth, ksize)
パラメータ | 説明 |
---|---|
src | 入力画像。通常はグレースケール画像を指定します。 |
ddepth | 出力画像のビット深度。例えば、cv2.CV_8U、cv2.CV_16S、cv2.CV_32Fなど。 |
ksize | ラプラシアンカーネルのサイズ。通常は1、3、5、7などの奇数を指定します。 |
サンプルコード②cv2.filter2Dで実装
以下は、cv2.filter2Dで実装したときのサンプルプログラムです。
コード解説
cv2.filter2Dは、画像に任意のカーネルでフィルター処理を適用します。
dst = cv2.filter2D(src, ddepth, kernel)
パラメータ | 説明 |
---|---|
src | 入力画像。通常はグレースケール画像またはカラー画像を指定します。 |
ddepth | 出力画像のビット深度。例えば、cv2.CV_8U、cv2.CV_16S、cv2.CV_32Fなど。-1を指定すると、入力画像と同じビット深度が使用されます。 |
kernel | NumPy配列でフィルタのカーネルを指定します。 |
サンプルコード③ アルゴリズムを書いて実装
以下は、アルゴリズムを書いて実装したときのサンプルプログラムです。
実行結果
サンプルプログラムの実行結果です。
■入力画像(左)と出力画像(右)
コード解説
filter2d
関数は、入力画像src
に対してカーネルkernel
を使用して空間フィルタリングを行います。詳細は以下ページで解説しています。

サンプルコード④ 輪郭画像を大津の手法で2値化
以下は、ラプラシアンフィルタを掛けて作成した輪郭画像を大津の手法で2値化するサンプルプログラムです。
輪郭と輪郭以外をはっきりさせることができます。
実行結果
サンプルプログラムの実行結果です。輪郭と輪郭以外の部分をはっきりさせることができます。
■入力画像(左)と出力画像(右)
サンプルコード⑤ 前処理(ガウシアンフィルタでノイズ除去)を追加
以下は、入力画像に対して前処理(ガウシアンフィルタを掛けてノイズを除去)してからラプラシアンフィルタで輪郭画像を作成し、2値化するサンプルプログラムです。
実行結果
サンプルプログラムの実行結果です。
■入力画像(左)と出力画像(右)
以下は前処理なし(サンプルコード④)と前処理あり(今回ガウシアンフィルタを追加)で出力画像の目の部分を拡大して比較したものです。
前処理することでノイズの影響を抑えることができています。
■前処理なしの一部分(左)と前処理ありの一部分(右)
ラプラシアンフィルタは2回微分を行うため、一次微分を利用するフィルタ(ソーベルフィルタなど)と比べて、画素値の変化が激しい箇所を輪郭として強調できます。つまり、画素値の変化が緩やかな箇所(ボケているところ)は輪郭としてほとんど強調しません。一方、2回微分により画素値の変化が激しい箇所を強調するため、輪郭だけでなくノイズも強調しやすく、ノイズの影響を受けやすいです。そのため、メディアンフィルタやガウシアンフィルタ等の平滑化フィルタで前処理してノイズを抑えることが重要です。
関連ページ

コメント