An exposure loop is only as good as the number you feed it. A frame arrives, the lighting or the part has changed, and the controller needs one decision: raise exposure, cut it, or leave it alone and fix something else. Four statistics computed from the frame's histogram give you that decision — clipped-pixel fraction at each end, mean, standard deviation and Shannon entropy. This guide defines each metric with its formula, shows which knob moves which metric and by how much, and works one 4000 × 3000 frame end to end: inputs, arithmetic, pass thresholds, the exact exposure change. You finish with a loop that holds exposure steady on an area scan camera without the built-in auto modes fighting it.
What the histogram says about a frame
Every 8-bit grey frame reduces to a histogram h(k): the count of pixels sitting at grey level k, for k from 0 to 255. The shape alone answers most of what an exposure controller needs. A pile hard against the left wall is underexposure — shadow detail has fallen into bin 0. A spike at 255 means saturation: those pixels carry no level or gradient information. One narrow peak mid-scale is a low-contrast frame; two well separated peaks, part against background, is the shape most segmentation and matching tools want.
Compute the histogram over an area of interest that covers the part, not the whole frame. A grey conveyor background at a fixed level pins the global mean wherever the part sits, and the loop ends up chasing the belt instead of the part. The same reasoning sets the brightness target: it is the value your inspection step was tuned on, and the target-setting procedure is in Set an auto exposure brightness target for inspection.
The four metrics, their formulas and their pass values
Compute all four from one histogram h(k) over N pixels, where p(k) = h(k)/N:
Clipped fraction. The share of pixels at 0 and at 255. Clipping is the only exposure error nothing downstream can undo, so it sets the hard pass limit: hold each end below 1% on general part views, below 0.5% where you measure dimensions or judge surfaces, because clipped edges bias centroid and edge fits.
Mean. The average grey level and the primary control variable. On a linear sensor it tracks exposure time almost proportionally, which is what makes the correction rule in the block above work. 128 is the neutral default for general object views; the correct target is the value your segmenter or matcher was tuned on.
Standard deviation. Spread around the mean, in grey levels — the contrast yardstick. Correctly exposed textured scenes typically read 30 to 50 on an 8-bit scale; below 20 usually means flat lighting rather than wrong exposure.
Entropy. The information content of the frame in bits; an 8-bit frame tops out at 8, and well-exposed textured scenes read 6 to 7. Entropy is a diagnostic only: it rewards noise exactly like detail, so never make it the control variable.
Mono frames keep all four statistics honest — one response curve, no demosaicing smearing the bins. A 20 MP mono USB3.0 camera such as the MV-CS200-10UM, 1" IMX183 sensor behind a C-mount, delivers full-frame statistics straight off the sensor:
- Sensor format
- 1"
- Lens mount
- C-mount
- Interface
- USB3
- Resolution
- 16-25 MP
Which knob moves which metric
On a linear-response sensor the sensitivities are predictable, and that is what makes single-variable control work. Exposure time scales the collected charge: the mean moves in proportion, and clip_hi rises steeply once highlights reach the wall. Gain scales the signal after capture: the mean rises, but noise rises with it and entropy drifts upward without new detail — which is why exposure comes first. Light power behaves like exposure but leaves the exposure time free for moving parts.
Work the knobs in the order exposure, then gain, then light power. On a moving line, motion blur caps the exposure time: keep t_exp below (allowed blur in pixels × pixel size at the part) / part speed. At a 0.05 mm pixel and a 100 mm/s belt that ceiling is 0.5 ms — beyond it, the extra photons must come from the light, dimmed or strobed through one of the light controllers. How to set that ceiling without stalling the line: Cap the maximum auto exposure time to stop motion blur.
Read the frame, then pick the knob from the signature:
| Histogram signature | Diagnosis | First knob |
|---|---|---|
| clip_hi at 1% or more, mean above target | Overexposed | Cut exposure × target/measured |
| Mean below target, clip_lo near 0 | Underexposed, headroom left | Raise exposure × target/measured |
| Mean on target, σ below 20 | Flat contrast | Lighting geometry or response curve, not exposure |
| Entropy below 4 bits with σ low | Featureless illumination | Change light type or angle |
| High clip_hi at a low mean | Highlights compressing early | Percentile spread, not the mean |
Worked example: scoring one 4000 × 3000 frame at 30 fps
The frame comes from the LS-CMR-0166, a 12 MP USB3 camera delivering 4000 × 3000 pixels at 30 fps:
- Sensor format
- 1/1.7"
- Interface
- USB3
- Resolution
- 12 MP
- Shutter
- Rolling
Inputs, and where each one comes from:
- N = 4000 × 3000 = 12,000,000 pixels, full frame used as the AOI — camera data.
- 8-bit mono pixel format — assumed output mode.
- Measured histogram: h(255) = 84,000 pixels, h(0) = 36,000 pixels, mean = 152, σ = 38, entropy = 6.1 bits — computed from the frame; mean and σ in grey levels, entropy in bits.
- Current exposure 5,000 µs, gain fixed — read from frame metadata; the live readout is in Read exposure time from frame metadata under auto exposure.
- Pass conditions: clipping below 1% at each end, tightened to 0.5% because this task measures dimensions, and the mean within ±4 of 128.
The rule, in words: with a linear response and gain fixed, exposure scales the mean, so correct exposure by the ratio of target mean to measured mean and let the clip fractions confirm or veto.
The arithmetic:
- clip_hi = 84,000 / 12,000,000 = 0.007 = 0.7%
- clip_lo = 36,000 / 12,000,000 = 0.003 = 0.3%
- correction factor = 128 / 152 = 0.842
- E_new = 5,000 µs × 0.842 = 4,210 µs
- predicted mean = 152 × 0.842 = 128 grey levels
Result: the frame is inside the 1% budget but over the 0.5% measurement line at the top, and the mean sits 24 grey levels above target, a 16% excess exposure. The histogram has used up its headroom at 255, so gain is the wrong knob — more of it would push more pixels into the wall.
Decision: set exposure to 4,210 µs, keep gain untouched, re-score the next frame. Expect a mean near 128 and both clip fractions well under 0.5%; the loop passes when the mean is within ±4 of 128 and clipping stays below 0.5% at each end. On a linear sensor this settles in two or three frames.
Closing the loop: a controller that settles
If you want the bounded adjustment loop written out for a raw camera, Software auto exposure for a raw camera: the bounded loop is the companion piece; the metrics above are what its score function computes. The loop itself is short:
- Turn the camera's auto exposure, auto gain and auto white balance off — they chase hidden targets and overwrite your setpoints. Why brightness drifts under auto modes: Camera image brightness drifts over time: turn every auto mode off.
- Fix gain, fix the AOI: one variable changes per iteration.
- Score the frame with the four metrics and apply the deadband first — mean within ±4 of target and both clip fractions below 0.5% means change nothing.
- Outside the deadband, apply E_new = E_old × target/measured, clamped to a 20% step, the blur cap and the camera's exposure range. Changing exposure and gain per frame from your code: Runtime camera parameter control: exposure and white balance live.
- Exposure at its floor or cap with the mean still off target: move the light, not the gain.
- Log the four metrics with every saved image; a slow mean creep is a light aging, visible weeks before parts start failing.
On a moving line, step 5 usually means strobing: the exposure stays short for a sharp image and the light pulse carries the energy. Two controllers cover most of those loops:
- Output
- Constant voltage 24 V
- Channels
- 4 channels
- Output
- Constant current
- Channels
- 4 channels
The LS-CTL-0070 switches 4 strobe channels at 200 W over RS232, and the LS-CTL-0180 drives 4 constant-current channels at 120 W for 24 V lights. A strobe also pins the image against ambient light changes, which is why it belongs inside the loop. The pulsing-light failure mode and its fix: Black bars in some camera images: fix lighting flicker vs exposure. The lighting-side counterpart of this same loop: Closed loop lighting control for repeatable vision images.
Where each metric misleads
Nonlinear response curves. The correction rule assumes a linear response. Cameras with a combined linear-logarithmic response compress highlights on purpose to hold bright regions, so the mean stops tracking exposure and target/measured overshoots — the loop thrashes. On such cameras, drive the clipped fraction and the spread between the 5th and 95th percentiles instead; both stay monotone through the curve.
Black level above zero. Many sensors run a black-level offset, so bin 0 never fills even at true black. Read the camera's black-level value and measure clip_lo there, not at 0 — an underexposed frame otherwise looks like it has headroom it does not have.
Flicker sampled by short exposures. Under mains or PWM lighting, a 0.5 ms exposure can land on different parts of the light pulse frame to frame, and the metrics swing while the scene sits still. Average three frames before deciding and fix the root cause: Camera flicker under artificial lighting: diagnose and fix.
Keep this loop separate from focus control: a sharpness score climbs with focus and falls with blur, while these metrics climb with photons. Choosing the focus metric is its own problem — Image sharpness measurement: choose a reliable focus metric.
Checks before you trust the numbers
- Bit depth: a 10- or 12-bit output moves the ceiling from 255 to 1,023 or 4,095 and reshuffles every threshold. Bin at full depth or unpack first: Access 10-bit RGB camera data: unpack to 16-bit planes first.
- Startup settings: an exposure or gain ceiling stored in the camera's startup configuration silently overrides what the loop writes. Symptoms and fix: Auto exposure upper limit not applied: check startup settings.
- Color sensors: demosaiced green dominates luma statistics, and a camera's own auto exposure counts a different pixel set than you expect: Auto exposure and auto gain on color cameras: which pixels count.
- Compute budget: scoring a 4000 × 3000 8-bit frame is one sequential read of about 12 MB, low single-digit milliseconds on one modern core, effectively free when the camera exposes hardware statistics. If scoring shares the box with heavy inference, current industrial mini PCs still carry the load.
- Prove convergence on a frozen scene: the loop should sit inside its deadband within five frames and stay there. Hunting means the step clamp or deadband is set wrong.
When exposure is not the problem
If the mean sits on target, both clip fractions are clean and entropy is still low, the frame is correctly exposed and the scene is genuinely flat. That is a lighting-geometry problem — shadows, speculars, the wrong light type for the surface — and no exposure setting fixes it. Change the light: angle it for dark field, diffuse it for a shiny or curved part, pick a different geometry; the lights finder sorts the options that way. The same logic runs in reverse: before tuning a response curve to manufacture contrast, check whether the photons were there and got crushed — illumination first, curve second.
Next step: shortlist the camera in the camera configurator, pair it with strobe or dimming channels in the controller configurator, or describe the scene on the contact page and we will spec the pair with you. More control-loop reading sits on the systems topic page.
Questions
How large must the AOI be before the clipped-pixel fraction is trustworthy?
Scale the AOI to the resolution you need. In a 200 × 200 AOI of 40,000 pixels, one pixel moves the clip fraction by 0.0025%, so a 1% reading is 400 pixels. Keep any bin you act on above a few hundred pixels, and prefer an AOI near 100,000 pixels so a 0.1% shift is still 100 pixels rather than single-pixel noise.
What target mean should a backlight silhouette inspection use?
A silhouette runs two levels, not one: push the backlight to a mean of 240 or higher with the clip budget still respected, and hold the part itself near 20 to 40 so the segmenter sees a clean valley between two peaks. The pass metric is the depth of that valley, not the global mean — a target of 128 is wrong for this task.
Why did entropy rise after I increased gain, with no new detail?
Gain amplifies sensor noise, and noise spreads pixel values over more bins, so Shannon entropy climbs without any new information arriving. Watch for it: entropy rising while edge counts or sharpness stay flat means you are measuring noise. That is why entropy stays a diagnostic and the loop drives on mean and clipped fraction, where noise contributes far less.
Does the exposure rule E_new = E_old × target / measured work on 12-bit cameras?
The proportional rule works at any bit depth while the response stays linear; only the constants change. On a 12-bit output the ceiling is 4,095, so count clipped pixels above a high threshold such as 4,000, set the target mean on the same 0 to 4,095 scale, and the factor arithmetic is unchanged. Recompute the pass thresholds once and store them per pixel format.
Do I need these metrics if the camera already has auto exposure?
Built-in auto exposure aims at a brightness value chosen by the camera, with no clipping budget and no view of your pass conditions; its region decisions are hidden and its behaviour can change with settings. Running the four metrics yourself keeps the targets explicit and loggable, so you can prove image quality per part. Leave the camera auto modes off and own the loop.



