我希望创建一个图像基表,然后将任何新图像与之进行比较,以确定新图像是否与基表完全相同(或接近)。

例如:如果你想减少100次相同图像的存储,你可以存储它的一个副本,并提供它的参考链接。当输入一个新图像时,你想要与现有的图像进行比较,以确保它不是重复的…想法吗?

我的一个想法是缩小到一个小缩略图,然后随机选择100个像素位置并进行比较。


当前回答

选择100个随机点可能意味着相似(有时甚至不相似)的图像将被标记为相同,我认为这不是您想要的。如果图像格式不同(png、jpeg等)、大小不同或元数据不同,MD5哈希就无法工作。将所有图像缩小到一个更小的尺寸是一个不错的选择,只要你使用的是一个好的图像库/快速的语言,做一个像素对像素的比较不应该花费太长时间,而且尺寸足够小。

你可以试着让它们变得很小,然后如果它们是一样的,就在更大的尺寸上进行另一次比较——这可能是速度和准确性的良好结合……

其他回答

正如卡特曼所指出的,您可以使用任何类型的哈希值来查找精确的重复项。

寻找近距离图像的一个起点可能在这里。这是CG公司用来检查修改后的图像是否仍然显示本质上相同的场景的工具。

我的公司每个月有大约2400万张来自制造商的图片。我正在寻找一个快速的解决方案,以确保我们上传到我们的目录的图像是新的图像。

I want to say that I have searched the internet far and wide to attempt to find an ideal solution. I even developed my own edge detection algorithm. I have evaluated speed and accuracy of multiple models. My images, which have white backgrounds, work extremely well with phashing. Like redcalx said, I recommend phash or ahash. DO NOT use MD5 Hashing or anyother cryptographic hashes. Unless, you want only EXACT image matches. Any resizing or manipulation that occurs between images will yield a different hash.

对于phash/ahash,查看这个:imagehash

我想通过发布我的代码和准确性来扩展*redcalx的帖子。

工作内容:

from PIL import Image
from PIL import ImageFilter
import imagehash

img1=Image.open(r"C:\yourlocation")
img2=Image.open(r"C:\yourlocation")
if img1.width<img2.width:
    img2=img2.resize((img1.width,img1.height))
else:
    img1=img1.resize((img2.width,img2.height))
img1=img1.filter(ImageFilter.BoxBlur(radius=3))
img2=img2.filter(ImageFilter.BoxBlur(radius=3))
phashvalue=imagehash.phash(img1)-imagehash.phash(img2)
ahashvalue=imagehash.average_hash(img1)-imagehash.average_hash(img2)
totalaccuracy=phashvalue+ahashvalue

以下是我的一些结果:

item1  item2  totalsimilarity
desk1  desk1       3
desk1  phone1     22
chair1 desk1      17
phone1 chair1     34

希望这能有所帮助!

我所知道的最好的方法是使用感知哈希。似乎有一个很好的开源实现这样的散列可用:

http://phash.org/

其主要思想是,通过识别原始图像文件中的显著特征,并对这些特征进行哈希(而不是直接对图像数据进行哈希),将每张图像简化为一个小的哈希代码或“指纹”。这意味着,相比简单的方法,如将图像缩小到一个小的拇指指纹大小的图像,并比较拇指指纹,假阳性率大大降低。

Phash提供了几种类型的哈希,可用于图像、音频或视频。

我们笼统地称之为副本的东西,算法很难识别。 你的副本可以是:

确切的副本 接近精确重复。(图像的轻微编辑等) 重复(相同的内容,但不同的视角,相机等)

第一个和第二个更容易解决。3号。是非常主观的,仍然是一个研究课题。 我可以提供1号和2号的解决方案。 这两个解决方案都使用了优秀的图像哈希-哈希库:https://github.com/JohannesBuchner/imagehash

确切的副本 使用感知哈希度量可以找到精确的重复项。 phash库在这方面做得很好。我经常用它来清洁 训练数据。 用法(来自github网站)简单如:

from PIL import Image
import imagehash

# image_fns : List of training image files
img_hashes = {}

for img_fn in sorted(image_fns):
    hash = imagehash.average_hash(Image.open(image_fn))
    if hash in img_hashes:
        print( '{} duplicate of {}'.format(image_fn, img_hashes[hash]) )
    else:
        img_hashes[hash] = image_fn

接近精确复制 在这种情况下,您必须设置一个阈值,并比较它们之间距离的哈希值 其他。这必须通过对图像内容的反复试验来完成。

from PIL import Image
import imagehash

# image_fns : List of training image files
img_hashes = {}
epsilon = 50

for img_fn1, img_fn2 in zip(image_fns, image_fns[::-1]):
    if image_fn1 == image_fn2:
        continue

    hash1 = imagehash.average_hash(Image.open(image_fn1))
    hash2 = imagehash.average_hash(Image.open(image_fn2))
    if hash1 - hash2 < epsilon:
        print( '{} is near duplicate of {}'.format(image_fn1, image_fn2) )

I believe that dropping the size of the image down to an almost icon size, say 48x48, then converting to greyscale, then taking the difference between pixels, or Delta, should work well. Because we're comparing the change in pixel color, rather than the actual pixel color, it won't matter if the image is slightly lighter or darker. Large changes will matter since pixels getting too light/dark will be lost. You can apply this across one row, or as many as you like to increase the accuracy. At most you'd have 47x47=2,209 subtractions to make in order to form a comparable Key.