一、Canny边缘检测
Canny边缘检测是一种非常流行的边缘检测算法,是John Canny在1986年提出的。它是一个多阶段的算法,有以下四个步骤组成。
1.1 图像降噪
噪声对图像影响很大,所以首先需要进行滤波,去掉噪声的干扰 这一步使用的是高斯滤波(前文中有提到),而高斯滤波主要使图像变得平滑(模糊),同时也有可能增大了边缘的宽度。
1.2 计算图像梯度
计算图像梯度能够得到图像的边缘,因为梯度是灰度变化明显的地方,而边缘也是灰度变化明显的地方。 这一步通常使用的是sobel算子,在前文有提到过,这一步是为了得到所有可能是边缘的地方,接下来的两步主要是过滤掉其中不是边缘的。
1.3 非极大值抑制
在高斯滤波过程中,边缘有可能被放大了。这个步骤使用一个规则来过滤不是边缘的点,使边缘的宽度尽可能为1个像素点:如果一个像素点属于边缘,那么这个像素点在梯度方向上的梯度值是最大的。否则不是边缘,将灰度值设为0。 即 将局部范围内的梯度方向上,灰度变化最大的保留下来。
1.4 阈值筛选
- maxVal以上保留
- maxVal和minVal之间,且连接到A区域的保留
- minVal以下剔除
所以这张图可以看出,AC为边缘,B剔除。
二、代码与效果
2.1 代码
EMGU中将2-4步合为一个算法 ,Cvinvork.Canny
var image1 = new Image<Bgr, byte>("bird1.png");
var image0 = image1.Mat.Clone();
PreviewImage1 = new WriteableBitmap(Bitmap2BitmapImage(Text(image1.Bitmap, "原图")));
Mat image2 = new Mat();
CvInvoke.CvtColor(image0.Clone(), image2, ColorConversion.Bgr2Gray);
PreviewImage2 = new WriteableBitmap(Bitmap2BitmapImage(Text(image2.Bitmap, "灰度")));
Mat image5 = new Mat();
CvInvoke.Canny(image2.Clone(), image5, 50, 150);
PreviewImage3 = new WriteableBitmap(Bitmap2BitmapImage(Text2(image5.Bitmap, "不降噪Canny 50,150")));
Mat image3 = new Mat();
CvInvoke.GaussianBlur(image2.Clone(), image3, new Size(5, 5), 4);
PreviewImage4 = new WriteableBitmap(Bitmap2BitmapImage(Text(image3.Bitmap, "高斯滤波")));
Mat image4 = new Mat();
CvInvoke.Canny(image3.Clone(),image4,50,150);
PreviewImage5 = new WriteableBitmap(Bitmap2BitmapImage(Text2(image4.Bitmap, "Canny 50,150")));
Mat image6 = new Mat();
CvInvoke.Canny(image3.Clone(), image6, 80, 100);
PreviewImage6 = new WriteableBitmap(Bitmap2BitmapImage(Text2(image6.Bitmap, "Canny 80,100")));
Mat image7 = new Mat();
CvInvoke.Canny(image3.Clone(), image7, 80, 150);
PreviewImage7 = new WriteableBitmap(Bitmap2BitmapImage(Text2(image7.Bitmap, "Canny 80,150")));
Mat image8 = new Mat();
CvInvoke.Canny(image3.Clone(), image8, 100, 150);
PreviewImage8 = new WriteableBitmap(Bitmap2BitmapImage(Text2(image8.Bitmap, "Canny 100,150")));
Mat image9 = new Mat();
CvInvoke.Canny(image3.Clone(), image9, 50, 80);
PreviewImage9 = new WriteableBitmap(Bitmap2BitmapImage(Text2(image9.Bitmap, "Canny 50,80")));
2.2 效果
|