图像像素颜色不正确

发布于 2024-12-22 16:43:20 字数 1455 浏览 2 评论 0原文

我正在尝试使用称为 SAD(平方差之和)的比较函数来比较 2 个图像,我从每个图像中取出一个块,然后将像素转换为灰度并进行比较。 但问题是,如果我比较两个相同的块,sad 的结果不是 0(因此存在差异)。我检查了多个消息框,然后发现程序返回了错误的像素颜色:例如,黑色像素=255而不是0。

这是我的比较函数的代码:

 public double SAD(bloc Bc, bloc Br)
    {
        double sad = 0;
        {
            BitmapData bmp = image1.LockBits(new Rectangle(Bc.x, Bc.y, taille_bloc, taille_bloc), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            BitmapData bmp2 = image2.LockBits(new Rectangle(Br.x, Br.y, taille_bloc, taille_bloc), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            IntPtr ptr2 = bmp2.Scan0;
            IntPtr ptr = bmp.Scan0;
            int bytes = bmp.Width * bmp.Height * 3;
            double gris1, gris2;
            byte[] rgb = new byte[bytes];
            byte[] rgb2 = new byte[bytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgb, 0, bytes);
            System.Runtime.InteropServices.Marshal.Copy(ptr2, rgb2, 0, bytes);
            for (int i = 0; i < rgb.Length; i += 3)
            {

                 gris1 = rgb[i] * 0.2989 + rgb[i+1] * 0.5870 + rgb[i+2] * 0.1140;
                 gris2 = rgb2[i] * 0.2989 + rgb2[i + 1] * 0.5870 + rgb2[i + 2] *  0.1140;

                sad = sad + Math.Abs(gris2 - gris1);

            }
            image2.UnlockBits(bmp2);

            image1.UnlockBits(bmp);
        }

        return sad;

    }

如果我的解释不清楚,请告诉我所以我将重新表述,

非常感谢您的帮助:)

I'm trying to compare 2 images with a comparison function called SAD (sum of square differences), I take a block from each image, and I convert the pixels to grayscale and I do the comparison.
but the problem is that if I compare two identical blocks, the result of sad isn't 0 (so there is a difference). I checked with multiple messageboxes and then I saw that the program returns incorrect colors for pixels: for example, black pixel=255 instead of 0.

here the code of my comparison function:

 public double SAD(bloc Bc, bloc Br)
    {
        double sad = 0;
        {
            BitmapData bmp = image1.LockBits(new Rectangle(Bc.x, Bc.y, taille_bloc, taille_bloc), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            BitmapData bmp2 = image2.LockBits(new Rectangle(Br.x, Br.y, taille_bloc, taille_bloc), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            IntPtr ptr2 = bmp2.Scan0;
            IntPtr ptr = bmp.Scan0;
            int bytes = bmp.Width * bmp.Height * 3;
            double gris1, gris2;
            byte[] rgb = new byte[bytes];
            byte[] rgb2 = new byte[bytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgb, 0, bytes);
            System.Runtime.InteropServices.Marshal.Copy(ptr2, rgb2, 0, bytes);
            for (int i = 0; i < rgb.Length; i += 3)
            {

                 gris1 = rgb[i] * 0.2989 + rgb[i+1] * 0.5870 + rgb[i+2] * 0.1140;
                 gris2 = rgb2[i] * 0.2989 + rgb2[i + 1] * 0.5870 + rgb2[i + 2] *  0.1140;

                sad = sad + Math.Abs(gris2 - gris1);

            }
            image2.UnlockBits(bmp2);

            image1.UnlockBits(bmp);
        }

        return sad;

    }

If I didn't be clear in my explanation please tell me so I will reformulate

thank you very much in advance for your help :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

吃兔兔 2024-12-29 16:43:20

一个可能的问题是您的字节数计算错误。你有:

int bytes = bmp.Width * bmp.Height * 3;

但是位图被填充,通常填充到 4 字节边界。您需要使用

int bytes = bmp.Stride * bmp.Height;

Stride 来表示扫描线所需的字节数。对于 24 位图像,这等于 3 * bmp.Width 加上填充所需的字节数(可能为零)。

然后,要对数组进行索引,请逐行进行索引,并忽略填充字节。您必须在每行的开头初始化索引。

for (int row = 0; row < bmp.Height; ++row)
{
    int i = row * bmp.Stride;
    for (int p = 0; p < bmp.Width; ++p)
    {
        // do comparisons with rgb[i], rgb[i+1], rgb[i+2]
        i += 3;
    }
}

One possible problem is that your number of bytes calculation is wrong. You have:

int bytes = bmp.Width * bmp.Height * 3;

But bitmaps are padded, typically to a 4-byte boundary. You need to use

int bytes = bmp.Stride * bmp.Height;

Stride is the number of bytes it takes to represent a scan line. For a 24-bit image, that will be equal to 3 * bmp.Width PLUS the number of bytes required for padding (which might be zero).

To index the array, then, you go line by line, and ignore the padding bytes. You have to initialize your index at the beginning of each row.

for (int row = 0; row < bmp.Height; ++row)
{
    int i = row * bmp.Stride;
    for (int p = 0; p < bmp.Width; ++p)
    {
        // do comparisons with rgb[i], rgb[i+1], rgb[i+2]
        i += 3;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文