Reading Accurately
OCR does not fail cleanly. A barcode either decodes or does not; text always comes back with something, and a misread looks exactly like a correct read until somebody checks it.
Five settings decide whether what comes back can be trusted. They matter roughly in this order.
1. Crop to the text
input/crop is the most effective setting here, and the one most often left at its default.
A full 1920x1080 frame containing a 200x60 label gives the engine an enormous amount of background to find text in - and it finds some: edges of the part, shadows, the conveyor. Those become low-scoring words that pad the reading, and they push the layout analysis toward "this is a complicated page" when it is one line of print.
Crop tight around where the text will be. It is faster, and it removes a whole class of wrong answers instead of filtering them afterwards.
|
A crop that does not fit the image is refused, not trimmed to fit. A region silently shrunk would show up much later as words that are simply missing. |
2. If you cannot crop, merge the colour channels
input/preprocess exists for one failure, and it is a nasty one: a colour frame in which a
photograph or other colourful scenery shares the image with the text can come back with no words at
all. Not garbled - empty, while status-code reports success. That is indistinguishable from an
image with no text in it, so it does not look like a setting to change; it looks like the camera is
pointed at the wrong thing.
Measured on one such frame - a 300x168 capture, a parrot photograph on the left, a title on a dark panel on the right:
preprocess |
Read |
|---|---|
|
nothing at all |
|
|
|
|
No layout and no engine rescues the first row - all 24 combinations of the two return nothing.
What defeats the engine is how it reduces a colour image before reading it, not the size of the
text: the same frame flattened to grey reads perfectly, and so does the colour frame cropped to the
panel.
|
Crop first. Cropping fixes this case in colour, costs nothing, and helps for all the reasons above.
Reach for |
GRAYSCALE is the one to use. BINARIZE_OTSU additionally forces every pixel to black or white, and
is worth trying only if GRAYSCALE did not help: it discards the smooth edges the engine reads
character shapes from, and on the frame above it reads Title 01 The where GRAYSCALE reads
Title OF The.
|
Neither setting invents text. On a frame with no text in it - the photograph alone, or a flat grey field - all three settings return nothing, so turning this on cannot manufacture a reading. |
3. Restrict the character set
input/characters/mode picks a set, allow adds to it, and deny removes from it.
The classic OCR errors are all substitutions between character classes: O/0, I/1/l, S/5,
B/8, Z/2. A part number that is only ever digits, read with mode = DIGITS, cannot produce
any of them. This is nearly free accuracy and costs one setting.
| Marking | Setting |
|---|---|
Numeric part or batch number |
|
Upper-case alphanumeric code |
|
Date code with separators |
|
Anything with a fixed alphabet |
|
Free text, human readable |
|
|
An empty character set is refused. |
4. Match the layout to what you are looking at
input/layout tells the engine how much structure to look for. The default is SINGLE_BLOCK,
because a cropped label is one block of text.
| Value | Use for |
|---|---|
|
A cropped label - the default |
|
One line of print, nothing else in the crop |
|
One part number, one code |
|
One character, e.g. a cavity or station mark |
|
One line, with no attempt to find structure at all |
|
Several blocks in unknown positions |
|
Text scattered across the frame with no layout |
|
As above, and work out the orientation as well |
|
The shapes their names describe |
Narrower is better when you know what you are looking at: telling the engine "this is one word" stops it inventing a second one.
|
The |
5. Set a confidence threshold
input/min-score is the confidence a word must reach to appear in the word list. It defaults to
0, which reports everything, including guesses the engine has almost no faith in.
That default is deliberate - a fresh installation should show you what it can see rather than silently hide most of it - but it is not a production setting.
To choose one:
-
Run a few known-good parts with
min-scoreat 0. -
Look at
mean_scoreand the individual word scores in the result. -
A correct reading on a decent image scores well above 0.8; the spurious words a loose crop picks up usually sit below 0.5.
-
Set the threshold in the gap, closer to the correct readings than to the noise.
min_score is reported back in the result, so a reader looking at a short word list can tell a
strict threshold from a bad image.
What this does not fix
-
Poor contrast, glare, or a part out of focus. No setting recovers text the camera did not capture. Fix the lighting.
-
Dot-matrix and laser-etched marking. These defeat the
LSTMengine more often than printed text;engine = LEGACYsometimes does better and is worth trying first. -
A part that moved. The reader has no idea where the label should be. If it drifts outside the crop the reading is empty rather than wrong - which is the better failure, and another reason to crop.