一. Canny 算法简介
Canny边缘检测算子是 John F.Canny 于 1986 年开发出来的一个多级边缘检测算法。更为重要的是,Canny 创立了边缘检测计算理论(Computational theory ofedge detection),解释了这项技术是如何工作的。Canny边缘检测算法以Canny的名字命名,被很多人推崇为当今最优的边缘检测的算法。
二. Canny 边缘检测的步骤
- 高斯模糊 - GaussianBlur
- 灰度转换 - cvtColor
- 计算梯度幅值和方向 - Sobel / Scharr
- 非最大信号抑制 ?说明
排除非边缘像素,仅仅保留一些细线条(候选边缘)。 - 滞后阈值
滞后阈值需要两个阈值,高阈值T1 和 低阈值T2
① 若某一像素位置的幅值超过了高阈值,该像素被保留为边缘像素。
② 若某一像素位置的幅值小于低阈值,该像素被排除。
③ 若某一像素位置的幅值在两个阈值之间,该像素仅仅在连接到一个高于高阈值的像素时被保留。
④ 推荐高低阈值比在 2:1 到 3:1 之间。
三. Canny() 函数介绍
void Canny(InputArray image,OutputArray edges, double threshold1, double threshold2, int apertureSize=3,bool L2gradient=false )
- InputArray类型的image,输入图像,即源图像,填Mat类的对象即可,且需为单通道8位图像。
- OutputArray类型的edges,输出的边缘图,需要和源图片有一样的尺寸和类型,一般是二值图像。
- double类型的threshold1,第一个滞后性阈值【低阈值】。值越大,找到的边缘越少
- double类型的threshold2,第二个滞后性阈值【高阈值】。
- int类型的apertureSize,表示应用Sobel算子的孔径大小,其有默认值3。
- bool类型的L2gradient,一个计算图像梯度幅值的标识,有默认值false。
四. 代码示例
int main(int argc, char** argv)
{
Mat src = imread("E:/Image/dl1.jpg");
if (src.empty())
{
cout << "load image error..." << endl;
return -1;
}
imshow("src img", src);
// 转为灰度图像
Mat gray;
cvtColor(src, gray, CV_BGR2GRAY);
// 高斯模糊
GaussianBlur(gray, gray, Size(3, 3), 0, 0, BORDER_DEFAULT);
// Canny检测
Mat cannyImg;
Canny(gray, cannyImg, 100, 100 * 2.5, 3, false);
imshow("canny img", cannyImg);
Mat cannyColor;
cannyColor.create(src.size(), src.type());
// 二值图像cannyImg中为1的部分,src的值赋给cannyColor
src.copyTo(cannyColor, cannyImg);
imshow("cannyColor img", cannyColor);
waitKey(0);
return 0;
}
结果示例:

本文介绍了Canny边缘检测算法,包括算法简介、检测步骤和OpenCV中的Canny()函数用法。Canny算法是一种多级边缘检测算法,通过高斯模糊、灰度转换、梯度计算等步骤,结合非最大信号抑制和滞后阈值策略来识别图像边缘。最后,文章提供了一个代码示例来展示Canny算法的应用。

1911

被折叠的 条评论
为什么被折叠?



