---
title: "How To: Read a Part Marking from a Camera Image"
product: "LumiScan Text Reader"
component: "lumiscan-text-reader"
version: "1.1.0"
display_version: "1.1.0.6"
latest_version: true
language: "en"
url: "https://docs.hdvisionsystems.com/en/lumiscan-text-reader/1.1.0/how-tos/read-a-part-marking-from-a-camera-image.html"
---

# How To: Read a Part Marking from a Camera Image – LumiScan Text Reader

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.

> [!TIP]
> 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
```

> [!NOTE]
> `min-score` filters `words[]` only; `text` is always the engine’s full output. Check `word_count` rather than `text` when you need to know whether the reading was good.

## 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:

1. Write `read-text/execute` - a blocking call, so there is no ready flag to poll.
2. Check `output/status-code`. Negative means the reading failed and produced nothing.
3. Read `output/result`.
4. Check `word_count` is 1 and `words[0].score` is acceptable, then compare `words[0].text` against 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](https://docs.hdvisionsystems.com/en/lumiscan-text-reader/1.1.0/troubleshooting.html):

- [Status code -3 (image cannot be read)](https://docs.hdvisionsystems.com/en/lumiscan-text-reader/1.1.0/troubleshooting.html#faq-status-minus-3)
- [Status code -2 (a setting is unusable)](https://docs.hdvisionsystems.com/en/lumiscan-text-reader/1.1.0/troubleshooting.html#faq-status-minus-2)
- [Status code -7 (OCR engine could not start)](https://docs.hdvisionsystems.com/en/lumiscan-text-reader/1.1.0/troubleshooting.html#faq-status-minus-7)
- [The reading is empty although the text is clearly visible in a colour image](https://docs.hdvisionsystems.com/en/lumiscan-text-reader/1.1.0/troubleshooting.html#faq-empty-colour-image)
- [Status code 1, but no words](https://docs.hdvisionsystems.com/en/lumiscan-text-reader/1.1.0/troubleshooting.html#faq-empty-reading)
- [Digits are read as letters (O for 0, S for 5)](https://docs.hdvisionsystems.com/en/lumiscan-text-reader/1.1.0/troubleshooting.html#faq-digits-letters)
- [The reading contains extra words from the background](https://docs.hdvisionsystems.com/en/lumiscan-text-reader/1.1.0/troubleshooting.html#faq-extra-words)
- [The text is read in another language than input/language](https://docs.hdvisionsystems.com/en/lumiscan-text-reader/1.1.0/troubleshooting.html#ts-wrong-language)
- [Reading is too slow](https://docs.hdvisionsystems.com/en/lumiscan-text-reader/1.1.0/troubleshooting.html#faq-reading-too-slow)
- [Dot-matrix or laser-etched marking reads badly](https://docs.hdvisionsystems.com/en/lumiscan-text-reader/1.1.0/troubleshooting.html#faq-dot-matrix)
