Canny边缘检测
Canny边缘检测算法是一种对噪声比较敏感的边缘检测算法
所以通常使用Canny检测之前,收先对图像进行降噪
一个完整的Canny边缘检测有以下几个步骤组成
- 高斯模糊:完成噪声抑制
- 灰度转换:在灰度图像上计算梯度值
- 计算梯度:使用Sobel/Scharr
- 非最大信号抑制:在梯度图像上寻找局部最大轮廓
- 高低阈值连接:吧边缘像素连接为线段,形成完整边缘轮廓
Canny边缘检测是函数
Canny(Mat image, Mat edges, double threshold1, double threshold2, int apertureSize, boolean L2gradient)
- image:输入图像
- edges:输出的二值边缘图像
- threshold1:最低阈值T1
- threshold2:最高阈值T2
- apertureSize:用于内部计算梯度的ksize值
- L2gradient:计算图像梯度计算方法
下面通过代码演示
Mat m1 = Imgcodecs.imread("C:\\test\\256_256_t1.png" );
Mat s1 = new Mat();
Imgproc.Canny(m1,s1,50,150,3,true)
HighGui.imshow("Canny",s1);
不同方向的Canny边缘检测
OpenCV支持从两个已经计算出来的X方向梯度和Y方向梯度,来检测边缘
他的Api如下
Canny(Mat dx, Mat dy, Mat edges, double threshold1, double threshold2)
- dx:X方向的梯度图像
- dy:Y方向的梯度图像
- edges :输出的二值边缘图像
- threshold1:最低阈值T1
- threshold2:最高阈值T2
这里需要注意的是 这里的dx个dy图像深度 必须是CV_16S
Mat m1 = Imgcodecs.imread("C:\\test\\256_256_t1.png" );
HighGui.imshow("原图",m1);
Mat s1 = new Mat();
Imgproc.Sobel(m1,s1, CvType.CV_16S,1,0);
Mat s2 = new Mat();
Imgproc.Sobel(m1,s2, CvType.CV_16S,0,1);
Mat s3 = new Mat();
Imgproc.Canny(s1,s2,s3,50,150);
//为了展示s1和s2 转换深度
Core.convertScaleAbs(s1,s1);
Core.convertScaleAbs(s2,s2);
HighGui.imshow("X方向梯度",s1);
HighGui.imshow("Y方向梯度",s2);
HighGui.imshow("Canny边缘检测",s3);
本来这里应使用灰度图,但是忘了…
最好是使用灰度图像进行计算,这样计算量会比较小