一些新图像X到达的图像,我想知道X是新的还是以前遇到的。我有下面的代码缩小图像,然后将其转换为哈希码。然后,我可以通过单个哈希查找查看是否已经遇到具有相同哈希码的图像,因此它非常快。
我的问题是,是否有一种有效的方法可以让我看到类似图像,但是已经看到了具有不同哈希码的图像?如果要将这个问题称为“数据结构,以便有效地确定是否已经包含类似的,不相同的项目”,但决定这将是the XY problem的实例。
当我说这个新图像是“相似的”时,我正在考虑一个可能经历过有损压缩的图像,因此看起来像原始的人眼但不完全相同。通常缩小图像消除了差异,但并非总是如此,如果我过度缩小图像,我会开始得到误报。
这是我目前的代码:
import PIL
seen_images = {} # This would really be a shelf or something
# From http://www.guguncube.com/1656/python-image-similarity-comparison-using-several-techniques
def image_pixel_hash_code(image):
pixels = list(image.getdata())
avg = sum(pixels) / len(pixels)
bits = "".join(map(lambda pixel: '1' if pixel < avg else '0', pixels)) # '00010100...'
hexadecimal = int(bits, 2).__format__('016x').upper()
return hexadecimal
def process_image(filepath):
thumb = PIL.Image.open(filepath).resize((128,128)).convert("L")
code = image_pixel_hash_code(thumb)
previous_image = seen_images.get(code, None)
if code in seen_images:
print "'{}' already seen as '{}'".format(filepath, previous_image)
else:
seen_images[code] = filepath
您可以将一堆图像文件的路径放入名为IMAGE_ROOT
的变量中,然后尝试使用以下代码:
import os
for root, dirs, files in os.walk(IMAGE_ROOT):
for filename in files:
filepath = os.path.join(root, filename)
try:
process_image(filepath)
except IOError:
pass
答案 0 :(得分:0)
有很多方法可以比较图像,但是对于你给出的例子,我怀疑简单性和速度是关键因素(因此你为什么要尝试使用哈希作为第一遍)。以下是一些建议 - 在所有情况下,我都建议将图像缩小并裁剪为常规尺寸和形状。
scipy.spatial.distance
)计算两幅图像之间的“距离”。例如,euclidean
距离将有效地与减去的总和相同,而cosine
将忽略敏感但匹配图像上的变化的轮廓,即相同图像的较暗版本将被认为是等同的。对于这些,您需要将图像展平为一维阵列。最后两个需要在上传时将每个图像与每个其他图像进行比较,这对于大量图像而言计算成本非常高。