Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 图像像素的颜色不正确_C#_Imaging - Fatal编程技术网

C# 图像像素的颜色不正确

C# 图像像素的颜色不正确,c#,imaging,C#,Imaging,我试图用一个叫做SAD(平方差之和)的比较函数来比较两幅图像,我从每幅图像中取一个块,将像素转换成灰度,然后进行比较。 但问题是,如果我比较两个相同的块,sad的结果不是0(因此存在差异)。我检查了多个MessageBox,然后发现程序返回的像素颜色不正确:例如,黑色像素=255,而不是0 下面是我的比较函数的代码: public double SAD(bloc Bc, bloc Br) { double sad = 0; { B

我试图用一个叫做SAD(平方差之和)的比较函数来比较两幅图像,我从每幅图像中取一个块,将像素转换成灰度,然后进行比较。 但问题是,如果我比较两个相同的块,sad的结果不是0(因此存在差异)。我检查了多个MessageBox,然后发现程序返回的像素颜色不正确:例如,黑色像素=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;

    }
public-double-SAD(集团Bc,集团Br)
{
双sad=0;
{
BitmapData bmp=image1.LockBits(新矩形(Bc.x,Bc.y,taille_bloc,taille_bloc),ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb);
BitmapData bmp2=image2.LockBits(新矩形(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;
双gris1,gris2;
字节[]rgb=新字节[字节];
字节[]rgb2=新字节[字节];
System.Runtime.InteropServices.Marshal.Copy(ptr,rgb,0,字节);
System.Runtime.InteropServices.Marshal.Copy(ptr2,rgb2,0,字节);
对于(int i=0;i
如果我的解释不清楚,请告诉我,我会重新解释


非常感谢您的帮助:)

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

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;
    }
}
for(int row=0;row
您确定图像相同吗?如果您正在比较相同的图像,则应获得相同计算的相同结果。也许可以将公共部分抽象为一个函数,并为每个图像/像素调用该函数?您能否提供一个简短、自包含、可编译的示例(请参阅),以便我们可以快速运行它并尝试帮助您。您提供的一个包含缺少的类型和变量。首先,我不认为这是计算平方差之和。它看起来像是在计算差异的总和。第二,由于您正在计算差异,您可能不需要应用人眼颜色感知的校正因子。第三,您确定需要转换为灰度吗?我希望你们能理解,理论上,这可能会将两幅图像归类为相同的,即使它们的颜色可能不同。在任何情况下,即使需要转换为灰度,您也应该将其隔离在一个完全不同的函数中,您应该对该函数进行测试以确保其正常工作,从而最大限度地减少我们正在查看的代码中可能出现的错误。感谢您的回答,如果我使用bmp.Stride,我将如何访问我的RGB值?(在我的代码中,每次迭代我都会前进3步,如果我不知道我的表中有多少列,我就不知道RGB值存储在哪里)对不起,我之前在这里发表的评论是错误的,我删除了它。不需要对位图数据的每个字节进行循环,而是需要对每行(y)进行循环,并且在该循环中,需要对每列(x)进行另一个循环。像素的位置位于rgb[(y*bmp.Stride)+(x*3)+c],其中c=0、1或2表示R、G或B。当然,除非位图每像素使用4个字节,在这种情况下需要相应调整。