canny对边缘检测质量进行分析时,有3个原则:
1、信噪比准则
2、定位精度准则
3、单边缘响应准则
canny边缘检测的基本思想是:首先对图像选择一定的Gauss滤波器进行平滑滤波,然后采用非极值抑制技术进行处理得到最后的边缘图像。
具体步骤:
1、用高斯滤波器平滑图像
2、用一阶偏导的有限差分来计算梯度的幅值和方向
3、对梯度幅值进行非极大值抑制
4、用双阈值算法检测和连接边缘
通俗的来说:就是在进行边缘检测时,还是要用到滤波减小噪声,先通过在水平和垂直方向的一阶偏导,求得梯度的幅值和方向,这样每个点都可能有4中方向情况(0,45,90,135度),在局部范围内,保留在同一方向上,梯度最大的点,非最大就置零,最后使用2个阈值T1和T2(T1<T2),T2用来找到每条线段,T1用来在这些线段的两个方向上延伸寻找边缘的断裂处,并连接这些边缘。
注:上下限阈值之比最好在2:1到3:1之间。
实现代码如下:
// 1.2.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include"opencv243.h"
using namespace cv;
using namespace std;
Mat image, cedge;
Mat gray, edge;
int edgeThresh = 1;
void onTrackbar(int, void*)
{
GaussianBlur(gray,edge,Size(3,3),0);//高斯滤波
// Canny 边缘检测
Canny(gray,edge, edgeThresh, edgeThresh*2, 3);
//全部设为0
cedge = Scalar::all(0);
//拷贝边缘的象素点
image.copyTo(cedge, edge);
imshow("edge", edge);
}
int _tmain(int argc, _TCHAR* argv[])
{
image=imread("C:\\Users\\sony\\Desktop\\Lena.jpg");
if(image.empty())
{
cout<<"miss the image file"<<endl;
return -1;
}
cedge.create(image.size(),image.type());//建立新的数组
cvtColor(image,gray,CV_RGB2GRAY); //转化为灰度图像
cvNamedWindow("edge",CV_WINDOW_AUTOSIZE);
createTrackbar("Canny Threshold", "edge", &edgeThresh, 100, onTrackbar);
waitKey(0);
return 0;
}