J'écris un outil en C # pour trouver des images en double. Actuellement, je crée une somme de contrôle MD5 des fichiers et les compare.
Malheureusement, mes images peuvent être
quelle serait la meilleure approche pour résoudre ce problème?
Voici une approche simple avec un hachage d'image de 256 bits (MD5 a 128 bits)
List<bool>
- c'est le hashCode :
public static List<bool> GetHash(Bitmap bmpSource)
{
List<bool> lResult = new List<bool>();
//create new image with 16x16 pixel
Bitmap bmpMin = new Bitmap(bmpSource, new Size(16, 16));
for (int j = 0; j < bmpMin.Height; j++)
{
for (int i = 0; i < bmpMin.Width; i++)
{
//reduce colors to true / false
lResult.Add(bmpMin.GetPixel(i, j).GetBrightness() < 0.5f);
}
}
return lResult;
}
Je sais que GetPixel
n'est pas si rapide, mais sur une image de 16 x 16 pixels, il ne devrait pas s'agir d'un goulot d'étranglement.
Code:
List<bool> iHash1 = GetHash(new Bitmap(@"C:\mykoala1.jpg"));
List<bool> iHash2 = GetHash(new Bitmap(@"C:\mykoala2.jpg"));
//determine the number of equal pixel (x of 256)
int equalElements = iHash1.Zip(iHash2, (i, j) => i == j).Count(eq => eq);
Donc, ce code est capable de trouver des images égales avec:
i
et j
Mise à jour/Améliorations:
après avoir utilisé cette méthode pendant un moment, j'ai remarqué quelques améliorations qui peuvent être apportées
GetPixel
pour plus de performance0.5f
pour faire la différence entre clair et foncé - utilisez la luminosité médiane distincte de l’ensemble des 256 pixels. Sinon, les images sombres/claires sont supposées être identiques et permettent de détecter les images dont la luminosité a changé.bool[]
ou List<bool>
_ Si vous devez stocker beaucoup de hachages tout en économisant de la mémoire, utilisez un Bitarray
car un booléen n’est pas stocké dans un bit, il faut un octet !Vous pouvez vérifier algorithme pour comparer deux images afin de voir les méthodes disponibles pour la comparaison d'images.
Sauf si vous souhaitez recréer vous-même l'intégralité des algorithmes, vous devriez essayer d'utiliser des bibliothèques déjà existantes ou une partie au moins de leur code (tant que leur licence vous convient).
Pour une implémentation C # open source de la détection Edge et des algorithmes de vision par ordinateur associés, vous pouvez essayer EmguCV qui est un wrapper d'OpenCV.
Après avoir ré-échantillonné les images à une résolution commune, vous pouvez utiliser une décomposition en ondelettes et comparer les coefficients de cette décomposition à la place des images elles-mêmes. La comparaison des seuls N premiers coefficients rendra cette méthode plus robuste au bruit et aux autres artefacts.
Il existe plusieurs implémentations C # pour les ondelettes disponibles. Un exemple est https://waveletstudio.codeplex.com/
Question intéressante, la comparaison d'images n'est pas si difficile étant donné que,
Une façon de faire la comparaison serait de:
Maintenant, si la valeur se situe dans une valeur raisonnable, disons 90% (vous devrez probablement déterminer en effectuant peu d'expériences), alors vous pouvez sans risque supposer que les deux sont identiques, mais cela ne fonctionnera pas si,