OpenCV のエッジ検出(Sobel)について

2021年5月3日

はじめに

OpenCV のsobelを使ったエッジ検出処理ついて調べたことをまとめた。

とりあえず関数を試してみたい方

実験用プログラム OpenCV_test の GitHubリポジトリ
URL
https://github.com/iryachi/OpenCV_test
実行ファイルだけ
https://github.com/iryachi/OpenCV_test/releases
使い方
https://iryachi.stars.ne.jp/opencv_test_imple/

Sobelフィルタとは

畳み込みを利用して色の変化度合いを可視化するフィルタ。色が急に変化する部分が強調される。
平滑化フィルタ(ガウシアン)の要素も入っているので、ノイズに少し対応できる。
縦方向と横方向それぞれにパラメータが設定できるので、縦線だけ強調したいなどの用途に向いている。
畳み込みフィルタについては以下参照
https://iryachi.stars.ne.jp/?p=90
畳み込みフィルタの基本となる filter2D は以下
https://iryachi.stars.ne.jp/opencv-filter2d/

Sobel関数について

void cv::Sobel (InputArray src,
OutputArray dst,
int ddepth,
int dx,
int dy,
int ksize = 3,
double scale = 1,
double delta = 0,
int borderType )

引数

srcInputArray入力画像グレースケールの画像
dstOutputArray出力画像グレースケールの画像 フォーマットはddepth による。
ddepthint出力画像深度出力画像のビット深度。
負数の場合、入力と同じビット深度。 CV_16S, CV_32F, CV_64F
dxintx方向微分係数x軸方向の微分回数。
dyinty方向微分係数y軸方向の微分回数。
ksizeintカーネルサイズフィルタのサイズ 1, 3, 5, 7
-1 の時 Scharr フィルタになる。
scaledoubleスケーリング係数処理後の画素値に乗算する値。
deltadouble加算係数処理後の画素値に加算する値。
borderTypeint境界外処理方法cv::BorderTypes
画面 もしくは roi の境界処理をどうするか。(後述)

パラメータ borderTypeについて

BORDER_DEFAULT画像境界で反射。
BORDER_CONSTANTある一定値を使用。
BORDER_REPLICATE境界の値を使用。
BORDER_REFLECTBORDER_DEFAULT 同様
BORDER_REFLECT_101BORDER_DEFAULT 同様
BORDER_REFLECT101BORDER_DEFAULT 同様
BORDER_TRANSPARENT元画像を変更しない
BORDER_WRAP画像自身を繰り返し (未対応)
BORDER_ISOLATED何もしない。

詳しくは下記参照
https://iryachi.stars.ne.jp/opencv_bordertype/

カーネル

ksize = 3 の時のカーネルは以下になる。(たぶん)

Scharr フィルタのアパーチャ (ksize = -1 の時)

処理例

元画像

左: dx = 1, dy = 0, ksize=3 | 右: dx = 2, dy = 0, ksize=3
左: dx = 0, dy = 1, ksize=3 | 右: dx = 0, dy = 2, ksize=3
左: dx = 1, dy = 1, ksize=3 | 右: dx = 2, dy = 2, ksize=3

おわりに

エッジ検出フィルタは実際に処理したい画像を用いてやってみないとどれがいいかわかりにくい。
Canny や Laplacian とかも比較検討してみるといいと思う。