1. 程式人生 > >Opencv中的幾種邊緣檢測演算法

Opencv中的幾種邊緣檢測演算法

1、Sobel導數
Sobel運算元結合了高斯平滑和微分求導。可以用來計算影象灰度函式的近似梯度。計算時是將原影象分別與水平方向和豎直方向的奇數大小的核心進行卷積,然後再影象的每一點上進行計算(求根號下兩數的平方和,有時會用兩數的絕對值和)得出近似梯度。
當核心大小等於3時使用Sobel核心的誤差會比較大,在這裡可以使用Scharr核心進行計算(將核心大小設為-1時呼叫的是Scharr核心)。
在求導時,最好水平豎直分開求然後再加起來,效果會好一點。
還有就是要將輸出型別設為CV_16S以防止溢位.

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

前兩個引數為輸入輸出影象,
第三個引數為輸出影象的型別,
然後第四個和第五個引數為x,y方向上的導數的階數
第六個引數為所使用的核心的大小,設為-1時使用Scharr核心
最後三個引數均使用預設值即可。

程式碼如下:

int main()
{
    Mat a
= imread("738b4710b912c8fc453a8235fe039245d7882178.jpg"); imshow("原圖", a); cvtColor(a, a, CV_RGB2GRAY); //轉為灰度圖 Mat ax, ay; Mat axx, ayy; Sobel(a, ax, CV_16S, 1, 0,-1); Sobel(a, ay, CV_16S, 0, 1,-1); convertScaleAbs(ax, axx); //將CV_16S轉為CV_8U convertScaleAbs(ay, ayy);
addWeighted(axx, 0.5, ayy, 0.5, 0,a); //將兩圖相加 imshow("效果圖", a); cvWaitKey(10000); }

這裡寫圖片描述

2、Laplace 運算元
Laplacian 運算元 的定義:
這裡寫圖片描述
是對二維影象求的二階偏導數,在函式中由於 Laplace使用了影象梯度,它內部呼叫了 Sobel 運算元。
在Laplace運算元中無法呼叫Scharr核心。同樣輸出影象的型別要定為CV_16S以防止溢位。

void Laplacian( InputArray src, OutputArray dst, int ddepth,
                             int ksize = 1, double scale = 1, double delta = 0,
                             int borderType = BORDER_DEFAULT );

第三個引數為輸出影象的型別,然後是核心的大小。
後三個引數均使用預設就行了。

程式碼如下:

int main()
{
    Mat a = imread("738b4710b912c8fc453a8235fe039245d7882178.jpg");
    imshow("原圖", a);
    cvtColor(a, a, CV_RGB2GRAY);     //轉為灰度圖
    Mat aa;
    Laplacian(a, aa, CV_16S,3);
    Mat aaa;
    convertScaleAbs(aa, aaa);     //將CV_16S轉為CV_8U
    imshow("效果圖", aaa);
    cvWaitKey(10000);
}

效果圖:
這裡寫圖片描述

3、Canny演算法
Canny 邊緣檢測演算法 是 John F. Canny 於 1986年開發出來的一個多級邊緣檢測演算法,也被很多人認為是邊緣檢測的 最優演算法。呼叫也很簡單,輸入輸出影象可以用同一幅。
程式碼如下:

int main()
{
    Mat a = imread("738b4710b912c8fc453a8235fe039245d7882178.jpg");
    imshow("原圖", a);
    cvtColor(a, a, CV_RGB2GRAY);     //轉為灰度圖
    Canny(a, a, 100, 300, 3);
    imshow("效果圖", a);
    cvWaitKey(10000);
}

執行圖:
這裡寫圖片描述