簡體   English   中英

使用Python快速確定圖像是否(模糊地)在集合中

[英]Quickly determining using Python whether an image is (fuzzily) in a collection

某個新圖像X到達的圖像,我想知道X是新圖像還是以前已經遇到過。 我下面有代碼,該代碼會縮小圖像,然后將其轉換為哈希代碼。 然后,我可以通過一次哈希查找來查看是否已經遇到了具有相同哈希碼的圖像,因此速度非常快。

我的問題是,是否有一種有效的方法讓我查看是否已經看到了相似的圖像,但是具有不同的哈希碼? 如果要給這個問題加上標題,諸如“用於有效確定是否包含相似,不同的項目的數據結構”之類的東西,但認為這將是XY問題的一個實例。

當我說這個新圖像“相似”時,我想到的是可能經過有損壓縮的圖像,因此看起來像原始圖像,但並不完全相同。 通常情況下,縮小圖像會消除差異,但並非總是如此,如果縮小圖像過多,則會開始出現誤報。

這是我當前的代碼:

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

有很多比較圖像的方法,但是對於您給出的示例,我懷疑簡單性和速度是關鍵因素(因此,為什么要嘗試使用哈希作為首次通過)。 這里有一些建議-在所有情況下,我建議將圖像縮小並裁剪為規則的大小和形狀。

  1. 在縮小之前使圖像平滑(高斯模糊),以最大程度地減少偽影的影響。 然后應用哈希或其他比較。
  2. 彼此相減圖像(RGB)並檢查其余部分。 相同的圖像將返回零,壓縮偽影將導致較小的細微變化。 您可以閾值,求和或取平均值,然后與截止值進行比較。
  3. 使用標准距離算法(請參閱scipy.spatial.distance )來計算兩個圖像之間的“距離”。 例如, euclidean距離將有效地提供與相減之和,而cosine將忽略強度,但匹配圖像上變化的輪廓,即,同一圖像的較暗版本將被視為等效。 對於這些,您將需要將圖像展平為一維數組。

最后兩個需要在上傳時將每個圖像與每個其他圖像進行比較,這對於大量圖像將在計算上變得非常昂貴。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM