作者:翟天保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");
}
测试效果
注意函数的两个阈值与边缘的识别息息相关。
如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容