当位图宽度不能被4整除时,为什么此边缘检测器无法正常工作?

问题描述 投票:2回答:1

使用下面的Sobel边缘检测器代码,如果输入位图的宽度不能被4整除,则我发现输出位图的对角线叠加有零值,而检测到的边缘上没有。4。 (80,80)被打碎,并且在这种情况下放置不正确。为什么会这样,如何使代码在任何位图宽度下都能工作?

        private Bitmap SobelEdgeDetect2(Bitmap original, byte Threshold = 128)
    {

        // https://stackoverflow.com/questions/16747257/edge-detection-with-lockbits-c-sharp

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

        int BitsPerPixel = Image.GetPixelFormatSize(original.PixelFormat);
        int OneColorBits = BitsPerPixel / 8;

        BitmapData bmpData = original.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, original.PixelFormat);
        int position;
        int[,] gx = new int[,] { { -1, 0, 1 }, { -2, 0, 2 }, { -1, 0, 1 } };
        int[,] gy = new int[,] { { 1, 2, 1 }, { 0, 0, 0 }, { -1, -2, -1 } };

        Bitmap dstBmp = new Bitmap(width, height, original.PixelFormat);
        BitmapData dstData = dstBmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, dstBmp.PixelFormat);

        int byteCount = dstData.Stride * dstBmp.Height;          
        byte[] input = new byte[byteCount];
        byte[] processed = new byte[byteCount];
        IntPtr ptr = bmpData.Scan0;
        IntPtr dst = dstData.Scan0;
        Marshal.Copy(ptr, input, 0, input.Length);
        Marshal.Copy(dst,processed, 0, input.Length);

        int BlackPoints = 0;
        int WhitePoints = 0;

        for (int i = 1; i < height - 1; i++) // y
        {
            for (int j = 1; j < width - 1; j++)  // x 
                 {
                int NewX = 0, NewY = 0;

                for (int ii = 0; ii < 3; ii++)
                {
                    for (int jj = 0; jj < 3; jj++)
                    {
                        int I = i + ii - 1;
                        int J = j + jj - 1;

                            byte Current = input[(I * (width) + J) * OneColorBits];
                            NewX += gx[ii, jj] * Current;
                            NewY += gy[ii, jj] * Current;                            
                    }
                }
                position = (i * (width) + j) * OneColorBits;

                if (NewX * NewX + NewY * NewY > Threshold * Threshold)
                {
                    processed[position] = 255;
                    processed[position + 1] = 255;
                    processed[position + 2] = 255;
                    WhitePoints++;
                }
                else
                {
                    processed[position] = 0;
                    processed[position + 1] = 0;
                    processed[position + 2] = 0;
                    BlackPoints++;
                }

                if (j >= 78 && j <= 82 && i >= 78 && i <= 82)
                {
                    processed[position] = 0;
                    processed[position + 1] = 0;
                    processed[position + 2] = 255;
                }

            }

        }

        Marshal.Copy(processed, 0, dst, input.Length);
        dstBmp.UnlockBits(dstData);

        return dstBmp;
    }
c# image-processing edge-detection
1个回答
0
投票
对于201像素宽的位图,dstData.Stride为604。对于200像素宽的位图dstData.Stride为612,这说明了为什么我的代码必须将宽度除以4。

替换

position = (i * (width) + j) * OneColorBits;

作者

position = i * dstData.Stride + j * OneColorBits;

byte Current = input[(I * (width) + J) * OneColorBits];

作者

byte Current = input[I * dstData.Stride + J * OneColorBits];

已解决问题。
© www.soinside.com 2019 - 2024. All rights reserved.