Bilder streamen (experimentell)
| Der Bild-Stream ist experimentell (ab v2.3.0). Seine Knoten können sich noch ändern. Verwenden Sie ihn zur Evaluierung, und prüfen Sie ihn mit Ihrer Kamera, bevor Sie sich darauf verlassen. |
capture liefert ein Bild pro Request, und jeder Request wartet, bis sein Bild eingetroffen ist. Bei
der von uns getesteten Kamera ergibt das etwa 34 Bilder pro Sekunde, deutlich weniger, als die Kamera selbst
liefern kann: Die nächste Belichtung kann nicht beginnen, bevor das vorherige Bild ausgelesen und gesendet wurde.
Der Bild-Stream arbeitet umgekehrt. Solange er läuft, veröffentlicht der Cam Driver jedes Bild,
das die Kamera liefert, auf <camera name>/control/publish/output/stream/frame. Ihr Programm abonniert
diesen Knoten und erhält jedes Bild, sobald es eintrifft - mit seiner Größe, seinem Pixelformat und seiner
Herkunft, siehe Was jeder Frame enthält.
Der Stream wird durch eine Funktion ein- und ausgeschaltet, control/publish: Setzen Sie ihre Eingaben, und rufen Sie dann
control/publish/execute auf, um sie anzuwenden. Siehe Einen Stream betreiben.
Das allgemeine Stream-Konzept - Produzenten, Konsumenten und die Lineage ihrer Ergebnisse - ist in Streams beschrieben. Diese Seite beschreibt den Stream des Cam Driver.
Der Cam Driver triggert die Kamera nicht von selbst. Ein Bild kommt, wenn die Kamera getriggert wird -
durch ein Signal an ihrem Trigger-Eingang oder durch control/trigger/execute - oder, bei ausgeschaltetem Trigger-Modus
der Kamera, so schnell, wie die Kamera läuft. Siehe Die Kamera triggern.
| Data Layer | Bilder, die ein Abonnent von control/publish/output/stream/frame erhält |
|---|---|
ctrlX Data Layer (ctrlX OS) |
Jedes Bild, in Reihenfolge, sobald es veröffentlicht wird, unabhängig vom Publish-Intervall des Abonnements. Bilder werden nur verworfen, wenn der Data Layer weit zurückfällt. |
LumiScan Keryx (PC) |
Jedes Bild, in Reihenfolge. Der Data Layer verwirft Bilder nur, wenn ein Abonnent weit zurückfällt. |
Jeder Frame trägt seine Nummer im Stream, sodass ein Abonnent ein verworfenes
Bild als Lücke erkennt. Ein Lesen von control/publish/output/stream/frame liefert immer das neueste Bild.
Adressen
Alle Adressen unten beginnen mit hdvisionsystems/lumiscan-cam-driver/<camera name>/. Sie folgen
der Regel jeder execute-Methode: Die Methode besitzt ihre Knoten, control/publish/execute,
control/publish/input/… und control/publish/output/….
| Adresse | Typ | Standard | Bedeutung |
|---|---|---|---|
|
Methode |
Wendet die folgenden Eingaben gemeinsam an. Eine Eingabe allein zu schreiben ändert nichts. Kehrt sofort zurück: Der
Stream startet oder stoppt innerhalb des nächsten Zyklus des Cam Driver, und |
|
|
bool |
|
|
|
bool |
|
|
|
string |
|
Das Tag auf den Bildern des Moduls: Der Schritt der Kamera in ihrer Lineage trägt es, und ebenso die
Ergebnisse jeder Anwendung, die sie verarbeitet. Leer: der Kameraname, zum Beispiel |
Was execute angewendet hat, wird nicht gespeichert, außer dem Tag: Nach dem Start des Cam Driver ist der Stream aus,
bis control/publish/execute mit enable true aufgerufen wird.
| Adresse | Typ | Bedeutung |
|---|---|---|
|
bool |
|
|
flatbuffers ( |
Jedes gestreamte Bild: die Pixel, ihre Größe und ihr Format sowie die Lineage des Bildes. Abonnieren Sie ihn, um die Bilder zu erhalten. Siehe Was jeder Frame enthält. |
|
uint64 |
Größe der gestreamten Bilder in Pixeln, zum Nachsehen. Jeder Frame trägt seine eigene. |
|
string |
Pixelformat der gestreamten Bilder, zum Nachsehen. Jeder Frame trägt sein eigenes. |
|
uint64 |
Zähler des aktuellen oder letzten Streams, siehe Die Statistik lesen. |
| Adresse | Typ | Bedeutung |
|---|---|---|
|
string |
Der Hash der Einstellungen, mit denen die Bilder aufgenommen werden, als 16 Hexadezimalziffern. Siehe Der Einstellungs-Hash. |
|
string |
Das Tag, das |
Das Tag
Ein geändertes control/publish/input/tag wird als stream.tag in der Modulkonfigurationsdatei gespeichert,
bevor control/publish/execute es anwendet; der Rest der Datei bleibt, wie er war. So tragen die Bilder es
auch nach einem Neustart, und control/publish/input/tag beginnt damit. Kann die Datei nicht geschrieben werden,
antwortet control/publish/execute mit DL_CREATION_FAILED, und weder das Tag noch die anderen Eingaben
ändern sich. Ein unverändertes Tag wird nicht gespeichert, sodass ein Modul, dessen Datei nicht geschrieben werden kann, trotzdem streamt.
Das Tag ist nicht Teil des Einstellungs-Hashs: Es benennt die Bilder, es verändert sie nicht.
Die Kamera triggern
Jeder Trigger, den die Kamera erhält, liefert ein Bild auf control/publish/output/stream/frame. Stellen Sie den
Trigger-Modus der Kamera ein, bevor Sie den Stream starten, über ihre Feature-Knoten unter features oder in
einer Feature-Datei.
| Bilder kommen | Kameraeinstellungen | Was zu tun ist |
|---|---|---|
Bei einem Hardware-Trigger |
|
Senden Sie für jedes Bild einen Impuls an den Trigger-Eingang. |
Auf Anforderung |
|
Rufen Sie für jedes Bild einmal |
Kontinuierlich |
|
Nichts. Die Kamera liefert so schnell, wie sie läuft, oder mit ihrer |
Eine Kamera ohne Software-Trigger-Modus - eine simulierte Kamera, die einen Ordner mit Bildern abspielt, oder eine Plugin-
Kamera ohne TriggerSoftware - nimmt ebenfalls bei jedem Aufruf von control/trigger/execute ein Bild auf.
control/trigger/execute antwortet, wenn der Trigger gesendet wurde, nicht, wenn sein Bild eingetroffen ist. Eine
Kamera, die noch mit dem vorherigen Bild beschäftigt ist, kann einen Trigger ignorieren, ohne es zu melden, siehe
Für die höchste Bildrate: TriggerOverlap.
Für die höchste Bildrate: TriggerOverlap
Ist das GenICam-Feature TriggerOverlap auf Off gesetzt, nimmt eine Kamera das nächste Bild erst auf, wenn das
vorherige ausgelesen wurde, und ignoriert einen Trigger, der früher kommt. Ein Overlap lässt die nächste
Belichtung beginnen, während das vorherige Bild noch ausgelesen oder gesendet wird, was die Bildrate erhöht, die die
Kamera erreicht.
Um mit der höchsten Bildrate zu streamen, darf TriggerOverlap nicht Off sein. Setzen Sie es auf einen Overlap,
den Ihre Kamera unterstützt - PreviousFrame oder ReadOut, siehe ihre Dokumentation - in einer Feature-Datei des
Kameramoduls, ein Feature pro Zeile:
TriggerOverlap PreviousFrame
Tragen Sie die Datei in cameras[].featureFiles des Moduls ein. Der Cam Driver wendet sie jedes Mal an, wenn er
die Kamera verbindet, bevor die Aufnahme beginnt, sodass sie auch für capture gilt. Ein Feature-Knoten
unter features funktioniert ebenfalls, aber manche Kameras lehnen Trigger-Features ab, während sie aufnehmen, und der
Wert geht verloren, wenn die Kamera erneut verbunden wird.
Was jeder Frame enthält
control/publish/output/stream/frame enthält eine FlatBuffers-Tabelle vom Typ stream_image, auf dem Data Layer
registriert als types/hdvisionsystems/lumiscan-cam-driver/stream_image. Ihr kompiliertes Schema wird als
bfbs/stream_image.bfbs installiert.
| Feld | Bedeutung |
|---|---|
|
Die Pixel, Zeile für Zeile, ohne Padding. |
|
Die Bildgröße in Pixeln. |
|
Das Pixelformat, zum Beispiel |
|
Woher das Bild stammt. Bei einem Kamerabild ist das ein Schritt, der der Kamera selbst: * |
Die Anwendungen, die den Stream verarbeiten - AI Object Matching, Calibration - übernehmen die Lineage dessen,
was sie empfangen, und fügen einen eigenen Schritt mit ihrem eigenen Tag hinzu. Ihre Ergebnisse benennen deshalb weiterhin
das Kamerabild, aus dem sie stammen, über producer, run und sequence, und jeder Schritt sagt über sein tag,
welches Modul ihn erzeugt hat.
Der Einstellungs-Hash
setting/settings-hash und der settings_hash jedes Frames identifizieren die Einstellungen, mit denen die Kamera
arbeitet. Der Hash ändert sich, wenn sich eine davon ändert:
-
die Moduleinstellungen und die Feature-Dateien, mit denen die Kamera verbunden wurde;
-
jedes Kamera-Feature, das geschrieben wird, während die Kamera verbunden ist, zum Beispiel
ExposureTimeüberinput/exposure-timeoder einen Feature-Knoten unterfeatures, mit dem Wert, den die Kamera angenommen hat; -
die Version des Cam Driver.
Einstellungen, die nur den Transport der Bilder betreffen, wie das Timeout oder die Paketgröße, ändern
den Hash nicht. Wenn ein Hash zum ersten Mal auftritt, schreibt der Cam Driver die Einstellungen, für die er steht, nach
settings-history/<camera name>-<hash>.json in seinem Konfigurationsordner, sodass ein in einem
Ergebnis gefundener Hash später nachgeschlagen werden kann.
| Eine Kamera nimmt die Bilder, die bereits unterwegs sind, mit den alten Einstellungen auf. Die Bilder, die direkt nach dem Schreiben eines Features eintreffen, können den neuen Hash tragen, obwohl sie vor der Änderung aufgenommen wurden. |
Was der Hash nicht sagt
-
Dass, nicht was. Ein Frame trägt nur den Hash. Ein anderer Hash sagt, dass sich etwas geändert hat, womit die Bilder aufgenommen werden, nicht was sich geändert hat. Um das herauszufinden, vergleichen Sie die beiden Dateien in
settings-history, die die Hashes benennen, von Hand. Die Dateien liegen auf dem Gerät, auf dem der Cam Driver lief. -
Nur, was durch den Cam Driver geht. Der Hash folgt einem Feature-Knoten unter
features,input/exposure-timeund den Einstellungen und Feature-Dateien, mit denen die Kamera verbunden wurde. Er folgt nicht Werten, die die Kamera selbst ändert: Bei eingeschaltetemExposureAutofolgt der Hash der EinstellungExposureAuto, nicht den Belichtungszeiten, die die Kamera wählt.
| Dass der Hash einer Änderung eines Kamera-Features folgt, wurde bisher nur in Unit-Tests geprüft, mit einem Ersatz für die Kamera, nicht mit einer echten Kamera. Bis das geschehen ist, verlassen Sie sich nicht allein auf den Einstellungs-Hash der Kamera, um zu erkennen, dass sich ein Kamera-Feature geändert hat. |
Einen Stream betreiben
-
Verbinden Sie die Kamera mit dem Handshake
connect-camera. Siehe Verbindungsschritte. -
Setzen Sie die benötigten Kamera-Features, wie die Belichtungszeit, den Trigger-Modus und
TriggerOverlap, bevor Sie den Stream starten. Siehe Die Kamera triggern. -
Abonnieren Sie
control/publish/output/stream/frame. -
Setzen Sie
control/publish/input/enableauftrueundcontrol/publish/input/keep-latest-outputauftrue, wenn Sie jedes Bild auch aufoutput/imagehaben möchten. -
Rufen Sie
control/publish/executeauf, und warten Sie, biscontrol/publish/output/stream/activetrueist. -
Triggern Sie die Kamera. Jedes Bild trifft auf
control/publish/output/stream/frameein. -
Zum Stoppen setzen Sie
control/publish/input/enableauffalseund rufen erneutcontrol/publish/executeauf.control/publish/output/stream/activewird innerhalb des nächsten Zyklusfalse. -
Bevor Sie wieder aufnehmen, warten Sie, bis
control/capture/readytrueist. Siehe Nach dem Stream.
Gut zu wissen:
-
Die Eingaben wirken erst bei
execute, alle gemeinsam. Ein Programm kann sie daher in beliebiger Reihenfolge setzen, und nichts ändert sich halb. -
Was
executeangewendet hat, bleibt bis zum nächstenexecute: Der Stream läuft, solangeenablealstrueangewendet wurde und die Kamera verbunden ist. Wird er angewendet, während die Kamera getrennt ist, startet der Stream, sobald die Kamera verbunden ist. -
connect-camera,disconnect-cameraundresetstoppen einen laufenden Stream. Wurdeenablealstrueangewendet, startet der Stream erneut, sobald die Kamera verbunden ist. -
Kann der Stream nicht starten, bleibt
control/publish/output/stream/activefalse, und der Grund wird in das Protokoll geschrieben. Es wird kein neuer Versuch unternommen, biscontrol/publish/executeerneut aufgerufen wird. -
Eine Kamera ignoriert Trigger, die schneller kommen, als sie Bilder aufnehmen kann, ohne es zu melden. Wenn
statistics/frameslangsamer wächst als die Zahl der gesendeten Trigger, triggern Sie seltener oder setzen Sie einen Overlap, siehe Für die höchste Bildrate: TriggerOverlap. -
Die Belichtungszeit auf
input/exposure-timeund das Inter-Packet-Delay werden nicht angewendet, solange der Stream läuft. Ändern Sie Kamera-Features nur, solange der Stream gestoppt ist.
Capture, während der Stream läuft
Der Stream und capture nutzen die Kamera auf unterschiedliche Weise, deshalb laufen sie nie gleichzeitig:
-
control/capture/readyistfalse, solange der Stream läuft, sodass ein Programm, das den Handshake verwendet, wartet. -
control/capture/executeantwortet mitDL_INVALID_OPERATION_MODE, solange der Stream läuft, und mitDL_TOO_MANY_OPERATIONS, während der Stream startet oder stoppt. Wiederholen SieDL_INVALID_OPERATION_MODEnicht in einer Schleife. Stoppen Sie stattdessen den Stream und warten Sie aufcapture/ready. Siehe Eine Methode ausführen. -
Ein Capture-Request, der den Cam Driver erreicht, während der Stream läuft, wird mit Status
-3(invalidInput) abgelehnt, mit dem Text "capture refused: the image stream (experimental) is active". Er speichert keinen Fehler, es ist also keinresetnötig. -
Ein Stream, der eingeschaltet wird, während ein Capture läuft, startet, sobald dieses Capture abgeschlossen ist. Er bricht ein Capture nie ab.
Gestreamte Bilder werden auf control/publish/output/stream/frame veröffentlicht. Sie erreichen output/image
nur, solange keep-latest-output als true angewendet ist: Dann ersetzt jedes das dortige Bild, und
output/package-identifier zählt es, wie es ein Capture zählt, fortlaufend ab der Nummer des letzten
Capture. save speichert auch dann weiterhin das letzte Bild, das mit capture oder load aufgenommen wurde.
Nach dem Stream
Während des Streamings liefert die Kamera ihre Bilder in einem anderen Aufnahmemodus als dem, den
capture verwendet. Um zurückzuschalten, trennt der Cam Driver die Kamera und verbindet sie erneut, wenn der
Stream stoppt, und wendet dabei jede Verbindungseinstellung an, wie connect-camera es tut. capture/ready wird
true, sobald das abgeschlossen ist. Bis dahin antwortet capture/execute mit DL_TOO_MANY_OPERATIONS.
Starten und Stoppen dauern deshalb unterschiedlich lang. Bei der von uns getesteten Kamera:
| Schritt | Dauer | Hauptsächlich verwendet für |
|---|---|---|
Stream starten |
etwa 0,35 s |
Umschalten des Aufnahmemodus der Kamera. |
Stream stoppen, bis |
etwa 2,2 s |
Erneutes Verbinden der Kamera: Öffnen des Geräts (etwa 0,8 s) und Lesen aller seiner GenICam- Features für den Data Layer (etwa 0,8 s). |
Wechseln Sie deshalb so selten wie möglich zwischen Streaming und Capture. Ein Programm, das während des Streamings
einzelne Bilder benötigt, kann sie von control/publish/output/stream/frame nehmen, statt den
Stream zu stoppen, oder keep-latest-output anwenden und output/image lesen, wenn sich output/package-identifier
ändert.
Gemessene Bildraten
Diese Werte wurden mit einer LUCID PHX016S (1440 x 1080, Mono8, Belichtung 1 ms) und LumiScan Keryx auf einem PC gemessen. Sie zeigen nur die Größenordnung: Ihre Kamera, Belichtungszeit, Ihr Netzwerk und Ihr Data Layer entscheiden, was Sie erreichen.
Sie wurden gemessen, als der Cam Driver die Kamera noch selbst triggerte, mit fester Rate. Ein
Hardware-Trigger oder eine kontinuierlich laufende Kamera sollte dasselbe ergeben. Das Triggern mit
control/trigger/execute fügt einen Methodenaufruf pro Bild hinzu; das wurde noch nicht gemessen.
| Methode | Gelieferte Bilder pro Sekunde |
|---|---|
|
etwa 34 |
Stream, |
bis zu 63, jedes Bild geliefert |
Stream, |
bis zu 66, jedes Bild geliefert |
Was die Kamera selbst liefern kann ( |
71,7 |
Die Statistik lesen
Die Zähler unter control/publish/output/stream/statistics/ beginnen bei jedem Start des Streams
bei null und werden etwa viermal pro Sekunde aktualisiert, solange er läuft.
| Zähler | Bedeutung |
|---|---|
|
Millisekunden seit dem Start des Streams, gemessen vom Cam Driver. Teilen Sie einen Zähler dadurch, um eine Rate zu erhalten. |
|
Vollständige Bilder, die die Kamera geliefert hat. |
|
Bilder, die die Kamera unvollständig geliefert hat. Sie werden nicht veröffentlicht. |
|
Bilder, die den Cam Driver nie erreicht haben, ermittelt aus Lücken in den Bildnummern der Kamera. |
|
Bilder, die auf |