[函数名称]
高斯平滑滤波器 GaussFilter(WriteableBitmap src,int radius,double sigma)
[算法说明]
高斯滤波器实质上是一种信号的滤波器,其用途是信号的平滑处理。它是一类根据高斯函数的
形状来选择权重的线性平滑滤波器,该滤波器对于抑制服从正态分布的噪声非常有效。高斯函数
的公式如下所示:
private static double[,] GaussFuc(int r, double sigma) { int size = 2 * r + 1; double[,] gaussResult = new double[size, size]; double k = 0.0; for (int y = -r, h = 0; y <= r; y++, h++) { for (int x = -r, w = 0; x <= r; x++, w++) { gaussResult[w, h] = (1.0 / (2.0 * Math.PI * sigma * sigma)) * (Math.Exp(-((double)x * (double)x + (double)y * (double)y) / (2.0 * sigma * sigma)));k += gaussResult[w, h]; } } return gaussResult; }
我们设置参数r=1,sigma=1.0,则得到一个3*3的高斯模板如下:
这个公式可以理解为先对图像按行进行一次一维高斯滤波,在对结果图像按列进行一次一维高斯滤波,这样速度将大大提高。
一维高斯滤波代码如下(包含归一化):
private static double[] GaussKernel1D(int r, double sigma) { double[] filter = new double[2 * r + 1]; double sum = 0.0; for (int i = 0; i < filter.Length; i++) { filter[i] = Math.Exp((double)(-(i - r) * (i - r)) / (2.0 * sigma * sigma)); sum += filter[i]; } for (int i = 0; i < filter.Length; i++) { filter[i] = filter[i] / sum; } return filter; }
[函数代码]
private static double[] GaussKernel(int radius, double sigma) { int length=2*radius+1; double[] kernel = new double[length]; double sum = 0.0; for (int i = 0; i < length; i++) { kernel[i] = Math.Exp((double)(-(i - radius) * (i - radius)) / (2.0 * sigma * sigma)); sum += kernel[i]; } for (int i = 0; i < length; i++) { kernel[i] = kernel[i] / sum; } return kernel; } ////// Gauss filter process /// /// The source image. /// The radius of gauss kernel,from 0 to 100. /// The convince of gauss kernel, from 0 to 30. ///public static WriteableBitmap GaussFilter(WriteableBitmap src,int radius,double sigma) 高斯滤波 { if (src != null) { int w = src.PixelWidth; int h = src.PixelHeight; WriteableBitmap srcImage = new WriteableBitmap(w, h); byte[] srcValue = src.PixelBuffer.ToArray(); byte[] tempValue=(byte[])srcValue.Clone(); double[] kernel = GaussKernel(radius, sigma); double tempB = 0.0, tempG = 0.0, tempR = 0.0; int rem = 0; int t = 0; int v = 0; double K = 0.0; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { tempB = tempG = tempR = 0.0; for (int k = -radius; k <= radius; k++) { rem = (Math.Abs(x + k) % w); t = rem * 4 + y * w * 4; K=kernel[k+radius]; tempB += srcValue[t] * K; tempG += srcValue[t + 1] * K; tempR += srcValue[t + 2] * K; } v = x * 4 + y * w * 4; tempValue[v] = (byte)tempB; tempValue[v + 1] = (byte)tempG; tempValue[v + 2] = (byte)tempR; } } for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { tempB = tempG = tempR = 0.0; for (int k = -radius; k <= radius; k++) { rem = (Math.Abs(y + k) % h); t = rem * w * 4 + x * 4; K = kernel[k + radius]; tempB += tempValue[t] * K; tempG += tempValue[t + 1] * K; tempR += tempValue[t + 2] * K; } v = x * 4 + y * w * 4; srcValue[v] = (byte)tempB; srcValue[v + 1] = (byte)tempG; srcValue[v + 2] = (byte)tempR; } } Stream sTemp = srcImage.PixelBuffer.AsStream(); sTemp.Seek(0, SeekOrigin.Begin); sTemp.Write(srcValue, 0, w * 4 * h); return srcImage; } else { return null; } }
最后,分享一个专业的图像处理网站(微像素),里面有很多源代码下载: