计算“视觉”的最快方法图像的校验和

发布于 2024-08-27 05:21:17 字数 203 浏览 12 评论 0原文

我正在寻找创建一个用于对图像进行编目的 ID 系统。我不能使用 md5(),因为如果我更改图像的 EXIF 标签,它就会改变。

我目前正在使用 imagemagick 计算的 SHA1 校验和。它工作得很好,但在处理较大的图像时速度真的非常慢(在四核至强处理器上处理 21 兆像素 JPG 大约需要 15 秒)。

是否还有其他更快的唯一识别图像的“视觉”方法?

I'm looking to create an ID system for cataloging images. I can't use md5() since that will change if I alter the EXIF tags of the image.

I am currently using the SHA1 checksum computed by imagemagick. It works perfectly, but it's really, really slow on larger images (~15 seconds on a quad-core xeon for a 21 megapixel JPG).

Are there any other "visual" methods of uniquely identifying an image that would be faster?

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

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

发布评论

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

评论(4

森林散布 2024-09-03 05:21:17

您可以尝试对实际位图数据而不是 JPEG 文件运行 MD5。我在我的机器(也是四核 Xeon)上进行了测试,以下在 23 兆像素图像上运行的时间约为 900 毫秒。

uint32_t width  = MagickGetImageWidth(imageWand);
uint32_t height = MagickGetImageHeight(imageWand);

uint8_t *imageData = malloc(width * height * 3);

MagickExportImagePixels(imageWand,
   0, 0, width, height, "RGB", CharPixel, imageData);

unsigned char *imageDigest = MD5(imageData, width * height * 3, NULL);

free(imageData);

You could try running MD5 on the actual bitmap data instead of the JPEG file. I tested on my machine (also a quad core Xeon) and the following runs in about 900ms on a 23 megapixel image.

uint32_t width  = MagickGetImageWidth(imageWand);
uint32_t height = MagickGetImageHeight(imageWand);

uint8_t *imageData = malloc(width * height * 3);

MagickExportImagePixels(imageWand,
   0, 0, width, height, "RGB", CharPixel, imageData);

unsigned char *imageDigest = MD5(imageData, width * height * 3, NULL);

free(imageData);
牛↙奶布丁 2024-09-03 05:21:17

“视觉校验和”是什么意思?您提到的算法(md5/sha/crc)以基于字节的方式工作,但没有考虑图像的视觉信息。如果将其中一张图像转换为 JPEG,这两个文件将显示相同的图像,但具有完全不同的 md5/sha/crc 校验和。

如果您唯一担心的是 exif 编辑,您可以制作图像的临时副本,使用 exiv2 库从中删除所有元数据,然后运行校验和算法。我想这比手动缩小图像要快得多。您还可以仅使用源文件的前 n KB 作为校验和来加快计算速度。

如果您的所有图像文件都直接来自相机,那么您的情况会更好:您可以使用 exiv2 提取预先生成的 exif 缩略图(通常只有几千字节)并计算其校验和。

关于缩小方法:还要注意 ImageMagick 将来可能会更改其缩放算法,这将使您的校验和无效(缩小版本的字节结构将会改变)。

what do you mean by "visual checksum"? the algorithms you mention (md5/sha/crc) work in a byte based manner, but don't take into account the visual information of the image. If you convert one of your images to JPEG, the two files will show the same image, but have totally different md5/sha/crc checksums.

if your only worry are the exif edits, you could make a temporary copy of the image, strip all metadata from it with the exiv2 library and run the checksum algorithm then. I suppose this is much faster than manually scaling down the images. You could also speed up the calculation by using just the first n kilobytes of the source file for the checksum.

If all your image files come directly from a camera, you are even better off: you could extract the pregenerated exif thumbnail with exiv2 (usually just a few kilobytes) and calculate its checksum.

About the scale-down-approach: Also be aware of the fact that ImageMagick might change its scaling algorithmsin the future, which would invalidate your checksums (the byte structure of the scaled-down versions would change then).

贵在坚持 2024-09-03 05:21:17

正如 Todd Yandell 所指出的,MD5 可能足够快。如果没有,您可以使用 32 位或 64 位 CRC 获得更快的速度作为你的校验和。主要区别在于任何人都可以使用相同的 CRC 构造新图像;这很容易被欺骗。有人很难欺骗 MD5 校验和。一个细微的差别是 CRC 的位数要少得多,但除非图像数量非常大,否则冲突仍然不太可能发生。

exiftool 声称能够提取来自 JPEG 文件的二进制图像,以便您可以在不解压缩的情况下计算校验和,但我无法从手册页中弄清楚如何执行此操作。

我在笔记本电脑 Intel Core 2 Duo L7100 CPU 上做了一些实验,8MP JPEG 大约需要 1 秒才能压缩为 PPM 格式,然后再花 1 秒进行校验和。使用 md5sumsumsha1sum 时,校验和时间没有显着差异。因此,最好的选择可能是找到一种在不解压缩的情况下提取二进制数据的方法。

我还注意到,即使使用更少的像素,您的校验和也几乎一样好。比较这两个:

djpeg -scale 1/8 big.jpg | /usr/bin/sha1sum   # 0.70s
djpeg            big.jpg | /usr/bin/sha1sum   # 2.15s

As noted by Todd Yandell, MD5 is probably fast enough. If not, you can get something even faster by using a 32-bit or 64-bit CRC for your checksum. The major difference is that anybody can make up a new image with the same CRC; it is very easy to spoof. It is quite hard for someone to spoof an MD5 checksum. A minor difference is that the CRC has many fewer bits, but unless you have a very large number of images, a collision is still unlikely.

exiftool claims to be able to extract the binary image from a JPEG file, so that you can compute your checksum without decompressing, but I can't figure out from the man page how to do it.

I did some experiments on a laptop Intel Core 2 Duo L7100 CPU, and an 8MP JPEG takes about 1 second to compress to PPM format, then another 1 second to do the checksum. Checksum times were not dramatically different using md5sum, sum, and sha1sum. So your best bet might be to find a way to extract the binary data without decompressing it.

I also note that your checksum is going to be almost as good even if it uses far fewer pixels. Compare these two:

djpeg -scale 1/8 big.jpg | /usr/bin/sha1sum   # 0.70s
djpeg            big.jpg | /usr/bin/sha1sum   # 2.15s
幸福不弃 2024-09-03 05:21:17

您应该考虑到有人可能会裁剪图像或修改调色板、颜色深度或任何内容,那么平面校验和将会有所不同,即使在视觉上原始图像和修改后的图像看起来仍然非常相似。
也许有一种有效的算法可以裁剪或重新着色,就像谷歌图像用于搜索相似图片一样。

You should consider that someone may crop the image or modify the pallette, color depth or anything, then a flat checksum will be different, even if visually the original and the modified image still look pretty much alike.
Perhaps there is an effective algorithm for cropped or re-colored ones, like Google Images uses for searching of similar pictures.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文