I have the following image:
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?
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.
OpenCV is used in many real-time applications also. OpenCV has some built-in functions to perform Color detection and Segmentation operations.
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.
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:
Result adding range [170, 180]:
Another interesting approach which needs to check a single range only is:
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; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With