Canny边缘检测算法是澳大利亚科学家John F. Canny在1986年提出来的,不得不提一下的是当年John Canny本人才28岁!到今天已经30年过去了,Canny算法仍然是图像边缘检测算法中最经典、有效的算法之一。
一起睹一下大家Canny的风采:

John Canny研究了最优边缘检测方法所需的特性,给出了评价边缘检测性能优劣的3个指标:
1 好的信噪比,即将非边缘点判定为边缘点的概率要低,将边缘点判为非边缘点的概率要低;
2 高的定位性能,即检测出的边缘点要尽可能在实际边缘的中心;
3 对单一边缘仅有唯一响应,即单个边缘产生多个响应的概率要低,并且虚假响应边缘应该得到最大抑制;
Canny算法就是基于满足这3个指标的最优解实现的,在对图像中物体边缘敏感性的同时,也可以抑制或消除噪声的影响。canny边缘检测 c语言canny边缘检测 c语言
Canny算子边缘检测的具体步骤如下:
一、用高斯滤波器平滑图像
二、用Sobel等梯度算子计算梯度幅和方向
三、对梯度幅进行非极大抑制
四、用双阈算法检测和连接边缘
高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,特别是对抑制或消除服从正态分布的噪声非常有效。滤波可以消除或降低图像中噪声的影响,使用高斯滤波器主要是基于在滤波降噪的同时也可以最大限度保留边缘信息的考虑。
//******************灰度转换函数*************************
//第一个参数image输入的彩色RGB图像;
//第二个参数imageGray是转换后输出的灰度图像;
//*************************************************************
void ConvertRGB2GRAY(const Mat &image,Mat &imageGray)
{
if(!image.data||image.channels()!=3)
{
return ;
}
imageGray=Mat::zeros(image.size(),CV_8UC1);
uchar *pointImage=image.data;
uchar *pointImageGray=imageGray.data;
int stepImage=image.step;
int stepImageGray=imageGray.step;
for(int i=0;i<imageGray.rows;i++)
{
for(int j=0;j<imageGray.cols;j++)
{
pointImageGray[i*stepImageGray+j]=0.114*pointImage[i*stepImage+3*j]+0.587*pointImage[i*stepImage+3*j+1]+0.299*pointImage[i*stepImage+3*j+2];
}
}
}RGB原图像: 转换后的灰度图:
//******************高斯卷积核生成函数*************************
//第一个参数gaus是一个指向含有N个double类型数组的指针;
//第二个参数size是高斯卷积核的尺寸大小;
//第三个参数sigma是卷积核的标准差
//*************************************************************
void GetGaussianKernel(double **gaus, const int size,const double sigma)
{
const double PI=4.0*atan(1.0); //圆周率π赋值
int center=size/2;
double sum=0;
for(int i=0;i<size;i++)
{
for(int j=0;j<size;j++)
{
gaus[i][j]=(1/(2*PI*sigma*sigma))*exp(-((i-center)*(i-center)+(j-center)*(j-center))/(2*sigma*sigma));
sum+=gaus[i][j];
}
}
for(int i=0;i<size;i++)
{
for(int j=0;j<size;j++)
{
gaus[i][j]/=sum;
cout<<gaus[i][j]<<" ";
}
cout<<endl<<endl;
}
return ;
}Sigma为1时,求得的3*3大小的高斯卷积核参数为:
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-33925-1.html
落导为你骄傲