锐化空间域中的过滤器

时间:2016-08-24 22:21:56

标签: c# image-processing filter bitmap convolution

以下例程仅锐化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;
    }

1 个答案:

答案 0 :(得分: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;

此外,您不应该乘以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