You want more frames per second without giving up pixels on the features that matter. Multi-ROI readout crops the sensor to several windows and reads only the rows inside them, so the frame rate scales with the rows you omit: a 5 MP global-shutter sensor that runs 60 fps full frame passes 1000 fps with eight small windows. This explainer gives the arithmetic behind that scaling, the cable and host limits that bite first, how window grids are defined at sensor level, whether windows can move while streaming, and when binning or a single window is the better call. It is written for engineers sizing cameras for assembly lines, robotics and embedded vision, who need the number before they order.
What is multi ROI capture, and why does it raise frame rate?
Multi-ROI lets one camera read several cropped windows in a single frame, and because a CMOS sensor shifts the picture out row by row, the rate rises almost in step with the rows you skip: read half the rows, get roughly double the fps.
A CMOS imager exposes and empties its array line by line. With a rolling shutter each row exposes in turn; with a global shutter every row exposes together, but the readout is still sequential. Either way, the frame period is the number of lines read multiplied by the line period, plus a short vertical blanking. Cropping rows out of the readout shortens that sum, and the frame rate follows. The speed-up is therefore identical for global- and rolling-shutter sensors.
Width matters far less than height. Many industrial sensors keep the horizontal period (Hmax) fixed, so a full-width window and a narrow window cost the same line time; the clock savings come from the rows you drop. Multi-ROI is a height game.
A single ROI uses the same physics; multiple windows simply keep several separated features in one frame. The bandwidth side of cropping, where fewer pixels leave the camera at all, is covered in camera ROI cropping at the source; this article stays on the sensor-side rate math.
How do you calculate the frame rate for a set of windows?
Estimate it from the line time: divide the full-frame period by the full row count to get microseconds per row, multiply by the rows your windows cover plus blanking, and invert. On a 5 MP sensor this turns 60 fps into about 120 fps at half the rows.
Worked example: a 1/1.8″ 5 MP global-shutter sensor of 2464 × 2064 pixels running 60 fps full frame.
- Full-frame period: 1 / 60 = 16.7 ms.
- Line time: 16.7 ms / 2064 rows = 8.1 μs per row.
- Two full-width windows 500 rows tall: 2 × 500 = 1000 rows, plus about 40 lines of blanking and window overhead, so 1040 × 8.1 μs = 8.4 ms, which is 119 fps.
- Four windows 200 rows tall: 800 + 40 = 840 lines, 6.8 ms, about 147 fps.
- Eight windows 12 rows tall: 96 + 20 = 116 lines, 0.94 ms, about 1064 fps.
That last line is what a four-figure headline is. Spec sheets in this class quote 1164 fps, and the estimate lands within 10 %, because those windows are a dozen rows tall: real, repeatable, and only useful for line profiles, edge tracking and point measurements. For inspection of real features, say a blister pocket 200 rows tall, the same sensor delivers about 150 fps — a 2.5× gain that still transforms a line-rate budget.
Overhead lines run 20 to 100 per frame on industrial CMOS sensors. Assume 40 for sizing and expect the measured rate within about 5 %.
How many regions can a sensor define, and how are they placed?
On grid-style sensors you set up to eight horizontal and eight vertical dividers, and every intersection becomes a window, up to 64 in theory, with all windows sharing one horizontal period, so width never buys speed.
This divider grid is the common implementation on current 5 MP class global-shutter imagers. Dividers land on any row or column measured from the pixel origin (0, 0), so window positions and sizes are free within the grid. What you give up is per-window horizontal timing: each window rides the fixed horizontal period, and the readout is concatenated into one image, left-justified, with blanking between windows. The frame that reaches your software is a single buffer with the windows side by side, not eight separate images.
That layout is where most integration bugs live. Your code must map each window back to its sensor coordinates before it steers a robot or grades a defect, and when windows change, the binding between inspection regions and windows has to follow, or you inspect the wrong patch. The failure mode and its fix are covered in ROI image source binding.
On the control side, single-window ROI is standard: GenICam exposes it through RegionSelector with RegionOffset and RegionWidth/RegionHeight, on GigE Vision and USB3 Vision cameras alike. Multiple windows per frame is a sensor mode the vendor maps into those registers or a vendor-specific block; the frame still arrives as one image. Sizing the windows is a pixel-budget exercise — for inline code reading the module width sets the window width, as setting an ROI for inline code reading works through. Devices with built-in optics expose the same windowing in their on-device tools; see smart cameras for sensors that crop and decide in one housing.
Can you change the windows while the camera is streaming?
Yes, when the sensor loads the window map frame-synchronously: new dividers take effect at the next frame start, so a 1000 fps stream can re-aim about every millisecond, while static maps need a stop-and-restart costing a few frames.
Two behaviours exist, and you design around the one your camera has. Frame-synchronous loading rewrites the divider registers between frames; the transition frame, where the map reloads, is dropped or duplicated, so skip it by frame count. Stream-static maps are built once at acquisition start, and changing them means stop-acquire-start, costing 2 to 5 frames, tens of milliseconds, each time.
The practical rule: re-derive windows per part type, not per frame. If the fixture presents a known family of parts, switch the map at part change and even the stop-and-restart cost vanishes between parts. Only applications that must swap windows at line rate need the frame-synchronous variant.
If your windows never need to be simultaneous — patches 1, 2 and 3 at one moment, patches 3, 4 and 7 later — a single-ROI camera re-aimed between triggers does the job at the same rate, and multi image capture per trigger covers capturing the set. One more planning point: changing the map changes payload size mid-stream, so allocate host buffers for the largest map you will use, not the first one.
Does the interface or the host become the limit first?
Usually the cable, not the sensor: a cropped 5 MP stream at 1000 fps still moves about 250 MB/s, which fits USB3 at roughly 350 MB/s practical and 10GigE near 1 GB/s, but not GigE at about 100 MB/s of payload.
Run the numbers from the worked example. Eight full-width windows 12 rows tall read 96 × 2464 = 236,544 pixels, about 0.24 MP. Mono 8-bit at 1064 fps is 0.24 M × 1064 ≈ 252 MB/s. On GigE that stream caps near 420 fps, since 0.24 M × 420 ≈ 100 MB/s; USB3 carries it; 10GigE and CoaXPress carry several such cameras. On embedded boards the MIPI CSI-2 receiver often sets the ceiling before the sensor does, and the lane-count and payload arithmetic behind sizing a CSI-2 capture interface on an embedded module applies to a cropped high-rate camera stream exactly as it does to video capture.
The host usually wins more than the fps suggests. Reading 0.24 MP instead of the 5.1 MP full frame is 96 % less data to copy and decode, so processing cost per second falls even as the frame count multiplies. Two ceilings sit above the cable: the trigger path, whose pulse rates and latencies are covered in camera hardware trigger frame rate with external pulses, and exposure, since no frame rate exceeds 1 divided by the exposure time.
Most multi-ROI work lands on area scan cameras. Small global-shutter board cameras are where cropped, high-rate readout earns its keep in embedded machines — two examples from board-level cameras:
- Sensor format
- 1/1.8"
- Lens mount
- C-mount
- Sensor format
- 1/2.9"
- Lens mount
- M12
For a standalone camera with a large global-shutter sensor, the MV-CH120-11UC is a 12 MP IMX304 camera, 1.1″ sensor, global shutter, USB3, high-speed version:
- Sensor format
- 1.1"
- Lens mount
- C-mount
- Interface
- USB3
- Resolution
- 12 MP
Multi ROI, binning, or subsampling: which one fits the task?
Use multi-ROI when you need full resolution in several separated spots, at about 2× fps for every halving of rows read; a single ROI when one region suffices; binning, at 2× to 4×, when you need the whole scene and can give up linear resolution.
| Mode | Pixels read | Rate vs full frame | Resolution kept | Scene coverage |
|---|---|---|---|---|
| Full frame | 100 % | 1× | full | whole scene |
| Single ROI | rows in one window | ~2× at half the rows | full in the window | cropped |
| Multi-ROI | rows inside all windows | ~2.5× for four 200-row windows | full in each window | whole scene, cropped readout |
| 2×2 binning | all rows, summed | 2× to 4× | half linear, better SNR | whole scene |
| 1/2 subsampling | every second row | ~2× | half linear, aliases | whole scene |
The decision hinges on one question: do you know where the features are before the frame is taken? Multi-ROI needs known geometry — fixtured parts, a defined web, repeatable robot presentation. When features can appear anywhere, binning keeps the whole scene at half linear resolution and roughly twice the signal-to-noise ratio, because four charges sum into one pixel. Subsampling reads every second row, gains the same rows, and aliases on periodic detail such as threads, meshes and printed edges; treat it as the last resort behind binning.
What should you confirm before building around multi-ROI?
Four checks decide it: the lens must still cover the full scene, each window must hold enough pixels for the feature, the exposure must fit the new frame period, and the driver must support the window mode and its reload behaviour.
- Lens field of view. Windows sit anywhere in the scene, so the lens covers the whole field, not just the windows. Example: a 123 mm wide scene on the 2464-pixel sensor gives 123 / 2464 = 0.05 mm per pixel; at 200 mm working distance the magnification is 7.1 / 123 = 0.058, so f = 200 × 0.058 / 1.058 = 11 mm, and a 12 mm C-mount lens covers it.
- Window size. Give the smallest feature three to five pixels across, then confirm the pixel budget with the resolution calculator:
- Exposure and light. At 1000 fps the frame period is about 1 ms, and motion usually sets a tighter bound: at 2 m/s with 0.05 mm per pixel, half a pixel of blur allows 0.025 mm / 2000 mm/s = 12.5 μs. That is 160× less light than a 2 ms full-frame exposure, so run the lens near f/2.8 rather than f/8 and pulse the strobe for exactly the exposure.
- Trigger and host. The trigger path must pulse at the target rate, and the exposure-to-frame relationship is laid out in trigger call versus exposure time. Plan buffers for the largest window map, not the first one.
When the four checks pass, size the whole chain — camera, lens, light, trigger — in the camera step of the configurator, and browse the cameras topic page for more camera-side selection guides.
Questions
Does multi ROI change what the lens has to cover?
No. The lens still images the entire scene at full field of view; only the sensor readout is cropped. Two consequences follow: the lens must stay sharp out to the corner where your outermost window sits, and a window far off-axis gains nothing from a smaller optic, because the image circle has to cover the whole array regardless of which rows you read.
Why does the frame rate stop climbing once the windows are already small?
Three ceilings stack up. Width never helps, because the fixed horizontal period charges the same line time for a narrow window as for a wide one. Overhead lines, 20 to 100 per frame, take a growing share: at 96 rows read, 20 overhead lines are already 17 % of the frame period. And the frame rate can never exceed 1 divided by the exposure time, so a stream needing 100 μs exposures tops out at 10,000 fps no matter how little you read.
Can the windows in one frame have different sizes?
On divider-grid sensors, yes, within limits. Row bands cost frame time in proportion to their height, and column dividers land anywhere, so widths differ freely, but since all windows share the fixed horizontal period, a narrow window saves payload, not frame time. Sensors that accept independent rectangles per region also exist in industrial cameras; they charge you the rows each rectangle covers, under the same rule.
How much host processing does multi ROI save?
Roughly in proportion to the pixels omitted. The windows arrive concatenated in one buffer, so the host sees one transfer and one decode per frame, not eight; your code splits the buffer using each window's sensor offset, which the camera reports with the frame. Copy bandwidth falls with the pixel count: the worked example reads about 0.24 MP against a 5.1 MP full frame.
What happens to lighting at 1000 fps?
Exposure collapses to the frame period, about 1 ms, and motion usually demands far less. Pulse the strobe for exactly the exposure window: 12.5 μs pulses at 1060 fps are a 1.3 % duty cycle, which lets the LED run well above its continuous-current rating within its pulse specification. Budget the optics too: opening from f/8 to f/2.8 recovers three stops, a factor of eight, of the roughly 160× shortfall.


