Canny算子
1986年,Canny边缘检测算子是John F. Canny开发出来的一个多级边缘检测算法。更为重要的是Canny创立了“边缘检测计算理论”(computational theory of edge detection)解释这项技术如何工作。到今天已经30多年过去了,但Canny算法仍然是图像边缘检测算法中最经典、先进的算法之一。
1、高斯平滑
2、计算梯度幅度和方向
可选用的模板:soble算子、Prewitt算子、Roberts模板等等;
一般采用soble算子,OpenCV也是如此,利用soble水平和垂直算子与输入图像卷积计算dx、dy
3、根据角度对幅值进行非极大值抑制
沿着梯度方向对幅值进行非极大值抑制,而非边缘方向
在每一点上,领域中心 x 与沿着其对应的梯度方向的两个像素相比,若中心像素为最大值,则保留,否则中心置0,这样可以抑制非极大值,保留局部梯度最大的点,以得到细化的边缘。
4、用双阈值算法检测和连接边缘
选取系数TH和TL,比率为2:1或3:1。(一般取TH=0.3或0.2,TL=0.1);
将小于低阈值的点抛弃,赋0;将大于高阈值的点立即标记(这些点为确定边缘点),赋1或255;
将小于高阈值,大于低阈值的点使用8连通区域确定(即:只有与TH像素连接时才会被接受,成为边缘点,赋 1或255)
voidquick_opencv::canny_Demo(Mat&img) { ConvertRGB2GRAY(img, imageGray); //RGB转换为灰度图 imshow("Gray Image", imageGray); intsize=5; //定义卷积核大小 double**gaus=newdouble*[size]; //卷积核数组 for (inti=0;i<size;i++) { gaus[i] =newdouble[size]; //动态生成矩阵 } GetGaussianKernel(gaus, 5, 1); //生成5*5 大小高斯卷积核,Sigma=1; imageGaussian=Mat::zeros(imageGray.size(), CV_8UC1); GaussianFilter(imageGray, imageGaussian, gaus, 5); //高斯滤波 imshow("Gaussian Image", imageGaussian); MatimageSobelY; MatimageSobelX; double*pointDirection=newdouble[(imageSobelX.cols-1)*(imageSobelX.rows-1)]; //定义梯度方向角数组 SobelGradDirction(imageGaussian, imageSobelX, imageSobelY, pointDirection); //计算X、Y方向梯度和方向角 imshow("Sobel Y", imageSobelY); imshow("Sobel X", imageSobelX); MatSobelGradAmpl; SobelAmplitude(imageSobelX, imageSobelY, SobelGradAmpl); //计算X、Y方向梯度融合幅值 imshow("Soble XYRange", SobelGradAmpl); MatimageLocalMax; LocalMaxValue(SobelGradAmpl, imageLocalMax, pointDirection); //局部非极大值抑制 imshow("Non-Maximum Image", imageLocalMax); MatcannyImage; cannyImage=Mat::zeros(imageLocalMax.size(), CV_8UC1); DoubleThreshold(imageLocalMax, 90, 160); //双阈值处理 imshow("Double Threshold Image", imageLocalMax); DoubleThresholdLink(imageLocalMax, 90, 160); //双阈值中间阈值滤除及连接 imshow("Canny Image", imageLocalMax); }