Code readingGuide

Decode barcodes from a live RTSP or MJPEG video stream

How to decode barcodes from a live video stream: which frames to grab, the 2-pixels-per-module rule, and when a fixed reader or smart camera wins.

LumaSpec Vision11 min read Share on LinkedIn

On this page 12 sections
  1. 01The decision up front
  2. 02The number that decides it: pixels per module
  3. 03Why H.264 frames fail and MJPEG frames survive
  4. 04Path A: decode the stream on an industrial PC
  5. 05Path B: a fixed code reader does the work
  6. 06Path C: a smart camera with the decode on board
  7. 07Comparing the three paths
  8. 08Worked example: 0.30 mm modules across a 400 mm field of view
  9. 09Checks before you commit
  10. 10When the usual answer is wrong
  11. 11Short checklist before you order
  12. 12Questions

Many plants run a barcode decode that grew rather than was designed: an IP camera streams video to a PC, a proprietary SDK decodes the frames, and exactly one person understands the whole chain. When that person changes roles, the station turns into a liability. This guide gives you the standard replacements: decode the RTSP or MJPEG stream yourself on an industrial PC with OpenCV and an open barcode SDK, or retire the stream and let a fixed code reader or smart camera return finished strings over TCP or OPC UA. You also get the pixels-per-module rule that decides whether your existing camera can do the job at all, a worked example with the arithmetic, and the checks to run before ordering hardware.

The decision up front

You have three sound moves, and one number, pixels per module, picks between them.

Keep the camera, move the decode. If the existing frames already carry 3 pixels per module, run OpenCV and an open decoder on an industrial mini PC beside the line and publish the strings over OPC UA (IEC 62541) or a TCP socket. Same camera, and the code base becomes something any automation engineer can read.

Fit a fixed code reader. When the module count is marginal, or you want the decode inside rated industrial hardware with its own light and optics, a unit from the fixed code readers range outputs finished strings and needs no PC to maintain.

Fit a smart camera. When the same view must also run presence checks or OCR, a smart cameras unit decodes on board and reports over Ethernet.

Decision rule: decode on a PC when the camera already resolves the code and your team can own the software; buy the reader or the smart camera when it does not, or when the station has to outlive its author.

The number that decides it: pixels per module

A 1D barcode is a row of dark and light bars. The narrowest bar is the module, and the decoder has to find both of its edges, so sampling density sets everything. The working rule: 2 pixels per module is the floor on a clean, uncompressed frame, and 3 pixels per module once frames pass through video compression.

px_per_module = (sensor_pixels_across / field_of_view) × module_size

Divide the sensor's pixel count across the image by the field of view to get pixels per millimetre, then multiply by the module width. If the product lands under 2, no SDK, preprocessing or lighting change saves the read. You need more pixels: a narrower view, a bigger sensor, or different optics.

Why H.264 frames fail and MJPEG frames survive

To an eye a video stream looks sharp; to a decoder it can be unusable. H.264 spends its bitrate by predicting most frames from their neighbours, and the fine dark-light transitions of a barcode are exactly the high-frequency detail it discards first. The symptom is an intermittent read on a stream that looks fine on a monitor.

MJPEG codes every frame on its own, so each frame you grab is complete and the quality setting applies per frame. It costs bandwidth, but bandwidth costs less than rejects. When the camera offers only H.264 over RTSP, three fixes, in order of preference:

  1. Use the camera's HTTP still-image endpoint; most IP cameras serve one JPEG per request.
  2. Switch to an MJPEG substream if the camera exposes one.
  3. Decode keyframes only, and set the keyframe interval to 1 s or less.

Latency is dominated by camera encoding and the decoder buffer; the barcode decode itself runs in milliseconds on a grayscale frame.

Path A: decode the stream on an industrial PC

The software chain is short, and every stage is a standard tool.

  1. Open the stream once with OpenCV's VideoCapture and keep the handle for the life of the program; reopening per request stalls and leaks. If the stream will not open, the capture backend is the first suspect, and video capture backend fallback plus OpenCV VideoCapture capitalization and camera initialization cover the two usual causes.
  2. Always decode the newest frame and drop the backlog, so a pause never feeds you stale images; the continuous camera acquisition mode for live image loops is the pattern.
  3. Convert to grayscale and hand the decoder the full frame without resizing. Downsampling destroys the pixels per module you fought for, which is the point of barcode image buffer decoding.
  4. Correct camera mounting rotation before decoding, not after: barcode image rotation and correcting camera frames shows why.
  5. Publish the string with a confidence value over OPC UA or TCP into your SCADA.

Hardware load is light: a current fanless box decodes a 2 MP grayscale frame in tens of milliseconds, so the stream, not the decoder, sets the pace.

The cleaner variant drops the IP camera entirely and puts a machine-vision camera on the lane: uncompressed frames, hardware trigger, global shutter, and no encoder settings to police. What GigE Vision guarantees for camera compatibility covers what that standard promises, and the area scan cameras range and the camera finder are where to pick one.

For a new lane, size from this class of camera:

Area scan cameras12 MP USB3 area scan camera, IMX226, 1/1.7" rolling shutter, 30 fps, 4000 × 3000 resolution (LS-CMR-0166)LS-CMR-0166
Sensor format
1/1.7"
Interface
USB3
Resolution
12 MP
Shutter
Rolling
$560.00View partBuild a system with it

The LS-CMR-0166 is a 12 MP USB3 area scan camera with an IMX226 sensor, 1/1.7" rolling shutter, 4000 × 3000 pixels and 30 fps.

Path B: a fixed code reader does the work

A fixed reader integrates sensor, optics, illumination and decoder in one housing, tunes its own exposure for codes, and outputs finished strings over Ethernet or wired I/O. Your software consumes a string; there is no image pipeline to own. Start here when the existing camera resolves the code poorly, or when the station should need configuration rather than code.

For a lane like this:

Fixed code readers2560 x 2048 fixed code reader, 30 fps, 60 codes/s, 8 mm lens (LS-CRD-0028)LS-CRD-0028
Interface
Fast Ethernet
Resolution
5 MP
Sensor format
1/1.7"
Shutter
Global
$920.00View part

The LS-CRD-0028 is a 5 MP fixed code reader: 2560 × 2048 pixels, 30 fps, 60 codes/s, an 8 mm lens and a Fast Ethernet interface. Close-range stations suit the LS-CRD-0047, a compact 1.2 MP reader on USB rated for a 60-120 mm reading distance.

Two habits keep a reader honest: validate the string against the running order, as in camera barcode decoding from image to validated data, and plan the PLC link so a lost packet cannot become a lost part, which barcode reader PLC communication lays out in detail.

Path C: a smart camera with the decode on board

A smart camera adds inspection to the same view: barcode, presence, count and OCR in one device, with strings reported over Ethernet. Operators can watch images from the same unit in a browser, the pattern in vision sensor browser display for local operator viewing. Whether to configure classic rules or train a model is a real fork, and AI versus rule-based smart camera inspection gives the criteria.

For shrink-wrapped or film-wrapped goods:

Smart cameras & vision sensors1.6 MP smart camera, 60 fps, 16 mm lens, white light (polarized, transparent light) (LS-SMC-0063)LS-SMC-0063
Interface
GigE
Resolution
Up to 3 MP
$1,110.00View part

The LS-SMC-0063 is a 1.6 MP smart camera with 60 fps capture, a 16 mm lens and polarized white light, on GigE. Polarized light on the device removes the film glare that preprocessing would otherwise fight.

Comparing the three paths

PC plus existing IP camera Fixed code reader Smart camera
Decode runs on your software the reader the device
Camera existing, compressed frames integrated optics and light integrated optics and light
Latency to string 0.2-0.5 s typical tens of milliseconds tens of milliseconds
Extra hardware industrial PC none none
To maintain your code base configuration configuration
Extra checks anything you write code quality grading presence, OCR, counts

The same three parts side by side:

Specification LS-CRD-0028 LS-SMC-0063 LS-CMR-0166
Shutter Global shutter – rolling shutter
Max. frame rate 30 fps 60 fps 30 fps
Sensor size 1/1.7" – 1/1.7"
Resolution 2560× 2048 px 1440x1080 4000 × 3000 (12MP)
Pixel size 3.2 μm x 3.2 μm – 1.85 μm
Lens focal length 8 mm 16 mm –
Data interface Fast Ethernet (100 Mbit/s) GigE USB 3.0
Digital I/O 3 non-isolated inputs, 3 non-isolated outputs, 1 RS-232 RS232, 2 Opto-isolated inputs, 3 Opto-isolated outputs –
Power supply 24 V 9-26 V DC 2 A –
Power consumption 20 W @ 24 V <18 W –
Ingress protection IP67 IP65 –
Dimensions 65.2 mm × 65.2 mm × 47 mm 82*55*53(excluding connectors) mm –
Price $920.00 $1,110.00 $560.00

Values as printed in each product's data sheet; open a part for its drawing and full specifications.

Worked example: 0.30 mm modules across a 400 mm field of view

Inputs, each with its source:

  • Field of view 400 mm, the lane width the camera must cover.
  • Module width 0.30 mm, from the label specification.
  • Target 3 pixels per module, because frames arrive through MJPEG.
  • Existing camera: a common 1080p stream, 1920 pixels across.
  • Candidate: a 12 MP camera, 4000 pixels across, a 1/1.7" sensor about 7.5 mm wide, an 8 mm lens.
m = sensor_width / field_of_view WD = focal_length × (1 + m) / m

The arithmetic:

  • Modules across the view: 400 / 0.30 = 1333.
  • Pixels needed at 3 px per module: 1333 × 3 ≈ 4000.
  • Existing 1080p stream: 1920 / 400 = 4.8 px/mm, so 4.8 × 0.30 = 1.4 px per module, below the 2 px floor.
  • 12 MP camera: 4000 / 400 = 10 px/mm, so 10 × 0.30 = 3.0 px per module, on target.
  • Working distance: m = 7.5 / 400 = 0.019; WD = 8 × 1.019 / 0.019 ≈ 430 mm.

Motion, one line: at 10 px/mm a pixel is 0.10 mm, so a belt at 0.5 m/s needs exposure under 0.10 / 500 = 0.2 ms to hold blur below one pixel.

Decision: the existing 1080p stream cannot decode 0.30 mm modules across a 400 mm view. At 1.4 px per module this is a hardware limit, not a tuning problem. Fit the 12 MP camera with an 8 mm lens at about 430 mm working distance, or a fixed reader with its own optics, and hold the view at or under 400 mm.

Camera resolution for the smallest feature
Units
Pixels needed
–
Sensor size
– MP
Smallest sensor that fits
–
Pixel on the part
– mm
Pixels across the feature, that sensor
–

Pixels needed = field / feature × pixels per feature on each axis (field incl. margin). The lens must resolve the pixels too: Nyquist = 1000 / (2 × pixel µm) lp/mm.

Find cameras with enough pixels Open the full calculator

Checks before you commit

  • Decode a recording first. Capture 60 s of the production stream to a file and run the decoder on it offline. If the recording does not decode, no platform will fix it.
  • Count pixels on the frame, not the spec sheet. Crop the code and divide its width in pixels by the module count. Cameras crop, scale and letterbox; only the frame tells the truth.
  • Freeze the motion. Exposure must stay under (mm per pixel) ÷ belt speed. Streamed cameras auto-expose for the whole scene, and video exposure and frame rate explains why stream frames come out darker than stills from the same camera.
  • Turn overlays off. Time and text stamps are burned into the frame, and they land wherever they like, including on the code.
  • Agree the interface before buying. String format, terminator, PLC register mapping, and the no-read policy. Barcode read confidence defines a no-read policy worth copying.
  • Check the symbology list. Confirm the decoder covers every code on the line, including 2 of 5 variants; industrial 2 of 5 barcode support in fixed readers is the cautionary case.

When the usual answer is wrong

Operators need live video anyway. Decoding and displaying are different consumers of the same camera. HMI video components usually want MJPEG, not RTSP: converting an RTSP camera stream to MJPEG and displaying a live RTSP feed on an HMI cover both routes. Decode on the frames you control; display whatever the screen wants.

The front end is a browser. Then decode in the browser too: webcam barcode scanning in browser-based vision systems sets the limits of that path.

Several codes land in one frame. Run the detector across the full image instead of cropping per code: reading multiple barcodes in one image shows the iterative method.

The code reads but prints badly. A successful decode says nothing about print quality; barcode white line defect detection beyond decoding covers what to check when the read is green and the label is not.

Shrink film and curved bottles glare. Polarized light beats preprocessing; whatever glare remains, the fixes are in 1D barcode preprocessing for rotation, blur and glare.

Short checklist before you order

  • Pixels per module measured on a real frame from the actual stream: 3 or better.
  • MJPEG substream or HTTP still endpoint confirmed, or keyframe interval at 1 s or less.
  • Exposure under the motion limit: (mm per pixel) ÷ belt speed.
  • Interface agreed: OPC UA, TCP or wired I/O, plus string format and no-read behaviour.
  • Decoder covers every symbology on the line.
  • Two people can maintain it, or nobody has to.

Next step: start the system configurator at the camera step, browse the other code reading guides, or ask us through the contact page — free expert support comes with every order.

Questions

Can ZBar read a barcode straight from an RTSP stream?

Not directly, because decoders take images, not streams. Open the RTSP URL with OpenCV's VideoCapture once, keep the handle open, grab the newest frame, convert it to grayscale and pass that frame to ZBar. Keeping the stream transport and the decode as separate steps is what lets you swap RTSP for an HTTP still endpoint later without touching the decoder code.

How many pixels per module does a barcode need?

Two pixels per module on a clean frame, three from MJPEG or H.264, because compression softens the very edges the decoder samples. The floor exists because both edges of the narrowest bar must land on separate pixels before they merge. For 2D codes such as Data Matrix, plan three pixels per module. If you measure borderline values, narrow the field of view or move the camera closer rather than chasing decoder settings.

How often should the PC decode frames from the stream?

Run the decode loop at 5 to 10 Hz rather than at full frame rate. The decoder outruns the stream, so extra passes cost nothing, and a slower loop drops stale frames cleanly. Before accepting a string, require two identical consecutive decodes from different frames; that filters the odd bad frame an encoder emits during a motion burst. If the part sits still during the read, switch to on-demand: one still frame per trigger.

How much latency does a decode from a network stream add?

Budget 0.2 to 0.5 s end to end. At 30 fps one frame is 33 ms, and the encoder lookahead, the network jitter buffer and the player buffer each hold several frames, which is where the time goes. The decode itself runs in milliseconds. An HTTP still endpoint is the fast option because nothing buffers ahead of it, which is why stationary reads should use it.

Do I lose the operator video view by switching to a fixed reader?

No. Code readers and smart cameras serve their images over Ethernet, so the HMI keeps a live view from the same device while decode strings flow separately to the PLC. If operators must keep watching the old IP camera as well, feed that stream straight to the display and let the reader own the decode; the two consumers do not interfere.