Isolating and tracking multiple objects in real time using OpenCV?

I'm currently making a program to track 4 paddles, with 3 different colors. I'm having trouble understanding how best to proceed, with the knowledge I have now, and how to reduce the computational costs of running the project. There are code examples of the steps listed at the end of this post.

The program contains a class file called Controllers, that has simple get and set functions for things such as X and Y position, and which HSV values are used for thresholding.

The program in its unoptimized state now does the following:

  • Reads image from webcam
  • Converts image to HSV colorspace
  • Uses the inRange function of OpenCV, together with some previously defined max/min values for HSV, to threshold the HSV image 3 times, one for each colored paddle. This saves to seperate Mat arrays.
  • (This step is problematic for me) - Performs erosion and dilation of EACH of the three thresholded images.
  • Passes the image into a function, that uses Moments to create a vector of point describing the contours, and then uses moments to calculate the X and Y location, which is saved as an object and pushed back into a vector of these paddle objects.
  • Everything technically works at this point, but the resources required to perform the morphological operations three times each loop through the while loop that reads images from the webcam is slowing the program immensely.(Applying 2 iterations of erosion, and 3 of dilation on 3 640*480 images at an acceptable frame rate.)

    Threshold Images for different paddles

    inRange(HSV, playerOne.getHSVmin(), playerOne.getHSVmax(), threshold1);
    inRange(HSV, playerTwo.getHSVmin(), playerTwo.getHSVmax(), threshold2);
    inRange(HSV, powerController.getHSVmin(), powerController.getHSVmax(), threshold3);
    

    Perform morphological operations

    morphOps(threshold1);
    
    void morphOps(Mat &thresh)
    {
        //Create a structuring element to be used for morph operations.
        Mat structuringElement = getStructuringElement(MORPH_RECT, Size(3,3));
        Mat dilateElement = getStructuringElement(MORPH_RECT, Size(6, 6));
        //Perform the morphological operations, using two/three iterations because the noise is horrible.
        erode(thresh, thresh, structuringElement, Point(-1, -1), 3);
        dilate(thresh, thresh, dilateElement, Point(-1, -1), 2);
    }
    

    Track the image

    trackFilteredObject(playerOne, threshold1, cameraFeed);
    trackFilteredObject(playerTwo, threshold2, cameraFeed);
    trackFilteredObject(powerController, threshold3, cameraFeed);
    
    void trackFilteredObject(Controllers theControllers, Mat threshold, Mat HSV, Mat &cameraFeed)
    {
        vector <Controllers> players;
    
        Mat temp;
        threshold.copyTo(temp);
        //these vectors are needed to save the output of findCountours
        vector< vector<Point> > contours;
        vector<Vec4i> hierarchy;
        //Find the contours of the image
        findContours(temp, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
        //Moments are used to find the filtered objects.
        double refArea = 0;
        bool objectFound = false;
        if (hierarchy.size() > 0)
        {
            int numObjects = hierarchy.size();
            //If there are more objects than the maximum number of objects we want to track, the filter may be noisy.
            if (numObjects < MAX_NUM_OBJECTS)
            {
                for (int i = 0; i >= 0; i = hierarchy[i][0])
                {
                    Moments moment = moments((Mat)contours[i]);
                    double area = moment.m00;
                    //If the area is less than min area, then it is probably noise
                    if (area > MIN_AREA)
                    {
                        Controllers player;
    
                        player.setXPos(moment.m10 / area);
                        player.setYPos(moment.m01 / area);
                        player.setType(theControllers.getType());
                        player.setColor(theControllers.getColor());
    
                        players.push_back(player);
    
                        objectFound = true;
                    }
                    else objectFound = false;
                }
    
                //Draw the object location on screen if an object is found
                if (objectFound)
                {
                    drawObject(players, cameraFeed);
                }
            }
        }
    }
    

    The idea is that I want to be able to isolate each object, and use the X and Y positions as points of a triangle, and use the information to calculate angle and power of an arrow shot. So I want to know if there is a better way to isolate the colored paddles and remove the noise, that doesn't require me to perform these morphological operations for each color.

    链接地址: http://www.djcxy.com/p/23694.html

    上一篇: 如何稳健地分割图像以正确计数模糊斑点?

    下一篇: 使用OpenCV实时隔离和跟踪多个对象?