Choosing the Best Range of Values ​​from a Histogram Curve

Scenario:

I am trying to track two different colored objects. First, the user is prompted to hold the first colored object (say, maybe RED) in a certain position in front of the camera (marked with a rectangle on the screen) and press any key, then my program will take that part of the frame (ROI) and analyze the color in it to find which color track. Similarly for the second object. Then, as usual, use the cv.inRange function in the HSV color plane and track the object.

What is done:

I took the object’s ROI for tracking, converted it to HSV, and checked the Hue histogram. I got two cases as shown below:

enter image description hereenter image description here

(there is only one main central peak here, but in some cases I get two such peaks: one large peak with some pixel cluster around it, and the second peak is smaller than the first, but significant in size with a small cluster around it, too. I don’t have a model images, but it is almost similar to below (created in paint))

enter image description here

Question:

How can I get best range of hue values from these histograms?

In the best range, I mean, maybe about 80-90% of the pixels in an ROI lie in that range.

Or is there a better way to track different colored objects?

+6
source share
1 answer

If I understand correctly, the only thing you need here is to find the maximum on the graph, where the maximum is not necessarily the highest peak, but the area with the highest density.

Here's a very simple, not too scientific, but quick O (n) approach. Run the histogram through the low pass filter. For instance. moving average. The length of your average can be indicated 20. In this case, the 10th value of your new modified histogram will be:

 mh10 = (h1 + h2 + ... + h20) / 20 

where h1, h2 ... are the values ​​from your histogram. The following value:

 mh11 = (h2 + h3 + ... + h21) / 20 

which can be easily calculated using the previously calculated mh10, discarding it with the first component and adding a new one at the end:

 mh11 = mh10 - h1/20 + h21/20 

Your only problem is how you process the numbers at the edge of your histogram. You can reduce your moving average length to an existing length or add values ​​before and after what you already have. But in any case, you could not cope with the peaks right on the edge.

And finally, when you have this modified histogram, just get the maximum. This works because now each value of your histogram contains not only itself, but also its neighbors.

A more sophisticated approach is to weigh the average value, for example, of a Gaussian curve. But this is no longer linear. That would be O (k * n), where k is the length of your average, which is also the length of the Gaussian.

+3
source

All Articles