2010-08-01 78 views
4

我有超過10K的產品文件,問題是許多圖像是重複的。是否有可能檢測到重複的圖像文件?

如果沒有圖像,則有標準圖像顯示'無圖像'。

如何檢測圖像是否爲此標準的「無圖像」圖像文件?

更新 圖像是一個不同的名稱,但它是完全一樣的圖像,否則。

人們說哈希,我會這樣做嗎?

im = cStringIO.StringIO(file.read()) 
img = im.open(im) 
md5.md5(img) 
+0

這是真的相同的圖像(二進制)還是隻是一個同名的圖像? – 2010-08-01 21:55:46

+3

你是什麼意思的「重複」?一樣的名字?相同的校驗和?相同的確切字節? – 2010-08-01 21:58:15

+1

我們確實需要更多信息。除了已經提出的問題之外,這些問題如何存儲?這些存儲爲包含圖像文件以及其他文件的目錄嗎?是否存儲在數據庫中?它們是以其他方式存儲的嗎?系統是什麼樣子的?所有的「無圖像」產品是否使用相同的文件作爲其圖像,還是每個產品都複製相同圖像的副本? – 2010-08-01 22:00:58

回答

4

我寫了一個劇本爲這個而回。首先它掃描所有文件,並在字典中註明它們的大小。您endup有:

images[some_size] = ['x/a.jpg', 'b/f.jpg', 'n/q.jpg'] 
images[some_other_size] = ['q/b.jpg'] 

然後,對每個地方有一個在字典超過1元密鑰(圖像尺寸),我讀到了文件的某些固定的金額,做一個哈希值。像這樣:

possible_dupes = [size for size in images if len(images[size]) > 1] 
for size in possible_dupes: 
    hashes = defaultdict(list) 
    for fname in images[size]: 
     m = md5.new() 
     hashes[ m.update(file(fname,'rb').read(10000)).digest() ] = fname 
    for k in hashes: 
     if len(hashes[k]) <= 1: continue 
     for fname in hashes[k][1:]: 
      os.remove(fname) 

這是所有關閉我的頭頂,沒有測試的代碼,但你明白了。

+0

所有沒有RLE壓縮且具有相同像素尺寸的Microsoft位圖文件大小相同。就像將有相同長度的內部名稱的XPM一樣,沒有壓縮的PNG也是如此,Netpbm圖像也是如此......列表繼續。但我同意;檢查大小將有助於避免無意義的碰撞 – amphetamachine 2010-08-02 23:03:03

4

假設您正在討論相同圖像數據的相同圖像。

計算「無圖像」的形象hash並將其與其他圖像的哈希值。如果哈希值相同,則它是相同的文件。

+1

這也是檢測其他地方重複的好方法。開始計算圖像的哈希值,然後爲每個圖像確保它不存在。如果是這樣,你有一個副本。如果沒有,請將其添加到數據庫並繼續。 – 2010-08-01 22:02:19

+0

實際上,如果Blankman正在尋找某個特定文件的副本(而不是查找集合中的所有副本),哈希值會適得其反 - 見我的答案。 – Gilles 2010-08-01 22:15:16

+0

@Gilles:有趣。是的,我知道你必須完整地閱讀所有文件,但我從來沒有說過這是最好的還是最快的方法;)給你+1。 – 2010-08-01 22:17:53

0

哈希它們。碰撞是重複的(至少,它們不是一個數學不可能的文件)。

+0

我假設你的意思是「不可能性」_,而不是「不可能性」。 – 2010-08-01 22:32:10

+1

您應該總是考慮散列衝突的可能性。將碰撞的**成本**與碰撞概率**相乘以得到**期望成本**。通常預期成本很小,因爲即使成本是百萬美元,碰撞的可能性也非常小。但寶貝照片等是不可替代的,所以有時候可能需要額外的努力;) – 2010-08-02 01:18:53

+0

@gnibbler這就是我們保留備份的原因。 – amphetamachine 2010-08-02 02:41:35

2

如果你正在尋找一個特定圖像的精確副本:加載此圖片到內存中,然後在你的圖像採集循環;跳過任何不具有相同大小的文件;比較具有相同大小的文件的內容,在第一個差異處停止。

計算在這種情況下的哈希其實是適得其反,因爲你必須仔細閱讀每一個文件到內存中(而不是能停在第一差),並在其上執行CPU密集型任務。

如果有幾套重複的,在另一方面,計算每個文件的散列比較好。

如果你也在尋找視覺近重複,findimagedupes可以幫助你。

+0

他可以計算散列,並保存圖像的大小,並跳過不同大小的圖像。測試什麼需要更多時間是明智的。計算散列或逐字節比較兩個圖像。 – Jaka 2010-08-01 22:22:55

+1

計算所有這些散列可能看起來很費事,但是將N個文件相互比較是O(N * N)。在足夠數量的文件中,計算散列值並在'set()'或'dict()'中進行比較的O(N)算法會更有效率。請注意,您不需要散列整個文件 - 第一個kb左右可能與第一個檢查一樣有用 – 2010-08-02 01:12:46

4

作爲旁註,對於圖像,我發現柵格數據散列比文件散列有效得多。

的ImageMagick提供了可靠的方法來計算這樣的散列,並有可用的蟒蛇不同的綁定。它有助於檢測具有不同無損壓縮和不同元數據的相同圖像。

用例:

>>> import PythonMagick 
>>> img = PythonMagick.Image("image.png") 
>>> img.signature() 
'e11cfe58244d7cf98a79bfdc012857a9391249dca3aedfc0fde4528eed7f7ba7' 
+1

此方法比文件哈希要好得多,以便與PNG和BMP進行比較,其中兩個具有不同EXIF數據或編碼技術的相同圖像應該被認爲是相似的。 – Vortico 2012-10-16 21:07:32

+0

謝謝Daniel。這對我來說是非常有用的,因爲我的一些圖像已被標記,有些還沒有。這讓我可以找到重複的圖像,無論其元數據如何。 – Phistrom 2013-04-20 16:04:34

+0

有關此功能的相應ImageMagick文檔的鏈接將有所幫助。例如,Google搜索[ImageMagick柵格數據散列](https://www.google.com/search?client=safari&rls=zh-CN&sclient=psy-ab&q=imagemagick+raster+data+hash&oq=imagemagick+raster+data+hash&gs_l = serp.3..33i21.278029.278492.1.278631.5.5.0.0.0.3.301.1022.0j2j2j1.5.0 .... 0 ... 1c.1.42.psy-ab..5.2.237.In0DXDbzF3w&PBX = 1&BIW = 1063&波黑= 799&cad = cbv&sei = QDVuU6K8BojPsAS81YDoDA)爲不一定知道他們在找什麼的人提供可能或不可用的信息。 – jptros 2014-05-10 14:19:41

相關問題