我正在尝试使用LockBits比较两个图像,但它不起作用 - 为什么?

时间:2013-12-22 10:41:51

标签: c# winforms

这是方法:

public static Bitmap FastComparison(Bitmap bmp1,Bitmap bmp2)
{
            Bitmap bmp3 = new Bitmap(512,512);
            PixelFormat pxf = PixelFormat.Format24bppRgb;
            Rectangle rect = new Rectangle(0, 0, bmp1.Width, bmp1.Height);
            BitmapData bmpData1 = bmp1.LockBits(rect, ImageLockMode.ReadWrite, pxf);
            BitmapData bmpData2 = bmp2.LockBits(rect, ImageLockMode.ReadWrite, pxf);
            BitmapData bmpData3 = bmp3.LockBits(rect, ImageLockMode.ReadWrite, pxf);

            IntPtr ptr1 = bmpData1.Scan0;
            IntPtr ptr2 = bmpData2.Scan0;
            IntPtr ptr3 = bmpData3.Scan0;

            int numBytes = bmpData1.Stride * bmp1.Height;
            byte[] rgbValues1 = new byte[numBytes];
            Marshal.Copy(ptr1, rgbValues1, 0, numBytes);
            bmp1.UnlockBits(bmpData1);

            byte[] rgbValues2 = new byte[numBytes];
            Marshal.Copy(ptr2, rgbValues2, 0, numBytes);
            bmp2.UnlockBits(bmpData2);


            for (int counter = 0; counter < rgbValues1.Length; counter += 3)
            {
                int  dr, dg, db;
                dr = (int)rgbValues1[counter] - (int)rgbValues2[counter];
                dg = (int)rgbValues1[counter + 1] - (int)rgbValues2[counter + 1];
                db = (int)rgbValues1[counter + 2] - (int)rgbValues2[counter + 2];

                int error = dr * dr + dg * dg + db * db;
                if (error < tolerancenumeric)
                {
                    rgbValues1[counter] = 0;
                    rgbValues1[counter + 1] = 0;
                    rgbValues1[counter + 2] = 0;
                }

            }
            Marshal.Copy(rgbValues1, 0, ptr3, numBytes);
            return bmp1;
}

这就是我在Form1中使用/调用它的方式:

private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
              CloudEnteringAlert.tolerancenum = (int)numericUpDown1.Value;
              pictureBox1.Image = CloudEnteringAlert.FastComparison(bitmapwithclouds, bitmapwithoutclouds);
}

我想要的是更改公差,所以最后我会得到一个结果,其中图像变量bmp1将仅在黑色背景上显示云。

我做错了什么?

这是我现在更改它的新方法。现在我只得到黑色图像:

public static Bitmap FastComparison(Bitmap bmp1,Bitmap bmp2)
        {
            Bitmap bmp3 = new Bitmap(512,512);
            PixelFormat pxf = PixelFormat.Format24bppRgb;
            Rectangle rect = new Rectangle(0, 0, bmp1.Width, bmp1.Height);
            BitmapData bmpData1 = bmp1.LockBits(rect, ImageLockMode.ReadWrite, pxf);
            BitmapData bmpData2 = bmp2.LockBits(rect, ImageLockMode.ReadWrite, pxf);
            BitmapData bmpData3 = bmp3.LockBits(rect, ImageLockMode.ReadWrite, pxf);

            IntPtr ptr1 = bmpData1.Scan0;
            IntPtr ptr2 = bmpData2.Scan0;
            IntPtr ptr3 = bmpData3.Scan0;

            int numBytes = bmpData1.Stride * bmp1.Height;
            byte[] rgbValues1 = new byte[numBytes];
            Marshal.Copy(ptr1, rgbValues1, 0, numBytes);
            bmp1.UnlockBits(bmpData1);

            byte[] rgbValues2 = new byte[numBytes];
            Marshal.Copy(ptr2, rgbValues2, 0, numBytes);
            bmp2.UnlockBits(bmpData2);


            for (int counter = 0; counter < rgbValues1.Length; counter += 3)
            {
                int  dr, dg, db;
                dr = (int)rgbValues1[counter] - (int)rgbValues2[counter];
                dg = (int)rgbValues1[counter + 1] - (int)rgbValues2[counter + 1];
                db = (int)rgbValues1[counter + 2] - (int)rgbValues2[counter + 2];

                int error = tolerancenumeric * tolerancenumeric + tolerancenumeric + tolerancenumeric + tolerancenumeric * tolerancenumeric;//dr * dr + dg * dg + db * db;
                if (error < tolerancenumeric)
                {

                }
                else
                {
                    rgbValues1[counter] = 0;
                    rgbValues1[counter + 1] = 0;
                    rgbValues1[counter + 2] = 0;
                }

            }
            Marshal.Copy(rgbValues1, 0, ptr3, numBytes);
            bmp3.UnlockBits(bmpData3);
            return bmp3;
        }

1 个答案:

答案 0 :(得分:1)

您似乎没有为超出容差的像素设置任何像素值。在其他情况下,您将它们设置为黑色。黑色实际上是默认的,因此您只需要设置“错误”像素。

另外你应该返回bmp3(需要解锁,顺便说一下),而不是bmp1。

最后,应该创建大小为bmp1或bmp2的bmp3(需要相同)。