【问题标题】:Blurred rather than Sharpened模糊而不是锐化
【发布时间】:2016-08-26 17:39:16
【问题描述】:

我正在使用以下内核,

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

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

这可能是什么问题?

这里是entire VS2013 solution。

原图,

生成的模糊图像,

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

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

【问题讨论】:

    标签: c# image-processing filter fft convolution


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 2017-12-01
      • 1970-01-01
      • 2018-10-28
      • 1970-01-01
      • 2011-09-02
      • 1970-01-01
      • 2014-10-03
      • 2023-03-17
      • 1970-01-01
      相关资源
      最近更新 更多