Help for detecting and tracking objects with findContours

asked 2014-11-24 07:38:35 -0600

MohZ gravatar image

Hello everyone,

For my projects, I have to detect and track colored objects (balls). This is how I proceed:

  1. Convert RGB webcam image to HSV (BGR2HSV);
  2. Then I use the inRange function to filter the colors;
  3. Finally, I use the thresholded image to detect my object.

I first use the HoughCircle methods to detect the circles, but it was unstable (it detects "imaginary" circles and the x,y position of the circle were always changed, even when the ball was not moving).

My second approach was to use the FindContours function, which reveals to be very stable. I can track my object without any problem.

My question: is it possible to get the radius of a detected object (with findContours) ?

Here is the code I use:

void trackFilteredObject(Ball ball,Mat threshold,Mat HSV, Mat &cameraFeed){


vector <Ball> yBalls;

Mat temp;
threshold.copyTo(temp);
//these two vectors needed for output of findContours
vector< vector<Point> > contours;
vector<Vec4i> hierarchy;
//find contours of filtered image using openCV findContours function
findContours(temp,contours,hierarchy,CV_RETR_CCOMP,CV_CHAIN_APPROX_SIMPLE );
//use moments method to find our filtered object
double refArea = 0;
bool objectFound = false;
if (hierarchy.size() > 0) {
    int numObjects = hierarchy.size();
    //if number of objects greater than MAX_NUM_OBJECTS we have a noisy filter
    if(numObjects<MAX_NUM_OBJECTS){
        for (int index = 0; index >= 0; index = hierarchy[index][0]) {

            Moments moment = moments((cv::Mat)contours[index]);
            double area = moment.m00;

            //if the area is less than 20 px by 20px then it is probably just noise
            //if the area is the same as the 3/2 of the image size, probably just a bad filter
            //we only want the object with the largest area so we safe a reference area each
            //iteration and compare it to the area in the next iteration.
            if(area>MIN_OBJECT_AREA){

                Ball yellowBall(ball.getType());

                yellowBall.setXPos(moment.m10/area);
                yellowBall.setYPos(moment.m01/area);
                yellowBall.setType(yellowBall.getType());
                yellowBall.setColour(yellowBall.getColour());

                yBalls.push_back(yellowBall);

                objectFound = true;

            }else objectFound = false;


        }
        //let user know you found an object
        if(objectFound ==true){
            //draw object location on screen
            drawObject(yBalls,cameraFeed);}

    }else putText(cameraFeed,"TOO MUCH NOISE! ADJUST FILTER",Point(0,50),1,2,Scalar(0,0,255),2);
}

}

If it is not possible to get the radius with findContours, is it possible to get houghCircles more stable ? Or can someone put me on the right path to track balls ?

Kind Regards,

MohZ

edit retag flag offensive close merge delete