How To: Read a Part Marking from a Camera Image
Reading a printed part number off a camera image, from a fresh installation to a setting you can put into production.
The example is a six-digit part number printed on a label. Adapt the character set and the layout to your marking as you go.
Before you start
-
LumiScan Cam Driver, or another image source, running on the same device - the same ctrlX CORE or ctrlX IPC, or the same PC - and delivering images.
-
Its image node address to hand, e.g.
hdvisionsystems/lumiscan-cam-driver/camera1/output/image. -
A part in front of the camera, with the marking in shot, in focus and well lit.
1. Point the reader at the camera
write hdvisionsystems/lumiscan-text-reader/module-1/read-text/input/input-image-address
= "hdvisionsystems/lumiscan-cam-driver/camera1/output/image"
2. Take a first reading
Leave everything else at its default and run it:
write .../module-1/read-text/execute read .../module-1/read-text/output/status-code -> 1 read .../module-1/read-text/output/status-text read .../module-1/read-text/output/result
A negative status code means it did not run - status-text says why. -3 is almost always a wrong
image address.
At this point the reading is usually poor: too many words, some of them nonsense picked out of the background. That is expected, and the next three steps fix it.
3. Crop to the marking
Find the pixel coordinates of the label in the image - on ctrlX OS the ctrlX camera view will show them - and set a region a little larger than the text:
write .../input/crop/startX = 620 write .../input/crop/startY = 310 write .../input/crop/width = 260 write .../input/crop/height = 90
Run it again. Most of the spurious words should be gone.
|
This is the step that helps most, and it also makes every reading faster. If the part can shift between cycles, make the crop large enough to cover the whole range it can occupy - a marking that drifts outside the crop reads as nothing, which is a better failure than reading as something wrong. |
4. Restrict the character set
A six-digit part number contains only digits, so say so:
write .../input/characters/mode = "DIGITS"
This is what stops 0 being read as O and 5 as S. If the number also contains letters, use
UPPERCASE_LETTERS with allow = "0123456789" instead, or CUSTOM with allow set to exactly the
characters your marking can contain.
5. Tell it what it is looking at
One line of print in a tight crop:
write .../input/layout = "SINGLE_LINE"
Run it again. output/result.text should now be the part number and nothing else.
6. Choose a confidence threshold
Run five or ten known-good parts and note mean_score from each result, and the individual
words[].score.
Correct readings on a decent image score well above 0.8. Set the threshold below your worst
known-good reading and above the noise:
write .../input/min-score = 0.7
|
|
7. Save the settings
Nothing above survives a restart until you save it:
write hdvisionsystems/lumiscan-text-reader/system/save-module-inputs/input/module-id = "module-1" write hdvisionsystems/lumiscan-text-reader/system/save-module-inputs/execute
8. Wire it into the control program
Per cycle:
-
Write
read-text/execute- a blocking call, so there is no ready flag to poll. -
Check
output/status-code. Negative means the reading failed and produced nothing. -
Read
output/result. -
Check
word_countis 1 andwords[0].scoreis acceptable, then comparewords[0].textagainst the expected part number.
Read the result before triggering the next reading: the next execute clears it.
Troubleshooting
The problems you can meet while setting up a reading are described step by step in Troubleshooting: