Python版OpenCVでPrewittフィルタを実装し、輪郭検出する方法をソースコード付きで解説します。
Prewittフィルタで輪郭検出
Prewitt Filter(プレヴィットフィルタ)は、画像の輪郭検出用フィルタの1つです。このフィルタは、一次微分フィルタに対して平滑化処理を加え、ノイズに対して強くなるように改良されたものです。原理と計算式については下記事で紹介しています。

今回は、Prewittフィルタの処理を以下の2通りの方法で実装します。
方法①・・・cv2.filter2Dで実装
方法②・・・NumPyでアルゴリズムを書いて実装(原理の理解を深めるため)
サンプルコード① cv2.filter2Dで実装
cv2.filter2Dで実装した場合のサンプルプログラムのソースコードです。
実行結果
サンプルプログラムの実行結果です。
■入力画像(左)と出力画像(右)
kernel_x
は水平方向の輪郭(輝度変化)を検出するためのカーネルです。
kernel_x = np.array([[-1, 0, 1],
[-1, 0, 1],
[-1, 0, 1]])
kernel_y
は垂直方向の輪郭(輝度変化)を検出するためのカーネルです。
kernel_y = np.array([[-1, -1, -1],
[0, 0, 0],
[1, 1, 1]])
cv.filter2D
を使用して、入力画像gray
に対して一次微分フィルタを適用します。gray_x
は水平方向の輪郭を検出した画像です。gray_y
は垂直方向の輪郭を強調した画像です。
gray_x = cv.filter2D(gray, cv.CV_64F, kernel_x)
gray_y = cv.filter2D(gray, cv.CV_64F, kernel_y)
水平方向と垂直方向の輪郭画像を合成して、最終的な輪郭画像dst
を求めます。輪郭画像の各画素値は、水平方向と垂直方向の勾配の二乗和の平方根から求めます。
dst = np.sqrt(gray_x ** 2 + gray_y ** 2)
サンプルコード② NumPyで実装
NumPyで実装した場合のサンプルプログラムのソースコードです。
実行結果
サンプルプログラムの実行結果です。
■入力画像(左)と出力画像(右)
コード解説
filter2d
関数は、入力画像src
に対してカーネルkernel
を使用して空間フィルタリングを行います。詳細は以下ページで解説しています。

注意点
先程の出力画像は正の勾配(黒→白)のみ白色になっています。
負の勾配(白→黒)も白色に塗って出力する方法は下記ページで紹介しています。

関連ページ
Python版OpenCV全般については以下ページで解説しています。

コメント