Release Notes: v1.1.0

First functioning release of LumiScan Text Reader. Earlier versions registered the application’s Data Layer nodes but returned a fixed placeholder result, so nothing below was usable before.

New

Text reading. <module>/read-text/execute reads the printed text in a camera image and reports it twice over: the whole text as the engine laid it out, and a per-word list carrying a confidence and a position for every word.

A choice of recognition engine, input/engine: the modern neural-network LSTM, the original pattern-matching LEGACY, both together, or DEFAULT to let the engine choose. LEGACY is worth trying on dot-matrix and laser-etched marking.

Twelve text layouts, input/layout, from SINGLE_CHAR up to whole-page analysis with orientation detection. The default SINGLE_BLOCK suits a cropped label.

A character set restriction, input/characters/mode with allow and deny. Reading a numeric part number with DIGITS removes the whole class of O/0 and S/5 substitutions rather than filtering them afterwards - the cheapest accuracy improvement available.

A confidence threshold, input/min-score, so a control program never sees a word the engine had little faith in. The result reports the threshold that was applied, so a short word list can be told apart from a bad image.

A region of interest per reading, input/crop, which is both the biggest accuracy improvement and the biggest speed improvement available.

Uploadable language models. English and the orientation model ship with the application, and you add more by uploading .traineddata files into …​/activeConfiguration/lumiscan-text-reader/tessdata. Uploading adds languages - the shipped ones are always searched as well, so English keeps working and you never copy our files anywhere. The file name is the language code, so there is nothing to look up: upload deu.traineddata and set input/language to deu. A model is usable on the very next reading, with no restart. system/tessdata-dirs shows every directory searched, system/languages what was found across them, and system/set-tessdata-dir points the upload directory somewhere else - a USB stick, for instance.

Several modules, each with its own settings and results, so one installation can watch several cameras. One licence covers ten modules.

A status on every operation: output/status-code and output/status-text, where a negative code always means the run failed and produced nothing.

Worth knowing

Text is not a code. An OCR reading always returns something, and a misread looks exactly like a correct reading. Set input/characters/mode and input/min-score before relying on one in production - see Reading Accurately.

An empty reading means no text was found, and nothing else. Every other reason a run could produce nothing - an unreachable camera, an unusable setting, an engine that could not start - is caught and reported as a negative status code. A reader that could not start reports -7 and says why, rather than looking like a working reader in front of a blank part.

A language that is not installed is replaced by English rather than refused. A reading validates the language up front and refuses an uninstalled one, naming what is available; and if a model disappears afterwards, output/result.language reports what was actually used. Read that field, not your own input, when you need to know how a reading was produced. See Language Models.

Every invalid input is reported at once, and each message names the node to change rather than an internal field name - min-score must be between 0 and 1, got 1.5.

The whole text is not filtered by the confidence threshold, only the word list is. They answer different questions and can legitimately disagree.