opencv-キャニー演算子とエッジ検出

エッジ検出

マット化のプロセスは、実際には画像内のインスタンス(人物など)のエッジを見つけるプロセスです。したがって、エッジ検出は、実際には画像内のインスタンスのエッジを検出するプロセスです。

ここで質問があります。マージンをどのように区別するのですか?

各インスタンスについて、そのエッジと周囲のピクセルの間のギャップは一般に比較的大きいことがわかりました。私たちのマットは、明らかなピクセルギャップに基づいてインスタンスのエッジを区別することです。

したがって、マットの基本は、画像のピクセルの明らかな変化です。画像のエッジは通常、画像上のピクセルに明らかな変化がある位置です。

次に、画像を使用して画像のピクセルを表します。ここに画像の説明を挿入します

画像のピクセル
画像のピクセルが大幅に変化する場合、画像の傾きが非常に大きくなります。つまり、傾きの絶対値が非常に大きくなります。これは、前に説明したいくつかの演算子の原則と一致しています。Sobel演算子は計算の位置です。
ここに画像の説明を挿入します

本のエッジ検出の定義は次のとおりです。

エッジ検出は、画像処理とコンピュータビジョンの基本的な問題です。エッジ検出の目的は、デジタル画像の明るさが明らかに変化するポイントを特定することです。画像属性の大幅な変更は、通常、重要なイベントと属性の変更を反映しています。

エッジ検出演算子

  • Sobel
  • シャー
  • ラプラス
  • キャニー

キャニーオペレーター

キャニーエッジ検出演算子は、1986年にジョンF.キャニーによって開発されたマルチレベルのエッジ検出アルゴリズムです。これには、次の5つのステップが含まれます。

  • 1.ガウスフィルタリングを適用して画像を滑らかにします。目的はノイズを除去することです

  • 2.灰色の変換

  • 3.画像、Sobel、Scharrの強度勾配を見つけます

  • 4.非最大抑制テクノロジーを適用して、エッジの誤検出を排除します(元々は検出されませんでしたが検出されました)

  • 5.二重しきい値法を適用して、可能な(潜在的な)境界を決定します

    • 5.1。ヒステリシス技術を使用して境界を追跡する

順番に紹介します

画像のスムージング

画像平滑化は、画像間のピクセルギャップを小さくし、より明白な特徴を持つエッジをより適切に抽出することです。したがって、画像平滑化の目的は、ノイズの一部除去することです。

画像のスムージング操作について考えてみましょう。隣接するピクセル間のギャップを小さくするだけではありませんか?それは画像のぼやけの影響ではありませんか?したがって、画像の平滑化操作は画像のぼかし操作を実行することであり、最も一般的に使用されるぼかし操作はガウスぼかしです。
ここに画像の説明を挿入します

グレースケール変換

cv :: cvtColor

画像勾配

キャニーのアルゴリズムの基本的な考え方は、画像内で最も強いグレー強度の変化の位置を見つけることです。いわゆる最強の変化とは、勾配の方向を指します。平滑化された画像の各ピクセルの勾配は、Sobel演算子(畳み込み演算)によって取得できます(opencvには、画像の各ピクセルのn次導関数を計算できるパッケージ化された関数があります)。まず、次のカーネルを使用して、それぞれ水平(x)方向と垂直(y)方向に沿った勾配G_XとG_Yを取得します。

SobelとScharr

非最大抑制

エッジ検出排除するために

このステップの目的は、ぼやけた境界をシャープにすることです。素人の言葉で言えば、各ピクセルの勾配強度の最大値保持され、他の値は削除されます。ピクセルごとに、次の操作を実行します。

  • a)勾配方向を次のいずれかの値に概算します。

                         (0,45,90,135,180,225,270,315)(即上下左右和45度方向)
    
  • b)ピクセルポイントを、その勾配方向の正および負の方向におけるピクセルポイントの勾配強度と比較します。

  • c)ピクセルの勾配強度が最大の場合は保持し、そうでない場合は抑制(削除、0に設定)

この概念をよりよく説明するために、次の図を見てください。図
ここに画像の説明を挿入します
の数字はピクセルの勾配強度を表し、矢印の方向は勾配の方向を表します。
例として、2行目の3番目のピクセルを取り上げます。勾配方向が上向きであるため、このポイント(7)の強度は、上下の2つのピクセル(5および4)の強度と比較されます。最高の強度、それは保持されます。

説明する別の例を次に示します。

ここに画像の説明を挿入します
勾配計算の前のステップで、xおよびy方向の勾配が取得されました。次に、この勾配に基づいて勾配の方向(角度)を取得できます。
ここに画像の説明を挿入します
たとえば、水平方向の勾配が最も変化し、次に方向をそれに垂直(最も遠い距離)に保ち、左側と右側の両方を削除します。

これは:

  • 0-22.5と157.5-180の2つの領域を水平方向と見なし、それを上部と下部のピクセル値と比較します。上部と下部のピクセル値がこのピクセルよりも小さい場合は、上部と下部の両方のピクセル値下位のピクセルは破棄されます。現在のピクセルは予約済みです。上位と下位のピクセル値がこのピクセルより大きい場合、現在のピクセルは破棄されます。

  • 67.5〜112.5の間隔では、水平と見なされ、現在のピクセルが左右の隣接するピクセルと比較されます。

  • 112.5〜157.5の間隔では、左上と右下の方向と見なされ、現在のピクセルが左下と右上の隣接するピクセルと比較されます。

  • 22.5〜67.5の間隔で、左下と右上の方向と見なされ、現在のピクセルが左上と右下の隣接するピクセルと比較されます。

ダブルスレッショルドの可能なエッジ

非最大抑制後も、画像にはまだ多くのノイズポイントがあります。

キャニーアルゴリズムでは、ダブルスレッショルドと呼ばれる手法が適用されます。つまり、上限しきい値と下限しきい値を設定します(通常はopencvで人間が指定します)

  • 画像内のピクセルがしきい値の上限しきい値よりも大きい場合は、境界(ストロングエッジと呼ばれます)と見なす必要があります。
  • しきい値の下限よりも小さい場合は、境界であってはなりません
  • 2つのうちの1つは候補(ウィークエッジと呼ばれます)と見なされ、しきい値を超えるピクセルに接続されている場合にのみ受け入れられます。それ以外の場合は破棄されます。このステップは、opencvでは境界追跡と呼ばれます

上限しきい値と下限しきい値は、高しきい値および低しきい値とも呼ばれます。

Cannyアルゴリズムは、高いしきい値を提案します。低いしきい値は2:1から3:1の間です。

下の写真は、テストパターンと写真を高:低5:1と3:2で処理した結果です。
ここに画像の説明を挿入します

境界追跡

輝度勾配が高いほどエッジである可能性が高く、低いしきい値を下回る輝度はエッジであってはなりません。
ただし、高しきい値と低しきい値の間の輝度勾配がエッジであるかどうかを定義する正確な値はないため、Cannyはヒステリシスしきい値を使用します。

ヒステリシスしきい値処理には、高しきい値と低しきい値の2つのしきい値が必要です。
画像の重要なエッジはすべて連続した曲線であると想定されているため、特定の曲線のぼやけた部分を追跡し、曲線をエッジとして構成しないノイズピクセルを回避できます。したがって、より大きなしきい値から始めます。これにより、より自信のある真のエッジが識別されます。前に取得した方向情報を使用して、これらの真のエッジから開始し、画像内のエッジ全体を追跡します。追跡するときは、開始点に戻るまで曲線のあいまいな部分を追跡できるように、より小さなしきい値を使用します。

これは:

高しきい値と低しきい値の間のエッジがしきい値を超えるピクセルに接続されている場合に受け入れられます

API

void Canny( 
    InputArray src, 
    OutputArray edges, 
    double threshold1, 
    double threshold2,
    int apertureSize = 3, 
    bool L2gradient = false
);

意味は次のとおりです

  • (1)InputArrayタイプのsrc、入力画像。
    シングルチャンネル画像である必要があります。

  • (2)OutputArrayタイプのエッジ、出力エッジ画像、シングルチャネル8ビット画像、そのサイズは画像と同じです。
    出力画像はグレースケール画像(実際にはブール画像)である必要があり、通常は背景を黒にします。

  • (3)ダブルタイプのしきい値1、ヒステリシスプロセスの最初のしきい値-低しきい値。
    下限しきい値、通常は上限しきい値の1/2または1/3

  • (4)ダブルタイプのしきい値2、ヒステリシスプロセスの2番目のしきい値-高しきい値。
    高いしきい値

  • (5)IntタイプのapertureSize、Sobel演算子のサイズ、通常は3x3、値は3です。

  • (6)ブール型のL2gradient。画像勾配の振幅を計算するためにより正確なL2を使用するか(L2gradient = true)、またはデフォルトのL1(L2gradient = false)を使用するかを示すフラグ。(注:ここでのL2は二乗和のルートであり、L1は下の図に示すように絶対値の合計です
    通常 L2の代わりにL1が使用され、デフォルトはfalseです。

ここに画像の説明を挿入します

コード

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;

Mat src, gray, dst;
Mat output;
int t1_value = 50;
int max_value = 255;

void Canny_demo(int,void*)
{
    
    

	blur(gray, gray, Size(3,3), Point(-1, -1), BORDER_DEFAULT);
	Canny(gray, output, t1_value, t1_value*2, 3, false);
	
	dst.create(src.size(), src.type());//将二值灰度图彩色化
	src.copyTo(dst, output);//将源图像像素拷贝到二值图为白色的对应像素
	imshow("bin img", output);
}

int main()
{
    
    


	namedWindow("input img", CV_WINDOW_AUTOSIZE);
	namedWindow("output img", CV_WINDOW_AUTOSIZE);

	src = imread("C:/Users/86176/Pictures/pics/lena(1).tiff");
	if (!src.data)
	{
    
    
		printf("fail to load img\n");
		return -1;
	}
	imshow("input img", src);

	cvtColor(src, gray, CV_BGR2GRAY);
	createTrackbar("Threshold Value:", "output img", &t1_value, max_value, Canny_demo);
	Canny_demo(0,0);

	imshow("output img", dst);

	waitKey(0);
	return 0;
}

結果

ここに画像の説明を挿入します
上限しきい値が低いほど、より多くの詳細が保持されます

おすすめ

転載: blog.csdn.net/qq_28258885/article/details/112909246