Win8 Metro(C#)數字圖像處理--2.64圖像高斯濾波算法

原文: Win8 Metro(C#)數字圖像處理--2.64圖像高斯濾波算法



[函數名稱]php

  高斯平滑濾波器      GaussFilter(WriteableBitmap src,int radius,double sigma)html

[算法說明]算法

  高斯濾波器實質上是一種信號的濾波器,其用途是信號的平滑處理。它是一類根據高斯函數的函數

形狀來選擇權重的線性平滑濾波器,該濾波器對於抑制服從正態分佈的噪聲很是有效。高斯函數網站

的公式以下所示:spa


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的高斯模板以下:.net

這個公式能夠理解爲先對圖像按行進行一次一維高斯濾波,在對結果圖像按列進行一次一維高斯濾波,這樣速度將大大提升。code

一維高斯濾波代碼以下(包含歸一化)htm

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;
        }

[函數代碼]blog

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;
            }
        }



最後,分享一個專業的圖像處理網站(微像素),裏面有不少源代碼下載:
相關文章
相關標籤/搜索