我正在使用以下内核,

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


下面的代码似乎使输入图像模糊,而不是锐化。

这里可能是什么问题?

这是entire VS2013 solution

原始图片,

c# - 模糊而不是锐化-LMLPHP

产生的模糊图像,

c# - 模糊而不是锐化-LMLPHP

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

    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类似,从无符号的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应该会为您提供所需的锐化图像:

c# - 模糊而不是锐化-LMLPHP

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

10-11 11:45