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

3Sobel邊緣檢測

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM