高斯模糊实现无法正常工作

时间:2014-01-12 20:42:38

标签: c# image-processing gaussian

我正在尝试实现一个简单的高斯模糊函数,但是当在图像上运行时,它会比原始图像更加不透明;没有模糊。

    public double[,] CreateGaussianFilter(int size)
    {
        double[,] gKernel = new double[size,size];

        for (int y = 0; y < size; y++)
            for (int x = 0; x < size; x++)
                gKernel[y,x] = 0.0;

        // set standard deviation to 1.0
        double sigma = 1.0;
        double r, s = 2.0 * sigma * sigma;

        // sum is for normalization
        double sum = 0.0;

        // generate kernel
        for (int x = -size/2; x <= size/2; x++)
        {
            for(int y = -size/2; y <= size/2; y++)
            {
                r = Math.Sqrt(x*x + y*y);
                gKernel[x + size/2, y + size/2] = (Math.Exp(-(r*r)/s))/(Math.PI * s);
                sum += gKernel[x + size/2, y + size/2];
            }
        }

        // normalize the Kernel
        for(int i = 0; i < size; ++i)
            for(int j = 0; j < size; ++j)
                gKernel[i,j] /= sum;

        return gKernel;
    }

    public void GaussianFilter(ref LockBitmap image, double[,] filter)
    {
        int size = filter.GetLength(0);
        for (int y = size/2; y < image.Height - size/2; y++)
        {
            for (int x = size/2; x < image.Width - size/2; x++)
            {
                //Grab surrounding pixels and stick them in an accumulator
                double sum = 0.0;
                int filter_y = 0;
                for (int r = y - (size / 2); r < y + (size / 2); r++)
                {
                    int filter_x = 0;
                    for (int c = x - (size / 2); c < x + (size / 2); c++)
                    {
                        //Multiple surrounding pixels by filter, add them up and set the center pixel (x,y) to this value
                        Color pixelVal = image.GetPixel(c, r);
                        double grayVal = (pixelVal.B + pixelVal.R + pixelVal.G) / 3.0;
                        sum += grayVal * filter[filter_y,filter_x];
                        filter_x++;
                    }
                    filter_y++;
                }
                //set the xy pixel 
                image.SetPixel(x,y, Color.FromArgb(255, (int)sum,(int)sum, (int)sum));
            }
        }
    }

非常感谢任何建议。谢谢!

1 个答案:

答案 0 :(得分:3)

您的解决方案有很多方面。

  1. 卷积图像变暗通常意味着内核中的增益小于1.虽然在这种情况下可能不是,但请参阅(5)。
  2. 高斯模糊是一个可分离的内核,可以在比蛮力更短的时间内执行。
  3. 将RGB平均为灰色不是计算亮度的光学“正确”方法。
  4. getpixel,setpixel方法一般都很慢。如果您使用支持指针的语言,则应使用它们。看起来像C#?使用不安全的代码来访问指针。
  5. int()truncates - 这可能是降低亮度的原因。你本质上总是四舍五入。
  6. 内核生成函数中的嵌套循环包含过多的边界调整。这可能会更快,但更好,但用可分离的方法取代。
  7. 您正在单个缓冲区中进行卷积。因此,您正在卷入令人心碎的价值观。
  8. 由于