ApplicationsExplainer

Auto threshold methods for grayscale images: pick the right one

Compare Otsu, moments, metric and entropy auto threshold methods on grayscale images, with a worked Otsu calculation and a pick-by-case decision.

LumaSpec Vision11 min read Share on LinkedIn

On this page 10 sections
  1. 01What an auto threshold method actually computes
  2. 02Inter-class variance (Otsu): the default for a reason
  3. 03Moments, metric and entropy: what each one optimizes
  4. 04Worked example: bright laser marks on a mid-gray housing
  5. 05When the usual answer is wrong
  6. 06Why the threshold drifts between runs
  7. 07Where to run it: smart camera or vision controller
  8. 08Checks before you trust an auto threshold
  9. 09The decision, case by case
  10. 10Questions

Every vision package ships a threshold function with several automatic modes, and the names — inter-class variance, moments, metric, entropy — do not say which one to trust on your image. The choice is made by the histogram, not by habit. This page works through what each auto threshold method optimizes on grayscale images, computes one Otsu threshold end to end so you can reproduce the check in a spreadsheet, and ends with a decision for each case: which method to run, when to distrust the returned level, and when to stop tuning and fix the lighting. The arithmetic is identical on a smart camera, a vision controller, or in your own code.

What an auto threshold method actually computes

A threshold collapses an 8-bit grayscale image into two classes with a single decision: every pixel at or above level t joins the bright class, everything below joins the dark one. An automatic method reads the image's histogram of gray levels, 0 through 255, and chooses t for you. All four methods covered here are global — one t for the whole image or ROI — and they differ only in the criterion they optimize. On a well-behaved histogram they agree; the disagreements are the interesting part.

If your tool only offers a fixed level, the threshold basics guide covers what the binary result does to an edge and why the level matters at all.

n = total pixels in the image or ROI ω0(t) = share of pixels at or below t, ω1(t) = 1 − ω0 μ0(t), μ1(t) = mean gray level of the two classes σ²_B(t) = ω0 · ω1 · (μ1 − μ0)² (between-class variance, in gray²)

Inter-class variance (Otsu): the default for a reason

Proposed in 1979, the inter-class variance method — Otsu's method — steps through every candidate level and keeps the one with the widest gap between the two class means, weighted by how big each class is. It needs no model of the scene, runs in one pass over 256 histogram bins, and returns the same level for the same image every time, which is what a production recipe wants.

Its comfort zone is two classes that each hold a decent share of the pixels and are not overly disproportionate in size. The failure list is just as specific: heavy noise, very small objects, uneven illumination across the field of view, and histograms where the variation inside a class exceeds the gap between classes. In those cases the method still returns a level — confidently, and wrongly.

The same criterion also drives color workflows: the Lab-color Otsu segmentation guide applies it per channel when brightness alone cannot separate the parts.

Moments, metric and entropy: what each one optimizes

The other three methods ask different questions about the same histogram.

Moments (moment-preserving). It chooses t so the binary image keeps the original's first three statistical moments: mean gray level, spread, and asymmetry. Run it when overall tone and contrast are stable by design — fixed optics, controlled light — and you want the segmentation to respect the scene's calibration rather than the loudest gap in the histogram.

Metric (minimum expected error). It fits a distribution model to each class and picks the level that minimizes the expected share of misclassified pixels. Run it when the two classes genuinely overlap and you want the statistically cheapest split, accepting that some pixels will land on the wrong side.

Entropy. It maximizes the sum of the two classes' entropies, splitting where each side is internally most uniform. It tolerates very unequal class sizes far better than inter-class variance, which is why it survives small-defect histograms that break Otsu.

Method Optimizes Run it first when Distrust it when
Inter-class variance (Otsu) Between-class variance Two modes, both well populated, clean valley One class is a few percent of pixels; shading; noise
Moments Match of mean, spread and skew Tone and contrast are stable by design A tiny class drowns in the background's moments
Metric Expected misclassified pixels Classes overlap but are roughly symmetric Multi-modal or heavy-tailed histograms
Entropy Sum of the class entropies Very unequal class sizes Flat histograms where every split looks similar

None of the four fixes lighting. If the modes are not separated on the sensor, no criterion can invent the gap.

Worked example: bright laser marks on a mid-gray housing

Take a laser-mark presence check on a mid-gray anodized housing. The ROI under the mark holds 1,000 pixels — an illustrative sample, collapsed to three gray levels so the arithmetic stays checkable: 900 pixels at gray 60 (the housing), 90 pixels at gray 90 (a shading band across the part), and 10 pixels at gray 190 (the mark). A real histogram spreads over neighboring levels; the split point does not move.

The rule in words: try every candidate split, compute the two class weights and means for each, score it with the between-class variance, and keep the maximum. Any level inside an empty gap gives the same partition, so the candidate values below are just labels.

Split A — between gray 90 and gray 190 (candidate t = 100): the dark class holds 990 pixels.

  • ω0 = 990 / 1000 = 0.99, ω1 = 0.01
  • μ0 = (900 × 60 + 90 × 90) / 990 = 62,100 / 990 = 62.7 gray
  • μ1 = 190 gray
  • σ²_B = 0.99 × 0.01 × (190 − 62.7)² = 0.0099 × 16,205 ≈ 160.4 gray²

Split B — between gray 60 and gray 90 (candidate t = 75): the dark class holds 900 pixels.

  • ω0 = 0.90, ω1 = 0.10
  • μ0 = 60 gray
  • μ1 = (90 × 90 + 10 × 190) / 100 = 10,000 / 100 = 100.0 gray
  • σ²_B = 0.90 × 0.10 × (100 − 60)² = 0.09 × 1,600 = 144.0 gray²

Result: the correct split wins, but at 160.4 versus 144.0 gray² the margin is 160.4 / 144.0 = 1.11. The method came within 11% of chopping the shading band off as the object and calling the mark background.

Decision rule: ship an automatic threshold only when the winning between-class variance is at least 1.5 times the runner-up's. At 1.11, this one fails. Fix the shading — diffuse or re-aim the light so the band merges into the background — and the same check flips the verdict. With the 90-gray pixels moved to gray 65: split B collapses to μ1 = 77.5 gray and σ²_B = 0.09 × (77.5 − 60)² ≈ 27.6 gray², while split A rises to μ0 = 59,850 / 990 = 60.45 gray and σ²_B = 0.0099 × (190 − 60.45)² ≈ 166.2 gray². The margin is now about 6.0. That setup ships.

When the usual answer is wrong

The failure you will actually meet is a global threshold asked to do a local job. Shading across the part, a hotspot from the lamp, or a finish change between batches moves the background mean by more than the defect moves it, and the histogram valley fills in. Ranked remedies:

  1. Fix the physics first — re-aim, diffuse, or run the stray light diagnosis to find where the contrast is going.
  2. Narrow the ROI so the shading leaves the frame; the histogram cleans up immediately.
  3. Switch to a local method: the local mean adaptive thresholding guide shows the bright-object case, where each neighborhood gets its own level.
  4. If the defect is texture rather than brightness, thresholding is the wrong tool entirely — local variance filtering finds defects in uniform gray regions without any global split.

A global auto threshold cannot separate a defect whose brightness step is smaller than the scene's own shading gradient. When the histogram shows that, stop tuning methods and change the optics.

Why the threshold drifts between runs

An auto threshold inherits every instability upstream. The classic is auto exposure: the camera lengthens exposure for a dark part and shortens it for a shiny one, and because recorded gray level scales roughly linearly with exposure time before saturation, a 2× exposure change moves the whole histogram by close to 2× — tens of gray levels, far more than the part-to-part difference under inspection. The auto exposure and gain article explains which pixels drive that decision.

Ambient light leaking under a shroud does the same between day and night shifts; the ambient light control guide shows the shroud-and-strobe fix. Lock exposure and gain manually, run the light from a controller output, and the histogram per part family becomes repeatable — the condition under which any auto method, or a fixed validated level, holds its number.

Where to run it: smart camera or vision controller

The histogram math is identical everywhere, so the decision is about the station, not the algorithm. One camera, one check, cycle times in the tens of milliseconds: run the threshold on the device with a smart camera, and pick a mono sensor — these methods consume the gray histogram directly, so mono saves the conversion step. The camera finder filters by resolution, shutter and mount. The cards below cover most thresholding stations.

Smart cameras & vision sensorsHikrobot HK-TD032-12-WBN 1.6 MP mono vision sensorHK-TD032-12-WBN
Interface
Fast Ethernet
Resolution
Up to 3 MP
$1,699.00View part
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
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
$1,629.00View part

The HK-TD032-12-WBN covers presence checks at 1.6 MP mono with a global shutter on an M12 mount; the LS-SMC-0063 adds a 16 mm lens, 60 fps and a polarized white light for shiny housings; the MV-SC5060XM-08M-WBN moves to 6 MP mono with an 8 mm lens on a 1/2.4" sensor when the mark detail needs more pixels.

Multi-camera lines, heavier inspection logic, or results that feed a line PLC belong on a vision controller.

Vision controllersHikrobot MV-VC2140-128G40-1T VC2100 Vision Controller, N97, 8GB+128G SSD+ 1THDDMV-VC2140-128G40-1T
LAN ports
3-4 LAN ports
USB 3 ports
2 USB 3 ports
Light outputs
4 built-in channels
Memory
8 GB
$1,679.00View partBuild a system with it

The MV-VC2140-128G40-1T runs the loop on an Intel N-series N97 with 8 GB of memory and a 128 GB SSD plus a 1 TB HDD, drives lights from four built-in channels, and gathers cameras on three to four LAN ports.

Checks before you trust an auto threshold

  • Histogram from production parts, not the golden part alone: shading bands, finish mix and noise only show up across a batch.
  • Two visible modes with a low valley between them; if the valley is populated, no global method will behave.
  • The 1.5× margin from the worked example, recomputed on parts from every family in the recipe.
  • Exposure and gain fixed manually — auto modes rewrite the histogram underneath the threshold.
  • The chosen level logged per image, with an alarm when it walks more than about 10 gray levels from setup: that points to lighting, not parts.
  • A full shift of validation with known-good and known-bad parts before the recipe is released.

The decision, case by case

  • Two modes, comparable sizes, clean valley: inter-class variance. Confirm the margin once, then let it run.
  • One small bright class, a few percent of pixels or less: entropy if the valley still exists; local adaptive thresholding or a lighting fix if it does not.
  • Stable, calibrated scene: moments — or drop auto entirely and ship a fixed level validated across a shift.
  • Overlapping, roughly symmetric classes: metric, with an expected error rate you have measured, not assumed.
  • Shading, hotspots, texture defects: change the lighting or the method class; a global threshold will lie confidently.

More applied inspection write-ups are collected on the applications topic page. To size the station around the check — camera, light, controller — start in the vision system configurator, or send the histogram that is misbehaving through the contact page and we will read it with you.

Questions

Do all four auto threshold methods return the same threshold on one image?

On a clean two-mode histogram they land within a few gray levels of one another and segment the same parts. As one class shrinks toward a few percent of the pixels, or shading smears the modes together, the answers spread apart by tens of gray levels: inter-class variance and moments pull toward the large class, entropy holds out for an even split. Run two methods on the same histogram; if they disagree by more than a few levels, neither answer is trustworthy yet.

Can I run an auto threshold method directly on a color image?

Convert to a single channel first. Every method here assumes one histogram, so either threshold the luminance or run the method per channel. If your contrast is in hue rather than brightness — same gray value, different color — brightness thresholding has nothing to split, and you should segment in a color space instead. The Lab-color Otsu workflow shows one way to do that per channel without losing the color information.

Should the threshold be re-calculated for every image or once per setup?

Once per recipe, not per frame. Re-running on every image lets one glare spec or exposure wobble rewrite the split point, and your pass population quietly changes meaning. Set exposure and gain manually, light the part steadily, compute the threshold on a golden sample, and apply the 1.5x margin check. Recompute only when part families change, and log the chosen level so a walk of more than roughly 10 gray levels raises an alarm.

What is a healthy margin between the best and second-best threshold split?

Use 1.5 as the shipping bar: the winning between-class variance should be at least 1.5 times the runner-up split's. The worked example computes 1.11 on an unevenly lit housing — a fail — and about 6.0 after the shading is fixed — a pass. Values between roughly 1.1 and 1.5 mean the histogram nearly favors a wrong split; tighten the lighting or the ROI before trusting the number.