Prüfen ob zwei Bilder die gleichen sind.

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
cube2000
User
Beiträge: 7
Registriert: Donnerstag 25. März 2021, 21:53

Hej
Ich bin gerade in einem kleinen Programmier Projekt, leider komme ich nicht weiter und dachte daher, ich frage hier mal nach.
Mein Ziel:
Ich will in einer while schleife das Bild einer Webcam herunterladen.
Wenn das Bild gleich ist wie das zuletzt heruntergeladene Bild, dann wieder löschen.
wenn es ein neues Bild ist, sauber in einem Ordner abspeichern.

Habe mir dazu folgenden Code überlegt:

Code: Alles auswählen

from PIL import Image
import urllib.request
repeat = 1
urllib.request.urlretrieve("https://www.impianticortina.it/webcam/socrepes.jpg",
                               'images/0.jpg')
while True:
    urllib.request.urlretrieve("https://www.impianticortina.it/webcam/socrepes.jpg",
                               'temp/pic.jpg')

    im1 = Image.open('temp/pic.jpg')
    im2 = Image.open(f'image/{repeat -1}.jpg')

    if list(im1.getdata()) == list(im2.getdata()):
        print("Identical")
    else:
        print("Different")
        im1.save(f'image/{repeat}.jpg')
        repeat += 1

Leider funktioniert es nicht, wie ich es mir vorgestellt habe.
Kann mir jemand weiter helfen?
Grüsse
Benutzeravatar
__blackjack__
User
Beiträge: 13919
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@cube2000: Du vergleichst nicht (immer) die heruntergeladenen Bilder sondern heruntergeladene Bilder mit einem Bild das Du selber als JPG kodiert und gespeichert hast. JPG ist verlustbehaftete Komprimierung — wenn Du das lädst und unter anderem Namen wieder speicherst, sind die Pixeldaten nicht mehr 100% gleich.

Ich sehe in diesem Fall aber auch nicht warum Du überhaupt die dekodierten Pixeldaten vergleichen willst. Du kannst einfach die Dateidaten direkt vergleichen. Siehe `filecmp`-Modul in der Standardbibliothek.

Da der Server in den Headern auch ein ETag-Feld hat, könnte man sich das herunterladen zum Vergleichen vielleicht auch ganz sparen.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
Zwangsgestörter
User
Beiträge: 20
Registriert: Freitag 23. Oktober 2020, 19:00

Moin,

Einfach binärdaten vergleichen wird nicht gehen. Da sind zum Beispiel die Metadaten, die sich evtl. ändern.
Die Ausgangsdaten sind auch nie gleich. Es werden immer leichte Abweichungen auftreten wie unterschiedliche Lichtsituationen um Groben und Sensorrauschen im Kleinen.

Zum Vergleich wirst du schon schwerere Geschütze wie z.Bsp. OpenCV.

https://www.pyimagesearch.com/2017/06/1 ... nd-python/

Den Link hab ich mit Google rausgesucht und sollte nur als erster Anhaltspunkt dienen.

Grüße
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@cube2000,

Kann es sein, dass du mit dem Vergleichen schauen willst ob es irgendeine Aktivität oder Bewegung auf dem Bild gab?
Da die Webcam anscheinend nur im Abstand von Minuten (10min?) neue Bilder aufnimmt, ist es nicht nötig immer wieder neue Bilder einzulesen.
Man könnte eine Wartezeit in die while-Schleife einbauen um den Server nicht zu oft, unnötig abzufragen.

Gerade weil die zeitlichen Abstände zwischen zwei Aufnahmen recht groß sind, wird es allein schon wegen Helligkeitsunterschieden, Änderungen im Bild ergeben.
Man muss also zusätzlich auswerten wie stark die Intensitätsänderung eigentlich ist.

Ich würde die Bilder in ein numpy - array speichern und dann die Differenz bilden. Dort wo die Differenz groß ist, hat sich etwas bewegt, dort wo die Differenz klein ist, haben sich vielleicht nur die Lichtverhältnisse geändert.
Je nachdem, was du wirklich erreichen willst muss du die entsprechenden Schwellwerte ermitteln.

Gerade am Morgen oder Abend oder bei Wolken wird die Differenz einen relativ gleichmäßig verteilten Unterschied zeigen. Wenn eine Person ins Bild läuft wird das eine konzentrierte eher starke Veränderung bedeuten.

Man kann sich auch überlegen, ob es Sinn macht, die Rot, Grün, Blau Werte einzeln auszuwerten, oder ob es reicht, das Bild zuerst in ein Graustufen-Bild umzuwandelt.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

@rogerb alleine schon durch Rauschen hast du Änderungen im gesamten Bild. Algorithmen zur Separierung von Vorder- und Hintergrund bzw. statischen und dynamischen Bildinhalten sind verfügbar in der OpenCV, aber deutlich komplexere statistische Modellierungen, als du es hier beschreibst. Siehe zb https://docs.opencv.org/3.4/d1/dc5/tuto ... ction.html

Ob durch die geringe Aufnahmefrequenz (und dadurch große, akkumulierte Änderungen) sowas überhaupt sinnvoll geht, steht auf einem anderen Blatt. Da muss ggf zb durch Masken der Himmel ausgeblendet werden.
Benutzeravatar
__blackjack__
User
Beiträge: 13919
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Zwangsgestörter: Da gibt es keine sich ändernden Metadaten, das ist keine Webcam die da Live abgefragt wird, sondern das Bild einer Webcam die der Server selber schon irgendwo her holt. Und die Datei ist immer gleich, bis der Server da eine neues Bild für eine gewisse Zeit zur Verfügung stellt.

Und wenn die Bilddateien dann unterschiedlich sind, funktioniert *ganz offensichtlich* auch ein simpler Vergleich *nicht*, selbst wenn man Rauschen etc. berücksichtigt, weil die Bilder nicht nur das reine Webcambild enthalten, sondern auch schon Informationen zum Bild die sich verändern *im Bild*. Man müsste also bestimmte Bereiche im Bild noch mal extra behandeln/vom Vergleich ausnehmen, weil die sich garantiert geändert haben, egal ob sich auf dem Webcambild was wesentliches getan hat, oder auch nicht.

Selbst wenn tatsächlich der *Inhalt* des Bildes analysiert werden soll, macht es Sinn als erstes mal die reinen Dateidaten zu vergleichen, beziehungsweise das ETag mit einer HEAD-Anfrage zu prüfen, denn wenn da schon Gleichheit festgestellt werden kann, braucht man erst einmal keinen komplexeren Schritt machen, oder eben noch nicht einmal das Bild tatsächlich herunterladen.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
Zwangsgestörter
User
Beiträge: 20
Registriert: Freitag 23. Oktober 2020, 19:00

ach so,

na dann, einfach einen Hash berechnen lassen und fertig.
Antworten