You can grab 7,000 lines per second from an 8k line scan camera, yet the moment a simple edge detector joins the loop the whole system settles near 1,500. The camera is fine, the frame grabber is fine, and the processor is more than half idle — the loop structure is the bottleneck. This walkthrough is for engineers running in-line processing against a line scan camera on a real-time target: it shows how to prove which side limits you, what pipelining, multi-line frames and core splitting buy in hard numbers, and how to reach a sustained 3,000 lines per second on the same two cores.
Why does the frame rate fall from 7k to 1.5k when processing is added?
Because one loop acquires and then processes every line in series: acquisition alone costs 1/7000 ≈ 0.14 ms per line, the combined loop costs 1/1500 ≈ 0.67 ms, and the difference — about 0.52 ms — is the edge tool running inside the acquisition cycle.
Nothing runs concurrently. While the tool searches the 8,192-pixel line, the acquisition engine waits; while the next line lands, the tool waits. The two rates add as times, not as capacities:
The case behind these numbers is a classic build: an 8k mono head feeding a Camera Link frame grabber, with a 2.66 GHz two-core real-time target running the analysis. The camera itself can clock 9.3 kHz, so the sensor is not the wall. At the 1,500-line cap the two cores read 21% and 57%, which means the machine is 61% idle while running at what looks like full speed.
- Lens mount
- M72
- Interface
- Camera Link
- Line length
- 8K
- Pixel size
- 7 μm
How do I prove which side is the bottleneck?
Comment out the processing and re-measure: bare acquisition near 7,000 lines per second against 1,500 with the edge tool live proves processing owns 0.52 ms of every 0.67 ms cycle, so the fix belongs on the processing side.
Make the measurement from frame timestamps rather than a loop counter — camera frame rate measurement from timestamped frames covers the method — and record core load at each commanded rate while you are there. The case system showed this:
| Commanded rate | Core 0 load | Core 1 load |
|---|---|---|
| 500 fps | 8% | 20% |
| 1000 fps | 13% | 39% |
| 1500 fps | 21% | 57% |
| 2000 fps | 25% | 73% |
Both cores climb, but not together. Core 1 gains about 35 percentage points per 1,000 fps and reaches 100% somewhere between 2,700 and 2,800 fps — that is the serial loop's real ceiling. Core 0 gains about 12 points per 1,000 fps and would not saturate before 6,000 fps, which matches the 7k bare-acquisition result. If your symptom is the opposite — the camera alone never reaches its rated speed — start with camera not reaching max frame rate instead.
How much does pipelining acquisition and processing recover?
Splitting acquisition and processing into two loops that exchange buffers through a queue lifts the ceiling from 1/(0.143 + 0.524) ≈ 1,500 lines per second to 1/0.524 ≈ 1,900, because throughput becomes the slowest stage rather than the sum of both stages.
One loop owns the camera: it hands each completed buffer to a lossless queue and immediately returns to grabbing. A second loop owns the analysis: it takes a buffer, runs the edge tool, releases the buffer, takes the next. Neither waits for the other.
The same discipline on real-time targets — queue sizing, loop priority, avoiding extra copies — is laid out in tuning acquisition loops for a sustained frame rate. Be honest with the arithmetic here: 1,900 lines per second is a 27% gain, not the doubling you need, because the processing stage is still the slow one at 0.524 ms per line. Pipelining is necessary but not sufficient; the next two sections close the rest of the gap.
Why acquire multi-line frames instead of single lines?
Because a single-line cycle pays fixed costs — one buffer completion, one tool call, one loop iteration — on every line, while a 16-line frame pays them once per 16 lines: at 3,000 lines per second, 3,000 handoffs fall to about 190.
The DMA engine then moves one 131 kB block instead of 16 separate 8,192-byte lines (8k mono, one byte per pixel), and the worker iterates over the lines inside the frame. Two things bound the frame size: latency and seams. A 16-line frame at 3,000 lines per second adds 16/3000 ≈ 5.3 ms before its last line is analysed; a 64-line frame adds 21 ms, too much if a reject gate waits on the result. A defect at a frame boundary also shows up as a stitched artefact, so check continuity across the seam — line scan image overlap across frame boundaries covers that failure mode. Sixteen to 32 lines is the working range for edge work at these rates.
How do I split the edge detection across both cores?
Give the lines to two worker loops — odd frames to one, even frames to the other — so the 0.67 ms of total per-line work spreads across two cores and the ceiling rises to 2 / 0.67 ms ≈ 3,000 lines per second.
You now run three loops: one acquisition loop plus two workers. The acquisition loop is light, 21% to 25% in the table above, so it shares a core with a worker comfortably. The measured loads carry good news too: at the 2,000 fps point the whole machine used 98 points of a single core — about 0.49 ms of processor time per line rather than 0.67 ms — so a balanced build should clear 3,000 and may reach 4,000. Design to 3,000, then soak-test to find the real number.
A GPU is the wrong instrument at this scale, since each line must be copied to the card before a sub-millisecond kernel runs; slow GPU image processing explains why that path disappoints. When both cores are the wall, the honest fix is more of them, and a vision controller is built for exactly that job:
- LAN ports
- 5+ LAN ports
- USB 3 ports
- 3-4 USB 3 ports
- PoE
- PoE camera ports
- Light outputs
- 8 built-in channels
Each added core buys roughly 1,500 lines per second of headroom at this per-line cost.
How many buffers does the pipeline need?
Size the ring for the worst stall, not the average: buffers ≥ frames per second × longest stall + 3 spares, so 190 frames per second and a 200 ms worst-case stall need 41 — install 48 and stop thinking about it.
Memory is not a constraint: 48 buffers of 16-line frames at 131 kB each is 6.3 MB. Two rules keep the ring healthy. First, acquisition must never block on the consumer — read buffers by index out of the ring rather than waiting for the next completed buffer, or the grab engine throttles itself to the processing rate and skips. Second, watch the skipped-buffer counter; if acquisition stalls with buffers still busy, stop camera acquisition with busy buffers is the playbook for that failure.
On the grabber side, the ring lives in target memory that the card's DMA fills. For a Camera Link camera the MV-GC1102IOL is that piece:
- Interface
- Camera Link
Should raw images cross the network to the host?
No: send results, not pictures — an 8k mono line is 8,192 bytes, so 3,000 lines per second is 24.6 MB/s, about 197 Mbps, twice what a 100 Mbps link carries, while an edge position is a few bytes.
Keep the pipeline on the target and ship coordinates. Even eight bytes per line at 3,000 lines per second is 24 kB/s, lost in the noise of any LAN. If full images must stream — for archiving or a second analyser — the link becomes the limit: a 100 Mbps path moves at most 1,525 raw 8k lines per second with zero protocol overhead, and about half that in reality. Plan cables and switches the way machine vision Ethernet bandwidth planning for cameras describes, or put the camera on a gigabit-class interface to begin with — the LS-LCM-0099 is an 8K line scan camera on 10GigE.
What line rate should the camera run at?
Run the camera at the rate the finished pipeline consumes — 3,000 lines per second in this case — fixed and matched to the part motion, never free-running at the sensor's 9.3 kHz maximum, because backlog, not the sensor, decides the image.
The rate follows the part, not the camera. Covering 400 mm of web with 8,192 pixels gives 400/8192 ≈ 0.049 mm per pixel across the line; at 150 mm/s of web speed the matching line rate is 150/0.049 ≈ 3,070 lines per second. The full derivation, with encoder matching, is in how to set the line rate of a line scan camera, and the calculator below runs it:
Keep exposure under the line period — 333 µs at 3,000 lines per second, so cap exposure near 300 µs — or each line's light bleeds into its neighbour as smear.
What checks confirm the pipeline is fixed?
Three numbers close it out: a sustained 3,000 lines per second over a ten-minute soak with processing live, zero skipped buffers on the ring counters, and both cores loaded with neither pinned at 100%.
- Measure the rate from frame timestamps across the full soak, not from a loop counter.
- Confirm the skipped-buffer and overwritten-buffer counters both read zero.
- Confirm core loads sit within about 20 points of each other; a 20%/70% split means one worker is starving.
- Confirm exposure stays at or below 300 µs while the line rate holds 3,000.
- Stitch a known straight edge across a frame boundary and confirm it stays straight.
- Stop the part and confirm the queue drains and both loops exit cleanly.
From here, build the system with the camera, grabber and controller chosen against these numbers, or contact us with your target rate and per-line budget and we will run this arithmetic on your parts list.
2K-16K for web and moving parts
170 models · from $639.00Questions
Does a faster camera fix a processing-limited system?
No. The camera in this case already delivers 7,000 lines per second with the processing stripped out, so the sensor has more than four times the speed the loop actually uses. A faster head widens the gap. Upgrade the camera only when bare acquisition, measured with no analysis running, still misses your target rate.
How much memory does a properly sized ring need?
An 8k mono line is 8,192 bytes, so a 16-line frame is 131 kB and 48 buffers cost about 6.3 MB. Even going to 64 buffers of 64-line frames, at 512 kB each, totals around 33 MB — invisible next to a 2 GB target. Memory is never a good reason to run short of buffers.
Is GPU processing the right fix for sub-millisecond line work?
Usually not at this scale. Every line must be copied to the card before the kernel runs, and against 0.52 ms of edge work per line the transfer alone can cost more than the computation it offloads. GPUs pay off on full frames with kernels measured in milliseconds; for per-line work at thousands of lines per second, CPU cores and a queue win.
Can I just slow the line instead of re-architecting the loop?
You can, if the inspection tolerates it: at 1,500 lines per second the serial loop is stable and needs no new code. The trade is throughput — halving the line rate halves your cross-web coverage or your part speed — and short defects begin to slip between sampled lines. It buys time, not a fix.
How do I keep display and logging from stalling the pipeline?
Keep them out of the acquisition and worker loops entirely. Push results into a second queue consumed by a low-priority loop, draw the image at 10 to 30 Hz instead of every line, and write to disk in batches. A blocking draw call inside a worker is the classic way a mathematically sound pipeline still drops buffers.


