OpenCV 4.13.0
Open Source Computer Vision
読み込み中...
検索中...
見つかりません
🤖 AIによる機械翻訳(非公式) — これは OpenCV 4.13.0 公式リファレンス(英語)を AI (Claude) で自動翻訳したものです。訳に誤りを含む場合があります。正確な情報は 公式英語版(原文) を参照してください。
画像の勾配

目標

理論

OpenCVは3種類の勾配フィルタ(ハイパスフィルタ)、Sobel、Scharr、Laplacianを提供している。それぞれを順に見ていく。

1. SobelおよびScharr微分

Sobelオペレータはガウシアン平滑化と微分を組み合わせた演算であり、ノイズに対してより頑健である。微分を取る方向を縦か横か(それぞれ引数 yorder と xorder で)指定できる。また引数 ksize でカーネルのサイズも指定できる。ksize = -1 の場合、3x3のScharrフィルタが使われ、3x3のSobelフィルタよりも良い結果が得られる。使われるカーネルについてはドキュメントを参照のこと。

次の関数を使用する: cv.Sobel (src, dst, ddepth, dx, dy, ksize = 3, scale = 1, delta = 0, borderType = cv.BORDER_DEFAULT)

引数
src入力画像。
dstsrc と同じサイズ・同じチャンネル数の出力画像。
ddepth出力画像のビット深度 (cv.combinationsを参照)。8ビット入力画像の場合、微分結果が切り捨てられる。
dxx方向の微分の階数。
dyy方向の微分の階数。
ksize拡張Sobelカーネルのサイズ。1、3、5、または7でなければならない。
scale計算された微分値に対する省略可能なスケール係数。
delta結果を dst に格納する前に加算される省略可能なデルタ値。
borderTypeピクセルの外挿方法(cv.BorderTypes を参照)。

cv.Scharr (src, dst, ddepth, dx, dy, scale = 1, delta = 0, borderType = cv.BORDER_DEFAULT)

引数
src入力画像。
dstsrc と同じサイズ・同じチャンネル数の出力画像。
ddepth出力画像のビット深度 (cv.combinationsを参照)。
dxx方向の微分の階数。
dyy方向の微分の階数。
scale計算された微分値に対する省略可能なスケール係数。
delta結果を dst に格納する前に加算される省略可能なデルタ値。
borderTypeピクセルの外挿方法(cv.BorderTypes を参照)。

試してみよう

2. ラプラシアン微分

次の関係式で与えられる画像のラプラシアンを計算する。\(\Delta src = \frac{\partial ^2{src}}{\partial x^2} + \frac{\partial ^2{src}}{\partial y^2}\) ここで各微分はSobel微分を用いて求められる。ksize = 1 の場合、フィルタリングには次のカーネルが使われる:

\[kernel = \begin{bmatrix} 0 & 1 & 0 \\ 1 & -4 & 1 \\ 0 & 1 & 0 \end{bmatrix}\]

次の関数を使用する: cv.Laplacian (src, dst, ddepth, ksize = 1, scale = 1, delta = 0, borderType = cv.BORDER_DEFAULT)

引数
src入力画像。
dstsrc と同じサイズ・同じチャンネル数の出力画像。
ddepth出力画像のビット深度。
ksize2次微分フィルタの計算に用いるアパーチャサイズ。
scale計算されたラプラシアン値に対する省略可能なスケール係数。
delta結果を dst に格納する前に加算される省略可能なデルタ値。
borderTypeピクセルの外挿方法(cv.BorderTypes を参照)。

試してみよう

一つ重要な点!

前の例では、出力データ型は cv.CV_8U であった。しかしこれには少し問題がある。黒から白への遷移は正の傾き(正の値を持つ)として扱われるが、白から黒への遷移は負の傾き(負の値を持つ)として扱われる。そのため、データを cv.CV_8U に変換すると、すべての負の傾きはゼロになる。簡単に言えば、そのエッジを見逃すことになる。

両方のエッジを検出したい場合は、出力のデータ型を cv.CV_16S や cv.CV_64F などのより大きな型に保ち、その絶対値を取ってから cv.CV_8U に戻すのがよい。以下のコードは、水平方向のSobelフィルタについてこの手順と結果の違いを示している。

試してみよう