锐化空间域中的过滤器

问题描述:

以下例程仅用于锐化8位索引灰度。锐化空间域中的过滤器

public static Bitmap Sharpen(Bitmap image, double strength) 
    { 
     using (var bitmap1 = image as Bitmap) 
     { 
      if (bitmap1 != null) 
      { 
       var bitmap = bitmap1.Clone() as Bitmap; 

       int width = image.Width; 
       int height = image.Height; 

       // Create sharpening filter. 
       const int filterSize = 5; 

       var filter = new double[,] 
       { 
        {-1, -1, -1, -1, -1}, 
        {-1, 2, 2, 2, -1}, 
        {-1, 2, 16, 2, -1}, 
        {-1, 2, 2, 2, -1}, 
        {-1, -1, -1, -1, -1} 
       }; 

       int channels = sizeof(byte); 
       double bias = 1.0 - strength; 
       double factor = strength/16.0; 
       const int halfOfFilerSize = filterSize/2; 

       byte[,] result = new byte[image.Width, image.Height]; 

       // Lock image bits for read/write. 
       if (bitmap != null) 
       { 
        BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), 
                   ImageLockMode.ReadWrite, 
                   PixelFormat.Format8bppIndexed); 

        // Declare an array to hold the bytes of the bitmap. 
        int memorySize = bitmapData.Stride * height; 
        byte[] memory = new byte[memorySize]; 

        // Copy the RGB values into the local array. 
        Marshal.Copy(bitmapData.Scan0, memory, 0, memorySize); 

        int rgb; 
        // Fill the color array with the new sharpened color values. 

        for (int y = halfOfFilerSize; y < height - halfOfFilerSize; y++) 
        { 
         for (int x = halfOfFilerSize; x < width - halfOfFilerSize; x++) 
         { 
          for (int filterY = 0; filterY < filterSize; filterY++) 
          { 
           double grayShade = 0.0; 

           for (int filterX = 0; filterX < filterSize; filterX++) 
           { 
            int imageX = (x - halfOfFilerSize + filterX + width) % width; 
            int imageY = (y - halfOfFilerSize + filterY + height) % height; 

            rgb = imageX * bitmapData.Stride + channels * imageY; 

            grayShade += memory[rgb + 0] * filter[filterX, filterY]; 
           } 

           rgb = x * bitmapData.Stride + channels * y; 

           int b = Math.Min(Math.Max((int)(factor * grayShade + (bias * memory[rgb + 0])), 0), 255); 

           result[x, y] = (byte)b; 
          } 
         } 
        } 

        // Update the image with the sharpened pixels. 
        for (int x = halfOfFilerSize; x < width - halfOfFilerSize; x++) 
        { 
         for (int y = halfOfFilerSize; y < height - halfOfFilerSize; y++) 
         { 
          rgb = y * bitmapData.Stride + 3 * x; 

          memory[rgb + 0] = result[x, y]; 
         } 
        } 

        // Copy the RGB values back to the bitmap. 
        Marshal.Copy(memory, 0, bitmapData.Scan0, memorySize); 

        // Release image bits. 
        bitmap.UnlockBits(bitmapData); 
       } 

       return bitmap; 
      } 
     } 
     return null; 
    } 

这个程序在下面的行抛出异常:

grayShade += memory[rgb + 0] * filter[filterX, filterY]; 

enter image description here

什么我计算错了吗?

P.S. GUI代码:

private void sharpenButton_Click(object sender, EventArgs e) 
    { 
     Bitmap sharpened = ImageSharpener.Sharpen(_inputImage, 0.5); 

     sharpenedPictureBox.Image = sharpened; 
    } 
+0

分手征服,使用调试器并逐步执行代码以查找原因! :)顺便说一句,不是你的过滤器应该通过'-halfSize'到每个像素的'+ halfSize',并通过夹紧或包装来处理边界? – Aybe

此:

rgb = imageX * bitmapData.Stride + channels * imageY;

应该是:

rgb = imageY * bitmapData.Stride + channels * imageX;

这:

rgb = x * bitmapData.Stride + channels * y;

应该是:

rgb = y * bitmapData.Stride + channels * x;

而且,你不应该channels大量繁殖,这已经是bitmapData.Stride一部分。另外,请注意channels = sizeof(byte),这只是1,而不是3(暗示为rgb = y * bitmapData.Stride + 3 * x;)。

修复上述错误之后,您的过滤器可能仍然不起作用。要么进行调试,要么与此处的解决方案进行比较:C# Convolution filter for any size matrix (1x1, 3x3, 5x5, ...) not fully applied

+0

@anonymous请参阅添加到答案底部的链接。 – Diego

+0

可以请你回答这个问题,http://*.com/questions/39302863/filter-spatial-domain-versus-frequency-domain – anonymous