2017-07-12 16 views
1

私は5000以上の画像のフォルダをjpeg/pngなどに持っています。画像が同じかどうかをどのように確認できますか?画像はWebスクラップで収集され、ファイル名を比較することができないように順次名前が変更されています。dirのファイルが同じであることを確認してください

現在、ハッシュが同じかどうかを確認していますが、これは非常に長い処理です。私は現在使用しています:

def sameIm(file_name1,file_name2): 
    hash = imagehash.average_hash(Image.open(path + file_name1)) 
    otherhash = imagehash.average_hash(Image.open(path + file_name2)) 

    return (hash == otherhash) 

ネストされたループ。 1画像と5000以上の画像を比較すると約5分かかるので、それぞれを比較すると計算に数日かかるでしょう。

これをPythonで実行する方法がありますか?私は並列処理を考えていましたが、まだまだ時間がかかりますか?

また、高速であるファイルを比較する別の方法がありますか?

おかげ

+0

すべてが同じ名前で始まるかどうかチェックしますか?ここにいくつかのファイル名を投稿できますか? – Sriram

+0

ハッシュリストを取得し、ハッシュリストで重複を見つけるために、すべての画像を 'imagehash.average_hash'でハッシュしないのはどうでしょうか? – Huang

+0

最初にファイルのサイズを確認し、等しい場合はハッシュのみを計算することができます。 –

答えて

3

このことをずっと高速道確かにあります:キーはあなたに与えられるように、ファイルのハッシュを持つ辞書を使用して

import collections 
import glob 
import os 


def dupDetector(dirpath, ext): 
    hashes = collections.defaultdict(list) 
    for fpath in glob.glob(os.path.join(dirpapth, "*.{}".format(ext)): 
     h = imagehash.average_hash(Image.open(fpath)) 
     hashes[h].append(fpath) 

    for h,fpaths in hashes.items(): 
     if len(fpaths) == 1: 
      print(fpaths[0], "is one of a kind") 
      continue 
     print("The following files are duplicates of each other (with the hash {}): \n\t{}".format(h, '\n\t'.join(fpaths))) 

はO(1)検索、あなたはドンを意味しています」ペアワイズの比較を行う必要があります。したがって、二次ランタイムからリニアランタイムに移動します(0120)。

+0

ありがとう!私はコードを試してみましたが、最後の行でt.joinに無効な構文が出ています – Stig

+0

@Stig:それは筋肉記憶によって引き起こされた指のつまよりのタイプミスです。今修正されました – inspectorG4dget

3

なぜハッシュを一度だけ計算しないのですか?最初の要素はイメージの名前です

hashes = [imagehash.average_hash(Image.open(path + fn)) for fn in file_names] 
def compare_hashes(hash1, hash2): 
    return hash1 == hash2 
2

一つの解決策は、ハッシュを使用して維持することですが、タプルのリストにそれをストック(またはDIC、私はウィッヒはこちらより効率的であるかわからない)と2番目はハッシュです。それは、ほぼ同じ5分を近似的に取るべきです。

4998他の人にあなたが5000枚の画像を持っている場合は、 あなたは4999他の人

に、リストの最初の要素の値を比較して第2(すでに最初のものをチェックすると)

そして、第三...

は、これは「ただ」あなただけの各画像のハッシュを計算するマップ構造を使用します(nは画像の数である)/ 2の比較

2

をn²ん作り、その後、としてハッシュを保存しますキーと名前o fイメージを値として返します。 その結果、のユニークな画像名の配列が表示されます。

def get_hash(filename): 
    return imagehash.average_hash(Image.open(path + filename)) 

def get_unique_images(filenames): 
    hashes = {} 
    for filename in filenames: 
     image_hash = get_hash(filename) 
     hashes[image_hash] = filename 
    return hashes.values() 
関連する問題