OpenCV3入門(八)圖像邊緣檢測

1、邊緣檢測基礎

圖像的邊緣是圖像的基本特徵,邊緣點是灰度階躍變化的像素點,即灰度值的導數較大或極大的地方,邊緣檢測是圖像識別的第一步。用圖像的一階微分和二階微分來加強圖像的灰度跳變,而邊緣也就是灰度變化的地方。所以,這些傳統的一階微分算子如Robert、Sobel、prewitt等,以及二階微分算子Laplacian等等本質上都是能夠用於檢測邊緣的。這些算子均可以稱爲邊緣檢測算子。html

邊緣檢測能夠大幅度的減小數據量,剔除那些不相關的信息,保留圖像重要的結構屬性,通常的邊緣檢測的步驟有:算法

1)濾波編程

邊緣檢測主要基於圖像的一階和二階微分,可是導數、微分對噪聲很敏感,梯度計算容易受噪聲影響,所以須要用濾波來抑制噪聲。函數

2)加強學習

爲了檢測邊界,須要肯定鄰域中灰度變化,加強邊緣的基礎是肯定圖像各點鄰域強度的變化值,利用銳化突出了灰度變化的區域。spa

3)檢測code

通過加強的圖像,鄰域中不少點的梯度值比較大,可是並非全部點都是邊緣點,須要採用某種方法來取捨,通常使用閾值來劃分圖像各點。orm

2、邊緣檢測算子

2.1一階微分算子htm

1)原理blog

圖像的邊緣就是圖像灰度發生快速變化的地方。對於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邊緣檢測

http://www.javashuo.com/article/p-qjryyhcc-bg.html

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

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

 

我的博客,轉載請註明。

http://www.javashuo.com/article/p-guuwmfyp-gx.html

相關文章
相關標籤/搜索