如何在OpenCV中跟踪两种颜色?

时间:2016-06-16 07:56:06

标签: c++ opencv

我正在构建此窗口屏幕:

enter image description here

我想使用黄色标记来确定播放矩形内的手势触摸,我想要绿色标记来确定退出矩形内的手势触摸。 但是,我写了这段代码:

//Capture a temporary image from the camera
Mat imgTmp;
cap.read(imgTmp);

//Create a black image with the size as the camera output
Mat imgLines = Mat::zeros(imgTmp.size(), CV_8UC3);;

while (true)
{
    Mat frame;

    bool bSuccess = cap.read(frame); // read a new frame from video

    if (!bSuccess) //if not success, break loop
    {
        cout << "Cannot read a frame from video stream" << endl;
        break;
    }

    //tracking colors
    Mat imgHSV;

    cvtColor(frame, imgHSV, COLOR_BGR2HSV); //Convert the captured frame from BGR to HSV

    Mat imgThresholded;

    inRange(imgHSV, Scalar(ylowH, ylowS, ylowV), Scalar(yhighH, yhighS, yhighV), imgThresholded); //Threshold the image
    inRange(imgHSV, Scalar(glowH, glowS, glowV), Scalar(ghighH, ghighS, ghighV), imgThresholded);

    //morphological opening (removes small objects from the foreground)
    erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
    dilate(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));

    //morphological closing (removes small holes from the foreground)
    dilate(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
    erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));

    //Calculate the moments of the thresholded image
    Moments oMoments = moments(imgThresholded);

    double dM01 = oMoments.m01;
    double dM10 = oMoments.m10;
    double dArea = oMoments.m00;

    // if the area <= 10000, I consider that the there are no object in the image and it's because of the noise, the area is not zero 
    if (dArea > 10000)
    {
        //calculate the position of the ball
        int posX = dM10 / dArea;
        int posY = dM01 / dArea;

但它只跟踪绿色,而绿色和黄色都在摄像机视野内。如何跟踪多种颜色并在屏幕上的某个坐标处找到它们的相互作用(如鼠标功能)?

1 个答案:

答案 0 :(得分:0)

它仅跟踪绿色对象,因为您只使用一个cv::Mat对象来存储二进制阈值图像。在您的代码中,您使用黄色值对图像进行阈值处理,并将其存储到cv::Mat imgThresholded。但在此之后,您使用绿色将原始图像阈值并将其存储到同一变量中。此操作将覆盖早期阈值处理的信息。形态学操作也是如此。要修复,只需使用两个矩阵

Mat imgThreshYellow
Mat imgThreshGreen

inRange(imgHSV, Scalar(ylowH, ylowS, ylowV), Scalar(yhighH, yhighS, yhighV), imgThreshYellow); //Threshold the image
inRange(imgHSV, Scalar(glowH, glowS, glowV), Scalar(ghighH, ghighS, ghighV), imgThreshGreen);

显然,您还需要更改形态操作以对相应的正确二进制图像矩阵进行操作,并分别计算两种颜色的图像时刻。