Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect RGB color interval with OpenCV and C++

Tags:

opencv

I would like to detect a red colored object in a video or image, with OpenCV and C++. What algorithms are available to do this?

I would like to do a comparison of the relationship between levels of color. Indeed, when the brightness varies, the ratio remains constant. So I want to determine the interval of acceptable values ​​for the colors of zone of interest.

For cases I look at the red R (x, y) and G (x, y) / R (x, y) and B (x, y) / R (x, y).

I will then find the ranges of acceptable values​​: to get a first idea, it releases the maximum and minimum for each report from a palette image red

I would like to find something like this :

if minR<=R(x,y)<=maxR and minG<=G(x,y)<=maxG minB<=B(x,y)<=maxB so couleur(x,y)=blanc else couleur(x,y)=NOIR

like image 483
SOS Avatar asked Nov 27 '22 22:11

SOS


1 Answers

Preprocess the image using cv::inRange() with the necessary color bounds to isolate red. You may want to transform to a color-space like HSV or YCbCr for more stable color bounds because chrominance and luminance are better separated. You can use cvtColor() for this. Check out my answer here for a good example of using inRange() with createTrackbar().

So, the basic template would be:

Mat redColorOnly;
inRange(src, Scalar(lowBlue, lowGreen, lowRed), Scalar(highBlue, highGreen, highRed), redColorOnly);
detectSquares(redColorOnly);

EDIT : Just use the trackbars to determine the color range you want to isolate, and then use the color intervals you find that work. You don't have to constantly use the trackbars.

EXAMPLE :
So, for a complete example of the template here you go,

I created a simple (and ideal) image in GIMP, shown below: enter image description here

Then I created this program to filter all but the red squares:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>

using namespace std;
using namespace cv;

Mat redFilter(const Mat& src)
{
    assert(src.type() == CV_8UC3);

    Mat redOnly;
    inRange(src, Scalar(0, 0, 0), Scalar(0, 0, 255), redOnly);

    return redOnly;
}

int main(int argc, char** argv)
{
    Mat input = imread("colored_squares.png");

    imshow("input", input);
    waitKey();

    Mat redOnly = redFilter(input);

    imshow("redOnly", redOnly);
    waitKey();

    // detect squares after filtering...

    return 0;
}

NOTE : You will not be able to use these exact same filter intervals for your real imagery; I just suggest you tune the intervals with trackbars to see what is acceptable.

The output looks like this:

enter image description here

Voila! Only the red square remains :)

Enjoy :)

like image 64
mevatron Avatar answered Mar 19 '23 13:03

mevatron