OpenCV-Canny边缘检测

作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

函数原型

void Canny( InputArray image, OutputArray edges,
            double threshold1, double threshold2,
            int apertureSize = 3, bool L2gradient = false );

参数说明

  1. InputArray类型的image,输入图像,8位图像。
  2. OutputArray类型的edges,输出边缘图,单通道 8 位图像,与 image 大小相同。
  3. double类型的threshold1,滞后过程的第一个阈值。
  4. double类型的threshold2,滞后过程的第二个阈值。
  5. int类型的apertureSize,算子的孔径大小。
  6. bool类型的L2gradient,若为ture则使用L2范数计算图像梯度幅度,若为false,则用L1范数。

函数原理

       Canny边缘检测算法是一种多级边缘检测算法,也被很多人认为是边缘检测的最优算法。其目标是找到一个最优的边缘检测算法,用三个主要评价标准来表征是否为最优:

  1. 低错误率:标识出尽可能多的实际边缘,同时尽可能地减少噪声产生的误报;
  2. 高定位率:标识出的边缘要与图像中的实际边缘尽可能接近。
  3. 最小响应:图像中的边缘只能标识一次,并且可能存在的图像噪声不应标识为边缘。

       为了满足上述标准,Canny使用了变分法,这是一种寻找满足特定功能的函数的方法。最优检测用4个指数函数项的和表示,其非常近似于高斯函数的一阶导数。

       Canny边缘检测的步骤:

  1. 消除噪声,采用高斯平滑滤波器卷积降噪。
  2. 计算梯度幅值和方向。梯度方向一般取0、45、90、135中的一个。
  3. 非极大值抑制。这是为了排除非边缘像素,仅仅保留一些细线条,作为候选边缘。
  4. 滞后阈值。如参数列表所示,有两个阈值(高阈值和低阈值)。若某一像素位置的幅值超过高阈值,该像素被保留为边缘像素;若某一像素位置的幅值小于低阈值,该像素被排除;若处于两阈值之间,该像素仅仅在连接到一个高于高阈值的像素时被保留。

测试代码

#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");
}

测试效果

图1 原图
图2 灰度边缘图
图3 彩色边缘图

       注意函数的两个阈值与边缘的识别息息相关。

       如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

© 版权声明
THE END
喜欢就支持一下吧
点赞559 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容