home     zurück
letzte Änderung am 13.03.2016

Erkennung der Bewegungsrichtung


Sicherlich könnte man für ein Pixel im Differenz-Bild anhand der beiden ursprünglichen Bilder erkennen, ob dieses Pixel von alt nach neu heller oder dunkler geworden ist. Die Frage ist aber, ob das was nützt.

Mal an zwei Beispielen ansehen.
1.) "ein heller Kaffeebecher wird vor einem dunklen Hintergrund von unten nach oben bewegt":
erstes Bild
zweites Bild
erstes Bild (Bild_0)
zweites Bild (Bild_1)
Differenz-Bild
Differenz-Bild mit Raster (Bild_d)

2.) "eine schwarze DVD-Spindel wird vor einem hellen Hintergrund von oben nach unten bewegt":
erstes Bild
zweites Bild
erstes Bild (Bild_0)
zweites Bild (Bild_1)
Differenz-Bild
Differenz-Bild mit Raster (Bild_d)

Das Programm kann davon ausgehen, dass Bild_0 zeitlich vor Bild_1 entstanden ist.
Anhand Bild_d kennt es die Bereiche, an denen sich was geändert hat.

Beispiel 1.)
Im unteren veränderten Bereich von Bild_d fällt auf, dass die Tastatur sichtbar geworden ist. Auf Bild_0 war sie das nicht, erst auf Bild_1.
Aber Strukturen im Bild will ich eigentlich nicht vergleichen. Das wird sicher viel zu lange dauern.
Es geht darum, ob anhand der Helligkeiten von den selben Pixeln in den beiden Bildern eine Bewegungsrichtung abgeleitet werden kann.
Ort
Bild_0 Bild_1
Tasse @ Bild_0
eher hell
stellenweise dunkel
Tasse @ Bild_1 stellenweise dunkel eher hell

Beispiel 2.)
Ort
Bild_0 Bild_1
Spindel @ Bild_0
dunkel
hell
Spindel @ Bild_1 relativ hell
dunkel

Fazit: so wird das schon mal nix. War eigentlich auch klar.
Wenn das sich bewegende Objekt sowohl heller, als auch dunkler als der Hintergrund sein kann, reicht ein bloßer Vergleich von Bild-Helligkeiten nicht.
Da müsste das Objekt schon als solches im Bild_0 erkannt und in Bild_1 wiedergefunden werden. Wie an den obigen Bildern zu erkennen, dürfte das jedoch ausgesprochen schwierig werden, wenn das Objekt in einem der beiden Bilder verhuscht ist...oder anderes ausgedrückt: Bewegungs-Unschärfe aufweist.

Mit drei Bildern könnte das jedoch schon anders aussehen.
Große strukturelle Umbauten bräuchte die Verwaltung eines dritten Bildes nicht. Vor der Schleife einfach zwei Bilder (img0 und img1) holen und am Ende der Schleife vor dem img1=img2 noch einen img0=img1 einfügen.
Die Richtung einer einheitlichen Bewegung sollte sich dann dadurch detektieren lassen, dass ein Differenz-Bild aus img0-img1 und eins aus img0-img2 gebildet wird. Damit hat man zwei Differenz-Bilder, die einen bewegten bzw. hellen Bereich gemeinsam haben (das bewegte Objekt in img0) und jeweils einen weiteren hellen Bereich, der in beiden Bildern an unterschiedlichen Stellen erscheint. Der gemeinsame helle Bereich ließe sich über eine AND-Verknüpfung der beiden Differenz-Bilder bestimmen. Wird dieses AND-Differenz-Bild dann XOR mit dem Differenz-Bild img0-img2 verknüpft, sollte der verbleibende helle Bereich der jüngsten Bewegung entsprechen.
....denke ich mir jedenfalls mal so rein theoretisch.
Wie sich uneinheitliche Bewegungen auswirken, will ich jetzt nicht mehr theoretisch betrachten.
Ich baue das dann mal nächstes Wochenende und schaue es mir an.


Nun habe ich das gebaut und folgendes Ergebnis bekommen:
Bild 0
Bild 1
Bild 2
erstes Bild (Bild_0)
zweites Bild (Bild_1) drittes Bild (Bild_2)
Differenz
              Bild_0 - Bild_1 Differenz Bild_0 -
              Bild_2 Diff01 AND Diff02
Differenz-Bild 0-1 (Bild_d01)
Differenz-Bild 0-2 (Bild_d02) Bild_d01 AND Bild_d02 (Bild_d1and2)


Diff02 XOR (Diff01 AND
              Diff02)


Bild_d02 XOR Bild_d1and2 (Bild_d2xor)

Das sieht also schon ziemlich genau so aus, wie angedacht.
Die letzten beiden Bilder wurden folgendermaßen gebildet:
    diff01b=diff01>100
    diff02b=diff02>100
    d1and2=np.logical_and(diff01b, diff02b)
    d2xor=np.logical_xor(diff02b, d1and2)
und gespeichert mittels:
        cam.saveImage(insertRaster(np.uint8(-d1and2-1)), "%s-5"%(t,))
        cam.saveImage(insertRaster(np.uint8(-d2xor-1)), "%s-6"%(t,))

Weil AND und XOR nicht sinnvoll auf Grauwerte angewandt werden kann, wurden die beiden Differenz-Bilder im ersten Schritt nach binär oder auch boolsch gewandelt.

Bild_d1and2 ist die Gemeinsamkeit der beiden Differenz-Bilder - also die älteste Bewegung.
In Bild_d2xor wurde aus der binären Version von Bild_d02 das Bild_d1and2 ausgeschnitten.
Somit bleibt dort die jüngste Bewegung übrig und die Kamera könnte entsprechend positioniert werden.

Das war nun der Gut-Fall mit einheitlicher Bewegungsrichtung.
Nicht so schön deutlich sieht es bei uneinheitlicher Bewegungsrichtung aus - aber besser als befürchtet.
Ist die Bewegung so langsam, dass sich Bereiche mit Bewegung in den Differenz-Bildern überschneiden, wird es ebenfalls undeutlicher, aber weil sich quasi alle Bewegung an einem Ort abspielt, sollte sich auch das nicht sonderlich negativ auf die korrekte Positionierung der Kamera auswirken.

Anbei nochmal das Script in [vorläufig] letzter Version.

Der Fuß-Fetisch ist nach wie vor ein Problem, ebenso wie Schatten, die manchmal als bewegtester Bereich angesehen werden.