Hilfe bei Python für Video-Stream

Alles rund um TX(T) und RoboPro, mit ft-Hard- und Software
Computing using original ft hard- and software
Forumsregeln
Bitte beachte die Forumsregeln!
Antworten
Benutzeravatar
uffi
Beiträge: 404
Registriert: 24 Jan 2014, 16:21
Wohnort: München

Hilfe bei Python für Video-Stream

Beitrag von uffi » 25 Nov 2023, 21:26

Hallo,
ich möchte im Online Modus eine am TXT angeschlossene USB-Kamera auf den PC Monitor streamen. Auf dem TXT läuft die Community Firmware und ich habe das FT-Gui gestartet.

Mit folgendem Code auf dem PC ist es mir möglich, Einzelbilder von der USB-Kamera einzulesen, auf dem PC zu speichern und in einem Fenster anzuzeigen:

Code: Alles auswählen

import numpy as np
import cv2
import ftrobopy
import time

txt=ftrobopy.ftrobopy('192.168.2.112')
txt.startCameraOnline()
time.sleep(3)
while True:
  img = txt.getCameraFrame()
  with open('txtimg.jpg','wb') as f:
    f.write(bytearray(img))
  frame = cv2.imread('txtimg.jpg', cv2.IMREAD_COLOR)
  cv2.imshow('FT Cam', frame)
  cv2.waitKey(0)
  cv2.destroyAllWindows()
Es wird ein Window mit folgendem Bild erzeugt:
txtimg.jpg
txtimg.jpg (18.57 KiB) 1358 mal betrachtet
In der Python Shell erfolgt folgendes Log:

Code: Alles auswählen

= RESTART: I:\Zirkel\Fischertechnik\FT_Community\python_programs\online_test\online_test_cam_ftrobopy.py
Connected to  TX2013 firmware version 4.7.0
Camera connected

================================ RESTART: Shell ================================
Soweit so gut. Ich würde aber gerne die Speicherung der Bilder unterlassen, um ein schnelleres Video-Streaming zu bekommen. Ich habe daher den Code verkürzt:

Code: Alles auswählen

import numpy as np
import cv2
import ftrobopy
import time

txt=ftrobopy.ftrobopy('192.168.2.112')
txt.startCameraOnline()
time.sleep(3)
while True:
  img = txt.getCameraFrame()
  cv2.imshow('FT Cam', img)
  cv2.waitKey(0)
  cv2.destroyAllWindows()
Leider klappt das nicht und es gibt folgende Fehlermeldung:

Code: Alles auswählen

= RESTART: I:\Zirkel\Fischertechnik\FT_Community\python_programs\online_test\online_test_cam_ftrobopy.py
Connected to  TX2013 firmware version 4.7.0
Camera connected
Traceback (most recent call last):
  File "I:\Zirkel\Fischertechnik\FT_Community\python_programs\online_test\online_test_cam_ftrobopy.py", line 14, in <module>
    cv2.imshow('FT Cam', img)
cv2.error: OpenCV(4.8.0) :-1: error: (-5:Bad argument) in function 'imshow'
> Overload resolution failed:
>  - mat is not a numpy array, neither a scalar
>  - Expected Ptr<cv::cuda::GpuMat> for argument 'mat'
>  - Expected Ptr<cv::UMat> for argument 'mat'
Was mache ich falsch?

Ich habe auch noch folgendes versucht:
statt

Code: Alles auswählen

cv2.imshow('FT Cam', img)
habe ich verwendet

Code: Alles auswählen

cv2.imshow('FT Cam', bytearray(img))
Das ergibt den gleichen Fehler wie oben.

Ich habe den Eindruck, dass das Bild nicht direkt abgerufen kann.
Könnt Ihr mir bitte einen Tipp geben?

Danke und Gruß, uffi

hypnotoad
Beiträge: 121
Registriert: 16 Feb 2019, 12:43
Wohnort: 30559 Hannover
Kontaktdaten:

Re: Hilfe bei Python für Video-Stream

Beitrag von hypnotoad » 25 Nov 2023, 22:39

Hallo Uffi. Das Bild ist noch als jpg komprimiert. Ich mache das üblicherweise so:

Code: Alles auswählen

while True:
    jpg = self.txt.getCameraFrame()
    if jpg != None:
        img = cv2.imdecode(np.frombuffer(bytearray(jpg)), cv2.IMREAD_COLOR)
    else:
        continue
    cv2.imshow('FT Cam', frame)
    cv2.waitKey(0)
In der Schleife sollten keine Fenster geschlossen oder erzeugt werden. Der Vergleich mit "None" ist meiner Erfahrung nach nötig, da USB-Kameras sporadisch defekte jpg-Bilder liefern, die nicht dekodiert werden können (dann wird None zurückgegeben).

Benutzeravatar
uffi
Beiträge: 404
Registriert: 24 Jan 2014, 16:21
Wohnort: München

Re: Hilfe bei Python für Video-Stream

Beitrag von uffi » 26 Nov 2023, 10:55

Vielen Dank, hypnotoad!!!
So funktioniert es jetzt. :D
Mit dem Code unten bekomme ich ein Fenster mit einem laufenden Video-Stream und kann (nach Mausklick auf das Video-Fenster) durch Drücken der Taste q den Python Thread beenden.

Code: Alles auswählen

import numpy as np
import cv2
import ftrobopy
import time

txt=ftrobopy.ftrobopy('192.168.2.112')
txt.startCameraOnline()
time.sleep(3)
cv2.namedWindow('FT Cam')
cv2.resizeWindow('FT Cam', 320, 240)

while True:
  jpg = txt.getCameraFrame()

  if jpg != None:
    img = cv2.imdecode(np.frombuffer(bytearray(jpg)), cv2.IMREAD_COLOR)
  else:
    continue

  cv2.imshow('FT Cam', img)
  if cv2.waitKey(1) & 0xFF == ord('q'):
    break

txt.stopCameraOnline()
txt.stopOnline()
cv2.destroyAllWindows()

Techum
Beiträge: 84
Registriert: 25 Dez 2014, 20:50
Kontaktdaten:

Re: Hilfe bei Python für Video-Stream

Beitrag von Techum » 01 Dez 2023, 21:38

Hallo Uffi, (und wer das sonst noch probiert hat)

weil ich in einem anderen Thread von Dir gelesen hatte, dass Du das Bild lokal geholt und ausgewertet hast, kannst Du mir vielleicht sagen, was schneller geht?

Ich habe bisher mit Python fast alles per PC im Onlinemodus gemacht (mit oder ohne Community Firmware) - also Python Script auf dem Rechner laufen lassen, weil der mehr Rechenpower hat und dem TXT die die Fahrbefehle per ftrobopy über WLAN gesendet und umsetzen lassen. Zwar hat das Bild einen kleinen Zeitverzug, aber das macht die schnelle Bildverarbeitung auf dem PC vermutlich wett.
Bei anspruchsvolleren Anwendungen, z.B. Objekterkennung, ist das ganz sicher der effizientere Weg - mal abgesehen davon, dass man am PC auch besser sehen kann, was zu welchem Zeitpunkt genau passiert.

Jetzt habe ich aber folgenden Fall:
Ich will an einem Modell demonstrieren, wie schnell TXT und TXT4.0 miteinander über MQTT Informationen austauschen können.
Die Kamera am TXT soll einen Videostream auswerten per Bildvergleich (das dürfte auch auf dem TXT schnell gehen). Die Stelle mit einer größeren Veränderung (Blob) soll der TXT an einen MQTT Server senden. Wird das insgesamt schneller gehen als das Versenden des Videostreams an den PC und die Bestimmung der Veränderung dort? Wenn nicht, bauche ich ein anderes Modellbeispiel.

ich dachte an das:
TXT Video -> TXT Bloberkennung -> TXT Blobkoordination -> MQTT -> TXT4.0 Verarbeitung

bisher mache ich das:
TXT Video -> PC Bloberkennung im Onlinemodus -> PC Blobkoordinaten -> MQTT -> TXT4.0 Verarbeitung
(das geht, ich habe aber eine Verzögerung durch das BIld von ca. 0.3s)

Schönen Abend
Techum

hypnotoad
Beiträge: 121
Registriert: 16 Feb 2019, 12:43
Wohnort: 30559 Hannover
Kontaktdaten:

Re: Hilfe bei Python für Video-Stream

Beitrag von hypnotoad » 01 Dez 2023, 22:33

Hallo Techum,

wenn Du Bildverarbeitung machst und niedrige Latenz möchtest, dann sollte Dein Algorithmus im Durchschnitt schneller als die Kamera arbeiten. Ansonsten füllen sich diverse Puffer (in der Kamera, im USB-Stack, ggf. im Thread zur Übermittlung über das Netzwerk) und Du verarbeitest Bilder, die schon alt sind, wenn Du anfängst, sie zu verarbeiten.

Niedrigere Auflösung sollte die Latenz auch reduzieren.

Wenn Dein Algorithmus langsamer ist, als die Kamera Bilder macht, kannst Du ggf. Bilder wegschmeissen, ohne die jpg-Dekodierung zu machen. Dann solltest Du deutlich unter 0,3s liegen, wenn Du auf dem TXT arbeitest.

lg,
Ralf

Techum
Beiträge: 84
Registriert: 25 Dez 2014, 20:50
Kontaktdaten:

Re: Hilfe bei Python für Video-Stream

Beitrag von Techum » 03 Dez 2023, 15:41

Hallo Ralf,

vielen Dank für Deine schelle Antwort. Ich hätte vermutet, dass es mit der Bildverarbeitung selbst zu tun hat, wenn die Latenz konstant ist und nicht ansteigt.
ftprobopy holt meines Wissens nach immer nur den letzten Frame und stellt diesen per internem Thread bereit.

Ich bin bei der Auflösung der Cam schon am unteren Limit. FPS habe ich auf 30 gesetzt.

Wo man vielleicht bei cv2.VideoCapture noch was holen kann, ist der Buffer. Wenn es nicht um ruckelfreies Video sondern möglichst real-time Video geht, sollte man wohl den Buffer auf einen kleinen Wert setzen z.b set(cv2.CAP_PROP_BUFFERSIZE, 1) oder sogar 0.
Habe auch gelesen, dass (CV_CAP_PROP_POS_FRAMES, 0) helfen soll. Bei mir hat beides nichts gebracht.

Ich gehe jetzt erst einmal dazu über, die Kamera direkt am Rechner zu betreiben. Wenn ich die FtcGuiApplication dort betreibe - mit der FT Kamera - ist keine Lazenz mehr festzustellen. Es handelt sich um ein statisches Modell daher geht das gut.

Vielen Dank nochmals
Techum Frank.

Benutzeravatar
uffi
Beiträge: 404
Registriert: 24 Jan 2014, 16:21
Wohnort: München

Re: Hilfe bei Python für Video-Stream

Beitrag von uffi » 12 Dez 2023, 18:25

Hallo,

ich brauche nochmal Hilfe bei einem Problem.

Ich bekomme neuerdings beim Online Betrieb der FT USB-Kamera am TXT mit Python 3.11 am PC (über LAN Verbindung mit der ft GUI App von der CFW) nach ein paar Sekunden erfolgreichen Betriebes mit Anzeige des Kamera Bildes am PC-Bildschirm folgende Fehlermeldungen:

Code: Alles auswählen

= RESTART: I:\Zirkel\Fischertechnik\FT_Community\python_programs\FTS\online_test_cam_ftrobopy_fts_slice_real.py
Connected to  TX2013 firmware version 4.7.0
Camera connected
Timeout while getting new frame from camera
Timeout while getting new frame from camera
Timeout while getting new frame from camera
Timeout while getting new frame from camera
Timeout while getting new frame from camera
Received data size ( 0 ) does not match length of format string ( 80 )
Connection to TXT aborted
Timeout while getting new frame from camera
Timeout while getting new frame from camera
Timeout while getting new frame from camera
Timeout while getting new frame from camera
Timeout while getting new frame from camera
Hat jemand schon ähnliche Erfahrungen gemacht und weiß woran das liegen könnte?

Danke und Gruß, uffi

hypnotoad
Beiträge: 121
Registriert: 16 Feb 2019, 12:43
Wohnort: 30559 Hannover
Kontaktdaten:

Re: Hilfe bei Python für Video-Stream

Beitrag von hypnotoad » 12 Dez 2023, 19:29

Hallo,

ist die Stromversorgung stabil? Ich habe auch manchmal leere Bilder und denke, dass es an Spannungsabfällen liegt, weil ich den TXT am Akku laufen habe.

Ralf

Benutzeravatar
uffi
Beiträge: 404
Registriert: 24 Jan 2014, 16:21
Wohnort: München

Re: Hilfe bei Python für Video-Stream

Beitrag von uffi » 12 Dez 2023, 19:50

Der TXT wird stationär an einer kräftigen stabilisierten 9V Stromversorgung betrieben, allerdings mit einem ca 2m langen FT Kabel. Ich teste mal, ob es mit einem dickeren oder kürzeren Kabel besser läuft
Danke für den Tipp

Nachtrag: zwei von den vier Steckern des langen Kabels waren schludrig montiert. Nach Korrektur lief abends alles einwandfrei. Ich habe aber noch eine andere Vermutung: tagsüber, als die Fehler auftraten, war mein WLAN Router parallel mit Telecons beschäftigt. Ich denke, dass die Fehler daher kamen...

Antworten