Bilder vergleichen mit PHP

09
Mrz
2014
Posted by: Byte  /   Category: PHP   /   Keine Kommentare

Für uns Menschen ist es leicht Bilder miteinander zu vergleichen. Wir beziehen sofort mehrere Aspekte wie Farbe, Form, Struktur und Muster mit in unsere Entscheidung ein. Wir können quasi sofort entscheiden ob ein Bild einem anderen Ähnlich sieht. Computer tun sich trotz allem Fortschritt damit mehr als schwer. Wenn man nicht gerade Lust hat ein neuronales Netz zu programmieren oder eine andere Bibliothek zu nutzen, gibt es noch einen anderen Weg. Unter PHP lässt sich ein Bild vergleich relativ schnell durchführen.

Wir werden in diesem Script definitiv nicht nach Formen oder Farben suchen. Wir möchten nur wissen ob das Bild ähnlich ist. Stellt euch mal vor ihr habt zwei ähnliche Bilder vor euch und ihr sollt entscheiden ob sie sich ähneln. Das Schwierige an dieser Sache ist, das ihr nur jeden einzelnen Bildpunkt mit dem des anderen Bildes vergleichen könnt. Erstens haben wir da eine Masse an unzusammenhängenden Informationen wenn wir jeden Bildpunkt einzeln betrachten und das Bild muss sich nur um einen Millimeter verschieben oder drehen, dann würdet ihr wahrscheinlich annehmen das es zwei verschiedene Bilder sind.

Da stellt sich die Frage, wie wir das am efiizientesten lösen könnten. Meine Überlegung zu dieser Frage war zunächst das Bild zu verkleinern. Hiermit werden nebeneinanderstehende Pixel schon einmal „zusammengefasst“. Wenn wir nun zwei Bilder nehmen welche vorher bspw. 300 x 400 Pixel groß sind und diese auf 100 x 100 Pixel verkleinern haben wir schon einen Teil der Unterschiede ausgelöscht… soweit so gut, aber das Ergebnis war nicht optimal. Ich saß also da und überlegte wie ich das mit meinen Augen machen würde. Als ich so vor mich hin überlegte ließ ich meinen Blick in die Ferne schweifen und da lag die Antwort auf der Hand. Stellt mal euere Augen „unscharf“ und vergleicht 2 Bilder miteinander. Das könnte was werden. Also habe ich noch einen Weichzeichner auf die Bilder gelegt, und siehe da, die Ergebnisse waren durchaus ansehbar. Selbst bei Drehungen und zusätzlichen Bildelementen wie Schriften oder Logos kann die Funktion immer noch erkennen dass es sich um ein ähnliches Bild handelt.

Nun zum Code. Die erste Funktion erstellt einen Code für das Bild, den man ggf. sogar in einer Datenbank oder in einer Datei speichern kann. (Mit dieser Funktion ist es sogar möglich einen Bilderpool miteinander zu vergleichen, aber vorsicht! Es zieht unglaublich viel CPU-Last wenn mehrere Bilder miteinander verglichen werden, es sind ja auch relativ viele Informationen die verarbeitet werden).

Das Bild wird zuerst auf 100 x 100 Pixel verkleinert, dann wird ein Weichzeichner über das Bild gejagt. Ein Wert von 50 durchläufen hat sehr gut funktioniert. Nun werden für jedes Pixel die RGB-Werte ausgelesen, addiert und durch 3 geteilt. Simpler Dreisatz und man erhält einen Mittelwert. Mit einem richtigen Grauwert hat das nicht viel zu tun, das ist noch ein bisschen komplizierter, da die einzelnen Farben auch noch eine Gewichtung haben, aber ich schweife ab.. Mittelwert ist richtig.

Dieser Mittelwert wird in einen String geschrieben. Die Werte im String sind mit einem „|“-Zeichen getretrennt. Für ein ein 100 x 100 Pixel großes Bild haben wir somit 10.000 Werte im String. Der String wird dann ganz normal über einen Return zurückgegeben. Was man damit macht ist einem selbst überlassen. Man kann ihn direkt weiterbenutzen oder auch zwischenspeichern.

Wir gehen jetzt mal davon aus das wir für 2 verschiedene Bilder jeweils einen String erstellt haben. Zum Beispiel für diese beiden:

Bild 1:
1

Bild 2:
2

Wir brauchen jetzt eine Funktion die, die beiden Strings miteinander vergleicht. Aber ein simpler Vergleich reicht leider nicht wie ich festgestellt hab. Wir müssen die „Computer-Ansicht“ der Bilder noch ein bisschen „tunen“. Die beiden Strings werden Wert für Wert miteinander verglichen. Der Vergleichswert wird in % angegeben. Wenn ein Wert über 78 % erreicht, wird dieser automatisch als 100 % gewertet. 78 % hat sich in meinen Tests als sehr gutes Ergebnis dargestellt. Natürlich hab ich jetzt nicht tausende von Bildern miteinander verglichen, aber so erhält zum Beispiel der Vergleich von den obrigen Bildern einen Übereinstimmungswert von 97 %.

Hier die Funktion die 2 Strings miteinander vergleicht:

Um 2 Bilder zu vergleichen holt man sich für jedes Bild den Wert und vergleicht die Bilder mittels compare

Wie gesagt, diese Funktionen sind weder ein neuronales Netz, noch suchen die Funktionen nach Formen oder ähnliches, aber für den Heimgebrauch reicht es vollkommen.

Als gut gemeinten Rat: Falls ihr mehrere Bilder miteinander vergleichen wollt, versucht das erst mal auf einem Server zu Hause. Eurer Hoster könnte aufgrund der erhöhten Ressourcennutzung leicht angefressen reagieren wenn ihr plötzlich für 1000 Bilder einen Schlüssel erstellt und diese miteinander vergleicht.