【问题标题】:Quickly determining using Python whether an image is (fuzzily) in a collection使用 Python 快速确定图像是否(模糊)在集合中
【发布时间】:2015-02-21 20:46:05
【问题描述】:

某个新图像 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

【问题讨论】:

  • 当你说 similar 时,你是指相似的构图(例如两个头像)还是包含相似的东西,例如猫的照片。
  • 谢谢,@mfitzp。澄清。

标签: python image data-structures


【解决方案1】:

有很多方法可以比较图像,但对于您给出的示例,我怀疑简单性和速度是关键因素(因此您尝试使用哈希作为第一遍)。以下是一些建议 - 在所有情况下,我都建议将图像缩小并裁剪为常规大小和形状。

  1. 在缩小之前平滑图像(高斯模糊)以最大限度地减少伪影的影响。然后应用哈希或其他比较。
  2. 将图像相互减去 (RGB) 并检查余数。相同的图像将返回零,压缩伪影将导致微小的变化。您可以阈值、求和或平均该值并与截止值进行比较。
  3. 使用标准距离算法(参见scipy.spatial.distance)计算两个图像之间的“距离”。例如,euclidean 距离将有效地给出与减法总和相同的值,而cosine 将忽略强度但匹配图像变化的轮廓,即同一图像的较暗版本将被视为等效。对于这些,您需要将图像展平为一维数组。

最后两个需要在上传时将每张图片与其他每张图片进行比较,对于大量图片来说,这将在计算上变得非常昂贵。

【讨论】:

    猜你喜欢
    • 2018-07-29
    • 2015-01-18
    • 2013-02-05
    • 2012-10-18
    • 1970-01-01
    • 1970-01-01
    • 2018-04-04
    • 2013-07-03
    • 1970-01-01
    相关资源
    最近更新 更多