Counting barcode bars is a run-counting problem, not a pixel-summing problem. A black bar may occupy several image columns, and wider bars occupy more columns than narrower ones. This procedure is for extracting bar and space structure from an existing image or a camera acquisition workflow. You will select a scan band, convert it to a binary profile, measure consecutive runs, and check whether the count is stable enough to use.
Define what you need to count
For a linear barcode, a scanline must cross the bars approximately perpendicular to their long edges. If the bars are vertical, scan horizontally across image columns. Scanning vertically along a bar measures its height instead of its width.
Use an explicit binary convention throughout the workflow:
-
0means a black bar. -
1means a white space or white background. - A run is a maximal sequence of consecutive equal values.
- A transition occurs where adjacent values differ.
Summing a binary profile counts white pixels under this convention. Subtracting that sum from the profile length counts black pixels. Neither operation directly counts bars.
Also distinguish internal spaces from background. White runs before the first black bar and after the last black bar are not internal spaces. Keep those regions in the original image for decoding, but report them separately when describing the bar pattern.
This procedure applies to linear barcodes. A row through a matrix code does not represent its complete symbol structure.
Choose an image source you can inspect
An existing grayscale image is enough to develop the algorithm. Before changing hardware, inspect the original image at native resolution and confirm that individual narrow bars remain visibly separated.
For a new acquisition station, area scan cameras suit workflows where your software processes captured images. Fixed code readers are another route when decoded data is the main requirement. Check image access, image format, triggering, and available measurements before choosing either approach.
For a camera-based workflow, review the LS-CMR-0166.
- Sensor format
- 1/1.7"
- Interface
- USB3
- Resolution
- 12 MP
- Shutter
- Rolling
For a reader-based station, review the LS-CRD-0028.
- Interface
- Fast Ethernet
- Resolution
- 5 MP
- Sensor format
- 1/1.7"
- Shutter
- Global
The supplied catalog information does not establish whether a reader exports grayscale images or individual run widths. Confirm those capabilities rather than assuming that a successful decode exposes the underlying measurements.
Use the camera finder to narrow acquisition options. Keep acquisition requirements separate from the counting algorithm: changing hardware does not correct a profile taken through text or a label border.
Check sampling before adjusting thresholds
A narrow bar represented by too few pixels can disappear or change width after a small position shift. Threshold adjustments cannot recover structure that the image never resolved.
For planning, choose a target number of pixels across the narrowest module. A module is the basic width unit used by many linear barcode symbologies. Four pixels per module is a useful starting assumption for this example, not a universal acceptance requirement.
Suppose the horizontal field of view is 100 mm and the narrowest module is 0.25 mm. With a target of 4 pixels per module:
These are geometric sampling estimates. Focus, optical contrast, motion blur, and processing still determine whether adjacent edges remain distinguishable.
The explanation of object-space pixel size connects this calculation to magnification. Evaluate the acquired image before resizing it; interpolation can change edge positions and apparent run widths.
Prepare the scan band in numbered steps
-
Keep an unchanged source image. Perform counting on a separate region or copy. Preserve the complete symbol and its surrounding quiet zones for any later decoding operation. The guidance on cropping barcode images while preserving quiet zones explains why the counting region and decoding region should not be treated as interchangeable.
-
Correct orientation before selecting a tall band. Place the scan direction across the bars. With skew, an edge moves horizontally as you move down the image. Combining many rows can therefore smear narrow features. Correct orientation first, or use a shorter band. The guide to barcode deskew and angle ambiguity covers that separate operation.
-
Select the bar body, not the label boundary. Avoid printed text, damaged corners, label outlines, and unrelated graphics. Include the full bar pattern horizontally. A region that starts inside a bar creates a truncated width, while one that includes a dark label border may add a false bar.
-
Reduce the band to a grayscale profile. Start with a single clean row. If isolated image defects cause instability, try the median intensity at each column across a narrow band, such as 3–7 rows. A median can suppress sparse contamination, but it cannot repair damage present across most of the band. Check that skew has not shifted edges appreciably within it.
-
Apply an explicit threshold. For an ordinary grayscale image where dark values are smaller, assign
0below threshold and1at or above threshold. Start with a global threshold when bars and spaces have clearly separated intensities. Verify polarity visually rather than relying on a software function's foreground convention. -
Inspect the binary profile against the image. Every reported transition should correspond to a real bar edge. If the background intensity changes substantially across the symbol, improve illumination or evaluate background correction or a local threshold. Check those changes against the original image because local processing can also introduce false edges.
The guide to barcode preprocessing for blur and glare addresses image formation problems that should be resolved before trusting a count.
Count transitions and measure consecutive runs
Let the binary profile contain N samples, with N greater than zero. Compare each sample with its predecessor:
A worked profile makes the distinction clear. Consider this illustrative sequence, which is not intended to represent a complete encoded symbol:
111000011000111110011
Its run-length representation is:
(value, width in pixels)
(1, 3), (0, 4), (1, 2), (0, 3), (1, 5), (0, 2), (1, 2)
| Measurement | Arithmetic | Answer |
|---|---|---|
| Profile length | 3 + 4 + 2 + 3 + 5 + 2 + 2 | 21 pixels |
| Black pixels | 4 + 3 + 2 | 9 pixels |
| White pixels | 3 + 2 + 5 + 2 | 12 pixels |
| Black bars | Number of zero-valued runs | 3 bars |
| All white runs | Number of one-valued runs | 4 runs |
| Internal spaces | White runs between black bars | 2 spaces |
| Transitions | Adjacent value changes | 6 transitions |
| Total runs | 6 + 1 | 7 runs |
Dividing black-pixel count by an assumed bar width works only if every bar has that width. Variable-width patterns invalidate that shortcut. Run-length measurement retains both the number of bars and their individual widths.
Implement the profile and run counter
The following Python example accepts a rectangular grayscale band represented as rows of numeric intensities. It uses a column median, applies a supplied global threshold, and returns run measurements. It does not decode the symbol or determine an appropriate threshold automatically.
from statistics import median
def count_bar_structure(gray_band, threshold):
if len(gray_band) == 0 or len(gray_band[0]) == 0:
raise ValueError("The scan band must not be empty")
width = len(gray_band[0])
if any(len(row) != width for row in gray_band):
raise ValueError("All rows must have equal width")
profile = [
median(row[x] for row in gray_band)
for x in range(width)
]
bits = [0 if value < threshold else 1 for value in profile]
runs = []
value = bits[0]
length = 1
for sample in bits[1:]:
if sample == value:
length += 1
else:
runs.append((value, length))
value = sample
length = 1
runs.append((value, length))
black_runs = sum(value == 0 for value, _ in runs)
white_runs = sum(value == 1 for value, _ in runs)
internal_spaces = sum(
value == 1
for value, _ in runs[1:-1]
)
return {
"bits": bits,
"runs": runs,
"black_pixels": bits.count(0),
"white_pixels": bits.count(1),
"black_runs": black_runs,
"white_runs": white_runs,
"internal_spaces": internal_spaces,
"transitions": len(runs) - 1,
}
The final append records the last run even though no later transition closes it. Omitting that operation is a common off-by-one error.
The internal-space calculation excludes the first and last runs. This remains a useful pattern description, but it cannot prove that the region contains a complete barcode. A truncated region may still produce plausible measurements.
Verify stability and diagnose disagreement
First test the implementation with a hand-constructed sequence, including profiles that begin or end black. Also test an all-white profile and an all-black profile. Each constant profile has one run and zero transitions.
Then compare measurements from several heights within the bar body. For example, inspect rows near 20%, 35%, 50%, 65%, and 80% of the usable bar height. Avoid text and special symbol geometry when choosing those locations.
Repeat the measurement at nearby thresholds. On an 8-bit image, testing the selected threshold and offsets of minus 10 and plus 10 intensity levels is a practical diagnostic. Keep thresholds within the image range. This test is not a formal acceptance standard: stable counts can still include the same unwanted border at every setting.
| Symptom | Likely explanation | Check or correction |
|---|---|---|
| Too many short runs | Noise, surface texture, or excessive sharpening | Compare transitions with original edges; inspect a narrow median band |
| Too few bars | Blur, poor focus, or threshold merging | Check narrow spaces at native resolution and improve acquisition |
| Count changes with band height | Skew or a band crossing text | Reduce band height and correct orientation |
| Extra bar at one end | Label border or neighboring graphic | Move the counting boundary without clipping the symbol |
| Count changes across the width | Uneven brightness or reflections | Inspect the grayscale profile and correct image formation |
Matching bar counts do not establish that the data is correct, the symbol is complete, or the print meets a grading requirement. Use camera barcode decoding and data validation when identity matters. If the task is print-defect inspection, the guide to white-line defects beyond successful decoding explains why additional measurements are needed.
Check the workflow before deployment
- Confirm that the profile crosses the bars rather than following them.
- Record the binary polarity and whether endpoint white runs are included.
- Preserve the original image and decoding quiet zones.
- Check that every transition matches a visible edge.
- Compare run counts and widths across scan heights and threshold settings.
- Reject incomplete regions instead of treating their counts as valid symbol measurements.
- Keep the run sequence alongside the final count so disagreements can be investigated.
A single scan band is the wrong measurement when you need to detect defects anywhere along the full bar height. Use multiple bands or a two-dimensional inspection for that task.
For acquisition planning, start with the camera configuration step. If image access, sampling, or the required output remains uncertain, send the field of view, minimum module width, motion conditions, and example images through applications support before selecting hardware.
Questions
Can I count barcode bars by summing a binary image?
No. With black represented by zero and white by one, summing the profile counts white pixels. Black-pixel count is the profile length minus that sum. To count bars, identify consecutive black runs, because a single bar can occupy several pixels and different bars can have different widths.
Should I use one image row or a band of rows?
Start with a clean row crossing the bars. A narrow band reduced by a column median can reduce isolated contamination, but it can also smear edges when the symbol is skewed. Compare both approaches and use a band only when it preserves the narrowest visible features.
Should quiet zones be removed before counting?
Keep quiet zones in the original image used for decoding. In the counting output, distinguish endpoint white background from spaces between bars. Do not crop so tightly that you cut into a bar, and do not include dark label borders that could become false runs.
Does the correct bar count prove that a barcode is valid?
Not necessarily. A correct count says only that the selected profile contains that many black runs. The region could be incomplete, include an unwanted graphic, or contain incorrect widths. Decode and validate the payload separately, and use an appropriate verification method when print grading is required.

