Search code examples
pythonopencvcolorsrobotics

How do I reliably classify colours as red, yellow, or "other" colours in OpenCV?


I have an input image from which I extracted the circles for a robotics project, and then got the average colour within those circles. The circles can either have a red or yellow colour as that is how I painted them on wood. I extracted the average colour from these circles and displayed them here for debugging purposes. This is not the input image, just a list of the colours I want to tell apart as red or yellow or neither.

I tried using cv2.inrange with a singular colour value converted to HSV to see if it was red or yellow but that was quite finnicky to adjust and I eventually decided to go for another option. I also tried converting the RGB values to LAB colours, and got the Euclidean Distance between that and the lab values of red and yellow to see which one is less. That also did not work as expected. I also tried various smaller ideas but all of them had some shortcoming one way or another also. Here are the colours I am trying to identify as red or yellow, the dull ones should be classified as neither: Colours List (ignore background)

Any ideas on how to tell apart these shades as red or yellow (or if they are none then ignore them)?


Solution

  • If I duplicate your image across the top row and place the separated HSV channels underneath with H on left, S in the centre and V on the right:

    enter image description here

    Hopefully you can see that the central S channel is a good discriminant for the dull/pastel purple purple disks which show up as black, while the others all show up somewhat brighter. That implies a simple thresholding on the S channel will find all your brightly coloured discs.


    Having extracted the brightly coloured discs, if we then want to discriminate the yellow from the purple we can look at the leftmost H channel in the above image.


    So, in concrete terms, I would look at using the S channel to make a mask of the brightly coloured discs, followed by the H channel to separate the purple from the yellow.