曾经学习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实现详解(二)
