VideoStream in Framebuffer schreiben (OpenGL und Qt)
-
Hallo zusammen,
ich möchte einen Videostream analysieren. Dafür müssen die Farbwerte und Helligkeitswerte der Pixel ermittelt werden. Aus diesen Daten möchte ich dann ein Histogramm und eine RGB-Parade erzeugen. Meine Idee ist die Daten aus dem VideoStream in einen OpenGL Framebuffer zu schreiben um daraus dann die Graphen zu generieren.
Ist das so möglich und wenn ja ist das auch in Sachen Performance eine gute Idee?Bin Laie, lerne das gerade und würde mich über eine Rückmeldung freuen.
-
Mit was für einem Framework?
Mit ffmpeg könnte man das relativ einfach machen.
Mit den QML müsste man auch schon recht einfach an einzelne Frames rankommen. Da kann man auch ziemlich einfach "Filter" implementieren, wenn ich mich recht erinnere.
-
Qt. Ich hatte erst überlegt das Video in eine
QImage
zu konvertieren und dieses dann zu analysieren. Aber das auslesen der Werte aus dem Image dauert ein wenig.
-
QtWidgets ignorier ich mal. In QML kriegst du ein QVideoFrame, da kannst du die Daten über die bits Funktion auslesen.
Bezüglich der Effizienz unterscheiden sich diese ganzen Darstellungen nicht großartig. Die Farbwerte müssen irgendwo im Speicher liegen. Sowohl über QImage als auch über QVideoFrame kommst du gleich effizient ran. Eine Konvertierung kann das alles auch nicht effizienter machen, die braucht mindestens die Zeit, die du zum Auslesen der Daten brauchen würdest.
-
Um an die einzelnen Frames ranzukommen, musst den VideoStream dekodieren(korrekter: entpacken und decodieren).
Da solltest dich schon mal einlesen ...
Da gibt's natürlich libs für. ffmpeg (eigentlich ein sammelsorium aus mehreren libs) ist da schon mal eine Wahl, aber nicht die komfortabelste.Für eher ungeübte würde ich aber zuerst mal OpenCV oder ähnliches Vorschlagen. Wenn der VideoStream aus ner Datei oder einem Standard Gerät (Kamera) kommt, kommt man da recht einfach an die PixelMatrix ran. Ausserdem ist das konvertieren da recht komfortabel. Für einen ersten Prototyp
Performance ist eine andere Sache ....
Will man decodieren, Konvertieren Anzeigen .. recht performant und recht latenzarm, kommt man um manuelles decodieren auf der Graka / decoderchip nicht drumherum ... und dann noch Anzeigen ohne das Bild wieder über die cpu zu schleussen, direkt in einen Texturbuffer kopieren ... dann helfen meist nur die low level API's des decoders und der Grafik karte (nvenc, intel media sdk, OpenCL / cuda).Bin Laie
Jeder hat mal angefangen. Aber Bildverarbeitung Video Codierung und Rendering sind nun echt nicht die besten Einsteigerthemen. Erst recht nicht eine Kombi davon
Aber schau dir OpenCV ( https://opencv.org/ ) an, das nimmt eine Menge Arbeit ab, wenn die Umgebung passt. Bei den Beispielen findest auch eines zum Thema Histogramm
Wenn das damit läuft, und mit mehr Erfahrung dann, kannst anfangen mit Low Level libs und mehr Controlle zu arbeiten.
-
Ich würde dir auch zu OpenCV raten, in Kombination mit QT zur Anzeige habe ich da auch schon auf einzelnen Frames eines Videostreams gearbeitet.
Performance ist halt so ne Sache. Da du dich selbst als Laie bezeichnest, würde ich dich bitten Code und Compileroptionen (Optimierungen, vor allem) zu zeigen.
Wir haben damals Tracking Algorithmen gebastelt, die quasi in Echtzeit funktioniert haben, das war noch in der Cuda Anfangszeit und lief auf der CPU.
-
Vielen Dank für eure Hinweise. Ich bin schon mit den Grundlagen der Computergrafik vertraut, allerdings nur sehr theoretisch. Meine praktischen Erfahrungen mit OpenGL, Qt und anderen Apis würde ich noch als laienhaft bezeichnen.
Und ich möchte mich ungern Stunden/Tage in eine Programmierung mit OpenGL verrennen, nur um am Ende zu merken das es nicht funktioniert. Daher dachte ich frage ich einfach mal nach.OpenCV hatte ich bei Projektstart auch schon in Betracht gezogen. Dachte aber das man sich mit Qt vielleicht eine weitere Library (also OpenCV) spart. Aber dann schaue ich mir erstmal OpenCV an.
-
Ich glaub schon, dass das mit Qt erstmal einfacher geht.
OpenCv ist schon eine schöne Library, wenn man paar fortgeschrittene Features braucht (und die haben sehr viele). Aber einfach nur paar Frames abgreifen dürfte mit Qt (QML) kein Problem sein.
-
Also beim auslesen der Pixeldaten sehe ich zwischen Qt und OpenCV keinen Unterschied. Die Frage ist wie geht es mit den Daten weiter? Lassen sich mit Qt leicht Graphen zeichnen oder ist OpenCV dafür die bessere Wahl? Ich habe da von der Extension
QCustomPlot
gelesen, mit der sowas in Qt möglich sein soll.Meine Idee ist: Man drückt einen Button und dadurch werden die Pixel Daten in den Bildspeicher geschoben. Aus diesen Daten wird der Graph erstellt. Gleichzeitig sollen die Werte für RGB und Luminanz in einer Textarea ausgegeben werden. Das bedeutet dann aber auch, das es keine Live-Aktualisierung gibt. Wird die Kamera bewegt, werden die Daten im Bildspeicher nicht aktualisiert und damit auch nicht der Graph. Drückt man den Button wieder werden die Daten im Bildspeicher überschrieben und der Graph aktualisiert. Das wird vermutlich das Beste für die Performance sein?
-
Über Performance Vermutungen anzustellen, kann schwer daneben gehen. Aber, es ist vlt eine gute Idee damit anzufangen, erstmal für ein Bild aus dem Videostream ein Histogram zu erzeugen und anzuzeigen. Dann kann man gucken, was passiert, wenn man das auf einen kontinuierlichen Datenstrom los lässt, vielleicht erstmal auf niedrigerer Framerate, oder so.
Für OpenCv gibt es ein ziemlich fertiges Tutorial für Histrogramme auf Bilddaten: https://docs.opencv.org/4.5.3/d8/dbc/tutorial_histogram_calculation.html
In QT würde ich vermuten, müsste man mehr selbst machen, weiß ich aber nicht genau.
Wenn du meinst, dass die Performance deines Codes zu schlecht ist, kann ich mich nur wiedeholen:
@Schlangenmensch sagte in VideoStream in Framebuffer schreiben (OpenGL und Qt):
Da du dich selbst als Laie bezeichnest, würde ich dich bitten Code und Compileroptionen (Optimierungen, vor allem) zu zeigen.
-
Ich würde das einfach mal probieren. Irgendwie. Wie es am leichtesten geht. Und dann eben gucken wie die Performance ist. Was man da für Performance zu erwarten hat hängt von so vielen Faktoren ab, das kann man so überhaupt nicht sagen. Kann sein dass du mit einer Live-Aktualisierung deiner Graphen gerade mal ein paar Prozent CPU Auslastung bekommst. Dann machst du einfach die Variante die für den User am besten ist (Live-Aktualisierung muss nicht immer das beste sein). Kann aber auch sein dass du nicht mehr als 1 Frame pro Sekunde schaffst. Und erst dann wäre der Zeitpunkt sich zu überlegen was man jetzt macht.
-
@makopo sagte in VideoStream in Framebuffer schreiben (OpenGL und Qt):
Meine Idee ist: Man drückt einen Button und dadurch werden die Pixel Daten in den Bildspeicher geschoben. Aus diesen Daten wird der Graph erstellt. Gleichzeitig sollen die Werte für RGB und Luminanz in einer Textarea ausgegeben werden. Das bedeutet dann aber auch, das es keine Live-Aktualisierung gibt. Wird die Kamera bewegt, werden die Daten im Bildspeicher nicht aktualisiert und damit auch nicht der Graph. Drückt man den Button wieder werden die Daten im Bildspeicher überschrieben und der Graph aktualisiert. Das wird vermutlich das Beste für die Performance sein?
Die gefühlte minimale Reaktions-Zeit eines Users liegt im Millisekundenbereich, also das was als "Sofort" wahrgenommen wird. D.H. was du beschreibst, und nicht beim implementieren der Anzeige grobe Fouls begeht, ist das von der erforderlichen Performance her .... mehr als unkritisch.
"Herausforderung", wär das bei üblichen Industrie Cam Daten Größen , also ca. 2 Megapixel bei 30 Hz, live zu rechnen ...
inklusive Formatkonvertierung & co. und dann noch genug Rechenzeit zu haben für die eigentlichen Computer vision themenProgrammierung mit OpenGL
Das ist das was du erst mal nicht brauchst ... Es macht kein Sinn, einen Renderer aufzuziehen nur um ein Pixmap auf deinen Desktop zu blitten. Rendern ist nur sinnvoll wenn du 3D Daten 2 dimensional projezieren willst. Einen fertiges Image anzuzeigen da ist eine normale GUI genau so gut.
Willst du fertig ein Video irgendwo in ein Programm mit normaler GUI einbetten, ist Qt + Multimediaframework eh besser geeignet.
Histogramme, Filter sind dann eher Computervision themen, deshalb -> OpenCV
Und ich möchte mich ungern Stunden/Tage in eine Programmierung mit OpenGL verrennen,
Sich in neue Bibs einarbeiten und bewerten ist tägliches Brot für uns eigentlich.
Aber viel wichtiger ist es, Computer und Konzepte zu verstehen. Die sprachen / Bibliotheken sind eigentlich nur das Werkzeug.
Auf Architektur / Idee / Konzept kommt es mehr an, und ist low/mid level bereich eher auch für Performance ausschlaggebend.Dein Program würd ich z.b. mit python + Qt + vielleicht opencv (python) umsetzen. C++ wäre mir da zu langsam (vom Zeitaufwand zum proggen) und die Performance würde trotzdem langen. Aber mit C++ als Anforderung geht das natürlich auch entsprechend super.