您的位置:首页 > 编程语言 > C#

Win8 Metro(C#)数字图像处理--2.64图像高斯滤波算法

2015-04-24 12:59 375 查看

[函数名称]
高斯平滑滤波器 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;
        }
        /// <summary>
        /// Gauss filter process
        /// </summary>
        /// <param name="src">The source image.</param>
        /// <param name="radius">The radius of gauss kernel,from 0 to 100.</param>
        /// <param name="sigma">The convince of gauss kernel, from 0 to 30.</param>
        /// <returns></returns>
        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;
            }
        }




最后,分享一个专业的图像处理网站(微像素),里面有很多源代码下载:

http://www.zealpixel.com/portal.php
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: