c# - 模糊而不是锐化

标签 c# image-processing filter fft convolution

我正在使用以下内核,

  double[,] kernel = new double[,]  { { -1, -1, -1, }, 
                                        { -1,  9, -1, }, 
                                        { -1, -1, -1, }, };

以下代码似乎模糊了输入图像,而不是锐化。

这里可能出现什么问题?

这是entire VS2013 solution .

原始图像,

enter image description here

生成的模糊图像,

enter image description here

我编写了以下代码来锐化图像,

    public static Bitmap FftSharpen(Bitmap image, double [,] mask)
    {
        if (image.PixelFormat == PixelFormat.Format8bppIndexed)
        {
            Bitmap imageClone = (Bitmap)image.Clone();
            double[,] maskClone = (double[,])mask.Clone();

            Complex[,] cPaddedImage = ImageDataConverter.ToComplex(imageClone);
            Complex[,] cPaddedMask = ImageDataConverter.ToComplex(maskClone);
            Complex[,] cConvolved = Convolution.Convolve(cPaddedImage, cPaddedMask);

            return ImageDataConverter.ToBitmap(cConvolved);
        }
        else
        {
            throw new Exception("not a grascale");
        }
    }

.

.

附注

以下是我的卷积代码,

public static class Convolution
{
    public static Complex[,] Convolve(Complex[,] image, Complex[,] mask)
    {
        Complex[,] convolve = null;

        int imageWidth = image.GetLength(0);
        int imageHeight = image.GetLength(1);

        int maskWidth = mask.GetLength(0);
        int maskeHeight = mask.GetLength(1);

        if (imageWidth == maskWidth && imageHeight == maskeHeight)
        {
            FourierTransform ftForImage = new FourierTransform(image); ftForImage.ForwardFFT();
            FourierTransform ftForMask = new FourierTransform(mask); ftForMask.ForwardFFT();

            Complex[,] fftImage = ftForImage.FourierImageComplex;
            Complex[,] fftKernel = ftForMask.FourierImageComplex;

            Complex[,] fftConvolved = new Complex[imageWidth, imageHeight];


            for (int j = 0; j < imageHeight; j++)
            {
                for (int i = 0; i < imageWidth; i++)
                {
                    fftConvolved[i, j] = fftImage[i, j] * fftKernel[i, j];
                }
            }

            FourierTransform ftForConv = new FourierTransform();

            ftForConv.InverseFFT(fftConvolved);

            convolve = ftForConv.GrayscaleImageComplex;

            Rescale(convolve);

            convolve = FourierShifter.FFTShift(convolve);
        }
        else
        {
            throw new Exception("padding needed");
        }

        return convolve;
    }

    //Rescale values between 0 and 255.
    private static void Rescale(Complex[,] convolve)
    {
        int imageWidth = convolve.GetLength(0);
        int imageHeight = convolve.GetLength(1);

        double maxAmp = 0.0;
        for (int j = 0; j < imageHeight; j++)
        {
            for (int i = 0; i < imageWidth; i++)
            {
                maxAmp = Math.Max(maxAmp, convolve[i, j].Magnitude);
            }
        }
        double scale = 255.0 / maxAmp;

        for (int j = 0; j < imageHeight; j++)
        {
            for (int i = 0; i < imageWidth; i++)
            {
                convolve[i, j] = new Complex(convolve[i, j].Real * scale, convolve[i, j].Imaginary * scale);
                maxAmp = Math.Max(maxAmp, convolve[i, j].Magnitude);
            }
        }
    }
}

最佳答案

类似于your other question ,内核是从无符号的位图获得的,从而产生有效的内核

255 255 255
255  9  255
255 255 255

而不是预期的

-1 -1 -1
-1  9 -1
-1 -1 -1

解决方案再次是 convert the bitmap to signed values 。或者,由于本问题中提供的代码还支持直接向 FftSharpen 提供数值内核,因此您可以使用以下内容填充 _numericalKernel:

public class MatrixPadder
{
  public static double[,] Pad(double[,] image, int newWidth, int newHeight)
  {
    int width = image.GetLength(0);
    int height = image.GetLength(1);
    /*
     It is always guaranteed that,

          width < newWidth

              and

          height < newHeight                  
     */
    if ((width < newWidth && height < newHeight)
          || (width < newWidth && height == newHeight)
          || (width == newWidth && height < newHeight))
    {
      double[,] paddedImage = new double[newWidth, newHeight];

      int startPointX = (int)Math.Ceiling((double)(newWidth - width) / (double)2) - 1;
      int startPointY = (int)Math.Ceiling((double)(newHeight - height) / (double)2) - 1;

      for (int y = startPointY; y < (startPointY + height); y++)
      {
        for (int x = startPointX; x < (startPointX + width); x++)
        {
          int xxx = x - startPointX;
          int yyy = y - startPointY;

          paddedImage[x, y] = image[xxx, yyy];
        }
      }

      return paddedImage;
    }
    else if (width == newWidth && height == newHeight)
    {
      return image;
    }
    else
    {
      throw new Exception("Pad() -- threw an exception");
    }
  }
}

您可以使用以下方式从 filterButton_Click 调用:

if (_convolutionType == ConvolutionType.FFT)
{
  double[,] paddedmask = MatrixPadder.Pad(_numericalKernel,
                                          _paddedImage.Width,
                                          _paddedImage.Height);
  sharpened = SharpenFilter.FftSharpen(_paddedImage, paddedmask);
}

同时调整Rescale功能as shown in my other answer然后应该为您提供所需的锐化图像:

Sharpened

关于c# - 模糊而不是锐化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39171901/

相关文章:

c# - 拒绝访问端口 "COM1"

基于Set类型的Java流过滤器

python - 点积过滤数据框 pandas

jquery - 使搜索输入通过列表 Jquery 进行过滤

c# - 在 ASP.NET MVC 4 架构注意事项中上传和处理 CSV 文件

c# - 有什么理由不重构它,使其更简单吗?

javascript - 从 C# 项目页面导航到 Javascript 项目页面 Windows Phone 8.1

matlab - 使用MatLab计算信号:noise ratio

python - Numpy 点积

image-processing - 公寓照片的图像相似度