Hallo,
um ein Objekt im Raum zu verfolgen, ist an dem Objekt eine LED
angebracht und die Webcam meines PC auf das Objekt gerichtet. Die LED
wird über einen UART-Befehl des PC über einen Atmega8 an-, bzw.
ausgeschaltet. Das klappt via Terminal-Programm und auch per Python so
wie es soll.
Ich will jetzt mit OpenCV immer abwechselnd ein Bild bei ausgeschalteter
LED aufnehmen, dann eines bei eingeschalteter, etc. Dann will ich die
jeweiligen Bilder vergleichen und dann (wie bereits bei anderen
Projekten) aus dem Unterschied zwischen den Bildern die Position des
Objektes berechnen.
Nur klappt das nicht richtig, denn bei den Aufnahmen ist mal die LED zu
sehen, obwohl sie aus sein sollte, oder umgekehrt. Ich habe erst
gedacht, dass im Hintergrund die Daten seriell noch nicht versendet
wurden, aber auch wenn ich den uC "antworten" lasse, und vor der
Aufnahme auf diese Antwort warte, sodass die LED sicher an sein müsste,
tritt das Problem auf.
Meine Mutmaßung: Es wird nicht das aktuellste Bild des Videostreams
ausgelesen, sondern eines aus einem Buffer, das schon etwas "älter" ist.
Liege ich da richtig, oder gibt es andere Ursachen? Hat jemand eine
Idee, wie ich dem Problem auf die Spur komme?
1
import cv2
2
from skimage.metrics import structural_similarity as ssim
3
import imutils
4
import numpy as np
5
import time
6
import serial
7
8
led_an = bytearray([10])
9
led_aus = bytearray([20])
10
ser = serial.Serial("COM3", 9600)
11
cap = cv2.VideoCapture(0)
12
try:
13
while True:
14
ser.write(led_aus)#beim Empfangen diese Befehls schaltet der uC (noch in der ISR) die LED aus
15
ser.write(bytearray([40]))#hiermit wird eine "Antwort" des uC angestoßen
16
eingang = ser.read(1)#Es gibt kein Timeout, also wartet das Programm hier, bis der uC wirlich geantwortet, ergo die LED ausgeschaltet hat
17
if eingang == bytearray([40]):
18
ret, bild0 = cap.read()
19
eingang = 0
20
ser.write(led_an)#hier das gleiche Spiel nochmal, nur dass hier die LED angeschaltet wird
21
ser.write(bytearray([40]))
22
eingang = ser.read(1)
23
if eingang == bytearray([40]):
24
ret, bild1 = cap.read()
25
eingang = 0
26
cv2.imshow("bild0", bild0)#hier sollte die LED nicht zu sehen sein (ist sie aber oft)
27
cv2.imshow("bild1", bild1)#...und hier sollte sie sichtbar sein
Mask-Man schrieb:> Python OpenCV Kamera lag bei Auslesen der aktuellen Aufnahme
Wo "lag" die Kamera denn? Das deutsche Wort dafür heißt "Verzögerung"
Mask-Man schrieb:> Meine Mutmaßung: Es wird nicht das aktuellste Bild des Videostreams> ausgelesen, sondern eines aus einem Buffer, das schon etwas "älter" ist.
Ja natürlich. Da gibt es diverse Puffer im System. Einen in der Webcam
selbst, einen im USB Treiber, einen im v4l Treiber dann noch welche im
opencv und so weiter. Wenn die Webcam ihre Daten bereits als kodierten
Videostream abliefert (Machen fast alle heute so) dann kommt da noch
mehr Verzögerung da die Daten ja auch noch dekodiert werden müssen.
Lass dir doch mal in einer Schleife das aktuelle ausgelesene Bild der
Kamera ausgeben. Dann solltest du sehen, in welchem Bereich die
Verzögerung liegt. Mit 1-2 Sekunden würde ich da schon rechnen.
lambda schrieb:> Mit 1-2 Sekunden würde ich da schon rechnen.
Höchstens bei Web-Cams im Sinne des Wortes, also über Netzwerk
angebunden mit h264-Streaming. Normale Cams über USB machen entweder raw
(dann aber nur mit so 5-10fps) oder Motion-JPEG. Da sind die
Verzögerungen deutlich kleiner. Aber wie oben beschrieben, sind da schon
ein paar (Frame)Buffer im Weg, d.h. eine Handvoll Frames (0.1-0.2s) wird
da immer an Latenz vorhanden sein. Die müsste aber relativ konstant
sein. Ich mach mit einer UVC-Mikroskop-Kamera und OpenCV eine
Feinpositionierung auf so 20um, da muss nach jedem Kalibrierungschritt
250ms gewartet werden. Stört mich aber nicht besonders, da sind noch ein
paar kg bewegte Masse, die sich auch erstmal beruhigen müssen ;)
Danke soweit für die Antworten. Das Denglisch ist natürlich ziemlich
missverständlich ;)
Ich bin tatsächlich bei weitem nicht bei zwei Sekunden Verzögerung, aber
200ms kommt schon hin. Der Umstand, dass dieser Wert etwa konstant
bleibt, hilft mir leider auch nicht wirklich weiter, in jedem Fall muss
ich das Projekt jetzt etwas anders umsetzen. Spontan denke ich an
IR-Leds mit IR-pass-filter vor der Kamera, oder an die Erkennung eines
farbigen Balles.
Falls jemand sinnvolle Möglichkeiten kennt, die Position und Ausrichtung
eines Objektes im Raum zu erfassen, gerne her damit! Konkret soll von
der Schulter aus die Position des Kopfes in Relation zu ebenjener
erfasst werden.
Mask-Man schrieb:> um ein Objekt im Raum zu verfolgen, ist an dem Objekt eine LED> angebracht und die Webcam meines PC auf das Objekt gerichtet. Die LED> wird über einen UART-Befehl des PC über einen Atmega8 an-, bzw.> ausgeschaltet. Das klappt via Terminal-Programm und auch per Python so> wie es soll.> Ich will jetzt mit OpenCV immer abwechselnd ein Bild bei ausgeschalteter> LED aufnehmen, dann eines bei eingeschalteter, etc. Dann will ich die> jeweiligen Bilder vergleichen und dann (wie bereits bei anderen> Projekten) aus dem Unterschied zwischen den Bildern die Position des> Objektes berechnen.
Also im Prinzip geht es um Bewegungserkennung, korrekt? Dann schau' doch
mal dies [1] und den Folgebeitrag an. Eine echte Bewegungserkennung habe
ich auf der Basis mit einem RasPi4, einer Logitech C920 und Redis für
den Datentransport auf 25 bis 30 FPS optimieren können, dann ist die CPU
saturiert...
[1]
https://www.pyimagesearch.com/2015/05/25/basic-motion-detection-and-tracking-with-python-and-opencv/