OpenCV better detection of red color?

In HSV space, the red color wraps around 180. So you need the H values to be both in [0,10] and [170, 180].

Try this:

#include <opencv2\opencv.hpp>
using namespace cv;

int main()
{
    Mat3b bgr = imread("path_to_image");

    Mat3b hsv;
    cvtColor(bgr, hsv, COLOR_BGR2HSV);

    Mat1b mask1, mask2;
    inRange(hsv, Scalar(0, 70, 50), Scalar(10, 255, 255), mask1);
    inRange(hsv, Scalar(170, 70, 50), Scalar(180, 255, 255), mask2);

    Mat1b mask = mask1 | mask2;

    imshow("Mask", mask);
    waitKey();

    return 0;
}

Your previous result:

enter image description here

Result adding range [170, 180]:

enter image description here


Another interesting approach which needs to check a single range only is:

  • invert the BGR image
  • convert to HSV
  • look for cyan color

This idea has been proposed by fmw42 and kindly pointed out by Mark Setchell. Thank you very much for that.

#include <opencv2\opencv.hpp>
using namespace cv;

int main()
{
    Mat3b bgr = imread("path_to_image");

    Mat3b bgr_inv = ~bgr;
    Mat3b hsv_inv;
    cvtColor(bgr_inv, hsv_inv, COLOR_BGR2HSV);

    Mat1b mask; 
    inRange(hsv_inv, Scalar(90 - 10, 70, 50), Scalar(90 + 10, 255, 255), mask); // Cyan is 90

    imshow("Mask", mask);
    waitKey();

    return 0;
}

enter image description here

Leave a Comment