Barcode-Teilenummer allein genuegt fuer Gruen, bekannter Code ueberspringt OCR
Der Teilenummer-Decoder kennt bislang nur das Samsung-Schema; ein Hynix-Modul mit einwandfrei gelesenem, aber unbekanntem Barcode-Schema endete deshalb in Rot. Zum Sortieren muss keine Kapazitaet bekannt sein - eine exakt gelesene Teilenummer genuegt, um ein Modul wiederzuerkennen. recognize() greift jetzt erst dann auf Rot zurueck, wenn auch die Texterkennung keine Kapazitaet und keine eindeutige Teilenummer liefert; die bestehende Vorsicht bei widerspruechlichen unverwertbaren Barcodes bleibt dabei unangetastet. Zusaetzlich kann recognize() jetzt ueber deps.isKnownCode (optional) erfahren, dass ein gelesener Code bereits einem Stapel bekannt ist, und die bis zu 20 Sekunden dauernde Texterkennung dann ueberspringen. Ohne diese Abhaengigkeit verhaelt sich die Pipeline unveraendert. recognize() liefert zusaetzlich die rohen gelesenen Barcode-Inhalte (codes), damit session.js sie einem Stapel zuordnen kann.
This commit is contained in:
+31
-6
@@ -55,7 +55,15 @@ function allCompatible(specs) {
|
||||
* deps.runOcr sind erforderlich. deps.barcodeTimeoutMs und deps.ocrTimeoutMs
|
||||
* sind optional und ueberschreiben die eingebauten Obergrenzen - fuer Tests,
|
||||
* die einen haengenden Adapter simulieren, ohne tatsaechlich zu warten.
|
||||
* @returns {Promise<{spec: object, source: 'barcode'|'ocr'|'none', confidence: 'green'|'yellow'|'red'}>}
|
||||
* deps.isKnownCode ist optional: eine Funktion (code: string) => boolean,
|
||||
* mit der der Aufrufer prueft, ob ein roher Barcode-Inhalt bereits einem
|
||||
* Stapel bekannt ist. Ist einer der gelesenen Codes bekannt, steht die
|
||||
* Zuordnung fest und die Texterkennung wird uebersprungen. Fehlt die
|
||||
* Funktion, verhaelt sich die Pipeline wie ohne diese Optimierung.
|
||||
* @returns {Promise<{spec: object, source: 'barcode'|'ocr'|'none', confidence: 'green'|'yellow'|'red', codes: string[]}>}
|
||||
* codes sind die im Bild gelesenen rohen Barcode-Zeichenketten (koennen
|
||||
* neben der Teilenummer z.B. auch eine Seriennummer enthalten) - zur
|
||||
* Weitergabe an proposeAssignment/commitAssignment in session.js.
|
||||
*/
|
||||
export async function recognize(frame, deps) {
|
||||
const barcodeTimeoutMs = deps.barcodeTimeoutMs ?? DEFAULT_BARCODE_TIMEOUT_MS;
|
||||
@@ -91,7 +99,7 @@ export async function recognize(frame, deps) {
|
||||
}
|
||||
|
||||
if (usable.length === 1) {
|
||||
return { spec: usable[0], source: 'barcode', confidence: 'green' };
|
||||
return { spec: usable[0], source: 'barcode', confidence: 'green', codes };
|
||||
}
|
||||
if (usable.length > 1) {
|
||||
if (allCompatible(usable)) {
|
||||
@@ -101,10 +109,19 @@ export async function recognize(frame, deps) {
|
||||
// da alle uebrigen Felder aus derselben Teilenummer abgeleitet werden,
|
||||
// sind vertraegliche Treffer ohnehin gleich. Es gibt nichts aufzufuellen,
|
||||
// der erste Treffer genuegt.
|
||||
return { spec: usable[0], source: 'barcode', confidence: 'green' };
|
||||
return { spec: usable[0], source: 'barcode', confidence: 'green', codes };
|
||||
}
|
||||
// Mehrdeutigkeit zwischen verwertbaren Barcodes: nicht raten, Nutzer entscheidet.
|
||||
return { spec: emptySpec(), source: 'none', confidence: 'red' };
|
||||
return { spec: emptySpec(), source: 'none', confidence: 'red', codes };
|
||||
}
|
||||
|
||||
// Ist einer der gelesenen Codes bereits einem Stapel bekannt, steht die
|
||||
// Zuordnung fest (siehe proposeAssignment in session.js) - die bis zu
|
||||
// zwanzig Sekunden dauernde Texterkennung waere reine Zeitverschwendung.
|
||||
// Bei einem tatsaechlich neuen Modul (kein Code bekannt) laeuft sie wie
|
||||
// bisher, denn dort liefert sie die lesbare Beschriftung des neuen Stapels.
|
||||
if (typeof deps.isKnownCode === 'function' && codes.some((code) => deps.isKnownCode(code))) {
|
||||
return { spec: best, source: 'barcode', confidence: 'green', codes };
|
||||
}
|
||||
|
||||
const ocrResult = await safely(() => deps.runOcr(frame), '', ocrTimeoutMs);
|
||||
@@ -119,7 +136,15 @@ export async function recognize(frame, deps) {
|
||||
}
|
||||
|
||||
if (isUsable(merged)) {
|
||||
return { spec: merged, source: 'ocr', confidence: 'yellow' };
|
||||
return { spec: merged, source: 'ocr', confidence: 'yellow', codes };
|
||||
}
|
||||
return { spec: merged, source: 'none', confidence: 'red' };
|
||||
// Zum Sortieren muss keine Kapazitaet bekannt sein - eine exakt gelesene
|
||||
// Teilenummer genuegt, um ein Modul wiederzuerkennen. Sie ueberlebt bis
|
||||
// hierher nur, wenn genau ein unverwertbarer Code sie lieferte oder
|
||||
// mehrere sich einig waren (siehe 'best' oben) - bei widersprechenden
|
||||
// Codes bleibt merged.partNumber null und die Vorsicht damit erhalten.
|
||||
if (merged.partNumber !== null) {
|
||||
return { spec: merged, source: 'barcode', confidence: 'green', codes };
|
||||
}
|
||||
return { spec: merged, source: 'none', confidence: 'red', codes };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user