模糊而不是削尖

时间:2016-08-26 17:39:17

标签: 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");
        }
    }

P.S。

以下是我的卷积码,

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

1 个答案:

答案 0 :(得分:2)

your other question类似,内核是从无符号Bitmap获得的,这导致了有效的内核

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