1. 程式人生 > >OpenCV3入門(八)影象邊緣檢測

OpenCV3入門(八)影象邊緣檢測

1、邊緣檢測基礎

影象的邊緣是影象的基本特徵,邊緣點是灰度階躍變化的畫素點,即灰度值的導數較大或極大的地方,邊緣檢測是影象識別的第一步。用影象的一階微分和二階微分來增強影象的灰度跳變,而邊緣也就是灰度變化的地方。因此,這些傳統的一階微分運算元如Robert、Sobel、prewitt等,以及二階微分運算元Laplacian等等本質上都是可以用於檢測邊緣的。這些運算元都可以稱為邊緣檢測運算元。

邊緣檢測可以大幅度的減少資料量,剔除那些不相關的資訊,保留影象重要的結構屬性,一般的邊緣檢測的步驟有:

1)濾波

邊緣檢測主要基於影象的一階和二階微分,但是導數、微分對噪聲很敏感,梯度計算容易受噪聲影響,因此需要用濾波來抑制噪聲。

2)增強

為了檢測邊界,需要確定鄰域中灰度變化,增強邊緣的基礎是確定影象各點鄰域強度的變化值,利用銳化突出了灰度變化的區域。

3)檢測

經過增強的影象,鄰域中很多點的梯度值比較大,但是並不是所有點都是邊緣點,需要採用某種方法來取捨,一般使用閾值來劃分影象各點。

2、邊緣檢測運算元

2.1一階微分運算元

1)原理

影象的邊緣就是影象灰度發生快速變化的地方。對於f(t),其導數f'(t)反映了每一處的變化趨勢,在變化最快的位置其導數最大,sobel運算元的思路就是模擬求一階導數。

其中:

梯度的方向就是函式f(x,y)最大變化率的方向。梯度的幅值作為最大變化率大小的度量,值為:

離散的二維函式f(i,j),可以用有限差分作為梯度的一個近似值。

為了簡化計算,可以用絕對值來近似。

|▽f(i,j)|= |f(i+1,j)-f(i,j)| +|f(i,j+1)-f(i,j)|

2)Sobel運算元

Sobel運算元是離散微分運算元(discrete differentiation operator),用來計算影象灰度的近似梯度,梯度越大越有可能是邊緣,Sobel集合了高斯平滑和微分求導,又被稱為一階微分運算元、求導運算元,在水平和垂直兩個方向上求導,得到的是影象在X方法與Y方向梯度影象。

函式原型:

CV_EXPORTS_W 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 );

示例程式碼:

img = imread("D:\\WORK\\5.OpenCV\\LeanOpenCV\\pic_src\\pic7.bmp", IMREAD_GRAYSCALE);
imshow("原圖", img);

//X方向梯度  
Sobel(img, imgX, CV_8U, 1, 0, 3, 1, 1, BORDER_DEFAULT);
convertScaleAbs(imgX, imgX);
imshow("X方向Sobel", imgX);

//Y方向梯度  
Sobel(img, imgY, CV_8U, 0, 1, 3, 1, 1, BORDER_DEFAULT);
convertScaleAbs(imgY, imgY);
imshow("Y方向Sobel", imgY);

//合併梯度(近似)  
addWeighted(imgX, 0.5, imgY, 0.5, 0, img2);
imshow("整體方向Sobel", img2);

輸出結果為:

2.2二階微分運算元

1)原理

二維函式f(x,y)在二階微分(拉普拉斯運算元)的定義為:

將上式相加後就得到拉普拉斯運算元:

對應的濾波模板如下:

考慮到求絕對值計算梯度,正負係數圖形的響應一樣,上面的模板也可以表示為:

上面的模板具有對稱性,所以求一次濾波就可以,不需要像一階微分那樣計算2次。

2)應用

拉普拉斯運算元是二階微分運算元,對噪聲敏感,Laplace運算元對孤立象素的響應要比對邊緣或線的響應要更強烈,因此只適用於無噪聲圖象。存在噪聲情況下,使用Laplacian運算元檢測邊緣之前需要先進行低通濾波。高斯-拉普拉斯運算元,又稱LoG運算元,就是為了補充這種缺陷被創立的,它先進行高斯低通濾波,然後再進行拉普拉斯二階微分銳化。

示例如下。

img = imread("D:\\WORK\\5.OpenCV\\LeanOpenCV\\pic_src\\pic7.bmp", IMREAD_GRAYSCALE);
imshow("原圖", img);
GaussianBlur(img, img2, Size(5, 5), 0, 0);
imshow("高斯圖", img2);
Laplacian(img2, img3, CV_8U, 3, 1, 0);
imshow("Laplacian圖", img3);

輸出結果為:

2.3 Canny運算元

1)原理

在影象邊緣檢測中,抑制噪聲和邊緣精準定位是無法同時滿足的,一些邊緣檢測演算法通過平滑濾波去除噪聲的同時,也增加了邊緣檢測的不確定性,而提高邊緣檢測運算元對邊緣的敏感性的同時,也提高了對噪聲的敏感性。Canny運算元力圖在抗噪聲干擾和精準定位之間尋求最佳折中方案。

Canny演算法主要有4個步驟:

  • 用高斯濾波器來平滑影象;
  • 用一介偏導的有限差分來計算梯度的幅值和方向;
  • 對梯度進行非極大值抑制,保留極大值,抑制其他值;
  • 用雙閾值演算法檢測和連線邊緣。

2)應用

函式原型為:

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

示例如下:

img = imread("D:\\WORK\\5.OpenCV\\LeanOpenCV\\pic_src\\pic7.bmp", IMREAD_GRAYSCALE);
imshow("原圖", img);
Canny(img, img2, 3, 9, 3);
imshow("canny", img2);

輸出效果如下圖。

修改閾值之後,Canny(img, img2, 45, 90, 3);效果如下圖。

3、參考文獻

1、《OpenCV3 程式設計入門》,電子工業出版社,毛星雨著

2、《學習OpenCV》,清華大學出版社,Gary Bradski, Adrian kaehler著

3、Sobel邊緣檢測

https://www.cnblogs.com/yibeimingyue/p/10878514.html

4、學習筆記-canny邊緣檢測

https://www.cnblgs.com/mmmmc/p/10524640.html

 

個人部落格,轉載請註明。

https://www.cnblogs.com/pingwen/p/12324348.html