OpenCV Canny边缘检测算法
1986年,JOHN CANNY 提出一个很好的边缘检测算法,被称为Canny编边缘检测器。Canny边缘检测器是一种经典的图像边缘检测与提取算法,应用广泛,主要是因为Canny边缘检测具备以下特点:
- 有效的噪声抑制,内带高斯模糊,x方向和y方向梯度和
用2个阈值代替一个阈值,高低阈值连接 - 更强的完整边缘提取能力
Canny算法是如何做到精准的边缘提取的,主要是靠下面五个步骤
- 高斯模糊 – 抑制噪声
- 梯度提取得到边缘候选 剃度边缘的计算论文里建议使用sobel算子或者prewitt,实际第一步和第二步可以连起来,其实就是一个LOG算子
- 角度计算与非最大信号抑制(只有中心像素点最大的时候才保留,比两边大)
- 高低阈值链接、获取完整边缘(但阈值过高边缘就少,过低噪点就多 高于高阈值全保留,低于全去掉,之间的只要通道高阈值的就保留,否则舍弃)
- 输出边缘
OpenCV中Canny边缘检测的API如下:
void cv::Canny(
InputArray image,
OutputArray edges,
double threshold1,
double threshold2,
int apertureSize = 3,
bool L2gradient = false
)
其中输入图像可以是单、三通道图像,而输出则是二值图形。参数threshold1 是Canny边缘检测算法第四步中高低阈值链接中低阈值,参数threshold2 是Canny边缘检测算法第四步中高低阈值链接中高阈值、高低阈值之比在2:1~3:1之间(经验值)。最后一个参数是计算gradient的方法L1(绝对值,计算量较小)或者L2(平方和开根号)。
代码实践:
/*
Canny边缘检测算法
*/
#include<iostream>
#include<cmath>
#include<opencv2\opencv.hpp>
using namespace std;
using namespace cv;
int main(int argc, char**argv)
{
/*
完整的Canny边缘检测算法包括以下步骤:
1. 彩色图像转换为灰度图像
2. 对图像进行高斯模糊
3. 计算图像梯度,根据梯度计算图像边缘幅值与角度
4. 非最大信号压制处理(边缘细化)
5. 双阈值边缘连接处理
6. 二值化图像输出结果
*/
Mat input = imread("./test_images/car.jpg");
if (input.empty())
{
cout << "read image failed!" << endl;
return -1;
}
imshow("input", input);
Mat gray,canny;
//bgr 2 gray
cvtColor(input, gray, CV_BGR2GRAY);
//canny
Canny(gray, canny, 100, 300, 3, false);
imshow("canny", canny);
waitKey(0);
return 0;
}
Canny结果: