Thresholding and Otsu's Method
Intuition
To separate dark text from a light page, or bright cells from a dark background, mark every pixel brighter than some value as foreground. Picking that value by hand works for one photo and fails on the next; Otsu's method picks it from the image's own histogram.
Precise explanation
t, mask = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # mask = 255 where gray > 127
t, mask = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) # t chosen by Otsu
THRESH_BINARYsets pixels strictly greater than the threshold tomaxval(255), others to 0;THRESH_BINARY_INVdoes the opposite.- With
THRESH_OTSUthe threshold argument is ignored and the returnedtis the chosen value. Otsu tries every threshold and keeps the one that maximises the between-class variance w₀w₁(μ₀ − μ₁)², where w are the fractions of pixels below/above and μ their mean intensities. It works best when the histogram has two clear peaks. - The input must be single-channel
uint8for Otsu.
Worked example
Pixels [10, 30, 200, 220]: any threshold from 30 to 199 separates the two groups; Otsu returns 30, and the mask is [0, 0, 255, 255].
What the library does inside
A fixed threshold is the comparison gray > t from CV-07 (the optional deep dive
after this step). Otsu adds one pass over the 256-bin histogram (CV-08 next) to score
each candidate threshold.
Common mistakes
- Expecting pixels equal to the threshold to be foreground (the test is strict).
- Passing a colour image to Otsu.
- Thresholding a photo with uneven lighting; blur first, or use
cv2.adaptiveThreshold.
Why this matters
Thresholding is the first step of document scanning, cell counting and many industrial inspection systems; contours and connected components work on its masks.
References
- Image Thresholding (OpenCV 4.13) — OpenCV team (
S117) - OpenCV Tutorials (OpenCV 4.13.0) — OpenCV team (
S023)