Codes auf einem Bild-Stream lesen (experimentell)
| Der Bild-Stream ist experimentell. Seine Knoten und Einstellungen können sich noch ändern. Verwenden Sie ihn zur Evaluierung, und prüfen Sie ihn mit Ihren Kameras und Ihrem Data Layer, bevor Sie sich darauf verlassen. |
execute liest ein Bild pro Aufruf: Ihr Programm setzt input/image-address und schreibt auf execute.
Ein Bild-Stream arbeitet umgekehrt. Der Cam Driver veröffentlicht jedes Bild, das er aufnimmt, auf
<camera name>/control/publish/output/stream/frame, mit seiner Größe, seinem Pixelformat und seiner
Lineage (siehe das Handbuch des Cam Driver, Bilder streamen). Der Reader abonniert den Stream einer
Kamera, liest jeden Data-Matrix-Code in jedem Frame, sobald er eintrifft, und veröffentlicht ein
Ergebnis pro Frame auf control/subscribe/output/stream/result.
Jeder Frame wird genau so gelesen, wie execute ein Bild liest. execute nimmt außer der Bildadresse
keine Eingabe entgegen, und der Frame tritt an deren Stelle. input/parameter wird von keinem der
beiden gelesen: siehe Data-Layer-Referenz.
Jedes Ergebnis trägt die Lineage seines Frames – welche Kamera ihn aufgenommen hat, in welchem Lauf des Kamerastreams, als welcher Frame des Laufs – ergänzt um den eigenen Schritt des Readers. Siehe Die Lineage eines Ergebnisses.
Standardmäßig fällt der Reader nie hinter seine Kamera zurück. Treffen Frames schneller ein, als der Reader sie liest, nimmt er jedes Mal, wenn der vorherige Lesevorgang abgeschlossen ist, den neuesten Frame. Die Frames dazwischen werden als übersprungen gezählt. Wie viele Frames warten dürfen, wird mit der Warteschlangengröße festgelegt, siehe Die Warteschlangengröße.
Das allgemeine Konzept der Streams, das die anderen LumiScan-Anwendungen teilen, ist in Streams beschrieben. Diese Seite beschreibt den Stream des Readers.
Die Knoten des Streams
Der Reader hat die Knoten des Streams, ob er einen Stream abonniert oder nicht. Um sie zu verwenden,
ist kein Neustart nötig. Alle Adressen unten beginnen mit hdvisionsystems/lumiscan-dmc-reader/. Es
gibt keine Module: ein Stream pro Installation.
| Adresse | Bedeutung |
|---|---|
|
Prüft die fünf Eingaben von |
|
Entfernt die von |
| Adresse | Typ | Bedeutung |
|---|---|---|
|
bool |
Stream-Modus: |
|
string |
Die eine Quelle: der Stream-Ordner einer Kamera, zum Beispiel
|
|
string |
Das Tag, das der Reader auf seine Ergebnisse setzt: Der Schritt des Readers in der Lineage jedes
Ergebnisses trägt es, sodass jeder, der ein Ergebnis weiter hinten in der Kette liest, sieht, welches
Modul es gelesen hat. Leer: der Name des Readers, |
|
uint32 |
Wie viele Frames warten dürfen, während ein Frame gelesen wird: |
|
bool |
|
Die Eingaben sind mit dem vorbelegt, was beim Start der Anwendung angewendet wird; ein Client kann
also eine davon ändern und execute aufrufen.
Was die Quelle enthalten muss: Lesen Sie system/meta/subscription-schema. Es ist ein JSON Schema des
Knotens frame der Quelle, eines stream_image mit seiner lineage und seinem image, in seiner
JSON-Form. Siehe Data-Layer-Referenz.
| Adresse | Typ | Bedeutung |
|---|---|---|
|
string |
Die zu entfernende Quelle: die Adresse, die |
| Adresse | Typ | Bedeutung |
|---|---|---|
|
wie die Eingaben |
Was |
|
string |
Der Hash dessen, womit die Ergebnisse erzeugt werden, als 16 Hexadezimalziffern. Schreibgeschützt. Siehe Der Einstellungs-Hash. |
| Adresse | Typ | Bedeutung |
|---|---|---|
|
bool |
|
|
flatbuffers |
Die aus jedem Frame gelesenen Codes und die Lineage des Frames. Abonnieren Sie den Knoten, um jedes Ergebnis zu erhalten. Siehe Das Ergebnis eines Frames. |
|
string |
Warum der letzte Frame, der nicht gelesen werden konnte, fehlgeschlagen ist. Nennt die Quelle über
ihre Adresse, zum Beispiel
|
|
uint64 |
Zähler des aktuellen oder des letzten Streams, siehe Die Statistik lesen. |
execute schreibt in output/results, der Stream in control/subscribe/output/stream/result –
Singular. In output/results schreibt der Stream nur mit eingeschaltetem keep-latest-output.
|
Einrichtung
-
Stellen Sie sicher, dass der Stream des Cam Driver läuft: Sein
hdvisionsystems/lumiscan-cam-driver/<camera name>/control/publish/output/stream/activeisttrue. -
Schreiben Sie den Stream-Ordner der Kamera, zum Beispiel
hdvisionsystems/lumiscan-cam-driver/camera1/control/publish/output/stream, incontrol/subscribe/input/address. Lassen Siecontrol/subscribe/input/tagleer, um die Ergebnisse mit dem Namen des Readers zu markieren, oder schreiben Sie ein eigenes Tag hinein. -
Abonnieren Sie
control/subscribe/output/stream/result. -
Setzen Sie
control/subscribe/input/enableauftrueund schreiben Sie dann aufcontrol/subscribe/execute. Warten Sie, biscontrol/subscribe/output/stream/activetrueist. Ab dann treffen die Ergebnisse ein. -
Zum Stoppen setzen Sie
control/subscribe/input/enableauffalseund schreiben erneut aufcontrol/subscribe/execute. Der Frame, der gerade gelesen wird, wird zuerst fertig gelesen.
Auf ctrlX OS nehmen Sie dieselben Schreibzugriffe in der Data-Layer-Ansicht der Weboberfläche von ctrlX OS oder aus Ihrem SPS-Programm vor.
Auf einem PC dieselben Schritte mit krxclient, dem Kommandozeilen-Client von LumiScan Keryx, der eine
SPS vertritt (siehe Werkzeuge). Ergänzen Sie die Optionen
--keryx-backend und --keryx-url, die Ihr Broker benötigt:
krxclient write hdvisionsystems/lumiscan-dmc-reader/control/subscribe/input/address hdvisionsystems/lumiscan-cam-driver/camera1/control/publish/output/stream
krxclient write hdvisionsystems/lumiscan-dmc-reader/control/subscribe/input/enable true
krxclient execute hdvisionsystems/lumiscan-dmc-reader/control/subscribe/execute
krxclient subscribe hdvisionsystems/lumiscan-dmc-reader/control/subscribe/output/stream/result --count 5
krxclient subscribe zeigt einen FlatBuffer nur über seine Größe an. Es sagt Ihnen, dass Ergebnisse
eintreffen, nicht, was sie enthalten.
Gut zu wissen:
-
Der Stream-Modus ist ein Pegel, kein Befehl: Der Stream läuft, solange das angewendete
enabletrueist. -
Der Stream kann vor dem Stream des Cam Driver gestartet werden. Ergebnisse treffen ein, sobald Frames eintreffen.
-
Was
control/subscribe/executeanwendet, wird in der Einstellungsdatei des Readers gespeichert. Nach einem Neustart der Anwendung startet der Reader so, wie er war: Einer, der gestreamt hat, streamt sofort wieder, ohne dass Ihr Programm etwas ausführt. Siehe In der Einstellungsdatei gespeichert.
Die Quelle ändern
Ein Reader nimmt eine Quelle. Eine SPS oder ein anderer Client ändert sie, während die Anwendung läuft, mit oder ohne laufenden Stream:
-
Schreiben Sie die neuen Werte in die Eingaben von
control/subscribe– nur die, die Sie ändern: Die anderen enthalten, was angewendet ist. -
Schreiben Sie auf
control/subscribe/execute. Die Eingaben werden gemeinsam geprüft, in der Einstellungsdatei des Readers gespeichert und erst dann angewendet:setting/stream/zeigt sie sofort an, und ein laufender Stream folgt bei seinem nächsten Zyklus. Eine andere Adresse ersetzt die Quelle; die Frames, die bei der alten noch warteten, werden als übersprungen gezählt. Ein neues Tag, eine neue Warteschlangengröße oder ein neueskeep-latest-outputbraucht kein neues Abonnement: Ein neues Tag markiert das nächste Ergebnis. -
Um die Quelle zu entfernen, schreiben Sie ihre Adresse in
control/unsubscribe/input/addressund schreiben dann aufcontrol/unsubscribe/execute. Damit endet der Stream-Modus. Die Eingaben voncontrol/subscribewerden auf das gesetzt, was angewendet wurde: Stream-Modus aus, keine Adresse. Das Tag bleibt: Es markiert die Ergebnisse des Readers, nicht die Quelle.
Kann die Einstellungsdatei nicht geschrieben werden, ändert sich nichts. Siehe In der Einstellungsdatei gespeichert.
Die Methoden antworten:
| Ergebnis | Wann |
|---|---|
|
Erledigt. |
|
|
|
Die Einstellungsdatei konnte nicht geschrieben werden, zum Beispiel weil sie kein gültiges JSON ist. Nichts hat sich geändert. |
Der Grund für eine Ablehnung wird in das Protokoll der Anwendung geschrieben. Die Namen aller Ergebnisse auf beiden Data Layern sind in Ergebnisse eines Methodenaufrufs aufgeführt.
Kann die Quelle nicht abonniert werden, versucht der Reader es alle 5 Sekunden erneut, solange der Stream läuft, und protokolliert den ersten Fehlschlag.
Das Ergebnis eines Frames
control/subscribe/output/stream/result enthält eine FlatBuffers-Tabelle vom Typ stream_codes
(Dateikennung HSCD), auf dem Data Layer registriert als
types/hdvisionsystems/lumiscan-dmc-reader/stream_codes. Ihr kompiliertes Schema wird als
bfbs/stream_codes.bfbs installiert.
| Feld | Bedeutung |
|---|---|
|
Woher das Ergebnis stammt, siehe Die Lineage eines Ergebnisses. |
|
Die Codes, als |
Ein Lesen von control/subscribe/output/stream/result liefert das neueste Ergebnis; vor dem ersten
Frame ein leeres. Das letzte Ergebnis bleibt erhalten, nachdem der Stream gestoppt wurde.
Ein Frame wird so dekodiert, wie execute den Bildknoten dekodiert; es werden also dieselben
Pixelformate akzeptiert, siehe Voraussetzungen. Der ganze
Frame wird durchsucht. Ein Frame und dasselbe Bild, über input/image-address gelesen, ergeben
dieselben Codes.
Ein Frame, der nicht gelesen werden kann – zum Beispiel einer in einem Pixelformat, das der Reader
nicht unterstützt, oder einer, dessen Pixel die angegebene Größe nicht ausfüllen – ergibt kein
Ergebnis. Er wird in statistics/failed-frames gezählt, und
control/subscribe/output/stream/last-failure sagt, warum.
Die Lineage eines Ergebnisses
lineage.steps listet auf, woher das Ergebnis stammt, der Ursprung zuerst:
-
Der Schritt der Kamera, wie der Cam Driver ihn erzeugt hat:
producerist die Adresse der Kamera,hdvisionsystems/lumiscan-cam-driver/<camera name>;run, wann der Stream der Kamera gestartet wurde;sequencedie Nummer des Frames in diesem Lauf;external_iddie eigene Bildnummer der Kamera;settings_hashdie Einstellungen der Kamera;tagdas Tag des Cam Driver für die Kamera, standardmäßig ihre Modul-ID, zum Beispielcamera1. -
Der Schritt des Readers:
producerist die Adresse des Readers,hdvisionsystems/lumiscan-dmc-reader;run, wann der Stream des Readers gestartet wurde (jeder Start ist ein neuer Lauf);sequencedie Nummer des Ergebnisses im Lauf, ab1;settings_hashdie Einstellungen des Readers, siehe Der Einstellungs-Hash;elapsed_usdie Mikrosekunden vom Eintreffen des Frames beim Reader bis zu seinem Ergebnis, Wartezeit eingeschlossen;time_us, wann das Ergebnis erzeugt wurde, in Mikrosekunden seit der Epoche;tagdas Tag des Readers,control/subscribe/input/tag, oderlumiscan-dmc-reader, wenn es leer ist.
Ein Ergebnis benennt seinen Frame also genau: die Kamera über producer, den Frame über run und
sequence. Um zu erfahren, von welcher Kamera ein Ergebnis stammt, lesen Sie den producer seines
ersten Schritts. Eine Lücke in der sequence des Kameraschritts zwischen zwei Ergebnissen derselben
Kamera sind Frames, die übersprungen wurden, fehlgeschlagen sind oder verloren gingen.
Eine Lineage enthält höchstens 16 Schritte. Eine längere behält den Ursprung und die neuesten
Schritte, und dropped zählt die ausgelassenen Schritte.
Ein Frame ohne Lineage ergibt ein Ergebnis nur mit dem Schritt des Readers. Ein Wert auf dem Knoten
frame eines Streams, der kein stream_image ist, wird ignoriert und einmalig protokolliert.
Der Einstellungs-Hash
setting/settings-hash und der settings_hash des Reader-Schritts in jedem Ergebnis identifizieren,
womit die Ergebnisse erzeugt werden. Der Knoten zeigt den Hash als 16 Hexadezimalziffern; der Schritt
enthält denselben Wert als Zahl.
Der Reader hat keine Einstellung, die einen Lesevorgang verändert; der Hash umfasst daher nur den Codetyp sowie Name und Version der Anwendung: Er ändert sich, wenn die Anwendung aktualisiert wird. Er umfasst nicht den Stream-Modus, die Quelle, die Warteschlangengröße oder keep-latest-output, die die Frames auswählen und takten.
Wenn ein Hash zum ersten Mal auftritt, schreibt der Reader die Einstellungen, für die er steht, nach
settings-history/dmc-reader-<hash>.json im Konfigurationsverzeichnis der Anwendung, sodass ein in
einem Ergebnis gefundener Hash später nachgeschlagen werden kann. Die Anwendung löscht diese Dateien
nicht. Eine Datei sieht so aus:
{
"format": 1,
"settings": {
"code-type": "datamatrix-code",
"software.name": "lumiscan-dmc-reader",
"software.version": "<version>"
},
"settingsHash": "<16 hex digits>"
}
Die Statistik lesen
Die Zähler beginnen bei jedem Start des Streams bei null, werden etwa viermal pro Sekunde
aktualisiert, solange er läuft, und behalten ihre letzten Werte, nachdem er gestoppt wurde. Alle
Adressen beginnen mit control/subscribe/output/stream/statistics/.
| Zähler | Bedeutung |
|---|---|
|
Millisekunden seit dem Start des Streams. Teilen Sie einen Zähler dadurch, um eine Rate zu erhalten. |
|
Frames, die das Abonnement geliefert hat. |
|
Gelesene Frames, jeder mit einem auf |
|
Nie gelesene Frames: von neueren aus der Warteschlange verdrängt, während ein Frame gelesen wurde (siehe Die Warteschlangengröße), oder wartend, als die Quelle ersetzt oder entfernt wurde. |
|
Frames, die nicht gelesen werden konnten. |
|
Frames, die verloren gingen, bevor sie eintrafen, ermittelt aus Lücken in der |
|
Mikrosekunden, die alle Lesevorgänge zusammen gedauert haben. Teilen Sie durch |
Frames, die beim Stoppen des Streams noch warten, werden verworfen, ohne gezählt zu werden.
In der Einstellungsdatei gespeichert
Der Stream-Modus und die Quelle sind Einstellungen des Readers. Sie werden im Member stream der
Einstellungsdatei des Readers gespeichert, dmc-reader.json im Konfigurationsverzeichnis der
Anwendung.
control/subscribe/execute und control/unsubscribe/execute speichern dort selbst, was sie anwenden,
alle fünf Werte in einem Schreibvorgang, bevor sie sie anwenden. Kann die Datei nicht geschrieben
werden, antwortet die Methode mit DL_CREATION_FAILED, und nichts ändert sich. Nach einem Neustart
abonniert der Reader dieselbe Quelle und startet, wenn stream.enable true ist, seinen Stream
sofort: Niemand muss etwas ausführen.
Das Speichern ändert nur den Member stream; der Rest der Datei bleibt, wie er war, Kommentare
eingeschlossen. Der Reader legt die Datei an, wenn es keine gibt.
Das Konfigurationsverzeichnis:
| Plattform | Konfigurationsverzeichnis |
|---|---|
ctrlX OS |
|
PC (Windows) |
|
Die Datei enthält einen Member, stream. Ein Beispiel; auf einem PC ist es das Beispiel, das die
Anwendung mit --generate-settings schreibt, siehe Mit einem Beispiel beginnen:
{
// The settings of the DMC Reader, read once, at the start: the image stream it reads codes in.
// control/subscribe/execute and control/unsubscribe/execute save what they change here before
// they apply it, the rest of the file left as it is, comments included.
"$schema": "schemas/dmc-reader.schema.json",
"stream": {
// Stream mode: read every frame of the source as it arrives. Off if left out.
"enable": false,
// The one image stream to read: its folder.
"address": "hdvisionsystems/lumiscan-cam-driver/camera1/control/publish/output/stream",
// "tag" (left out here): what marks the codes it reads, in their lineage - the reader's name,
// lumiscan-dmc-reader, if left out.
// How many frames may wait while a frame is read: 1 to 64, 1 if left out.
"queueSize": 1,
// Each stream result also on output/results, as execute writes it. Off if left out.
"keepLatestOutput": false
}
}
| Schlüssel | Erforderlich | Bedeutung |
|---|---|---|
|
Nein |
Stream-Modus: |
|
Nein |
Die eine Quelle: der Stream-Ordner einer Kamera. |
|
Nein |
Was die Ergebnisse des Readers markiert: das |
|
Nein |
Wie viele Frames warten dürfen: |
|
Nein |
|
|
Nein |
Die Schritte, die auf jeden eintreffenden Frame angewendet werden, jeder ein Objekt mit einem
|
control/subscribe/execute und control/unsubscribe/execute schreiben alle fünf.
Gut zu wissen:
-
Die Datei wird einmal gelesen, beim Start der Anwendung. Von Hand an der Datei vorgenommene Änderungen wirken beim nächsten Start.
-
Ein Wert, der nicht verwendet werden kann, wird ignoriert und protokolliert: ein
enableoderkeepLatestOutput, das nichttrueoderfalseist, eineaddressoder eintag, das kein String ist, einequeueSizeaußerhalb von1bis64(1wird verwendet). Stream-Modus ohneaddresswird ignoriert: Der Reader startet außerhalb des Stream-Modus. -
Der Member
subscriptionsfrüherer Versionen wird nicht mehr gelesen, und der Reader protokolliert, dass er umgezogen ist: Geben Sie die Quelle alsaddressan. -
Eine Datei, die kein gültiges JSON ist, wird ignoriert und protokolliert.
Die Warteschlangengröße
control/subscribe/input/queue-size legt fest, wie viele Frames warten dürfen, während ein Frame
gelesen wird: 1 bis 64, standardmäßig 1. Sie wird als stream.queueSize gespeichert, und
setting/stream/queue-size zeigt den verwendeten Wert an. Ein Frame, der eintrifft, wenn so viele
warten, verdrängt den ältesten von ihnen, was in statistics/skipped-frames gezählt wird. Eine neue
Warteschlangengröße gilt ab dem nächsten eintreffenden Frame, ohne neues Abonnement.
| Warteschlangengröße | Wirkung |
|---|---|
1 (Standard) |
Der Reader liest den neuesten Frame. Er fällt nie zurück; ist das Lesen langsamer als die Kamera, überspringt er Frames. |
Mehr als 1 |
Kurze Frame-Schübe werden vollständig gelesen, und weniger Frames werden übersprungen. Ist das Lesen über längere Zeit langsamer als die Kamera, fällt der Reader zurück: Er liest Frames, die bis zu so viele Lesevorgänge alt sind. Jeder wartende Frame hält ein ganzes Bild im Speicher. |
Das neueste Ergebnis behalten
Mit control/subscribe/input/keep-latest-output true – angewendet von control/subscribe/execute,
gespeichert als stream.keepLatestOutput – schreibt der Reader jedes Stream-Ergebnis zusätzlich in
output/results, so wie execute es schreibt, sobald das Ergebnis auf
control/subscribe/output/stream/result veröffentlicht ist.
Ein Client, der output/results liest, hat dann das Ergebnis des neuesten Frames, ohne den Stream zu
abonnieren. Das kostet eine Kopie jedes Ergebnisses. Standardmäßig aus.
execute, während der Stream läuft
execute und der Stream behindern sich nicht. Jeder Frame wird von einem eigenen Detektor gelesen,
wie auch jeder Aufruf von execute, und nichts wird zwischen beiden geteilt: execute kann jederzeit
aufgerufen werden, während der Stream läuft, und ein Frame wartet nie darauf.
Einschränkungen
-
input/parameterwird weder vonexecutenoch vom Stream gelesen. -
Der Stream wurde nur unter Windows mit LumiScan Keryx und simulierten Bildern getestet. Er wurde nicht unter Linux (ctrlX OS oder Ubuntu), auf dem ctrlX Data Layer oder mit einer echten Kamera geprüft.
-
LumiScan Cockpit zeichnet die Ergebnisse des Streams noch nicht.
-
Von Hand an der Einstellungsdatei vorgenommene Änderungen wirken beim nächsten Start der Anwendung.
Mit einem Beispiel beginnen (PC)
Auf einem PC schreibt der DMC Reader ein Beispiel seiner Einstellungen in einen Ordner Ihrer Wahl und beendet sich, ohne zu starten. Unter Windows zum Beispiel:
lumiscan-dmc-reader --generate-settings C:\work\dmc-reader-settings
Ohne Ordner (-g allein) schreibt er in den aktuellen Ordner. Das Beispiel ist die Einstellungsdatei
dmc-reader.json: Stream-Modus aus, der Stream der camera1 des Cam Driver als Quelle, die
Warteschlangengröße, die er standardmäßig hat, und keep-latest-output aus. Daneben liegen in
schemas/ das Schema, das sie in "$schema" nennt, dmc-reader.schema.json, und
stream.schema.json, das den Abschnitt stream beschreibt; ein Editor, der JSON Schema versteht, kann
die Datei dagegen prüfen. Kopieren Sie den Ordner schemas zusammen mit der Datei. Vorhandene Dateien
werden nie überschrieben: Liegt eine davon bereits im Ordner, wird nichts geschrieben, und der DMC
Reader sagt, welche.
Der DMC Reader nennt dann den Ordner, aus dem er seine Einstellungen liest, unter Windows
standardmäßig
C:\ProgramData\HD Vision Systems GmbH\LumiScan Vision Suite\lumiscan-dmc-reader\etc\lumiscan-dmc-reader.
Bearbeiten Sie das Beispiel, kopieren Sie es dorthin, und starten Sie den DMC Reader.