Python版OpenCVの微分フィルタ(Sobelなど)を利用する時の注意点についてソースコード付きで解説します。
【微分フィルタの注意点】負の値の処理について
微分フィルタで画像の勾配を計算すると、黒(0)→白(255)へ変化するときの微分値は正、その逆は負になります。
OpenCVの微分フィルタの関数(cv2.Sobelやfilter2Dなど)では、デフォルトのデータ型(8ビット符号なし整数)で使用すると0負の値は0になります。
つまり、負の勾配(白→黒)の情報を失ってしまいます。
負の勾配情報を残すには、データ型をfloat64(cv2.CV_64F)などに指定してやります。
【サンプルコード1】Python + OpenCV
実際にコードと実行結果を見てみましょう。
配列のデータ型をfloat64にすると、負の値が残っていることがわかります。
■10*10の入力画像(左)、負の値が0になった出力画像(中)、負の値を正にした出力画像(右)
ポイント
float64で微分画像の配列を取り出した後、次の1行で配列内の要素の絶対値を計算します。
np.uint8(np.abs(dst2))
これで負の値は正に変換され(例:-255 → +255)、データ型を符号なし8ビット整数に戻してからcv2.imwrite()で画像を出力します。
白→黒の勾配も出力画像に反映できます。
【サンプルコード2】Python + OpenCV + NumPy
NumPyで実装した場合は、データ型は畳み込み演算の計算過程で自動的にfloat64に変換されます。
そのため、先程のポイント
np.uint8(np.abs(dst2))
だけ実装すれば出力画像に負の勾配を反映させることが出来ます。
【おすすめ記事】
PythonでOpenCV入門 サンプル集
【Python】画像処理プログラミング入門
【画像処理入門】アルゴリズム&プログラミング
コメント