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