上記で提案したように、Matlab Cannyエッジ検出器は、「ドキュメントに記載されているように」「ガウスフィルターの導関数」を使用して勾配を計算します。言い換えると、Matlabは画像のガウスぼかしを行い、その平滑化された画像の勾配を検出します...すべて1つのファンシーフィルターを使用します。[詳細を知りたい場合は、edit edge
Andreyの提案どおりに入力してから、smoothGradient()
関数までスクロールしてください。]
ぼかし操作は、画像に存在するノイズの量を大幅に減らし、多くの偽のエッジを取り除き、良いものを残します。
残念ながら、OpenCV Canny関数では、関数パラメーターを介して、使用するフィルターカーネルを変更できません。しかしながら。最初に入力画像をぼかしてから、このぼかした画像をキャニー関数に渡すことで、同じ結果を生成できます。
これにより、結果のエッジマップが大幅にクリーンアップされます。入力画像をぼかすために、私はOpenCVのGaussianBlur()
関数をで個人的に使用していsigmaX=2
ます。これは、Matlabのデフォルトのシグマを模倣しています。最適なぼかしカーネルサイズは場合によって異なりますが、Matlabではを使用して計算さfilterLength = 8*ceil(sigma);
れるため、シグマ2の場合、カーネルサイズは(16,16)
ガウスぼかしフィルターとソーベルフィルターはどちらも線形であるため、ぼやけた入力画像をOpenCV Canny()
関数に渡すことは、この擬似コードで示されているように、重ね合わせの原理によりMatlabが行うことと数学的に同等です(注:*
はたたみ込み演算子です)。
// The Matlab method: the sobel and blur operations are combined into
// a single filter, and that filter is then convolved with the image
matlabFancyFilter = (sobel * blur);
gradient = matlabFancyFilter * image;
// Equivalent method: image is first convolved with the blur filter, and
// then convolved with the sobel filter.
gradient = sobel * (blur * image); // image is filtered twice
ここには、C ++を使用してこれを行う方法を示すOpenCV Cannyチュートリアルがあります。私はpythonの人なので、ここに私がやっていることがあります:
smoothedInput = cv2.GaussianBlur(image, (7,7), 2);
edges = cv2.Canny(smoothedInput, 25, 50);