Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV better detection of red color?

Tags:

I have the following image:

enter image description here

I would like to detect the red rectangle using cv::inRange method and HSV color space.

int H_MIN = 0; int H_MAX = 10; int S_MIN = 70;  int S_MAX = 255; int V_MIN = 50; int V_MAX = 255;  cv::cvtColor( input, imageHSV, cv::COLOR_BGR2HSV );  cv::inRange( imageHSV, cv::Scalar( H_MIN, S_MIN, V_MIN ), cv::Scalar( H_MAX, S_MAX, V_MAX ), imgThreshold0 ); 

I already created dynamic trackbars in order to change the values for HSV, but I can't get the desired result.

Any suggestion for best values (and maybe filters) to use?

like image 847
Kristian Vitozev Avatar asked Sep 11 '15 11:09

Kristian Vitozev


People also ask

How does OpenCV detect red?

RGB is not a good color space for specific color detection. HSV will be a good choice. For RED, you can choose the HSV range (0,50,20) ~ (5,255,255) and (175,50,20)~(180,255,255) using the following colormap.

Can OpenCV detect colors?

OpenCV is used in many real-time applications also. OpenCV has some built-in functions to perform Color detection and Segmentation operations.

What is the HSV range for red?

The HSV values for true RED are (0, 255, 255) and to accommodate for color variations, we will consider a range of HSV values for the red color. The red color, in OpenCV, has the hue values approximately in the range of 0 to 10 and 160 to 180.


1 Answers

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

like image 90
Miki Avatar answered Oct 15 '22 06:10

Miki