OpenCV中的边缘检测
0赞边缘检测一般的步骤:
(1)滤波
边缘检测的算法主要是基于图像强度的一阶和二阶导数,但导数通常对噪声很敏感,因此必须采用滤波器来改善与噪声相关的边缘检测器的性能。
(2)增强
增强边缘的基础是确定图像各点邻域强度的变化值。增强算法可以将图像灰度点邻域强度值有显著变化的点凸显出来。
(3)检测
经过增强的图像,邻域中往往有很多点的梯度值比较大,而在特定的应用中,这些点并不是要找的边缘点,所以要采用某种方法对这些点进行取舍。实际工程中,经常通过阈值化的方法来检测。
下面介绍几种边缘检测的算子:
1、Canny边缘检测
(1)canny算子
Canny边缘检测算子是一个多级边缘检测算法,被很多人推崇为当今最优的边缘检测算法。一个最优边缘检测的三个主要评价标准:
<1>低错误率:标识出尽可能多的实际边缘,同时尽可能地减少噪声产生的误报。
<2>高定位性:标识出的边缘要与图像中的实际边缘尽可能接近。
<3>最小响应:图像中的边缘只能标识一次,并且可能存在的图像噪声不应标识为边缘。
(2)canny边缘检测的步骤
<1>消除噪声
通常使用高斯平滑滤波器卷积降噪。
<2>计算梯度幅值和方向
梯度方向一般取0°、45°、90°、135°这四个可能的角度之一。
<3>非极大值抑制
排除非边缘像素,仅仅保留了一些细线条(候选边缘)。
<4>滞后阈值
滞后阈值有高阈值和低阈值两个阈值:若某一像素位置的幅值超过高阈值,该像素被保留为边缘像素;若某一像素位置的幅值小于低阈值,该像素被排除;若某一像素位置的幅值在两个阈值之间,该像素仅仅在连接到一个高于高阈值的像素时被保留。
(3)Canny边缘检测:Canny()函数
void Canny(InputArray image,OutputArray edges,double threshold1,double threshold2,int apertureSize=3,bool L2gradient=false)
<1>单通道8位图像输入。
<2>输出的边缘图。
<3>第一个滞后性阈值。
<4>第二个滞后性阈值。
<5>表示应用Sobel算子的孔径大小,默认值为3。
<6>计算图像梯度幅值的标识,默认值false。
这个函数阈值1和阈值2两者中较小的值用于边缘连续,而较大的值用来控制边缘的初始段,推荐的高低阈值在2:1到3:1之间。
(4)Canny边缘检测OpenCV实现
#include<opencv2\opencv.hpp> #include<iostream> using namespace cv; using namespace std; int main() { // 图片读取与显示 Mat srcImage = imread("flower.jpg"); // 载入图片 if(!srcImage.data) { cout << "图片加载失败!!!" << endl; system("pause"); return 1; } imshow("【原始图】canny边缘检测",srcImage); // 显示原始图 // 将原图转换成灰度图 Mat grayImage; cvtColor(srcImage,grayImage,COLOR_BGR2GRAY); // 对灰度图进行滤波 Mat blurImage; blur(grayImage,blurImage,Size(3,3)); // Canny边缘检测 Mat dstImage; Canny(blurImage,dstImage,3,9,3); // 效果图显示 imshow("【效果图】Canny边缘检测",dstImage); waitKey(0); return 0; }