Bildaufnahme ohne "Optimierung" durch die GPU der Broadcom-SoC BCM28xx

  • Achtung:

    Dieser Thread beinhaltet eine Fragestellung zu einem Projekt bei meinem Arbeitgeber. Es soll sich bitte jeder seine Meinung bilden, ob er hierfür seine Freizeit "opfern" und sich damit befassen will. Allerdings glaube ich, dass die Thematik auch für die Forengemeinde interessant sein könnte. Am Ende will ich meine Erkenntnisse hier vorstellen. Dabei werde ich aber gewisse Firmeninterna zurückhalten müssen.


    Ich habe in der Firma eine Schaltung/Leiterplatte entwickelt, mit der die in vielen neumodernen KFZ (z.B. VW) in der Mittelkonsole verbauten Displays als Bildschirm für eine DVI-Videoquelle (Windows-PC, RPi etc.) verwendet werden können. Normalerweise ist im KFZ ein vierpoliges HF-Kabel vom Autoradio ("Head Unit", HU) zum Display verlegt. Meine Schaltung wandelt die DVI-/HDMI-Videosignale in dieses HF-Format um. Außerdem kann meine Schaltung zwischen den Videoquellen HU und DVI umschalten.



    Prüfkonzept:

    Zur Prüfung der Produkte aus der Fertigung wird das HF-Signal am Videoausgang meiner Schaltung über zwei Evalboards des Herstellers nach DVI zurückgewandelt. Dies geschieht verlustfrei, da in allen Stufen digitale Videosignale vorliegen. Bei Anschluss einer FullHD-Videoquelle an meine Schaltung und Weiterleitung über die beiden Evalboards an einen handelsüblichen FullHD-Monitor erhalte ich ein glasklares und unverfälschtes Bild der Videoquelle.


    Zur Automatisierung des Prüfablaufs ist nun angedacht, über meine Schaltung ein definiertes (Stand-)Bild von einem RPi zu übertragen und das zurückgewandelte Bild über die Kamera-CSI-Schnittstelle des RPi mit raspistill o.ä. aufzunehmen, als verlustfreie PNG-Datei abzuspeichern und per Software einen pixelweisen 1:1-Bildvergleich mit dem PNG-Quellbild vorzunehmen (z.B. mit diffimg) . Damit sollen Fehler in der Übertragungskette erkannt werden. Da unterstellt wird, dass die Bildquelle (RPi) und die Evalboards funktionieren, liegt ein erkannter Bildunterschied/Fehler somit beim Prüfling, dem getesteten Exemplar meiner Schaltung aus der Fertigung.


    Problem:

    Die Bildaufnahme kann natürlich nicht über die "echten" PiCamera-Module erfolgen. Vielmehr gibt es vom Hersteller Lintest Systems (Achtung: langsame Seite!) das Modul PiCapture-HD1. Dabei handelt es sich um ein HAT-konformes Modul, das eine "Kamera mit einem HDMI-Anschluss anstelle einer Linse" darstellt. Es ist so aufgebaut, dass es für den RPi aussieht, als sei ein originales PiCamera-Modul angeschlossen: Die am HDMI-Eingang angeschlossenen Videosignale können auf dem RPi mit den einschlägigen Befehlen raspistill, raspivid etc. aufgenommen werden.

    Nur leider entspricht das aufgenommene Bild nicht 1:1 den Videosignalen am HDMI-Eingang des Moduls. Die Bildaufnahme über die CSI-Schnittstelle auf dem RPi-SoC findet über die GPU statt. Dabei scheint die GPU automatisch Optimierungsmaßnahmen vorzunehmen, die für die ARM-CPU relativ rechenintensiv wären. Für "echte" Linsenkameras ist dies wohl vorteilhaft, aber am Lintest-PiCapture-Modul führt dies offenbar dazu, dass die DVI-Daten nicht 1:1 aufgenommen werden:

    * Es entsteht eine gewisse Unschärfe

    * Helligkeit und Farbton sind nicht originalgetreu

    * Helligkeit und Farbton des Bildes ändern sich bei Bewegung!

    * Flimmern der empfangenen HDMI-Daten in der Vorschau: Führt bei Bildvergleich zweier an sich identischer Einzelbilder zu Pixelfehlern!


    Nun gibt es für raspistill etc. eine Menge Kommandozeilenparameter, die ich auch alle(?) durchprobiert habe, aber an obigen Problemen ändert sich nichts. Immerhin habe ich es geschafft, mit den Parametern -awb off -awbg 1.0,1.0 einen einigermaßen originalen Farbton hinzubekommen, vorher hatte ein graues Bild einen leichten Magentastich.


    Im Dateianhang habe ich mal ein 10s langes Video beigefügt, in dem man sehen kann, wie sich die Sache auswirkt:


    Fragen:

    * Kann man die GPU so einstellen, dass sie bei Aufnahmen mit raspistill etc. keine Optimierung vornimmt?

    * Gibt es eine andere Möglichkeit, auf dem RPi eine DVI-Quelle aufzunehmen?



    Dateianhänge:


    Einstellungen des zweiten Windows10-Desktops auf dem PiCapture-Modul


    Da die Forensoftware nur bestimmte Dateierweiterungen akzeptiert, musste ich die Videodatei in rpivid.h264.txt umbenennen. EDIT: Um sie im vlc-Player abspielen zu können, muss sie vor dem Laden wieder in rpivid.h264 umbenannt werden.


    PS:

    Ich verwende einen RPi 3B (ohne Plus), da der RPi4 von PiCapture angeblich nicht unterstützt wird. Aber auch mit einem RPi4 das gleiche Problem. Andere RPis habe ich (noch) nicht getestet.

  • Schade!

    Ich konnte das Programm zwar problemlos herunterladen und kompilieren:

    Code
    git clone https://github.com/6by9/raspiraw
    make # Software kompilieren


    Beim Aufruf mit ./raspiraw -md 7 -t 1000 kommt leider folgende Fehlermeldung:

    Code
    Using i2C device /dev/i2c-0
    RaspiRaw: Probing sensor ov5647 on addr 36
    RaspiRaw: Probing sensor imx219 on addr 10
    RaspiRaw: Probing sensor adv7282 on addr 21
    RaspiRaw: Probing sensor imx477 on addr 1A
    RaspiRaw: No sensor found. Aborting


    Es werden anscheinend nur die angegebenen Kamera-Sensormodule erkannt bzw. unterstützt. Bevor ich mich in die Untiefen des Quellcodes begebe, werde ich morgen(?) mal mein "echtes" Pi-Kameramodul V2 in die Firma mitnehmen und ./raspiraw damit mal testen...


    Idee:

    Vielleicht kann im Code der Test auf die Module irgendwie übersprungen und eine Datenstruktur mit Fake-Werten angelegt werden? Nur überspringen wird vermutlich zu einer Nullpointer-Exception führen... :denker:

  • Sind diese Optimierungen so nachteilig? Oder geht es um die echtzeitfähigkeit?


    Es gibt in China VideoGrabber die FHD aufzeichnen können und eine HDMI-Buchse haben. Die haben meistens den UTV007(F) Chipsatz.

    Wenn's brennt 112 hilft weiter!

    Edited once, last by raspbastler ().

  • Die Optimierungen sind deshalb nachteilig bzw. sogar störend, da sie einige Pixel im Bild verfälschen und somit einen 1:1-Pixelvergleich unmöglich machen. Es ist auch keine Lösung, Abweichungen bis zu einem gewissen Grad als "gut" zu bewerten, da man an dieser Stelle nicht mehr feststellen kann, was die Ursache für einen bestimmten Pixelunterschied ist: Ist es das bei der Aufnahme "optimierte" Bild oder ist es ein echter Fehler des Prüflings?


    Hier ein mit der Windows-Version von diffimg.exe (V2.2.0) erstellter Vergleich von zwei Aufnahmen derselben Videoquelle. Die einzelnen Pixelunterschiede sind gelb markiert:


    Ein Erklärungsversuch von meiner Seite, ohne es genauer zu wissen:

    Die gelbe Zeile im oberen Drittel des Bildes resultiert aus einem Flackern einzelner Zeilen, die bei der Aufnahme/Vorschau durch das erfasste Bild laufen.

    Zwischen den beiden Aufnahmen wurde zwischenzeitlich ein anders Programm aktiviert, weshalb in der Taskleiste ein anderes Programmicon hervorgehoben ist. "Interessant" daran ist, dass neben dem eigentlich unterschiedlichen Rechteckbereich auch außen herum einige Pixel in bester JPG-Manier abweichen. Dies beruht vermutlich auf irgendwelchen Kompressions(?)-Artefakten durch die GPU-Optimierung.


    Auf diese Art ist kein automatisierter Prüfablauf möglich.


    EDIT:

    Echtzeitfähigkeit ist bei dieser Anwendung im Übrigen kein Thema, da definierte Standbilder verglichen werden sollen. Aber die Störungen verschwinden durch Wartezeiten nicht.

  • Du könntest vielleicht noch raspistill mit Qualität 100 ausprobieren. Der Encoder macht glaube ich standardmäßig 75 Prozent, steht aber nicht direkt in der Dokumentation. Oder ohne Encoder mit "raspiyuv".

  • beides bereits im Vorfeld ausprobiert -- und jetzt nochmals getestet:

    bringt leider nichts ;(


    Dieses Flackern des grauen Hintergrundes beim Verschieben des schwarzen Fensters beruht wohl auf einer Optimierung für echte Linsenkameras. Wenn etwas Dunkles/Schwarzes im Bild auftaucht (Schatten?), wird die "Belichtung" des Rohkamerabildes künstlich digital durch die GPU erhöht.


    raspiyuv für originalgetreuere Rohdatenübernahme habe ich auch bereits gefunden. Auch diese Programmvariante zeigt diesbezüglich keine (erkennbaren) Unterschiede.

  • Es gibt in China VideoGrabber die FHD aufzeichnen können und eine HDMI-Buchse haben. Die haben meistens den UTV007(F) Chipsatz.

    Dann solltest du keine Probleme haben, weil du dann nicht den Umweg über die raspberry-cam machen musst. Wie viel Ressourcen mehr verbraucht werden, bei der Nutzung der CPU kann ich dir nicht sagen.

    Wenn's brennt 112 hilft weiter!

  • Die Frage ist, welche Degradierung bei der Qualitätskontrolle denn bestimmt werden soll. Die möglichst genaue Reproduktion der Ausgabe ist doch an sich irrelevant, wenn die resultierende Eingabe den immer gleichen (oder zumindest sehr ähnlichen) Veränderungen unterliegt. Du kannst ja problemlos einen guten Prüfling zur Gewinnung von Testeingaben nutzen, und auf die Abweichung davon prüfen.



    Denn da HDMI digital ist, können ja bestimmte Klassen von Fehlern gar nicht vorkommen. Zb eine nichtlineare Verzerrung eines Farbkanals oder so.


    Ansonsten mag ein Blick zu HDMI Video grabbern wert sein.

  • In dem Repository steht, dass folgende Sensoren unterstützt werden:

    Code
    adv7282m
    imx219
    ov5647



    Möglicherweise musst du einen anderen I2C-Bus verwenden:

    Code
    -y, --i2c	: Set the I2C bus to use.
    Range is 0-2.


    Es war mir gar nicht bewusst, dass die Sensoren via I2C gesteuert werden.

  • Danke euch allen schon mal für euer Interesse an dieser Sache! :thumbup:


    raspbastler

    Solche Videograbber (so Teile mit HDMI-Eingang und USB-"Ausgang" wie z.B. dieser (Affiliate-Link)) wären durchaus eine Option. Allerdings nur, wenn man damit nicht nur Videos, sondern auch Standbilder (idealerweise verlustfrei als PNG oder BMP) aufnehmen kann. Weißt Du da Genaueres?


    @__deets__

    Eine Degradierung ist dann irrelevant, wenn sie jedes Mal identisch ist. In dem Augenblick, in dem variable Unterschiede (z.B. aufgrund von Flackern o.Ä. wie im Bild von Beitrag #5) auftreten, kann ich damit nichts anfangen.
    Meine Vermutung ist, dass das PiCapture-Modul die digitalen DVI-/HDMI-Daten 1:1 nach DSI CSI wandelt und die GPU des RPi dann Veränderungen ("Optimierungen") vornimmt. Ideal wäre, man könnte dies einfach ausschalten, ich weiß aber nicht wie.


    DeaD_EyE

    Die genannten Kamera(?)-Sensoren kommen auf dem PiCapture-Modul nicht vor. Stattdessen enthält es ein FPGA (Altera(intel) Max10 10M04DAF256I7G), das offenbar die vom AnalogDevices-Baustein ADV7604 aufbereiteten HDMI-Daten nach DSI wandelt. Der Rest der Schaltung des Moduls gaukelt dem RPi ein zumindest kompatibles Kameramodul vor.

    I2C muss ich noch abchecken...

  • Danke euch allen schon mal für euer Interesse an dieser Sache! :thumbup:


    raspbastler

    Solche Videograbber (so Teile mit HDMI-Eingang und USB-"Ausgang" wie z.B. dieser (Affiliate-Link)) wären durchaus eine Option. Allerdings nur, wenn man damit nicht nur Videos, sondern auch Standbilder (idealerweise verlustfrei als PNG oder BMP) aufnehmen kann. Weißt Du da Genaueres?

    Zunächst ist dein Grabber ungeeignet, weil dieser zu teuer ist und wahrscheinlich keine Linux-Kompatibilität bietet. Du brauchst sowas:


    Nsendato UTVF007 USB 2,0 Zu HDMI Video Catpure Karte USB 2,0 HD 1 Weg Video Karte Konverter adapter für Windows XP/Vista/7/8/10


    https://a.aliexpress.com/_BOHo2r


    Dieser wird mit v42l benutzt soweit ich das sehe.. Damit kannst du entweder Videos aufzeichnen oder Einzelbilde. Sog. Screenshots.


    Diese Screenshots sollten identisch sein, solange bis sich die Quelle oder die Auflösung ändert.

    Wenn's brennt 112 hilft weiter!

  • erster Teilerfolg: Das Helligkeitsflackern ist weg!


    Ich habe die Problematik im Forum der RPi-Foundation in diesem Thread geschildert. Dort bekam ich sehr schnell eine Antwort vom RPi-Entwickler 6by9, der auch dieses raspiraw entwickelt hat.


    Erstmal bekam ich eine Rüge: ;)

    Die Kameraschnittstelle auf dem RPi heißt CSI (camera serial interface) und nicht DSI (display serial interface). Das habe ich soeben in allen Beiträgen hier korrigiert.


    Dieses Flackern bei Bewegung dunkler Bereiche innerhalb des Aufnahmebereichs bekommt man mit dem Kommandozeilenparameter -ex off weg. Die Helligkeitsanpassung beruht auf der Standardeinstellung "auto exposure" (Blendenweite), die man mit diesem Kommandozeilenparameter deaktiviert:

    raspistill -k -p 0,0,1920,1080 -awb off -awbg 1.0,1.0 -ex off


    Dennoch bleibt das Problem des unscharfen Bildes (mit Farbverfälschungen insbesondere bei waagrechten Linien) bestehen.

    Ich werde jetzt mal einen Schwung Bilder vom zweiten Desktop meines Windows-PCs "schießen" und schauen, ob sich die einzelnen Aufnahmen unterscheiden oder nicht. Vielleicht kann man damit stabil arbeiten? Schön ist es aber nicht!


    EDIT:

    Im Forum der RPi-foundation gibt es den Thread High definition video capture using PiCapture HD1, in dem ein Entwickler von Lintest ("Marshal") mit dem Entwickler "6by9" der RPi-Foundation Erfahrungen austauschen.

  • Das klingt ja vielversprechend .. Ich würde dennoch den Weg des grabbers mal testen.. Vor allem die Perfomanceunterschiede könnten interessant sein .


    Ich denke der Weg über das CSI ist umständlich weil du einen Adapter brauchst um ein HDMI Signal zu wandeln über ein Interface, welches gar nicht dafür ausgelegt war.


    Der Clou bei den Grabber ist sogar, dass du mehrere Grabber an einen Pi anschließen kannst oder eine HDMI-Matrix. Somit kannst du mehrere Testobjekte anschließen und schauen, wie diese sich eventuell unterscheiden (du kannst dann jedes HDMI-Signal durchschalten).

    Wenn's brennt 112 hilft weiter!

  • Eine Degradierung ist dann irrelevant, wenn sie jedes Mal identisch ist. In dem Augenblick, in dem variable Unterschiede (z.B. aufgrund von Flackern o.Ä. wie im Bild von Beitrag #5) auftreten, kann ich damit nichts anfangen.
    Meine Vermutung ist, dass das PiCapture-Modul die digitalen DVI-/HDMI-Daten 1:1 nach DSI CSI wandelt und die GPU des RPi dann Veränderungen ("Optimierungen") vornimmt. Ideal wäre, man könnte dies einfach ausschalten, ich weiß aber nicht wie.

    Das würde ich so nicht sagen. Praktischer wäre das, aber genau wie bei vielen anderen Prüfverfahren kann man auch hier mit Toleranzen arbeiten. Es ist dann halt ein bisschen aufwändiger, aber deswegen je nach Anwendung genauso aussagekräftig.


    Es geht doch hier nicht darum, dass zB bestimmte Pixel ausfallen, oder ein Fix-Focus-Objektiv leicht verstellt ist. Sondern massive Ausfälle zb wegen ringing auf Leitungen oder ähnlichem. Wozu du über die Zeit arbeiten musst, und zb auch ein einzelnes Bild gar nichts aussagt. Mit Methoden wie zb dem OpenCV Template matching bekommst du Scores, die dir quantitativ etwas über den Fehler sagen. Wenn das innerhalb eines gewissen Testzeitraumes unterhalb einer Schwelle bleibt, ist der Prüfling ok.

  • kurzer Zwischenbericht:


    Auvidea-Modul B101 funktioniert besser als Lintest PiCapture-HD1-Modul

    Dieses Modul verwendet den Toshiba-Baustein TC358743 anstelle eines selbst programmierten FPGA wie auf dem PiCapture. Das Resultat der aufgenommenen Bilder mit dem B101 ist wesentlich besser als beim PiCapture und vor allem ohne Flackern. Auch beim B101 gibt es leichte Farbschleier (wegen der Emulation eines Bayer-Sensors ?), aber das Ergebnis ist wenigstens deterministisch und das ist für meinen Anwendungsfall entscheidend.


    Das Blöde ist nur, dass damit nur Videodaten bis 1080p25 erfasst werden können. Meine Prüflinge müssen im Test aber an ihrer spezifizierten Obergrenze von 1080p60 betrieben werden. Da werde ich die Variante auvidea B102 im Zusammenspiel mit dem neuen (und erst in Kürze lieferbaren) RPi4 Compute Module verwenden müssen. Denn nur bei den Compute Modulen ist ein 22-poliger CSI-Kameranaschluss vorhanden, der alle vier Datenleitungspaare enthält. Und das benötigt man offenbar, um die Videodaten mit der benötigten Bandbreite für 1080p60 übertragen zu können.


    Bildvergleich

    Anstelle von diffimg.exe werde ich das compare-Modul aus dem Softwarepaket ImageMagick verwenden.


    Wen es interessiert:

    Hier der Bildvergleich des Desktops mit Aufnahmen vom auvidea-Modul B101

    Bild1, 13:59 Uhr:



    Bild 2, 14:00 Uhr:


    Differenzbild:

    Die Bereiche mit dem Grauschleier bedeuten, dass dort keine Unterschiede sind. Eche Unterschiede sind in kräftigem Rot markiert. In diesem Fall rechts oben bei der Anzeige der Uhrzeit.

    Es gibt außerdem eine in der Doku sogenannte mathematische Ausgabe in Textform. Die werde ich dann versuchen, zu parsen...

  • raspbastler:

    Nein, noch nicht. Da es ein Firmenprojekt ist, ist die Vorgabe, Module zu verwenden, für die es saubere Spezifikationen (datasheets, technische Daten, Anleitung/Dokumentation, ...) gibt. Das ist bei den meisten USB-Grabbern auf amazon etc. leider nicht gegeben.


    Es kann aber durchaus sein, dass ich das nach Abschluss dieses Projektes mal privat ausprobieren werde...

  • Oh ... interessant und nachvollziehbar... Aber auch gleichzeitig nervig, weil viel Arbeit fürs selbe Ergebnis (Korrekter Bildvergleich) gemacht werden muss :(

    Wenn's brennt 112 hilft weiter!

  • /boot/config.txt r RPi4 mit zwei Anzeigegeräten (Bildschirmen) an beiden HDMI-Ports


    Ich habe mir für dieses Projekt eine /boot/config.txt erstellt, die an beiden HDMI-Ports jeweils 1080p60 ausgibt:

    Im allgemeinen Abschnitt für alle RPis die Einträge für den Standardport HDMI0

    Code
    hdmi_ignore_edid=0xa5000080
    hdmi_force_hotplug=1
    hdmi_group=2
    hdmi_mode=87
    hdmi_cvt=1920 1080 60 3 0 0 0

    und für den Port HDMI1 im Abschnitt [pi4]:

    Code
    hdmi_ignore_edid:1=0xa5000080
    hdmi_force_hotplug:1=1
    hdmi_group:1=2
    hdmi_mode:1=87
    hdmi_cvt:1=1920 1080 60 3 0 0 0

    Wichtig ist hier die Angabe der Portnummer mit :1 vor dem =-Zeichen


    EDIT:
    Mit hdmi_force_hotplug ist es egal, ob beim Start/Booten des RPi die HDMI-Anzeigegeräte (hier die Prüflinge) bereits dranhängen oder noch nicht.


    siehe auch: Desktopwallpaper via ssh ändern