曾经学习canny时,学到了大神的高斯模板生成,由于二维高斯的可分离性,形成一维的x方向和y方向的高斯模板,之所以选择一维的原因,
一是,处理图像速度效率高
二是,图像周边处理效果好
大神的代码是c++的,我翻译成c#的呈上:
double nSigma = 1.25; //定义高斯函数的标准差
int nWidowSize = (int)(1 + 2 * Math.Ceiling(3 * nSigma)); //定义滤波窗口的大小 int nWidowSize = 1 + 2 * ceil(3 * nSigma );
int nCenter = (nWidowSize) / 2;
double[] nData = new double[512 * 512];
byte[] glob_buffer512512smooth1dot25 = new byte[512 * 512];
//生成一维高斯滤波系数/
double[] pdKernal_1 = new double[nWidowSize]; //定义一维高斯核数组
double dSum_1 = 0.0; //求和,用于进行归一化
//一维高斯函数公式//
// x*x /
// -1*---------------- /
// 1 2*Sigma*Sigma /
// ------------ e /
// /
// \/2*pi*Sigma /
//
for (int i = 0; i < nWidowSize; i++)
{
double nDis = (double)(i - nCenter);
pdKernal_1[i] = Math.Exp(-(0.5) * nDis * nDis / (nSigma * nSigma)) / (Math.Sqrt(2 * 3.14159) * nSigma);
dSum_1 += pdKernal_1[i];
}
for (int i = 0; i < nWidowSize; i++)
{
pdKernal_1[i] /= dSum_1; //进行归一化
}
for (int i = 0; i < 512; i++) //进行x向的高斯滤波(加权平均)
{
for (int j = 0; j < 512; j++)
{
double dSum = 0;
double dFilter = 0; //滤波中间值
for (int nLimit = (-nCenter); nLimit <= nCenter; nLimit++)
{
if ((j + nLimit) >= 0 && (j + nLimit) < 512) //图像不能超出边界
{
dFilter += (int)glob_buffer512512[i * 512 + j + nLimit] * pdKernal_1[nCenter + nLimit];
dSum += pdKernal_1[nCenter + nLimit];
}
}
nData[i * 512 + j] = dFilter / dSum;//x方向处理完成的中间结果
}
}
for (int i = 0; i < 512; i++) //进行y向的高斯滤波(加权平均)
{
for (int j = 0; j < 512; j++)
{
double dSum = 0.0;
double dFilter = 0;
for (int nLimit = (-nCenter); nLimit <= nCenter; nLimit++)
{
if ((j + nLimit) >= 0 && (j + nLimit) < 512) //图像不能超出边界
{
dFilter += nData[(j + nLimit) * 512 + i] * pdKernal_1[nCenter + nLimit];
dSum += pdKernal_1[nCenter + nLimit];
}
}//完成了x,y方向的整个高斯平滑
oct1globbuffer1layer[j * 512 + i] = glob_buffer512512smooth1dot25[j * 512 + i] = (byte)((int)dFilter / dSum);
}//第一组高斯金字塔第一层图像生成实现
}
注:参考csdn大神的博客:Canny边缘检测算法原理及其VC实现详解(二)