---
title: "Vorlagen in einem Bild-Stream finden (experimentell)"
product: "LumiScan Template Finder"
component: "lumiscan-template-finder-de"
version: "1.1.0"
display_version: "1.1.0.7"
latest_version: true
language: "de"
url: "https://docs.hdvisionsystems.com/de/lumiscan-template-finder-de/1.1.0/lumiscan-template-finder/processing-an-image-stream.html"
---

# Vorlagen in einem Bild-Stream finden (experimentell) – LumiScan Template Finder

> [!IMPORTANT]
> 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.

`find-template` durchsucht ein Bild pro Aufruf: Ihr Programm setzt `input/input-image-address` und schreibt auf `execute`. Ein Bild-Stream funktioniert umgekehrt. Der Cam Driver veröffentlicht jedes aufgenommene Bild 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*). Ein Modul abonniert den Stream einer Kamera, durchsucht jedes Bild, sobald es eintrifft, und veröffentlicht ein Ergebnis pro Bild auf `control/subscribe/output/stream/result`.

Jedes Bild wird mit den Eingaben von `find-template` durchsucht, wie sie in diesem Moment sind: die Vorlage, die Ausschnittsregion, die Skalierungs- und Drehungsbereiche und jeder andere Knoten unter `find-template/input/`. Die einzige Eingabe, die der Stream nicht verwendet, ist `input/input-image-address`: Das Bild tritt an ihre Stelle. Ändern Sie eine Eingabe, während der Stream läuft, wird das nächste Bild mit dem neuen Wert durchsucht.

Jedes Ergebnis trägt die Lineage seines Bilds - welche Kamera es aufgenommen hat, in welchem Lauf des Kamera-Streams, als welches Bild des Laufs - ergänzt um den eigenen Schritt des Moduls. Siehe [Die Lineage eines Ergebnisses](https://docs.hdvisionsystems.com/de/lumiscan-template-finder-de/1.1.0/lumiscan-template-finder/processing-an-image-stream.html#lineage).

Standardmäßig fällt das Modul nie hinter seine Kamera zurück. Treffen Bilder schneller ein, als das Modul sie durchsucht, nimmt es jedes Mal, wenn die vorherige Suche abgeschlossen ist, das neueste Bild. Die Bilder dazwischen werden als übersprungen gezählt. Wie viele Bilder warten dürfen, legt die Warteschlangengröße fest, siehe [Die Warteschlangengröße](https://docs.hdvisionsystems.com/de/lumiscan-template-finder-de/1.1.0/lumiscan-template-finder/processing-an-image-stream.html#queue-size).

Ein Modul nimmt den Stream einer Kamera. Für eine andere Kamera oder andere Einstellungen verwenden Sie ein anderes Modul.

Die Stream-Knoten und das Starten und Stoppen eines Streams sind in jeder LumiScan-App gleich, die einen Stream konsumiert; [Streams (experimentell)](https://docs.hdvisionsystems.com/de/lumiscan-keryx-de/1.0.0/streams.html) im Data-Layer-Handbuch beschreibt sie allgemein. Diese Seite beschreibt, was für den Template Finder besonders ist.

## Die Knoten des Streams {#addresses}

Jedes Modul hat die Knoten des Streams, ob es einen Stream abonniert oder nicht. Um sie zu verwenden, ist kein Neustart nötig. Alle folgenden Adressen beginnen mit `hdvisionsystems/lumiscan-template-finder/<module-id>/`. Sie liegen neben `find-template/`, nicht darin.

**Tabelle 1. Methoden**

| Adresse | Bedeutung |
| --- | --- |
| `control/subscribe/execute` | Prüft die fünf Eingaben von `control/subscribe` gemeinsam, speichert sie in der Einstellungsdatei des Moduls und wendet sie dann an: Ein laufender Stream folgt bei seinem nächsten Zyklus, ohne Neustart. Nur eine Eingabe zu schreiben ändert nichts. Siehe [Die Quelle ändern](https://docs.hdvisionsystems.com/de/lumiscan-template-finder-de/1.1.0/lumiscan-template-finder/processing-an-image-stream.html#subscribing). |
| `control/unsubscribe/execute` | Entfernt die von `control/unsubscribe/input/address` genannte Quelle, was auch den Stream-Modus beendet. Das Tag bleibt. Wird wie ein Subscribe in der Einstellungsdatei des Moduls gespeichert. |

**Tabelle 2. Eingaben von control/subscribe**

| Adresse | Typ | Bedeutung |
| --- | --- | --- |
| `control/subscribe/input/enable` | bool | Stream-Modus: `true` lässt den Stream laufen, `false` stoppt ihn. |
| `control/subscribe/input/address` | string | Die eine Quelle: der Stream-Ordner einer Kamera, zum Beispiel `hdvisionsystems/lumiscan-cam-driver/camera1/control/publish/output/stream`. Das Modul liest dessen Knoten `frame`. Eine andere Adresse ersetzt die Quelle. |
| `control/subscribe/input/tag` | string | Das Tag, das das Modul auf seine Ergebnisse setzt: Der Schritt des Moduls in der Lineage jedes Ergebnisses trägt es, sodass jeder, der ein Ergebnis weiter unten liest, sieht, welches Modul es erzeugt hat. Leer: die Modul-ID, das letzte Segment der Moduladresse, zum Beispiel `module-1`. Ein neues Tag markiert das nächste Ergebnis; die Quelle bleibt abonniert. |
| `control/subscribe/input/queue-size` | uint32 | Wie viele Bilder warten dürfen, während ein Bild durchsucht wird: `1` bis `64`. Siehe [Die Warteschlangengröße](https://docs.hdvisionsystems.com/de/lumiscan-template-finder-de/1.1.0/lumiscan-template-finder/processing-an-image-stream.html#queue-size). |
| `control/subscribe/input/keep-latest-output` | bool | `true`, um jedes Stream-Ergebnis zusätzlich auf `find-template/output/result` zu schreiben. Siehe [Die neueste Ausgabe behalten](https://docs.hdvisionsystems.com/de/lumiscan-template-finder-de/1.1.0/lumiscan-template-finder/processing-an-image-stream.html#keep-latest-output). |

Die Eingaben beginnen mit dem, was beim Start der Anwendung angewendet ist, sodass ein Client eine von ihnen ändern und die Methode ausführen kann.

Was die Quelle enthalten muss: Lesen Sie `hdvisionsystems/lumiscan-template-finder/system/meta/subscription-schema`, für jedes Modul gleich. Es ist ein JSON Schema des Knotens `frame` der Quelle, ein `stream_image` mit seiner `lineage` und seinem `image`, in seiner JSON-Form. Siehe [Data-Layer-Referenz](https://docs.hdvisionsystems.com/de/lumiscan-template-finder-de/1.1.0/lumiscan-template-finder/datalayer-reference.html).

**Tabelle 3. Eingabe von control/unsubscribe**

| Adresse | Typ | Bedeutung |
| --- | --- | --- |
| `control/unsubscribe/input/address` | string | Die zu entfernende Quelle: die Adresse, die `setting/stream/address` zeigt. Ein `/` am Anfang oder Ende zählt nicht. |

**Tabelle 4. Einstellungen**

| Adresse | Typ | Bedeutung |
| --- | --- | --- |
| `setting/stream/enable`, `setting/stream/address`, `setting/stream/tag`, `setting/stream/queue-size`, `setting/stream/keep-latest-output` | wie die Eingaben | Was `control/subscribe/execute` oder `control/unsubscribe/execute` zuletzt angewendet hat, wie die Einstellungsdatei es enthält. Schreibgeschützt. |
| `setting/settings-hash` | string | Der Hash dessen, womit die Ergebnisse erzeugt werden, als 16 Hexadezimalziffern. Schreibgeschützt. Siehe [Der Einstellungs-Hash](https://docs.hdvisionsystems.com/de/lumiscan-template-finder-de/1.1.0/lumiscan-template-finder/processing-an-image-stream.html#settings-hash). |

**Tabelle 5. Ausgaben**

| Adresse | Typ | Bedeutung |
| --- | --- | --- |
| `control/subscribe/output/stream/active` | bool | `true`, solange der Stream läuft. |
| `control/subscribe/output/stream/result` | flatbuffer `stream_template_matches` | Die in jedem Bild gefundenen Treffer und die Lineage des Bilds. Abonnieren Sie den Knoten, um jedes Ergebnis zu erhalten. Siehe [Das Ergebnis eines Bilds](https://docs.hdvisionsystems.com/de/lumiscan-template-finder-de/1.1.0/lumiscan-template-finder/processing-an-image-stream.html#result). |
| `control/subscribe/output/stream/last-failure` | string | Warum das letzte Bild, das nicht durchsucht werden konnte, fehlgeschlagen ist. Nennt die Quelle anhand ihrer Adresse, siehe [Das Ergebnis eines Bilds](https://docs.hdvisionsystems.com/de/lumiscan-template-finder-de/1.1.0/lumiscan-template-finder/processing-an-image-stream.html#result). Wird beim Start des Streams geleert. |
| `control/subscribe/output/stream/statistics/…` | uint64 | Zähler des aktuellen oder des letzten Streams, siehe [Die Statistik lesen](https://docs.hdvisionsystems.com/de/lumiscan-template-finder-de/1.1.0/lumiscan-template-finder/processing-an-image-stream.html#statistics). |

Der Stream veröffentlicht seine Ergebnisse auf `control/subscribe/output/stream/result`. Von den Knoten von `find-template` schreibt er nur `find-template/output/result`, und nur mit eingeschaltetem `keep-latest-output`: `status-code` und `status-text` behalten, was der letzte Aufruf der Methode dort hinterlassen hat.

## Einrichtung {#setting-up}

1. Stellen Sie sicher, dass der Stream des Cam Driver läuft: Sein `hdvisionsystems/lumiscan-cam-driver/<camera name>/control/publish/output/stream/active` ist `true`.
2. Setzen Sie die Eingaben von `find-template` wie für eine einzelne Suche, siehe [Eine Vorlage finden](https://docs.hdvisionsystems.com/de/lumiscan-template-finder-de/1.1.0/lumiscan-template-finder/finding-a-template.html). Ein Aufruf von `find-template/execute` auf das `output/image` der Kamera ist ein schneller Weg, sie zu prüfen.
3. Schreiben Sie den Stream-Ordner der Kamera, zum Beispiel `hdvisionsystems/lumiscan-cam-driver/camera1/control/publish/output/stream`, auf `control/subscribe/input/address`. Lassen Sie `control/subscribe/input/tag` leer, um die Ergebnisse mit der Modul-ID zu markieren, oder schreiben Sie ein eigenes Tag hinein.
4. Abonnieren Sie `control/subscribe/output/stream/result`.
5. Setzen Sie `control/subscribe/input/enable` auf `true` und schreiben Sie dann auf `control/subscribe/execute`. Warten Sie, bis `control/subscribe/output/stream/active` `true` ist. Von da an treffen die Ergebnisse ein.
6. Zum Stoppen setzen Sie `control/subscribe/input/enable` auf `false` und schreiben erneut auf `control/subscribe/execute`. Das gerade durchsuchte Bild wird zuerst fertig bearbeitet.

Auf ctrlX OS verwenden Sie für diese Schritte die Data-Layer-Ansicht der Weboberfläche von ctrlX OS oder Ihr SPS-Programm.

Auf einem PC dieselben Schritte mit `krxclient`, dem Kommandozeilen-Client von LumiScan Keryx, der die SPS vertritt. Ergänzen Sie die Optionen `--keryx-backend` und `--keryx-url`, die Ihr Broker benötigt (siehe [krxclient](https://docs.hdvisionsystems.com/de/lumiscan-keryx-de/1.0.0/tools.html#krxclient)):

```none
krxclient write hdvisionsystems/lumiscan-template-finder/module-1/control/subscribe/input/address hdvisionsystems/lumiscan-cam-driver/camera1/control/publish/output/stream
krxclient write hdvisionsystems/lumiscan-template-finder/module-1/control/subscribe/input/enable true
krxclient execute hdvisionsystems/lumiscan-template-finder/module-1/control/subscribe/execute
krxclient subscribe hdvisionsystems/lumiscan-template-finder/module-1/control/subscribe/output/stream/result --count 5
```

`krxclient subscribe` zeigt einen FlatBuffer nur anhand seiner Größe. Es sagt Ihnen, dass Ergebnisse eintreffen, nicht, was sie enthalten.

Gut zu wissen:

- Der Stream-Modus ist ein **Pegel**, kein Befehl, und der Stream kann vor dem Stream des Cam Driver gestartet werden: Die Ergebnisse treffen ein, sobald Bilder eintreffen. Siehe [Stream starten und stoppen](https://docs.hdvisionsystems.com/de/lumiscan-keryx-de/1.0.0/streams.html#running).
- Was `control/subscribe/execute` anwendet, wird in der Einstellungsdatei des Moduls gespeichert. Nach einem Neustart der Anwendung startet das Modul, wie es war: Eines, das gestreamt hat, streamt sofort wieder, ohne dass Ihr Programm etwas ausführt. Siehe [In der Einstellungsdatei gespeichert](https://docs.hdvisionsystems.com/de/lumiscan-template-finder-de/1.1.0/lumiscan-template-finder/processing-an-image-stream.html#saving).

## Die Quelle ändern {#subscribing}

Ein Modul nimmt eine Quelle. Eine SPS oder ein anderer Client ändert sie im laufenden Betrieb, mit oder ohne laufenden Stream:

1. Schreiben Sie die neuen Werte auf die Eingaben von `control/subscribe` - nur die, die Sie ändern: Die anderen enthalten, was angewendet ist.
2. Schreiben Sie auf `control/subscribe/execute`. Die Eingaben werden gemeinsam geprüft, in der Einstellungsdatei des Moduls gespeichert und erst dann angewendet: `setting/stream/` zeigt sie sofort, und ein laufender Stream folgt bei seinem nächsten Zyklus. Eine andere Adresse ersetzt die Quelle; die Bilder, die bei der alten warteten, werden als übersprungen gezählt. Ein neues Tag, eine neue Warteschlangengröße oder ein neues `keep-latest-output` braucht kein neues Abonnement: Ein neues Tag markiert das nächste Ergebnis.
3. Um die Quelle zu entfernen, schreiben Sie ihre Adresse auf `control/unsubscribe/input/address` und dann auf `control/unsubscribe/execute`. Der Stream-Modus endet damit. Die Eingaben von `control/subscribe` werden auf das gesetzt, was angewendet wurde: Stream-Modus aus, keine Adresse. Das Tag bleibt: Es markiert die Ergebnisse des Moduls, nicht die Quelle.

Kann die Einstellungsdatei nicht geschrieben werden, ändert sich nichts. Siehe [In der Einstellungsdatei gespeichert](https://docs.hdvisionsystems.com/de/lumiscan-template-finder-de/1.1.0/lumiscan-template-finder/processing-an-image-stream.html#saving).

Die Methoden antworten mit einem Ergebnis, dessen Name vom Data Layer abhängt (siehe [Ergebnisse eines Methodenaufrufs](https://docs.hdvisionsystems.com/de/lumiscan-keryx-de/1.0.0/status-codes.html#method-results)):

| ctrlX Data Layer | LumiScan Keryx (PC) | Wann |
| --- | --- | --- |
| `DL_OK` | `Ok` | Erledigt. |
| `DL_INVALID_VALUE` | `Rejected` | `control/subscribe/execute`: Stream-Modus ohne Adresse oder eine Warteschlangengröße außerhalb von `1` bis `64`. `control/unsubscribe/execute`: Die Adresse ist nicht die Quelle, oder es gibt keine Quelle. |
| `DL_CREATION_FAILED` | `CreationFailed` | Die Einstellungsdatei konnte nicht geschrieben werden, zum Beispiel weil sie kein gültiges JSON ist. Nichts wurde geändert. |

Diese Methoden haben keinen `status-text`. Der Grund für eine Ablehnung wird in das Protokoll der Anwendung geschrieben.

Kann die Quelle nicht abonniert werden, versucht das Modul es alle 5 Sekunden erneut, solange der Stream läuft, und protokolliert den ersten Fehlschlag.

## Das Ergebnis eines Bilds {#result}

`control/subscribe/output/stream/result` enthält eine FlatBuffers-Tabelle vom Typ `stream_template_matches` (Dateikennung `HSTM`), auf dem Data Layer registriert als `types/hdvisionsystems/lumiscan-template-finder/stream_template_matches`. Ihr kompiliertes Schema wird als `bfbs/stream_template_matches.bfbs` installiert.

| Feld | Bedeutung |
| --- | --- |
| `lineage` | Woher das Ergebnis stammt, siehe [Die Lineage eines Ergebnisses](https://docs.hdvisionsystems.com/de/lumiscan-template-finder-de/1.1.0/lumiscan-template-finder/processing-an-image-stream.html#lineage). |
| `result` | Die Treffer, als `hdv.template_match.Result`: dieselbe Tabelle, die `find-template` für dasselbe Bild auf `output/result` schreibt, beschrieben in [Eine Vorlage finden](https://docs.hdvisionsystems.com/de/lumiscan-template-finder-de/1.1.0/lumiscan-template-finder/finding-a-template.html). `image_width` und `image_height` sind die Größe des Bilds. |

Ein Lesen von `control/subscribe/output/stream/result` liefert das neueste Ergebnis; vor dem ersten Bild ein leeres. Das letzte Ergebnis bleibt nach dem Stoppen des Streams erhalten.

Ein Bild wird so dekodiert, wie `find-template` den Bildknoten dekodiert; es werden also dieselben Pixelformate akzeptiert, siehe [Voraussetzungen](https://docs.hdvisionsystems.com/de/lumiscan-template-finder-de/1.1.0/lumiscan-template-finder/requirements.html). Ein Bild des Streams und dasselbe Bild, über `input/input-image-address` gelesen, ergeben dieselben Treffer.

Ein Bild, das nicht durchsucht werden kann, ergibt kein Ergebnis. Es wird in `statistics/failed-frames` gezählt, und `control/subscribe/output/stream/last-failure` sagt warum, zum Beispiel:

```
a frame of 'hdvisionsystems/lumiscan-cam-driver/camera1/control/publish/output/stream' failed: invalid input: template-name is empty
```

Die Gründe sind dieselben, die `find-template` in seinem `status-text` nennt: eine Eingabe, die es ablehnen würde, eine Vorlage, die es nicht lesen kann, eine Ausschnittsregion, die nicht in das Bild passt, eine Region, die kleiner als die Vorlage ist.

## Die Lineage eines Ergebnisses {#lineage}

`lineage.steps` listet auf, woher das Ergebnis stammt, Ursprung zuerst:

1. Der Schritt der Kamera, wie der Cam Driver ihn erzeugt hat: `producer` ist die Adresse der Kamera, `hdvisionsystems/lumiscan-cam-driver/<camera name>`; `run`, wann der Stream der Kamera gestartet wurde; `sequence` die Nummer des Bilds in diesem Lauf; `external_id` die eigene Bildnummer der Kamera; `settings_hash` die Einstellungen der Kamera; `tag` das Tag des Cam Driver für die Kamera, standardmäßig ihre Modul-ID, zum Beispiel `camera1`.
2. Der Schritt des Moduls: `producer` ist die Adresse des Moduls, `hdvisionsystems/lumiscan-template-finder/<module-id>`; `run`, wann der Stream des Moduls gestartet wurde (jeder Start ist ein neuer Lauf); `sequence` die Nummer des Ergebnisses im Lauf, ab `1`; `settings_hash` die Einstellungen des Moduls, siehe [Der Einstellungs-Hash](https://docs.hdvisionsystems.com/de/lumiscan-template-finder-de/1.1.0/lumiscan-template-finder/processing-an-image-stream.html#settings-hash); `elapsed_us` die Mikrosekunden vom Eintreffen des Bilds beim Modul bis zu seinem Ergebnis, Wartezeit eingeschlossen; `time_us`, wann das Ergebnis erzeugt wurde, in Mikrosekunden seit der Epoche; `tag` das Tag des Moduls, `control/subscribe/input/tag`, oder die Modul-ID, wenn es leer ist.

Ein Ergebnis benennt sein Bild also genau: die Kamera über `producer`, das Bild ü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 Bilder, die übersprungen wurden, fehlgeschlagen oder verloren gegangen sind.

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 Bild ohne Lineage ergibt ein Ergebnis mit dem Schritt des Moduls allein. Ein Wert auf dem Knoten `frame` eines Streams, der kein `stream_image` ist, wird ignoriert und einmal protokolliert.

## Der Einstellungs-Hash {#settings-hash}

`setting/settings-hash` und der `settings_hash` des Modulschritts 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 Hash umfasst:

- jede Eingabe von `find-template`, die die Suche liest, genau so, wie sie für das Bild gelesen wurde - alle außer `input/input-image-address`;
- die Vorlagendatei, anhand ihres Inhalts: Eine neue Vorlage, die unter dem alten Namen gespeichert wird, ist ein neuer Hash;
- Name und Version der Anwendung.

Er umfasst nicht den Stream-Modus, die Quelle, die Warteschlangengröße oder keep-latest-output: Sie wählen und takten die Bilder, sie ändern nicht, was darin gefunden wird.

`setting/settings-hash` wird etwa alle halbe Sekunde aktualisiert, auch bei ausgeschaltetem Stream. Wenn ein Hash zum ersten Mal erscheint, schreibt das Modul die Einstellungen, für die er steht, nach `settings-history/<module-id>-<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, gekürzt:

```json
{
    "format": 1,
    "settings": {
        "find-template/input/match-thresh": 0.9,
        "find-template/input/template-name": "screw",
        "find-template/template": {
            "file": "<configuration directory>/templates/screw.png",
            "fnv1a64": "<16 hex digits>"
        },
        "software.name": "lumiscan-template-finder",
        "software.version": "<version>"
    },
    "settingsHash": "<16 hex digits>"
}
```

> [!NOTE]
> Ein Ergebnis trägt nur den Hash. Ein anderer Hash sagt, dass sich etwas geändert hat, womit die Ergebnisse erzeugt werden, nicht was. Um das herauszufinden, vergleichen Sie die beiden Dateien in `settings-history`, die die Hashes benennen, von Hand. Jede Eingabe, die die Suche liest, wird gehasht; eine Änderung, die ein Ergebnis nicht verändert, kann den Hash trotzdem ändern.

## Die Statistik lesen {#statistics}

Die Zähler beginnen bei jedem Start des Streams bei null, werden etwa viermal pro Sekunde aktualisiert, solange er läuft, und behalten nach dem Stoppen ihre letzten Werte. Alle Adressen beginnen mit `control/subscribe/output/stream/statistics/`.

| Zähler | Bedeutung |
| --- | --- |
| `elapsed-ms` | Millisekunden seit dem Start des Streams. Teilen Sie einen Zähler dadurch, um eine Rate zu erhalten. |
| `received-frames` | Bilder, die das Abonnement geliefert hat. |
| `processed-frames` | Durchsuchte Bilder, jedes mit einem auf `control/subscribe/output/stream/result` veröffentlichten Ergebnis. |
| `skipped-frames` | Nie durchsuchte Bilder: von neueren aus der Warteschlange gedrängt, während ein Bild durchsucht wurde (siehe [Die Warteschlangengröße](https://docs.hdvisionsystems.com/de/lumiscan-template-finder-de/1.1.0/lumiscan-template-finder/processing-an-image-stream.html#queue-size)), oder wartend, als die Quelle ersetzt oder entfernt wurde. |
| `failed-frames` | Bilder, die nicht durchsucht werden konnten. `control/subscribe/output/stream/last-failure` sagt, warum das letzte fehlgeschlagen ist, und das Protokoll nennt die Fehlschläge, höchstens eine Zeile alle 5 Sekunden. |
| `lost-frames` | Bilder, die verloren gingen, bevor sie ankamen, gezählt anhand von Lücken in der `sequence` der Kamera innerhalb eines Laufs ihres Streams. Eine neue Quelle oder ein neuer Lauf des Kamera-Streams beginnt die Zählung neu. |
| `processing-us` | Mikrosekunden, die alle Suchen gedauert haben, summiert, ohne die Zeit, die ein Bild auf `find-template` gewartet hat. Teilen Sie durch `processed-frames` für den Mittelwert. |

Bilder, die beim Stoppen des Streams noch warten, werden verworfen, ohne gezählt zu werden.

## In der Einstellungsdatei gespeichert {#saving}

Stream-Modus und Quelle sind Einstellungen des Moduls. Sie werden im Element `stream` der Einstellungsdatei des Moduls gespeichert, `<module-id>.json` im Konfigurationsverzeichnis der Anwendung - die Datei, in die `system/save-module-inputs` die Eingaben schreibt.

`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 `CreationFailed` (ctrlX: `DL_CREATION_FAILED`), und nichts ändert sich. Nach einem Neustart abonniert das Modul dieselbe Quelle und startet, wenn `stream.enable` `true` ist, seinen Stream sofort: Niemand muss etwas ausführen.

Das Speichern ändert nur das Element `stream`; der Rest der Datei bleibt, wie er war. Das Modul legt die Datei an, wenn noch keine vorhanden ist - ein Modul, dessen Eingaben nie gespeichert wurden, hat keine. `system/save-module-inputs` wiederum behält das Element `stream` bei, wenn es die Datei neu schreibt; die Eingaben von `control/subscribe` werden nicht als Eingaben des Moduls gespeichert.

| Plattform | Konfigurationsverzeichnis |
| --- | --- |
| ctrlX OS | `/var/snap/rexroth-solutions/common/solutions/activeConfiguration/lumiscan-template-finder` |
| PC (Windows) | `%APP_RESOURCE_DIR%\etc\lumiscan-template-finder`; ohne `APP_RESOURCE_DIR` `C:\ProgramData\HD Vision Systems GmbH\LumiScan Vision Suite\lumiscan-templ-find\etc\lumiscan-template-finder` |

Das Element `stream`, neben den Eingaben von `find-template` (hier gekürzt):

```json
{
    "find-template": {
        "template-name": "screw"
    },
    "stream": {
        "enable": true,
        "address": "hdvisionsystems/lumiscan-cam-driver/camera1/control/publish/output/stream",
        "queueSize": 1,
        "keepLatestOutput": false
    }
}
```

| Schlüssel | Erforderlich | Bedeutung |
| --- | --- | --- |
| `enable` | Nein | Stream-Modus: `true` startet den Stream beim Start der Anwendung. Benötigt eine `address`. `false`, wenn weggelassen. |
| `address` | Nein | Die eine Quelle: der Stream-Ordner einer Kamera. |
| `tag` | Nein | Was die Ergebnisse des Moduls markiert: das `tag` des Modulschritts in ihrer Lineage. Die Modul-ID, wenn weggelassen. |
| `queueSize` | Nein | Wie viele Bilder warten dürfen: `1` bis `64`, `1`, wenn weggelassen. |
| `keepLatestOutput` | Nein | `true`, um jedes Stream-Ergebnis zusätzlich auf `find-template/output/result` zu schreiben. `false`, wenn weggelassen. |
| `onEntry` | Nein | Die Schritte, die auf jedes eintreffende Bild angewendet werden, jeder ein Objekt mit einem `kind`, wie das `stream` jeder LumiScan-Anwendung sie hat. Diese Anwendung hat noch keine: Lassen Sie es weg oder leer (`[]`). Ein Schritt startet das Modul außerhalb des Stream-Modus, mit einer Warnung im Protokoll; das Speichern behält ihn bei. |

`control/subscribe/execute` und `control/unsubscribe/execute` schreiben alle fünf.

Gut zu wissen:

- Die Datei wird einmal gelesen, wenn das Modul beim Start der Anwendung wiederhergestellt wird: ein Modul in der gespeicherten Modulliste oder `module-1` auf einer neuen Installation. Von Hand an der Datei vorgenommene Änderungen werden beim nächsten Start wirksam.
- Ein mit `system/create-module` angelegtes Modul startet mit ausgeschaltetem Stream, ohne Quelle, mit einer Warteschlangengröße von `1` und ausgeschaltetem `keep-latest-output`, unabhängig davon, was eine Datei seines Namens enthält. Was es von da an anwendet, wird in dieser Datei gespeichert.
- Damit ein Modul und sein Stream nach einem Neustart wieder da sind, speichern Sie auch die Modulliste mit `system/save-current-modules`. Das Speichern einer Liste, die ein Modul nicht mehr nennt, löscht die Datei dieses Moduls und mit ihr seine Stream-Einstellungen. Siehe [Modulverwaltung](https://docs.hdvisionsystems.com/de/lumiscan-template-finder-de/1.1.0/lumiscan-template-finder/module-management.html).
- Ein Wert, der nicht verwendet werden kann, wird ignoriert und protokolliert: ein `enable` oder `keepLatestOutput`, das nicht `true` oder `false` ist, eine `address` oder ein `tag`, das kein String ist, eine `queueSize` außerhalb von `1` bis `64` (`1` wird verwendet). Stream-Modus ohne `address` wird ignoriert: Das Modul startet außerhalb des Stream-Modus.
- Das Element `subscriptions` früherer Versionen wird nicht mehr gelesen, und das Modul protokolliert, dass es umgezogen ist: Geben Sie die Quelle als `address` an.

> [!WARNING]
> Fügen Sie `<module-id>.json` keine Kommentare hinzu. Der Stream liest eine Datei mit Kommentaren, aber die Eingaben des Moduls werden dann beim Start nicht wiederhergestellt: Das Protokoll meldet die Datei als nicht lesbar.

## Die Warteschlangengröße {#queue-size}

`control/subscribe/input/queue-size` legt fest, wie viele Bilder warten dürfen, während ein Bild durchsucht wird: `1` bis `64`, standardmäßig `1`. Sie wird als `stream.queueSize` gespeichert, und `setting/stream/queue-size` zeigt den verwendeten Wert. Ein Bild, das eintrifft, wenn so viele warten, drängt das älteste von ihnen hinaus, was in `statistics/skipped-frames` gezählt wird. Eine neue Warteschlangengröße gilt ab dem nächsten eintreffenden Bild, ohne neues Abonnement.

| Warteschlangengröße | Wirkung |
| --- | --- |
| 1 (Standard) | Das Modul durchsucht das neueste Bild. Es fällt nie zurück; ist die Suche langsamer als die Kamera, überspringt es Bilder. |
| Mehr als 1 | Kurze Bildfolgen werden vollständig durchsucht, und weniger Bilder werden übersprungen. Ist die Suche über längere Zeit langsamer als die Kamera, fällt das Modul zurück: Es durchsucht Bilder, die bis zu so viele Suchen alt sind. Jedes wartende Bild hält ein ganzes Bild im Speicher. |

## Die neueste Ausgabe behalten {#keep-latest-output}

Mit `control/subscribe/input/keep-latest-output` `true` - angewendet durch `control/subscribe/execute`, gespeichert als `stream.keepLatestOutput` - schreibt das Modul jedes Stream-Ergebnis zusätzlich auf `find-template/output/result`, so wie `find-template/execute` es schreibt, sobald das Ergebnis auf `control/subscribe/output/stream/result` veröffentlicht ist. Ein Client, der `find-template/output/result` liest, hat dann das Ergebnis des neuesten Bilds, ohne den Stream zu abonnieren. `status-code` und `status-text` werden nicht geschrieben: Sie behalten, was der letzte Aufruf von `find-template` dort hinterlassen hat. Es kostet eine Kopie jedes Ergebnisses. Standardmäßig aus.

## find-template bei laufendem Stream {#while-streaming}

Der Stream und `find-template` verwenden dieselben Eingaben, und sie laufen auf einem Modul nie gleichzeitig:

- Ein Bild, das eintrifft, während `find-template` läuft, wartet, bis die Methode abgeschlossen ist. Es wird verzögert, nicht als fehlgeschlagen gewertet.
- Ein Aufruf von `find-template/execute`, während ein Bild durchsucht wird, antwortet mit belegt: `output/status-code` ist `-1`, der Schreibvorgang antwortet mit `TooManyOperations` (ctrlX: `DL_TOO_MANY_OPERATIONS`), und nichts wird getan. `output/result` behält seinen Wert, wie bei jedem belegten Aufruf (siehe [Eine Methode ausführen](https://docs.hdvisionsystems.com/de/lumiscan-template-finder-de/1.1.0/lumiscan-template-finder/execute-a-method.html)). Bei einer streamenden Kamera passiert das häufig. Stoppen Sie den Stream, bevor Sie die Methode aufrufen, oder rufen Sie sie erneut auf.
- `system/remove-module` antwortet ebenfalls mit belegt (`-1`), während ein Bild dieses Moduls durchsucht wird. Stoppen Sie zuerst den Stream. Das Entfernen eines Moduls stoppt seinen Stream.
- `system/create-template` hat eine eigene Sperre und wird vom Stream nicht aufgehalten.

Andere Module sind nicht betroffen: Jedes Modul hat seine eigene Sperre und seinen eigenen Stream.

## Einschränkungen {#limitations}

- Der Stream wurde nur unter Windows mit LumiScan Keryx und simulierten Bildern getestet. Er wurde nicht unter Linux - auf ctrlX OS oder Ubuntu -, auf dem ctrlX Data Layer oder mit einer echten Kamera verifiziert.
- LumiScan Cockpit zeichnet die Ergebnisse des Streams noch nicht.
- Von Hand an der Einstellungsdatei vorgenommene Änderungen werden beim nächsten Start der Anwendung wirksam.
- Der Hash umfasst jede Eingabe, die die Suche liest. Er ändert sich bei manchen Änderungen, die ein Ergebnis nicht verändern.
