2010-08-01 3 views
4

제품에 대해 10K 이상의 파일을 가지고 있습니다. 문제는 많은 이미지가 중복 된 것입니다.중복 된 이미지 파일을 감지 할 수 있습니까?

이미지가 없으면 '이미지 없음'이라는 표준 이미지가 있습니다.

이미지가이 표준 '이미지 없음'이미지 파일인지 어떻게 알 수 있습니까?

업데이트 이미지는 다른 이름이지만 그렇지 않은 경우 정확히 동일한 이미지입니다.

사람들이 해시를 말하고 있습니다.

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

정말 같은 이미지 (바이너리)입니까, 아니면 같은 이름의 이미지입니까? –

+3

"복제"란 무엇을 의미합니까? 같은 이름? 같은 수표?정확한 바이트 수? –

+1

정말 많은 정보가 필요합니다. 이미 제기 된 질문 외에도 이러한 질문이 어떻게 저장됩니까? 다른 파일과 함께 이미지 파일을 포함하는 디렉토리로 저장되어 있습니까? 데이터베이스에 저장되어 있습니까? 그들은 다른 방법으로 저장되어 있습니까? 시스템은 어떻게 생겼습니까? "이미지 없음"제품 모두 이미지에 대해 동일한 파일을 사용합니까, 아니면 각 제품에 대해 복제 된 동일한 이미지의 사본입니까? –

답변

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

4

동일한 이미지 데이터에 대해 동일한 이미지를 사용한다고 가정합니다.

"no image"이미지의 hash을 계산하여 다른 이미지의 해시와 비교하십시오. 해시가 같으면 동일한 파일입니다.

+1

다른 위치에서 중복을 감지하는 좋은 방법이기도합니다. 이미지의 컴퓨팅 해시를 시작한 다음 각 이미지에 대해 이미 존재하지 않는지 확인하십시오. 그럴 경우 복제본을 가지고 있습니다. 그렇지 않은 경우 데이터베이스에 추가하고 계속 진행하십시오. –

+0

사실, Blankman이 특정 파일의 복제본을 찾고 있다면 (콜렉션에서 모든 중복 집합을 찾는 것과는 대조적으로) 해시는 비생산적입니다 - 내 대답을 참조하십시오. – Gilles

+0

@ Gilles : 흥미 롭습니다. 그래, 나는 당신이 모든 파일을 완전히 읽어야한다는 것을 안다. 그러나 나는 이것이 최고 또는 빠른 접근이라고 결코 말하지 않았다;) +1을 주었다. –

0

해시합니다. 충돌은 중복입니다 (적어도 동일한 파일이 아니라는 것은 수학적으로 불가능합니다).

+0

"불가능 함"이 아닌 _ "있음직하지 않음"을 의미한다고 가정합니다. –

+1

항상 해시 충돌 가능성을 고려해야합니다. 충돌의 ** 비용 **에 ** 충돌 확률 **을 곱하여 예상 비용 **을 얻으십시오. 대개 예상 비용은 비록 비용이 백만 달러이더라도 충돌 가능성이 너무 작기 때문에 작습니다. 그러나 아기 사진 등은 변경할 수 없기 때문에 때로는 약간의 노력이 필요할 수도 있습니다.) –

+0

@gnibbler 이것은 우리가 백업을 유지하는 이유입니다. – amphetamachine

2

특정 이미지의 정확한 중복을 찾으려면이 이미지를 메모리에로드 한 다음 이미지 컬렉션을 반복하십시오. 같은 크기가 아닌 파일은 건너 뜁니다. 동일한 크기를 가진 파일의 내용을 비교하여 첫 번째 차이점에서 멈 춥니 다.

첫 번째 차이점에서 멈출 수없는 대신 각 파일을 메모리로 완전히 읽고 CPU 집중적 인 작업을 수행해야하기 때문에이 상황에서 해시를 계산하는 것은 실제로 비생산적입니다.

중복 집합이 여러 개인 경우 각 파일의 해시 계산이 더 좋습니다.

시각적으로 가까운 복제물을 찾고있는 경우 findimagedupes을 사용하면 도움이됩니다.

+0

그는 해시를 계산하고 이미지의 크기를 저장하고 크기가 다른 이미지를 건너 뛸 수 있습니다. 더 많은 시간이 걸리는지 테스트하는 것이 현명합니다. 해시를 계산하거나 두 이미지를 바이트 단위로 비교합니다. – Jaka

+1

모든 해시를 계산하는 것은 낭비처럼 보일 수 있지만 N 개의 파일을 서로 비교하는 것은 O (N * N)입니다. 충분한 수의 파일을 가지고 O (N) 알고리즘의 해시 계산과'set()'또는'dict()'의 비교가 더 효율적입니다. 전체 파일을 해시 할 필요가 없습니다. 첫 번째 KB 정도는 첫 번째 검사만큼 유용 할 것입니다. –

4

이미지의 경우 사이드 위와 마찬가지로 래스터 데이터 해시가 파일 해시보다 훨씬 효율적이라는 것을 알았습니다.

ImageMagick은 이러한 해시를 계산할 수있는 신뢰할 수있는 방법을 제공하며, 파이썬에 사용할 수있는 다른 바인딩이 있습니다. 다양한 무손실 압축 및 다른 메타 데이터로 동일한 이미지를 감지하는 데 도움이됩니다.

사용 예 :

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

이 방법은 PNG 및 BMP와 비교할 때 파일 해시보다 훨씬 뛰어납니다. 다른 EXIF ​​데이터 또는 인코딩 기술을 사용하는 동일한 이미지를 비슷한 것으로 간주해야합니다. – Vortico

+0

감사합니다, Daniel. 내 이미지 중 일부는 태그를 달았고 어떤 이미지는 태그하지 않았기 때문에 이것은 매우 유용했습니다. 이렇게하면 메타 데이터에 관계없이 중복 된 이미지를 찾을 수 있습니다. – Phistrom

+0

이 기능에 대한 적절한 ImageMagick 문서에 대한 링크가 도움이 될 것입니다. 예를 들어 [ImageMagick 래스터 데이터 해시] (https://www.google.com/search?client=safari&rls=en&sclient=psy-ab&q=imagemagick+raster+data+hash&oq=imagemagick+raster+data+hash&gs_l)에 대한 Google 검색 = 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 & bih = 799 & cad = cbv & sei = QDVuU6K8BojPsAS81YDoDA)는 정확히 무엇을 찾고 있는지 정확히 알지 못하는 사람에게 유용한 정보를 제공합니다. – jptros

관련 문제