作者:翟天保Steven
著作權宣告:著作權歸作者所有,商業轉載請聯系作者獲得授權,非商業轉載請注明出處
函式原型
void Canny( InputArray image, OutputArray edges,
double threshold1, double threshold2,
int apertureSize = 3, bool L2gradient = false );
引數說明
- InputArray型別的image,輸入影像,8位影像,
- OutputArray型別的edges,輸出邊緣圖,單通道 8 位影像,與 image 大小相同,
- double型別的threshold1,滯后程序的第一個閾值,
- double型別的threshold2,滯后程序的第二個閾值,
- int型別的apertureSize,算子的孔徑大小,
- bool型別的L2gradient,若為ture則使用L2范數計算影像梯度幅度,若為false,則用L1范數,
函式原理
Canny邊緣檢測演算法是一種多級邊緣檢測演算法,也被很多人認為是邊緣檢測的最優演算法,其目標是找到一個最優的邊緣檢測演算法,用三個主要評價標準來表征是否為最優:
- 低錯誤率:標識出盡可能多的實際邊緣,同時盡可能地減少噪聲產生的誤報;
- 高定位率:標識出的邊緣要與影像中的實際邊緣盡可能接近,
- 最小回應:影像中的邊緣只能標識一次,并且可能存在的影像噪聲不應標識為邊緣,
為了滿足上述標準,Canny使用了變分法,這是一種尋找滿足特定功能的函式的方法,最優檢測用4個指數函式項的和表示,其非常近似于高斯函式的一階導數,
Canny邊緣檢測的步驟:
- 消除噪聲,采用高斯平滑濾波器卷積降噪,
- 計算梯度幅值和方向,梯度方向一般取0、45、90、135中的一個,
- 非極大值抑制,這是為了排除非邊緣像素,僅僅保留一些細線條,作為候選邊緣,
- 滯后閾值,如引數串列所示,有兩個閾值(高閾值和低閾值),若某一像素位置的幅值超過高閾值,該像素被保留為邊緣像素;若某一像素位置的幅值小于低閾值,該像素被排除;若處于兩閾值之間,該像素僅僅在連接到一個高于高閾值的像素時被保留,
測驗代碼
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
void main()
{
// 灰度Canny檢測
Mat src = imread("test.jpg", 0);
Mat result;
Canny(src, result, 100, 150, 3, true);
// 高階Canny用法,轉灰度圖,降噪,將得到的邊緣作為掩碼加到原圖上,得到彩色的邊緣圖
Mat src2 = imread("test.jpg");
Mat edge, result2;
result2=cv::Mat::zeros(src2.size(), src2.type());
blur(src, edge, Size(5, 5));
Canny(edge, edge, 3, 9, 3);
src2.copyTo(result2, edge);
// 結果顯示
imshow("src", src2);
imshow("gray", result);
imshow("color", result2);
waitKey(0);
system("pause");
}
測驗效果
注意函式的兩個閾值與邊緣的識別息息相關,
如果文章幫助到你了,可以點個贊讓我知道,我會很快樂~加油!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/344094.html
標籤:AI
