OpenCV學習筆記(十三)邊緣檢測

2021-07-25 09:44:58 字數 3168 閱讀 8251

邊緣檢測:

邊緣檢測運算元有很多,sobel、laplace、prewitt、canny、marr-hildresh。

sobel運算元:

sobel運算元是主要用於邊緣檢測的離散微分運算元,它結合了高斯平滑和微分求導,用於計算影象灰度函式的近似梯度。

void sobel

(inputarray src, outputarray dst, int ddepth, int xorder, int yorder, int ksize=3, double scale=1, double delta=0, int bordertype=border_default )

一般情況下,都是使用ksize*ksize核心計算導數的。當ksize=1時,往往使用3x1或者1x3的核心。

程式實現:

#include #include #include #include using namespace cv;

using namespace std;

int main()

原圖:

效果圖:

laplacian運算元:

laplacian運算元是二階微分運算元。凡是二階運算元對雜訊都比較敏感,在使用前要進行濾波去噪。

讓一幅影象減去它的laplacian運算元可以增強對比度。

laplacian函式:

void 

laplacian

(inputarray src, outputarray dst, int ddepth, int ksize=1, double scale=1, double delta=0, intbordertype=border_default )

當ksize=1時,laplacian()函式採用3x3的孔徑。

例項程式實現:

#include #include #include #include using namespace cv;

using namespace std;

int main()

效果圖:

prewitt運算元:

prewitt運算元是一階邊緣檢測運算元,該運算元對雜訊有抑制作用,不用進行濾波去噪。和sobel運算元相似,都是在影象空間利用兩個方向模板與影象進行領域卷積來完成的,分別對水平與垂直方向邊緣進行檢測。

prewitt運算元定位精度不如sobel運算元,在真正的使用中,一般不會用到這個運算元,效果較差。

改進邊緣檢測運算元--canny運算元:

canny運算元檢測原理是通過影象訊號函式的極大值來判定影象的邊緣畫素點。邊緣檢測的演算法主演是基於影象強度的一階和二階微分操作,但導數通常對雜訊很敏感,邊緣檢測演算法常常需要根據影象源的資料進行預處理操作,因此必須採用濾波器來改善與雜訊有關的邊緣檢測的效能。在進行canny運算元邊緣檢測前,應當先對原始資料與高斯模板進行卷積操作,得到的影象與原影象相比有些模糊。通常使用高斯平滑濾波器卷積降噪。

void canny

(inputarray image, outputarray edges, double threshold1, double threshold2, int aperturesize=3, booll2gradient=false )

推薦的高低閾值比在2:1到3:1之間。

例項程式實現:

#include #include #include #include using namespace cv;

using namespace std;

int main()

效果圖:

改進的邊緣檢測運算元——marr—hildreth:

marr—hildreth運算元以高斯函式為平滑運算元,結合拉普拉斯運算元提取二階導數的零交叉理論進行邊緣檢測。

效果更好的邊緣檢測器是log運算元,它把高斯平滑濾波器和拉普拉斯銳化濾波器結合起來,先平滑掉雜訊,再進行邊緣檢測,所以效果更好。

運算元程式實現:

#include #include #include #include using namespace cv;

using namespace std;

void marredge(const mat src, mat& result, int kervalue, double delta)

} //設定輸入引數

int keroffset = kervalue / 2;

mat laplacian = (mat_(src.rows - keroffset * 2, src.cols - keroffset * 2));

result = mat::zeros(src.rows - keroffset * 2, src.cols - keroffset * 2, src.type());

double sumlaplacian;

//遍歷計算卷積影象的拉普拉斯運算元

for (int i = keroffset; i < src.rows - keroffset; ++i)

}//生成拉普拉斯結果

laplacian.at(i - keroffset, j - keroffset) = sumlaplacian;

} }for (int y = 1; y < result.rows - 1; ++y)

if (laplacian.at(y, x - 1)*laplacian.at(y, x + 1) < 0)

if (laplacian.at(y + 1, x - 1)*laplacian.at(y - 1, x + 1) < 0)

if (laplacian.at(y - 1, x - 1)*laplacian.at(y + 1, x + 1) < 0)

} }}

int main()

效果圖:

十三 邊緣提取

影象邊緣 找到畫素值差異比較大的地方 1.對影象進行一階求導 即sobel 最大變化處的絕對值最大值 2.對影象進行二階求導 即laplance 最大變化處的值為零 1.sobel運算元 原理 權重的差異擴大了差異 當kernal覆蓋的區域的畫素值一樣時,kernel覆蓋的畫素卷積和為0 即錨點的值...

opencv學習筆記十三 邊界填充

opencv新增邊緣的方式有 border default 將最近的畫素進行對映 border constant 用常數填充 border replicate 複製最近的一行或一列畫素並一直延伸至新增邊緣的寬度或高度 border wrap 將對面的畫素進行對映。對於卷積操作,最邊緣的畫素一般無法處...

OpenCV學習筆記(七)之Canny邊緣檢測

老規矩 妹妹鎮樓 灰度轉換 cvtcolor 計算梯度 sobel scharr 非最大訊號抑制 高低閾值輸出二值影象 t1,t2為閾值,凡是高於t2的都保留,凡是低於t1的都丟棄,從高於t2的畫素出發,凡是大於t1且相互連線的都保留。最終得到乙個輸出二值影象。推薦的高低閾值比值為t2 t1 3 1...