2016-08-26 25 views
2

我使用下面的内核,模糊而不是削尖

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

回答

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