Essayer de résoudre un problème d'empêcher le téléchargement d'images en double.
J'ai deux fichiers JPG. En les regardant, je peux voir qu'ils sont en fait identiques. Mais pour une raison quelconque, ils ont une taille de fichier différente (l'un est tiré d'une sauvegarde, l'autre est un autre téléchargement) et donc ils ont une somme de contrôle md5 différente.
Comment puis-je comparer efficacement et en toute confiance deux images de la même manière qu'un humain serait capable de voir qu'elles sont clairement identiques ?
Exemple: http://static.peterbe.com/a.jpg et http://static.peterbe.com/b.jpg
Mise à jour
J'ai écrit ce script:
import math, operator
from PIL import Image
def compare(file1, file2):
image1 = Image.open(file1)
image2 = Image.open(file2)
h1 = image1.histogram()
h2 = image2.histogram()
rms = math.sqrt(reduce(operator.add,
map(lambda a,b: (a-b)**2, h1, h2))/len(h1))
return rms
if __name__=='__main__':
import sys
file1, file2 = sys.argv[1:]
print compare(file1, file2)
Ensuite, j'ai téléchargé les deux images visuellement identiques et ai exécuté le script. Sortie:
58.9830484122
Est-ce que quelqu'un peut me dire quel devrait être le seuil approprié ?
Mise à jour II
La différence entre a.jpg et b.jpg est que le deuxième a été enregistré avec PIL:
b=Image.open('a.jpg')
b.save(open('b.jpg','wb'))
Cela applique apparemment quelques modifications de qualité très légères. J'ai maintenant résolu mon problème en appliquant le même enregistrement PIL au fichier en cours de téléchargement sans rien faire avec lui et maintenant cela fonctionne !
0 votes
Autant que je sache, aucun d'entre eux ne contient de données exif.
3 votes
réduire(opérateur.ajouter(...))
->sum(...)
.0 votes
Pour ce que cela vaut (principalement en référence à des informations de base), c'est comme une version simplifiée de cette question : stackoverflow.com/questions/1819124/algorithme-de-comparaison-d'images
5 votes
Les liens de vos images ont été rompus. Notez que stackoverflow dispose désormais d'un service d'hébergement d'images.
0 votes
Pour améliorer la robustesse aux changements de teinte ou de saturation entre les images de la même scène, vous pouvez soustraire la moyenne (dans chacune des 3 valeurs RGB ou HSV) avant de calculer un histogramme. Vous pouvez également vouloir calculer d'autres caractéristiques jusqu'au RMS (comme vous l'avez fait pour les histogrammes), comme la rugosité, le tranchant, et tout élément des métadonnées qui vous est important, comme la localisation GPS, le modèle de l'appareil photo, l'heure de la journée, la date de la photo, etc.
0 votes
@J.F.Sebastian la source de cet algorithme réutilisé
réduire(operator.add(
est de 1997 : mail.python.org/pipermail/image-sig/1997-March/000223.html (il vaut toujours la peine de le mettre à jour avecsum
, mais peut-être que son ancienneté raconte une histoire plus grande).0 votes
Ma démarche:
rms = math.sqrt(sum([(a-b)**2 for (a,b) in zip(h1, h2)])/len(h1))
J'ai réécrit cet algorithme en python d'aujourd'hui. Destiné à être plus lisible.0 votes
@naxa: Je supprimerais les parenthèses dans la boucle for :
for a, b in zip(h1, h2)
et[]
immédiatement à l'intérieur desum()
- cela réduit le bruit des lignes (plus lisible). Y a-t-il quelque chose dans le modulestatistics
de la bibliothèque standard qui peut être utilisé?2 votes
@J.F.Sebastian si j'ai bien compris
statistics.pstdev
vient étonnamment proche, mais il opère sur une seule séquence et utilise une constantemu
au lieu d'éléments d'une autre séquence. dommage. réécrit commerms = math.sqrt(sum((a-b)**2 for a,b in zip(h1, h2))/len(h1))