比较两个图像的问题

本文关键字:图像 问题 两个 比较 | 更新日期: 2023-09-27 17:58:13

我想逐字节比较两个图像。它们都是8位BMP图像,大小正好是40000字节。第一个图像在内存中生成为字节数组,第二个图像从文件中读取到image对象中。

我使用MemoryStream实例进行比较:

    byte[] generatedImage = new byte[40000];
    // some unrelated logic of image generation ...
    MemoryStream imageStream1 = new MemoryStream(generatedImage);
    // loaded image, 200x200 bmp - 40000 bytes
    MemoryStream imageStream2 = new MemoryStream();
    Image loadedImage = Image.FromFile("image.bmp");
    loadedImage.Save(imageStream2, ImageFormat.Bmp);

问题是加载的图像imageStream2的内存流包含的超过40000字节,据我所知,它还包含一些关于BMP本身的信息。因此,第二流被创建为Length等于41078并且Position等于1278。如果Position是1078,我会理解,但事实并非如此,从这个位置来看,只剩下不到40000个字节。

在我的算法中,我需要尽快比较图像,所以我拒绝了创建位图并通过GetPixel方法进行比较的想法。我使用MemoryStream.ReadByte方法进行比较。

如何从第二个Stream中获取"真实"BMP字节?在这种情况下,有什么方法可以在逐字节的基础上比较图像吗?

比较两个图像的问题

这里有一篇关于快速比较C#中的图像的文章。它一开始是一个相当慢的版本(仍然比GetPixel好),最后是一个快25倍的版本:

http://danbystrom.se/2008/12/14/improving-performance/

如果图像相同,它会返回一个为零的数字,并且返回值越高,它们之间的差异就越大。它应该为你指明正确的方向。

不过,有一点需要提醒。它经过优化,仅适用于32bpp图像。如果您有24bpp的图像(加载后默认为.jpg),您要么需要更"复杂"的代码,要么简单地将其转换为32bpp。"复杂之处"在于,不能在一个循环中进行所有比较,而是逐行循环并单独比较每一行。

http://en.wikipedia.org/wiki/BMP_file_format#Bitmap_file_header

在偏移量10处读取4个字节,以获得像素数据的偏移量。在偏移量2处读取4个字节,以获得包括标头在内的整个内容的大小。从后者中减去前者,得到像素数据的大小。

我不会在字节级别上比较它们。相反,我会把它们放入Bitmap中。并通过调用具有从零到WidthHeight的所有可能值的GetPixel(x,y)来迭代所有像素。

逐字节比较图像不是解决问题的好方法。在这种情况下,您可以使用其中一个哈希算法的实现。

"哈希函数"获取一个可变长度的值,并产生一个恒定长度的输出。例如,SHA256算法获取输入值并生成256位输出。请注意,当且仅当相应的数据匹配时,两组数据的哈希是相同的,并且数据中的任何微小变化都会导致哈希值急剧变化,因此在比较大量数据时,这是一种很酷的方法。有关更多信息,请阅读本文的"Hash in a Flash"部分:http://www.codeproject.com/KB/GDI-plus/comparingimages.aspx?msg=3503625&display=移动