Besonderheiten bei embedded Vision

Der menschliche Sehnerv ist nicht umsonst eine der „Autobahnen“ im menschlichen Körper. Videostreams erfordern hohe Datenraten und Rechenoperationen über großen Datenmengen in Echtzeit. Von ihrer Natur her sind die Rechenoperationen in der Regel SIMD (Single Instruction, Multiple Data). Hier schlägt Hardware in fast aller Regel Software, und dieser Umstand wird noch bedeutender, wenn die Leistungsaufnahme eine Rolle spielt. Und so kommt es bei embedded Vision Plattformen zuerst auf die richtige Hardware als Basis an, auf die richtigen Komponenten und ihrer Kopplung untereinander durch schnelle Busse. Tatsächlich ist die CPU bei solchen Systemen nur ein „Mitspieler“ unter vielen. Auch hier wieder ein Vergleich: wir treffen mit unserem Gehirn Entscheidungen, steuern bewusst unsere Arme, Beine etc., aber im Vergleich dazu ist die Datenflut der Bilderfassung und -verarbeitung in unserem Hirn gewaltig. Wir müssen nicht überlegen, um Kanten oder Farben sofort zu erfassen.

Auf dem Weg vom Auge zum Gehirn findet die erste Signalverarbeitung bereits auf der Netzhaut statt. Dazu gehören nicht nur „triviale“ Eigenschaften wie Helligkeit, Kontrast und Farbe, sondern sogar schon Kanten- und Bewegungserkennungen. Auch auf einem Bildsensor selbst beginnt die erste Signalverarbeitung. Zuständig dafür ist der ISP (Image Signal Processor). Ein ISP dient u.a. der Kontrolle des Bildsensors, wie Belichtungszeit, Setzen des Vorverstärkers (Gain) vor dem ADC, Rauschreduzierung, Farb- und Kontrastkorrektur, Debayering etc. etc. etc. Dazu muss der ISP von Haus aus selbst statistische Daten aus einzelnen Frames bestimmen, z.B. einen repräsentativen Helligkeitswert zur Regulierung von Belichtungszeit und Vorverstärker. Manche Dinge sind dabei nicht so offensichtlich, aber wenn man um ihre Existenz weiß, sehr hilfreich. So etwa der Focus FoM (Figure of Merit), eine Gütezahl, welche für Auto Focus Regelkreise genutzt werden kann. ISPs sind eine sehr effiziente Kombination aus Hard- und Software, oft eine Kombination aus ASIC, DSP und gegebenenfalls FPGA, und sie müssen mit fortschreitender Erhöhung der Pixelzahl von Bildsensoren immer leistungsfähiger werden.

Der so erfasste und vorverarbeitete Videostream muss nun an die weiterverarbeitenden Komponenten übertragen werden, wie der Sehnerv des Menschen. Im embedded Bereich gewinnt dabei MIPI CSI immer mehr an Bedeutung, ein für diesen Zweck zugeschnittener sehr schneller Bus mit bisher bis zu 6 GBit/s. Die weiterverarbeitende Komponente muss nun aber auch in der Lage sein, diesen Datenstrom auch aufnehmen und verarbeiten zu können, ohne „Schluck auf“. Viele SoCs unterstützen heute MIPI CSI direkt. Ich nehme als Beispiel den Broadcom BCM2711, verwendet als Herz des Raspberry PI 4. Heise hat eine sehr schöne Übersicht über diesen SoC veröffentlicht, welche ich aus urheberrechtlichen Gründen hier nur verlinkt habe. Innerhalb des SoCs sind verschiedene Komponenten mittels eines schnellen AMBA AXI Busses (Advanced eXtensible Interface, ein on chip Bus Protokoll) verbunden. Zum Herz des BCM2711 gehört der Video Core (genauer VC6). Dieser enthält u.a. das CSI-Interface, einen eigenen ISP(!!!), eine Video Processing Unit, GPU sowie Encoder und Decoder für verschiedene Standards zur Videokompression. Ideale Hardwarevoraussetzungen für Videostreams bei geringer Leistungsaufnahme. Video Processing Units und GPUs sind eine gute Ergänzung zueinander, Video Processing Units sind auf niedrige Leistungsaufnahmen getrimmt, aber dazu die Algorithmen „starr“ in Silizium „gemeißelt“. GPUs waren zwar ursprünglich für Bildberechnungen konzipiert, haben aber längst ihren festen Platz für sehr rechenintensive SIMD-Aufgaben eingenommen. In gewisser Hinsicht kann man sie als bedingt programmierbare Hardware betrachten, wesentlich effizienter als eine CPU, solange sich ein Algorithmus effizient auf die Arbeitsweise der GPUs abbilden lässt. Abgerundet wird das Paket durch die CPU selbst, heute besitzen diese ebenfalls Erweiterungen wie NEON (eine SIMD Befehlssatzerweiterung in ARM-Prozessoren für Multimediaanwendungen, natürlich auch im ARM Cortex-A72 des BCM2711).

Um diese vorhandene Hardware nun effizient zu nutzen, muss diese richtig angesteuert werden. Ein Tod bei Videostreams wäre z.B. memcpy, gerade Kopieren auf dem Speicher treibt die Leistungsaufnahme in die Höhe. Weiter haben wir es hier mit Hardwarekomponenten auf einem SoC zu tun, sprich, Anbindung an PHYSISCHEN Speicher. Aber Programmierungen im Userland laufen aus Sicht des Entwicklers im virtuellen Speicher der MMU (Memory Management Unit, und ok, die GPU der VC6 hat aus gutem Grund im Gegensatz zum Vorgänger auch eine eigene MMU). Dann möchte man auch nicht alles in Assembler programmieren, um auch die letzten Möglichkeiten der Befehlssätze der CPU auszureißen. Was also tun?

Tatsächlich wurde die meiste Vorarbeit bereits gemacht, und sie wird stetig weiterentwickelt, in Form von Standards und Bibliotheken. In diesem Fall zählen dazu hauptsächlich libcamera, GStreamer und OpenCV, OpenCL könnte man der Liste noch ergänzen. Libcamera übernimmt die Kontrolle des ersten Abschnitts des Videostreams von der Steuerung und Kontrolle des Bildsensors ausgehend bis in den SoC. GStreamer erlaubt die Erstellung von Pipes, „fertige“ Komponenten werden zu Verarbeitungsstrecken zusammengefügt und konfiguriert. Hier sind z.B. schon die Ansteuerungen zu z.B. Hardware De- und Encodern schon fertig verpackt, Komponenten sehr effizient implementiert, diese handeln sogar untereinander „gemeinsame Sprachen“ aus. OpenCV ist eine der bedeutendsten Bibliotheken in der Bildverarbeitung. Sie erhält stetig „neue Nahrung“ auch aus gerade dem Forschungslager, ihre algorithmischen Umsetzungen nutzen bei SIMD Aufgabem CPU-Befehlssatzerweiterung und wenn gewünscht GPU-Unterstützung. Richtig kombiniert und konfiguriert lassen sich so viele Videoverarbeitungsaufgaben auf die Hardware setzen.

Wird mehr Leistung benötigt, so steht Nvidias Jetson Familie zur Verfügung. Nvidias Kernkompetenz ist ganz klar GPU, und wie bereits erläutert ist diese für SIMD ideal. ARM CPUs dagegen sind nicht gerade eine Kernkompetenz von Nvidia, vielleicht auch daher der Versuch des Aufkaufs von ARM. Aber das an anderer Stelle. Der Sprung von Raspberry PIs zu Nvidias Jetsons ist allerdings brachial. Ein Nano zaubert 472 GFlops aus 10W, ein T2 1,33 TFlops aus 15W, ein Jetson AGX Xavier 64GB 30 TOps aus 30 Watt und ein AGX Orin 64GB bringt brutale 275 TOps aus 60W. Und die Entwicklungsrichtung von Nvidia ist leider klar, immer mehr Power, mit immer mehr Leistungsaufnahme. Leider ist Nvidia aber auch neben anderen schmerzlichen Punkten nicht gerade Vorbild im Langzeitsupport (siehe https://developer.nvidia.com/embedded/lifecycle), und man sollte auch immer die Aktualität der Images betrachten, Stichworte wie Ubuntu Version als Basis, OpenCV etc. Das soll nicht verschrecken, nicht umsonst hat Nvidia seinen Platz im embedded Vision Sektor eingenommen, aber man sollte diese Punkte eben gut abwägen.