I'm building an image processing pipeline and one step in the process requires thresholding the image based on saturation.

Example code using OpenCV-Python:

H, S, V = cv2.split(img)
mask = cv2.threshold(S, low, 255, cv2.THRESH_BINARY)

I know how to set the low value manually, if I look at the histogram:

histogram examples

(the red arrow indicates the value I would pick)

My question is: how can I programatically find that value?

Some non-rigorous descriptions of the problem:

  • find the lower boundary of the right-most "hump"
  • find the minimum value that's not at the edges
  • $\begingroup$ I think I understand what you need, but it's not the rightmost local minimum (that would be the local minimum still on your "hump", at least visually. $\endgroup$ – Marcus Müller Mar 15 '18 at 19:55
  • 1
    $\begingroup$ I believe the world of signal processing is not ready yet for such tricky questions. I'll award a Nobel Prize to whoever can provide an algorithm to pick the second maximum of a discrete, noisy envelope $\endgroup$ – Laurent Duval Mar 15 '18 at 20:30

To me, this looks like you want something like

  • start from right. Add up bins' values, as long as
    • the added bin is larger than the last or
    • the value added by that bin divided by the current sum is still above a fixed threshold

Adjust the threshold to fit your needs.

Often, things like smoothing the histogram (effectively: applying a low pass filter to it) help. Or you do something like finding a function fit, something like a polynomial of fixed degree (let's say 5) that minimizes some error function (for example, sum square absolute error in all bins), and then analytically find local extrema.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.