2

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
scribu
  • 123
  • 6
  • 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. – Marcus Müller Mar 15 '18 at 19:55
  • 1
    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 – Laurent Duval Mar 15 '18 at 20:30

1 Answers1

3

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.

Marcus Müller
  • 30,525
  • 4
  • 34
  • 58