? ?最近小可愛們有沒有等我們的技術推等到望穿秋水啊?大家日思夜想的技術推來啦。今天我們來一起學習一下opencv里面一個重要方面:邊緣檢測。
01.什么是邊緣檢測
opencv邊緣檢測,?????邊緣檢測是圖像處理和計算機視覺中的基本問題,邊緣檢測的目的是標識數字圖像中亮度變化明顯的點。圖像屬性中的顯著變化通常反映了屬性的重要事件和變化。
? ? ?? 這些包括:
(i)深度上的不連續
prewitt算子邊緣檢測?(ii)表面方向不連續
(iii)物質屬性變化
(iv)場景照明變化?
opencv算法精解。? 邊緣檢測是圖像處理和計算機視覺中,尤其是特征提取中的一個研究領域。圖像邊緣檢測大幅度地減少了數據量,并且剔除了可以認為不相關的信息,保留了圖像重要的結構屬性。
02.邊緣檢測的步驟
???它的步驟簡單來說可以分成三種:
kirsch算子,(1)濾波:邊緣檢測的 算法 主要是基于圖像強度的一階和二階導數,但導數通常對噪聲很敏感,因此必須采用濾波器來改善與噪聲有關的邊緣檢測的性能。常見的濾波方法主要有 高斯濾波,即采用離散化的高斯函數產生一組歸一化的高斯核(具體見“高斯濾波原理及其編程離散化實現方法”一文),然后基于高斯核函數對圖像灰度矩陣的每一點進行加權和(具體程序見下文)
?(2)增強 :增強邊緣 的基礎是確定圖像各點鄰域強度的變化值。增強算法可以將圖像灰度點鄰域強度值有顯著變化的點凸顯出來。在具體編程實現時,可通過計算梯度幅值來確定。
(3)檢測:?經過增強的圖像,往往鄰域中有很多點的梯度值比較大,而在特定的應用中,這些點并不是我們想要的找的邊緣點,所以應該采用某種方法來對這些點進行取舍。在實際工程中,常用的方法是 通過閾值化方法來檢測。
03.Canny算子
????Canny算子在opencv中是最常用來進行邊緣檢測的,接下來我們就簡要介紹一下它。
?????Canny邊緣檢測算子是John F.Canny于 1986 年開發出來的一個多級邊緣檢測算法。更為重要的是 Canny 創立了邊緣檢測計算理論,解釋了這項技術是如何工作的。Canny邊緣檢測算法以Canny的名字命名,被很多人推崇為當今最優的邊緣檢測的算法。
????其中,Canny 的目標是找到一個最優的邊緣檢測算法,最優邊緣檢測的三個主要評價標準是:
??1 低錯誤率:標識出盡可能多的實際邊緣,同時盡可能的減少噪聲產生的誤報
??2 高定位性:標識出的邊緣要與圖像中的實際邊緣盡可能接近
??3 最小響應:圖像中的邊緣只能標識一次,并且可能存在的圖像噪聲不應標識為邊緣
04.如何利用Canny算子進行檢測
利用Canny算法進行圖像的邊緣檢測:
1 void Canny (InputArray image,OutputArray edges , double threshold1,
2 Threshold2 ,int apertureSize = 3,bool? L2gradient = false);
注解:
·第一個參數,InputArray類型的image,輸入圖像,即源圖像,填Mat類的對象即可,且需為單通道8位圖像.
·第二個參數,OutputArray類型edges,輸出的邊緣圖,需要和源圖片有一樣的尺寸和類型.
·第三個參數,double類型threshold1,第一個滯后性閾值.
·第四個參數,double類理的threshold2,第二個滯后性閥值.
·第五個參數,int類型的apertureSize,表示應用Sobel算子的孔徑大小,其有默認值3.
·第六個參數,bool類型的L2gradient,一個計算圖像梯度幅值的標識,有默認值false.
?(需要注意的是,這個函數閾值1和閾值2兩者的小者用于邊緣連接,而大者用來控制強邊緣的初始段,推薦的高低閾值比在2:1到3:1之間)
05.函數實例
使用示例:
1 // 輸入原始圖
2? Mat src = inread (“1.jpg”)
3 Canny ( src , src , 3,9,3);
4 inshow? (“[效果圖]邊緣檢測”,src);
如上三句,就有結果出來,非常好用。
▲向上滑動
函數示例:
#include
#include
#include
#include
#include
?using namespace std;
using namespace cv;
?/*------------------------------
????????? 【1】Canny算子
---------------------------------*/
int main()
{
??? //載入原始圖
??? Mat src = imread("1.jpg");
??? Mat src1 = src.clone();
??? //Mat src2 = src.clone();
?? //顯示原始圖
??? imshow("【原始圖】Canny邊緣檢測", src);
?? /*----------------------------
?//?(1) 最簡單的canny用法,拿到原圖后直接用
??? -----------------------------------*/
??? Canny(src,src,150,100,3);
??? imshow("【效果圖】Canny邊緣檢測", src);
?? /*---------------------------------------
???//(2)高階的canny用法,轉成灰度圖,降噪,? ?用Canny, ? 最后得到的邊緣作為掩碼,拷貝原 圖到效果圖上,得到 彩色的邊緣圖
??? ----------------------------------*/
??? Mat dst, edge, gray;
????//(1)創建與src 同類型和大小的矩陣
??? dst.create(src1.size(),src1.type());
???//(2)將原圖轉換為灰度圖像
? cvtColor(src1,gray,CV_BGR2GRAY);
??//(3)使用3*3內核來降噪
??? blur(gray,edge,Size(3,3));
??//(4)運行Canny算子
??? Canny(edge,edge,3,9,3);
??//(5)將g_dstImage內的元素設為0
??? dst = Scalar::all(0);
??//(6)使用Canny算子輸出的邊源:
g_canny DetectEdges作為掩碼,將g_srcImage拷到目標圖g_dstImage中,
src1.copyTo(dst,edge);
?//(7)顯示效果圖
?? imshow("【效果圖】Canny邊緣檢測2", dst);
? ?? waitKey();
? ? return 0;
}
示例圖如下
原圖是這樣的
檢測完后的效果圖。
?????可以看出這個算法非常細膩地把圖里面的輪廓都給找出來了。
? ? ?不過,有時候過于細膩也不好,這時候就需要調整參數或者采用其他算法,比如sobel算法和拉普拉斯算法。嘻嘻,這些就等下次再來介紹咯。
文案/ 謝函瀚
排版/胡文博
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态