Code readingHow-to

Read display values from video frames every second

Sample one frame per second from a video, OCR the digits on the display and plot the values over time, with the sampling arithmetic, ROI rules and checks.

LumaSpec Vision12 min read Share on LinkedIn

On this page 9 sections
  1. 01How many frames do you actually need to OCR?
  2. 02Why count frames instead of watching the clock?
  3. 03How do you crop the digits before OCR?
  4. 04How many pixels does each digit need?
  5. 05What does the sampling and OCR loop look like?
  6. 06How do you keep a half-switched digit from corrupting the plot?
  7. 07Which camera reads the display live instead of a recording?
  8. 08How do you verify the plot before you trust it?
  9. 09Questions

A recording of a digital display is a data log nobody has read yet. Panel meters, machine HMIs, bench power supplies and process controllers all display values that change over time, and a camera left watching one records the entire history. OCR on one still gives one number; what the engineer usually needs is the trend. The job is not harder OCR — it is a sampling loop around the OCR you already have: take one frame per second, read the digits in a fixed crop, keep only the reads that pass a few quick checks, and plot the rest. This guide gives the arithmetic for the sample rate, the pixel budget for the digits, the loop step by step, and the cameras that run the same job live at the machine instead of from a file.

How many frames do you actually need to OCR?

OCR one frame per second: at a 30 f/s source that is every 30th frame, so a 20-minute video shrinks from 36,000 frames to 1,200 OCR reads — 3.3% of the stream — and each read lands exactly 1 s apart on the plot.

The arithmetic is one multiplication and one division:

N = frame rate × sample period = 30 f/s × 1 s = 30 frames total frames = 30 f/s × 1,200 s = 36,000 frames sampled frames = 1,200 s ÷ 1 s = 1,200 frames

One frame in thirty carries a reading; the other twenty-nine repeat the same displayed value. Frame counting also fixes the time axis: sample k sits at k ÷ 1 sample/s = k seconds, with no clock to drift.

Match the rate to the display, not to the camera. A panel meter that refreshes once per second cannot show more than one new value per second, so one sample per second loses nothing. A readout that steps five times a second needs a sample every 6th frame, and the same formula scales.

Reading one display from a single still is the half of the job the digital meter OCR guide covers. This guide is the loop around it.

Why count frames instead of watching the clock?

Count frames, never wall-clock time: the stream produces frames at a fixed 30 f/s, so frame number 30 × k is always exactly k seconds in, while a timer drifts and drops whole seconds whenever one OCR pass runs past its 33 ms frame budget.

Put numbers on the failure, and take 30 ms as the working cost to OCR one cropped read on a desktop CPU. At 30 f/s the grab loop owns each frame for 1,000 ms ÷ 30 ≈ 33 ms. A one-second sleep does not respect that budget: it fires while the previous OCR is still running, the queue grows, and the driver starts dropping frames to keep up. The samples that survive land at uneven times, and the plot's time axis lies.

Frame counting is self-correcting. The counter increments on every decoded frame, and OCR runs only when the count is a multiple of 30. If OCR is slow, wall-clock time stretches, but the set of frames you read never changes. Offline, from a saved file, this cannot lose data at all: the file decodes at whatever speed the CPU manages. Live, it caps the load: 1,200 reads × 30 ms = 36 s of OCR inside a 1,200 s run, about 3% of one core.

When a read can occasionally run past 33 ms, decode in one thread and OCR from a queue, so the grab loop never waits. Where the time actually goes is its own measurement problem — the CPU time vs wall-clock time guide walks the traps. At 3% duty, this loop runs on anything from a laptop to one of the compact industrial mini PCs mounted next to the line.

How do you crop the digits before OCR?

Crop a fixed region around the digits and OCR nothing else: on a 1920 × 1080 frame a display ROI of roughly 640 × 320 px cuts the OCR work to about a tenth of the frame and removes every other pixel as a source of false characters.

The savings check out in pixels: 640 × 320 = 204,800 px against 1920 × 1080 = 2,073,600 px, about one pixel in ten. Fix the rectangle once, in pixels, for the display you watch. Frame the digit box, then add margin of a quarter to a half of the digit height on every side, so antialiased edges, a decimal point and a minus sign all survive the crop. Keep the decimal point inside it: a displayed 12.8 cropped without the point plots as 128, ten times the real value.

On the 4.8 px/mm example below, a 133 mm × 67 mm display window is that 640 × 320 px ROI: 133 mm × 4.8 px/mm ≈ 640 px, and 67 mm × 4.8 px/mm ≈ 320 px.

Reduce the crop to what the classifier wants: grayscale, a threshold that separates lit segments from the background, and normalization to the digit height the model was trained on. If the camera sits at a small angle, deskew the crop so the digit baseline is horizontal; accuracy falls quickly past a few degrees of tilt. The seven segment display OCR guide walks the ROI and the reject logic for exactly this display type.

How many pixels does each digit need?

Aim for a digit at least 20-30 px tall, and 40 px when you can: at that height the strokes stay separated after lens blur and video compression, and a trained classifier stops confusing a 5 with a 6 or a 3 with an 8.

Work it from the field of view: pixels per millimetre is frame width divided by the scene width you imaged, and digit height in pixels is physical digit height times that density.

pixels per mm = frame width ÷ imaged scene width digit height px = digit height mm × pixels per mm min scene width = frame width × digit height mm ÷ 25 px

Worked example: a 1920 px-wide frame covering a 400 mm panel gives 1920 ÷ 400 = 4.8 px/mm. Digits 8 mm tall measure 4.8 × 8 = 38 px, comfortably above the floor, and OCR reads them cleanly. Move the same camera back to cover 800 mm and the density falls to 1920 ÷ 800 = 2.4 px/mm, so the digits drop to 2.4 × 8 = 19 px and the misreads start.

Inverted into a decision rule: to hold 25 px on 8 mm digits, the display window may span at most 1920 × 8 ÷ 25 = 614 mm of scene width. A 1080p camera watching a whole machine 2 m wide gives 1920 ÷ 2,000 mm ≈ 1 px/mm, so 8 mm digits land near 8 px — far below the floor, and no crop or filter recovers strokes the pixels never held. Crop to the display or buy pixels.

Compression matters as much as pixel count: a heavily compressed recording smears segment edges, and the same digit at the same height reads better from a high-bitrate capture.

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

What does the sampling and OCR loop look like?

Run one loop — decode, count, OCR on multiples of 30 — and store one value per second with its sample index; the plot then holds 1,200 points for a 20-minute video, spaced exactly 1 s apart.

The library calls differ by name, but the loop is the same seven steps:

  1. Open the source and read its frame rate; compute the decimation N = frame rate × sample period, which is 30 for a 30 f/s source.
  2. Decode frames and increment a frame counter on every decoded frame.
  3. When counter mod N = 0, crop the display ROI from that frame.
  4. Run OCR with the one classifier trained for this display; record the string, its confidence and the sample index k.
  5. Validate the read: confidence floor, the three-frame vote in the next section, and a plausibility check against the previous accepted value.
  6. Append accepted rows of k, value and confidence to a CSV; the time axis is k × 1 s.
  7. When the loop ends, plot value against time and inspect every gap where reads were rejected.

Budget check for the 20-minute case: 1,200 samples × 30 ms = 36 s of OCR, plus decoding 36,000 frames — the decode is usually the longer half. On a live network camera the same loop runs in the receive thread; the decode barcodes from a live RTSP or MJPEG stream guide shows that receive-loop plumbing. Turning recorded frames into text is a pattern with many uses: the license plate OCR pipeline guide runs the same frames-to-text chain at traffic speed.

How do you keep a half-switched digit from corrupting the plot?

Take three frames 100 ms apart within each sample second and keep the value that appears twice: a seven-segment display can spend a few hundred milliseconds half-switched between values, so one grab per second occasionally lands mid-transition and reads a ghost 8.

The vote adds little work. Grab the ROI at t, t + 100 ms and t + 200 ms, OCR all three and accept the repeated value: 3,600 OCR passes across the 20-minute video instead of 1,200, with the grabs and 3 × 30 ms of OCR inside roughly 300 ms of every second. If no value repeats — all three grabs landed mid-transition, rare but possible — mark the sample invalid. A gap on the plot is honest; a ghost 8 between 199 and 201 is not.

Add two guards on top of the vote. Set a confidence floor — a common starting point is 60 on a 0-100 scale, tuned on your own rejects — and a plausibility limit that refuses any step larger than the process can physically make in 1 s: a temperature readout that jumps 40 units between seconds is a misread, not a trend.

Which camera reads the display live instead of a recording?

If the values must be read live at the machine, use a smart camera or vision sensor pointed at the display: it runs the same trained OCR on board at the full frame rate and ships one number per read over Ethernet instead of a video file.

Code readers are a different tool: the fixed code readers category targets 1D and 2D codes on the line, not seven-segment digits. The smart cameras category is where display reading lives, because the inspection runs on the device with no PC in the loop. For a once-per-second duty almost any model sits idle, so pick by digit size and working distance. The parts below do the job:

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 captures at 60 fps with its 16 mm lens, so a once-per-second sample leaves it idle for most of every second.

Smart cameras & vision sensorsHikrobot MV-SC3050XC-16M-ATN-H 5 MP color vision sensorMV-SC3050XC-16M-ATN-H
Interface
Fast Ethernet
Resolution
5 MP
Sensor format
1/1.45"
Shutter
Global
$1,809.00View part

When the display sits farther away, more pixels hold the digit floor: the MV-SC3050XC-16M-ATN-H is a 5 MP color vision sensor with a global shutter, an M12 mount and a Fast Ethernet interface.

Smart cameras & vision sensorsHikrobot MV-SC5060XM-08M-WBN SC5000X series Smart Camera, 6 MP, Mono, 8 mm focal length, M12-mountMV-SC5060XM-08M-WBN
Interface
GigE
Resolution
6-10 MP
Sensor format
1/2.4"
Shutter
Rolling
$1,629.00View part

For a backlit monochrome LCD, mono helps most: the MV-SC5060XM-08M-WBN is a 6 MP mono smart camera with an 8 mm lens on GigE, and its rolling shutter costs nothing on a display that is static between updates.

Size the camera from the digit arithmetic above, then confirm the choice in the camera finder or the configurator before ordering.

How do you verify the plot before you trust it?

Before you trust the curve, hand-check five samples against the video at their timestamps — first, last, highest, lowest and one in the middle — and expect your validator to reject roughly 1-5% of reads; a run with zero rejects means the validator is set too loose.

Timestamp arithmetic makes the checks exact: sample k sits at k × 1 s, so the claim that the display read 87 at 12 min 40 s means frame 30 × 760 = 22,800 shows 87. Open the video at those five frames and compare.

Two automated checks earn their keep. A synthetic unit test renders digits at your exact pixel height and expects the parser to return them exactly; run it whenever the ROI or the threshold changes. And let the reject count steer the tuning: past one read in ten, the fix is in the crop, the focus or the lighting, not in a harder filter.

Keep the raw CSV with every read and its confidence, and archive the cropped ROIs: at 100-150 KB per crop, the 1,200 crops of a 20-minute video take 120-180 MB, so any plotted point can be re-checked without the recording.

To move this job from a recording to the line, the camera finder filters smart cameras and vision sensors by resolution and interface, and the configurator walks the chain from display to plotted value.

Questions

Does the same loop work on a live camera stream instead of a saved file?

Yes. The frame counter sits in the receive loop exactly where the file decoder sits in the offline version. Over a TCP-based stream the frames arrive in order and none are silently lost, so sample k still lands at k seconds. Over lossy UDP delivery, count only frames that actually arrive, expect small gaps on the time axis, or move the stream to TCP first.

How do I train the OCR for an unusual display font?

Crop 30-50 examples of every digit from your own video, at the exact pixel height the runtime ROI will produce, label them, and train a single classifier for the ten digits plus a blank. Test on frames the training never saw. If the model reads in the lab but fails at runtime, a preprocessing or parameter step differs between the two runs — set every parameter to match.

What sample rate does a display that updates faster than once per second need?

Sample at least once per display update to catch every value, and twice per update if you must also bound how late you notice a change. A readout that steps every 200 ms needs 5 samples/s at minimum — every 6th frame at 30 f/s — or every 3rd frame for margin. A 30 f/s source cannot go above 30 samples/s.

Can I up-sample small digits instead of moving the camera closer?

Interpolation adds pixels, not information: a 15 px digit enlarged to 60 px still carries 15 px of detail, and accuracy usually stays flat or drops. Up-sample only to normalize digit height to what the classifier expects, which is a legitimate last step. To recover real detail, tighten the crop, shorten the working distance, or choose a camera with more pixels.

How long does it take to process a shift of recordings?

At 30 ms per sampled read, one 20-minute video needs 1,200 × 30 ms = 36 s of OCR — about 33× faster than real time — so a shift of 24 recordings processes in roughly 15 minutes of compute. Decoding adds its own time, which is why sampling matters: OCR on all 36,000 frames multiplies the work by 30 and can fall behind real time.