opencv邊緣檢測,c#用canny算子做邊緣提取_干貨 | 邊緣檢測

 2023-10-06 阅读 29 评论 0

摘要:? ?最近小可愛們有沒有等我們的技術推等到望穿秋水啊?大家日思夜想的技術推來啦。今天我們來一起學習一下opencv里面一個重要方面:邊緣檢測。01.什么是邊緣檢測opencv邊緣檢測,?????邊緣檢測是圖像處理和計算機視覺中的基本問題,邊緣檢測的目的是標識數

? ?最近小可愛們有沒有等我們的技術推等到望穿秋水啊?大家日思夜想的技術推來啦。今天我們來一起學習一下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;

}

示例圖如下

原圖是這樣的

fbe379dd5e81603250bb0d0efd87c114.png

檢測完后的效果圖。

a3bf668c3bb91d55774d9df7a0cee32e.png

?????可以看出這個算法非常細膩地把圖里面的輪廓都給找出來了。

? ? ?不過,有時候過于細膩也不好,這時候就需要調整參數或者采用其他算法,比如sobel算法和拉普拉斯算法。嘻嘻,這些就等下次再來介紹咯。

aad7291e05209ce95b42948d714f42f5.png

文案/ 謝函瀚

排版/胡文博

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/4/121242.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息