Doku: vierte Funktion "Zählen" im README ergänzt

Funktionstabelle, Ablaufbeschreibung, Aufbau-Tabelle (threshold.js,
count-objects.js), Testzahl (165), neuer Grenzen-Abschnitt (beruehrende/
gestapelte Teile, ungleichmaessige Ausleuchtung, geringer Kontrast, stark
unterschiedliche Teilegroessen) sowie ein Geraete-Pruefpunkt fuer "Zählen".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-29 15:48:04 +02:00
co-authored by Claude Opus 5
parent 8c761c6fb5
commit ffb2409c24
+134 -44
View File
@@ -4,10 +4,13 @@ Browser-App, die per Handykamera gebrauchte Server-RAM-Module erkennt und
beim physischen Sortieren am Tisch anleitet: Modul vor die Kamera halten, die
App nennt den Stapel.
Vor dem Scannen wählt der Nutzer eine von drei Funktionen — Strichcode,
QR-Code oder Text erkennen (siehe „Funktionsweise" unten). Jede Funktion nutzt
ausschließlich ihre eigene Quelle; anders als früher weicht die App nicht mehr
automatisch auf Texterkennung aus, wenn kein Code gefunden wird.
Vor dem Scannen wählt der Nutzer eine von vier Funktionen — Strichcode,
QR-Code, Text erkennen oder Zählen (siehe „Funktionsweise" unten). Jede
Funktion nutzt ausschließlich ihre eigene Quelle; anders als früher weicht die
App nicht mehr automatisch auf Texterkennung aus, wenn kein Code gefunden
wird. Die vierte Funktion, „Zählen", gehört nicht zum eigentlichen Sortieren:
Sie bucht nichts, sondern zeigt beim Auslegen von Kleinteilen (z. B.
Festplattenschrauben) fortlaufend deren Anzahl an.
Zwei Module gelten als zusammengehörig, wenn sie denselben Barcode-Inhalt
tragen — ein Barcode ist exakt gelesen, das ist der zuverlässigste Maßstab.
@@ -57,16 +60,17 @@ keine Daten verlassen das Gerät.
## Funktionsweise
0. **Funktion wählen.** Vor dem ersten Scan (und jederzeit erneut über die
antippbare Anzeige in der Scan-Ansicht) wählt der Nutzer eine von drei
antippbare Anzeige in der Scan-Ansicht) wählt der Nutzer eine von vier
Funktionen. Kennung, Beschriftung, gelesene Codearten und Verhalten stehen
ausschließlich in `src/scan-modes.js` — es gibt keine zweite Stelle, an der
das steht:
| Funktion | Liest | Laufende Suche | Texterkennung |
| Funktion | Liest | Laufende Suche/Zählung | Texterkennung |
|---|---|---|---|
| **Strichcode** | Code128, Code39, Code93, ITF, EAN-13, EAN-8, UPC-A, UPC-E, Codabar | ja | nein |
| **QR-Code** | QRCode, MicroQRCode, RMQRCode, DataMatrix, Aztec, PDF417 | ja | nein |
| **Strichcode** | Code128, Code39, Code93, ITF, EAN-13, EAN-8, UPC-A, UPC-E, Codabar | ja (Codesuche) | nein |
| **QR-Code** | QRCode, MicroQRCode, RMQRCode, DataMatrix, Aztec, PDF417 | ja (Codesuche) | nein |
| **Text erkennen** | keine Codes | nein | ja, auf Knopfdruck |
| **Zählen** | keine Codes | ja (Zählung, keine Buchung) | nein |
„QR-Code" heißt auf Wunsch des Auftraggebers „QR-Code", liest aber bewusst
nicht nur QR-Varianten, sondern auch DataMatrix, Aztec und PDF417. Der
@@ -90,17 +94,21 @@ keine Daten verlassen das Gerät.
verschwindet.
Liegt beim Start eine gesicherte Sitzung vor, erscheint zuerst die Frage
nach dem Fortsetzen (siehe Punkt 5 unten) und erst danach die Funktionswahl
nach dem Fortsetzen (siehe Punkt 6 unten) und erst danach die Funktionswahl
— die Kamera startet in jedem Fall erst, nachdem beides geklärt ist.
Technisch bekommen „Strichcode" und „QR-Code" eine Texterkennung
hineingereicht, die sofort leeren Text liefert, ohne Tesseract anzustoßen;
„Text erkennen" bekommt eine Barcode-Dekodierung hineingereicht, die sofort
eine leere Liste liefert (`buildRecognitionAdapters` in
`src/scan-recognition.js`). Die Erkennungs-Pipeline selbst (`src/pipeline.js`,
Punkte 14 unten) bleibt dabei unverändert und kennt keine Funktionen — die
drei Funktionen unterscheiden sich ausschließlich darin, welche Adapter ihr
übergeben werden.
eine leere Liste liefert; „Zählen" bekommt beides leer hineingereicht
(`buildRecognitionAdapters` in `src/scan-recognition.js`). Die
Erkennungs-Pipeline selbst (`src/pipeline.js`, Punkte 13 und 5 unten)
bleibt dabei unverändert und kennt keine Funktionen — die drei
code-/textbasierten Funktionen unterscheiden sich ausschließlich darin,
welche Adapter ihr übergeben werden. „Zählen" ruft diese Pipeline im
normalen Betrieb gar nicht erst auf (siehe Punkt 4 unten) — es gibt dort ja
nichts zu buchen, das leere Adapterpaar dient nur als Absicherung für den
seltenen Ersatzweg ohne Kamera (Punkt 7).
1. **Barcode-Dekodierung** (nur in „Strichcode" und „QR-Code"). Die zur
Funktion gehörenden Codearten werden laufend aus dem Kamerabild dekodiert
(`zxing-wasm`, `decodeBarcodes` in `src/barcode.js` bekommt die Codearten
@@ -163,18 +171,44 @@ keine Daten verlassen das Gerät.
auszublenden wie in den beiden Barcode-Funktionen (`showResult` in
`src/ui/result-overlay.js`). Der Rohtext jedes Eintrags lässt sich später
auch in der Sitzungsliste nachlesen.
4. **Stapel-Zuweisung.** Grün (Barcode) und Gelb (OCR) laufen ohne Eingabe
4. **Zählen** (ausschließlich in Funktion „Zählen"). Reine Anzeige, ohne
jeden Bezug zur Sitzung: Solange die Kamera läuft, wird der Zielrahmen
mehrmals pro Sekunde ausgewertet und die Anzahl der darin gefundenen
Fundstücke groß im Bild eingeblendet (`countObjects` in
`src/count-objects.js`, aufgerufen über denselben Zeitgeber/dieselbe
Überlappungssperre wie die Barcode-Dauersuche — siehe
`continuousSearchLoop` in `src/main.js`). Es gibt in dieser Funktion
keinen „Modul scannen"-Knopf, keine Treffer-Rückmeldung und keine
Stapel-Zuweisung; die Zahl wird nirgends gespeichert, nicht einmal
flüchtig für die Dauer der Sitzung.
Kein Bilderkennungsmodell: Der Ausschnitt wird über denselben
**Otsu-Schwellwert** wie die Texterkennung in zwei Klassen geteilt
(`threshold.js`, aus `ocr.js` herausgezogen, damit beide Funktionen sich
dieselbe Schwellwertbestimmung teilen, ohne dass die reine Zählung an
`tesseract.js` hinge). Die flächenmäßig **kleinere** der beiden Klassen
gilt als Objekt — die ausgelegten Teile belegen so gut wie immer weniger
Fläche als der Untergrund, unabhängig davon, ob sie heller oder dunkler
sind als dieser; der Nutzer muss nichts einstellen. Anschließend werden
zusammenhängende Objektflächen ermittelt (Connected-Component-Labeling
mit einer eigenen Arbeitsliste statt Rekursion, damit ein rund eine
Million Bildpunkte großer Ausschnitt nicht in den Stapelüberlauf läuft),
winzige Flächen als Rauschen verworfen und auffällig große Flächen
(mehrere berührende Teile) auf ein Vielfaches der typischen
Einzelteilgröße hochgerechnet. Details und Begründung der verwendeten
Schwellen: `.superpowers/sdd/counting-report.md`.
5. **Stapel-Zuweisung.** Grün (Barcode) und Gelb (OCR) laufen ohne Eingabe
durch; nur bei roter Konfidenz (nichts Eindeutiges erkannt, widersprüchliche
Barcodes oder widersprüchliche unbekannte Barcodes ohne jede OCR-Kapazität)
oder mehrdeutiger Stapelzuordnung fragt die App nach.
5. **Sitzungsfortsetzung beim Start.** Findet die App beim Laden eine in
6. **Sitzungsfortsetzung beim Start.** Findet die App beim Laden eine in
`localStorage` gesicherte, nicht leere Sitzung vor, wird sie nicht
stillschweigend übernommen, sondern zur Fortsetzung oder zum Verwerfen
angeboten (`askResumeSession` in `src/ui/resume-dialog.js`, verdrahtet über
`initResumeOffer()` in `src/main.js`). Erst „fortsetzen“ stellt Stapel,
Zähler und die „Zuletzt“-Zeile wieder her; „verwerfen“ löscht den
gesicherten Stand und die App startet leer.
6. **Ersatzweg ohne Kamera.** Lässt sich die Kamera nicht starten (z. B.
7. **Ersatzweg ohne Kamera.** Lässt sich die Kamera nicht starten (z. B.
verweigerte Berechtigung), bleibt die App bedienbar: eine dauerhaft
sichtbare Schaltfläche „Bild auswählen“ öffnet stattdessen die native
Dateiauswahl (`setFilePickerVisible` in `src/ui/scan-view.js`). Die App
@@ -213,22 +247,26 @@ korrekt funktioniert.
npm test
```
154 Tests, alle grün (Stand dieses Dokuments). Getestet werden ausschließlich
165 Tests, alle grün (Stand dieses Dokuments). Getestet werden ausschließlich
die reinen Module ohne Browser-Zugriff: Teilenummer-Decoder, Spec-Normalisierung
und toleranter Vergleich, OCR-Bildaufbereitung (Otsu-Schwellwert) und
-Feldextraktion, Stapel-Zuweisung, die Erkennungs-Pipeline samt Zeitgrenzen,
Mehrdeutigkeitsbehandlung und dem additiven OCR-Rohtext (`rawText` wird nur
zurückgegeben, wenn die Texterkennung tatsächlich lief, und beeinflusst
nachweislich nie die Stapelzuordnung), die Sitzungssicherung samt Prüfung
eines wiederhergestellten Zustands (einschließlich `entry.rawText`), die drei
Scan-Funktionen (`scan-modes.js`
Codearten je Funktion, DataMatrix/Aztec/PDF417 in „QR-Code") sowie die je Funktion
und toleranter Vergleich, OCR-Bildaufbereitung (Otsu-Schwellwert, jetzt in
`threshold.js`) und -Feldextraktion, Stapel-Zuweisung, die Erkennungs-Pipeline
samt Zeitgrenzen, Mehrdeutigkeitsbehandlung und dem additiven OCR-Rohtext
(`rawText` wird nur zurückgegeben, wenn die Texterkennung tatsächlich lief,
und beeinflusst nachweislich nie die Stapelzuordnung), die Sitzungssicherung
samt Prüfung eines wiederhergestellten Zustands (einschließlich
`entry.rawText`), die vier Scan-Funktionen (`scan-modes.js` Codearten je
Funktion, DataMatrix/Aztec/PDF417 in „QR-Code") sowie die je Funktion
tatsächlich aufgerufenen Adapter (`scan-recognition.js` — Texterkennung läuft
nachweislich nie in „Strichcode"/„QR-Code", Barcode-Dekodierung nachweislich
nie in „Text erkennen"). Kamera, Barcode-/OCR-Adapter selbst, die
Auswahl-Oberfläche und die Verdrahtung in `main.js` laufen nur im echten
Browser und werden dort manuell geprüft (siehe „Am Gerät noch zu prüfen"
unten) — `node --test` kennt kein DOM.
nie in „Text erkennen"/„Zählen"). Dazu die Zähl-Berechnung selbst
(`count-objects.js` — leeres Bild, einzelne und mehrere getrennte Flächen,
verworfenes Rauschen, Hochrechnung berührender Teile ohne ein nur leicht
größeres Einzelteil zu verdoppeln, helle wie dunkle Objekte, ein Bild ohne
Bildpunkte). Kamera, Barcode-/OCR-Adapter selbst, die Auswahl-Oberfläche und
die Verdrahtung in `main.js` laufen nur im echten Browser und werden dort
manuell geprüft (siehe „Am Gerät noch zu prüfen" unten) — `node --test` kennt
kein DOM.
## Produktion
@@ -293,14 +331,16 @@ worauf du bei der Veröffentlichung achten solltest.
| `src/ocr-extract.js` | OCR-Rohtext → Spec-Felder |
| `src/session.js` | Stapel halten, vorschlagen, buchen, umsortieren, zurücknehmen — inklusive der aus den Einträgen abgeleiteten, je Stapel bekannten Barcode-Inhalte (`stack.codes`), die vor dem Vergleich der technischen Angaben über die Zuordnung entscheiden, sofern diese Angaben nicht widersprechen |
| `src/pipeline.js` | Barcode → Teilenummer → OCR → Ampelfarbe, inkl. Zeitgrenzen, Mehrdeutigkeitsbehandlung und Kurzschluss über einen bereits bekannten Barcode-Inhalt (`deps.isKnownCode`) — kennt keine Scan-Funktionen; liefert zusätzlich (additiv) den ungefilterten OCR-Rohtext (`rawText`), leer, wenn keine Texterkennung lief |
| `src/scan-modes.js` | Die drei Scan-Funktionen (Strichcode, QR-Code, Text erkennen): Kennung, deutsche Beschriftung, gelesene Codearten, laufende Suche ja/nein, Texterkennung ja/nein — einzige Quelle, sowohl für die Auswahl-Oberfläche als auch für `main.js` |
| `src/scan-recognition.js` | Baut die an `recognize()` übergebenen Adapter anhand der gewählten Funktion: in „Strichcode"/„QR-Code" liefert die Texterkennung sofort leeren Text ohne Tesseract anzustoßen, in „Text erkennen" liefert die Barcode-Dekodierung sofort eine leere Liste ohne `zxing-wasm` anzustoßen |
| `src/scan-modes.js` | Die vier Scan-Funktionen (Strichcode, QR-Code, Text erkennen, Zählen): Kennung, deutsche Beschriftung, gelesene Codearten, laufende Suche ja/nein, Texterkennung ja/nein, laufende Zählung ja/nein — einzige Quelle, sowohl für die Auswahl-Oberfläche als auch für `main.js` |
| `src/scan-recognition.js` | Baut die an `recognize()` übergebenen Adapter anhand der gewählten Funktion: in „Strichcode"/„QR-Code" liefert die Texterkennung sofort leeren Text ohne Tesseract anzustoßen, in „Text erkennen" liefert die Barcode-Dekodierung sofort eine leere Liste ohne `zxing-wasm` anzustoßen, in „Zählen" liefern beide sofort leer (diese Funktion ruft `recognize()` im normalen Betrieb ohnehin nicht auf) |
| `src/threshold.js` | Otsu-Schwellwertbestimmung (Graustufen, Histogramm, Schwellwert) — reines Modul ohne Browser-Zugriff, aus `ocr.js` herausgezogen; gemeinsame Grundlage für `preprocess()` (ocr.js) und `countObjects()` (count-objects.js) |
| `src/count-objects.js` | Reine Berechnung für Funktion „Zählen": zählt zusammenhängende Objektflächen in einem Bildausschnitt (Otsu-Schwellwert aus `threshold.js`, flächenmäßig kleinere Klasse gilt als Objekt, Connected-Component-Labeling mit eigener Arbeitsliste, Rauschfilter, Hochrechnung berührender Teile über den Flächen-Median) |
| `src/storage.js` | Absturzschutz der laufenden Sitzung: sichert und lädt aus `localStorage`, verwirft beim Laden jeden in sich unstimmigen Zustand vollständig (siehe unten); `entry.rawText` ist wie `entry.codes` optional und wird bei Fehlen als leerer Rohtext wiederhergestellt |
| `src/camera.js` | Kamerastart, Einzelbildaufnahme (herunterskaliert, für die Dateiauswahl), Rahmenausschnitt in voller Auflösung (`grabFrameRegion`, für die laufende Barcode-Suche **und** für „Modul scannen" in „Text erkennen"), Bilddatei-Ersatzweg |
| `src/camera.js` | Kamerastart, Einzelbildaufnahme (herunterskaliert, für die Dateiauswahl), Rahmenausschnitt in voller Auflösung (`grabFrameRegion`, für die laufende Barcode-Suche, „Modul scannen" in „Text erkennen" **und** die laufende Zählung in „Zählen"), Bilddatei-Ersatzweg |
| `src/barcode.js` | Adapter zu `zxing-wasm`; `decodeBarcodes(imageData, formats)` bekommt die Codearten übergeben, ohne Angabe wie bisher (Code128 + DataMatrix) |
| `src/ocr.js` | Bildaufbereitung (Otsu) und Adapter zu `tesseract.js`; Zeichen-Whitelist deckt Groß- und Kleinbuchstaben, Ziffern sowie übliche Etiketten-Sonderzeichen ab |
| `src/ui/scan-view.js` | Scan-Ansicht: Kamera-Vorschau, antippbare Anzeige der gewählten Funktion (Wechsel), Scan-Knopf (nur in „Text erkennen" sichtbar), Stapel-Leiste, „Zuletzt"-Zeile, Ersatzweg-Schaltfläche bei fehlender Kamera |
| `src/ui/mode-dialog.js` | Vollbild-Auswahl der Scan-Funktion vor dem Start und beim Wechsel: drei große Flächen, eine je Funktion aus `src/scan-modes.js` |
| `src/ocr.js` | Bildaufbereitung (Otsu, über `threshold.js`) und Adapter zu `tesseract.js`; Zeichen-Whitelist deckt Groß- und Kleinbuchstaben, Ziffern sowie übliche Etiketten-Sonderzeichen ab |
| `src/ui/scan-view.js` | Scan-Ansicht: Kamera-Vorschau, antippbare Anzeige der gewählten Funktion (Wechsel), Scan-Knopf (nur in „Text erkennen" sichtbar), große Zählanzeige (nur in „Zählen" sichtbar), Stapel-Leiste, „Zuletzt"-Zeile, Ersatzweg-Schaltfläche bei fehlender Kamera |
| `src/ui/mode-dialog.js` | Vollbild-Auswahl der Scan-Funktion vor dem Start und beim Wechsel: vier große Flächen, eine je Funktion aus `src/scan-modes.js` |
| `src/ui/result-overlay.js` | Treffer-Rückmeldung (grün/gelb): blendet sich in „Strichcode"/„QR-Code" nach kurzer Zeit selbst aus; in „Text erkennen" bleibt sie stehen, zeigt den vollen OCR-Rohtext und wartet auf eine Eingabe, bevor sie schließt |
| `src/ui/ambiguous-dialog.js` | Rot-Dialog bei roter Konfidenz oder mehrdeutiger Stapelzuordnung |
| `src/ui/resume-dialog.js` | Dialog beim Start: gesicherte Sitzung fortsetzen oder verwerfen — läuft vor der Funktionswahl |
@@ -312,10 +352,11 @@ worauf du bei der Veröffentlichung achten solltest.
| `.vch/deploy.yaml` | Bau- und Startbefehl sowie Gesundheitspfad für die Hosting-Umgebung |
`spec`, `pn-decoder`, `ocr-extract`, `session`, `pipeline`, `storage`,
`scan-modes` und `scan-recognition` sind reine Funktionen ohne Browser-Zugriff
(kein `window`, `document` oder `localStorage` direkt) und deshalb vollständig
mit `node:test` prüfbar. `camera.js`, `barcode.js`, `ocr.js` und `src/ui/`
brauchen einen echten Browser und werden nur manuell geprüft.
`scan-modes`, `scan-recognition`, `threshold` und `count-objects` sind reine
Funktionen ohne Browser-Zugriff (kein `window`, `document` oder
`localStorage` direkt) und deshalb vollständig mit `node:test` prüfbar.
`camera.js`, `barcode.js`, `ocr.js` und `src/ui/` brauchen einen echten
Browser und werden nur manuell geprüft.
### Sitzungssicherung im Detail
@@ -390,6 +431,37 @@ Eintrag und fließt in keine Stapel-Berechnung ein.
Aufnahmen (Zeilenumbrüche, zusätzlich erkannte Wörter, Groß-/
Kleinschreibung, …) und würde als Gruppierungsmerkmal für praktisch jedes
Modul einen eigenen Stapel erzeugen.
- **Funktion „Zählen" ist eine Schätzung, keine exakte Zählung** — sie wird
ungenau, wenn eine der folgenden Bedingungen zutrifft:
- **Berührende oder gestapelte Teile.** Mehrere Teile, die sich berühren,
bilden eine einzige zusammenhängende Fläche. Die App rechnet diese über
die typische Einzelteilgröße (Median der gefundenen Flächen) auf ein
Vielfaches hoch, aber je unregelmäßiger sich die Teile überlappen
(z. B. drei Schrauben, die sich gegenseitig teilweise verdecken statt
sich nur zu berühren), desto ungenauer wird die hochgerechnete Fläche.
Liegen Teile übereinander gestapelt statt nebeneinander ausgelegt, sieht
die Kamera von oben nur die Fläche des obersten Teils — verdeckte Teile
werden nicht mitgezählt.
- **Ungleichmäßige Ausleuchtung.** Der Otsu-Schwellwert ist ein einziger,
fester Wert für den gesamten Ausschnitt. Fällt Licht sehr einseitig ein
(z. B. ein Teil des Rahmens hell, der Rest im Schatten), kann derselbe
Untergrund an einer Stelle über und an einer anderen Stelle unter dem
Schwellwert liegen — Teile im schlechter ausgeleuchteten Bereich werden
dann leicht übersehen oder der Untergrund selbst fälschlich als
Objektfläche gewertet.
- **Zu geringer Kontrast zum Untergrund.** Je ähnlicher sich Objekt- und
Untergrundhelligkeit sind, desto unschärfer die Trennung durch Otsu —
bei sehr geringem Kontrast können Teile am Rand verloren gehen oder mit
dem Untergrund verschmelzen.
- **Stark unterschiedlich große Teile.** Die Hochrechnung setzt voraus,
dass die meisten Fundstücke ungefähr gleich groß sind (der Median dient
als Maßstab für „ein Teil"). Liegen im selben Rahmen sowohl deutlich
größere als auch deutlich kleinere Teile derselben Sorte (oder gar
unterschiedliche Teile gemischt), kann die Rauschschwelle ein
tatsächliches kleines Teil verwerfen oder die Hochrechnung ein einzelnes
großes Teil als mehrere zählen.
- Details, die verwendeten Schwellenwerte und ihre Begründung stehen in
`.superpowers/sdd/counting-report.md`.
## Herstellertabellen erweitern
@@ -433,10 +505,11 @@ werden:
- Datei-Auswahl als Ersatzweg (ohne Kamera) öffnet den nativen Dialog und
hinterlässt keine leere Fläche im Layout.
**Funktionswahl (neu)**
- Erster Start ohne gesicherte Sitzung: Auswahl mit drei großen Flächen
(„Strichcode", „QR-Code", „Text erkennen") erscheint, *bevor* die Kamera
startet — kein Kamerabild sichtbar, solange keine Funktion gewählt ist.
**Funktionswahl**
- Erster Start ohne gesicherte Sitzung: Auswahl mit vier großen Flächen
(„Strichcode", „QR-Code", „Text erkennen", „Zählen") erscheint, *bevor* die
Kamera startet — kein Kamerabild sichtbar, solange keine Funktion gewählt
ist.
- Erster Start *mit* gesicherter Sitzung: erst die Frage „Gesicherte Sitzung
gefunden" (fortsetzen/verwerfen), erst danach die Funktionswahl.
- „Strichcode" wählen: laufende Suche erkennt Code-128/Code-39/EAN/UPC/…,
@@ -488,6 +561,23 @@ werden:
dass die Vorbereitung tatsächlich nur einmal läuft)? In Funktion „Text
erkennen" darf dieses Laden dagegen gar nicht erst anlaufen, da dort nie
`decodeBarcodes` aufgerufen wird.
**Zählen (neu)**
- „Zählen" wählen, Kamera auf ausgelegte Kleinteile richten (z. B. silberne
Festplattenschrauben auf dunklem Untergrund): Eine große Zahl erscheint im
Bild und aktualisiert sich laufend, ohne dass etwas angetippt werden muss.
Kein „Modul scannen"-Knopf, keine Treffer-Rückmeldung, kein roter Dialog,
keine Stapel-Zuweisung — der Zielrahmen bleibt sichtbar und zeigt weiterhin,
was gezählt wird.
- Die angezeigte Zahl aus normalem Bedienabstand (Armlänge) lesbar prüfen.
- Ein paar Teile wegnehmen bzw. hinzufügen, während die Kamera läuft: Die
Zahl folgt ohne spürbare Verzögerung.
- Zugänge zur Sitzungsliste und zum Funktionswechsel bleiben auch in dieser
Funktion erreichbar (Anzeige der Funktion antippen, Stapel-Leiste antippen).
- Gegenprobe der Grenzen (siehe „Grenzen" oben): Teile eng aneinanderlegen
(Hochrechnung), Teile stapeln (nur oberste Schicht zählt), einseitige
Beleuchtung, geringer Kontrast zum Untergrund — beobachten, wo die Zahl
spürbar daneben liegt, bisher nur an synthetischen Testbildern geprüft, nie
an einem echten Foto.
- Verbindung während des allerersten Scans einer Sitzung unterbrechen (WASM
lädt per CDN), danach mit wiederhergestellter Verbindung erneut scannen:
Das muss einen echten neuen Ladeversuch auslösen statt dauerhaft mit