2016-08-24 19 views
0

次のルーチンは、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

征服するには、デバッガを使用して原因を突き止めてください! :) BTWは、各ピクセルに対して '-halfSize'から' + halfSize'に移動し、クランプまたはラッピングのいずれかによって枠線を処理するフィルタではありませんか? – Aybe

答えて

1

この:

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

は次のようになります。

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

そして、この:

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

は次のようになります。

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

また、あなたはそれがすでにbitmapData.Strideの一部だ、channelsを掛けてはいけません。また、が暗示しているように、channels = sizeof(byte)は3でなく1だけです。

上記のエラーを修正した後でも、フィルタが動作しないことがあります。デバッグするか、ソリューションと比較してください:C# Convolution filter for any size matrix (1x1, 3x3, 5x5, ...) not fully applied

+0

@anonymous答えの一番下に追加されたリンクを参照してください。 – Diego

+0

この質問にお答えください。http://stackoverflow.com/questions/39302863/filter-spatial-domain-versus-frequency-domain – anonymous

関連する問題