之OpenCV中canny算子边缘检测
时间:10-02
整理:3721RD
点击:
具体介绍之前,先来一起看看边缘检测的一般步骤
- 滤波:边缘检测的算法主要是基于图像强度的一阶和二阶导数,但导数通常对噪声很敏感,因此必须采用滤波器来改善与噪声有关的边缘检测器的性能。常见的滤波方法主要有高斯滤波,即采用离散化的高斯函数产生一组归一化的高斯核,然后基于高斯核函数对图像灰度矩阵的每一点进行加权求和。
- 增强:增强边缘的基础是确定图像各点邻域强度的变化值。增强算法可以将图像灰度点邻域强度值有显著变化的点凸显出来。在具体编程实现时,可通过计算梯度幅值来确定。
- 检测:经过增强的图像,往往邻域中有很多点的梯度值比较大,而在特定的应用中,这些点并不是我们要找的边缘点,所以应该采用某种方法来对这些点进行取舍。实际工程中,常用的方法是通过阈值化方法来检测。
Canny 算子的目标是找到一个最优的边缘检测算法,让我们看一下最优边缘检测的三个主要标准:
1.低错误率: 标识出尽可能多的实际边缘,同时尽可能的减少噪声产生的误报。
2.高定位性: 标识出的边缘要与图像中的实际边缘尽可能接近。
3.最小响应: 图像中的边缘只能标识一次,并且可能存在的图像噪声不应标识为边缘。
为了满足这些要求 Canny 使用了变分法,这是一种寻找满足特定功能的函数的方法。最优检测使用四个指数函数项的和表示,但是它非常近似于高斯函数的一阶导数。其中具体算法设计到很多数学问题,其实在实际应用中我们只要了解如何调用接口函数即可,下面我们来看下接口函数调用方法
- #include <opencv2/opencv.hpp>
- #include <opencv2/imgproc/imgproc.hpp>
- using namespace cv;
- int main( )
- {
-
- Mat srcImage = imread("1.jpg");
- imshow("CannyOriginal", srcImage);
- Mat dstImage,edge,grayImage;
- dstImage.create( srcImage.size(), srcImage.type() );
- cvtColor( srcImage, grayImage, CV_BGR2GRAY );
- blur( grayImage, edge, Size(3,3) );
- Canny( edge, edge, 3, 9,3 );
- imshow("Canny", edge);
- waitKey(0);
- return 0;
- }
上面是两个不同图片的处理效果,具体应用中,我们需要根据自己需要调整参数,所以需要了解下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。
需要注意的是,这个函数阈值1和阈值2两者的小者用于边缘连接,而大者用来控制强边缘的初始段,推荐的高低阈值比在2:1到3:1之间。