Ask Your Question

MohZ's profile - activity

2019-01-11 02:05:02 -0600 received badge  Famous Question (source)
2018-04-04 06:32:43 -0600 received badge  Popular Question (source)
2017-08-14 20:19:25 -0600 received badge  Notable Question (source)
2017-03-20 07:45:55 -0600 received badge  Popular Question (source)
2014-11-27 09:35:08 -0600 commented question Help detecting/tracking circles with findContours

Thanks for your reply! I tried the HoughCircle method but it seems to be very unstable. Example: in frame x the (x,y, radius) of the detect ball is (193, 202, 20). In the frame x+y: the (x,y, radius) of the detect ball is (195, 205, 23). In the frame x+y+z: it detects no balls at all.

This is what I mean by beeing unstable. I also make use of Morphological operations for the thresholded image but I didn't fixed it.

2014-11-26 07:26:45 -0600 commented question Help detecting/tracking circles with findContours

Thanks StevenPuttemans. I will try the 2 approaches to get the radius. But can you briefly explain how to do the first one with the HoughCircles and the findContours ? because in the vector Contours I only get points and not an image (so far i understood).

Is it normal that i can't see the others answers ? I see only my question and the comment of StevenPuttemans ...

2014-11-25 08:05:34 -0600 received badge  Editor (source)
2014-11-25 06:50:08 -0600 asked a question problem with detecting and tracking of objects

Hi everyone,

For my project I have to detect and track color based objects (billiard balls). This is how I proceed:

  1. Convert Image from BGR to HSV;
  2. Applying inRange function;
  3. Applying some morphological operations;
  4. and finally, houghCircles to detect the balls.

The HoughCircles functions seems to be unstable. Even when the ball is not moving, the x, y coordinates of the balls are updated (???).

Then, I went for another approach, with the FindContours and Moments that I've found on the internet. But I cannot get the radius of the ball, in order to draw a circle around it.

This is the code:

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

bool objectFound = false;
if (circles.size() > 0) {
    int numObjects = circles.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 < circles.size(); index++) {



                Ball b;

                b.setXPos(cvRound(circles[index][0]));
                b.setYPos(cvRound(circles[index][1]));
                b.setType(b.getType());
                b.setColour(b.getColour());

                yBalls.push_back(b);

                objectFound = true;


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

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

My question is, is there any possibility to get/calculate the radius of a ball ? Or is there any fix for the HoughCircle approach ?

Thanks!

2014-11-24 07:38:35 -0600 asked a question Help for detecting and tracking objects with findContours

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

2014-11-24 05:39:57 -0600 asked a question Help detecting/tracking circles with findContours

Hello everyone,

I am a beginner with OpenCV and need some help for my project. For my project I need to detect color based objects and track them.

The detection part is done, I am using cvtColor to convert a RGB image to an HSV, and use then the inRange function. Now, for the detections of balls, I first made use of houghCircles, but it seems to be unstable. The (x,y) coordinates of the balls were always updated, even when the ball wasn't moving. This is why the circle that I draw around the ball is always changing of place.

I decided to go for a second approach, with findContours. Here the code:

//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 );
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;

                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);
}

It works fine! Now my question is, is it possible to get the radius of the detected objects with this code ? If not, is it possible to get houghCircles more stable ?

Thanks!

2014-10-30 11:41:01 -0600 received badge  Student (source)
2014-10-30 10:49:28 -0600 asked a question Cannot detect yellow balls using OpenCV

Hello!

For a school project, I have to detect some colored balls. OpenCV is new for me so, my code is based on the following example:

http://wiki.elphel.com/index.php?title=File:Tennis.tar.gz

The problem is that I cannot detect the yellow balls. This is what the threshold image look like:

image description

This is my code:

    #include <iostream>
#include <opencv\cv.h>
#include <opencv\highgui.h>

using namespace std;
char key;

void cvOpen(const CvArr *src, CvArr *dst, IplConvKernel *element)
{
    cvErode (src, dst, element, 1);
    cvDilate(src, dst, element, 1);
}

void cvClose(const CvArr *src, CvArr *dst, IplConvKernel *element)
{
    cvDilate(src, dst, element, 1);
    cvErode (src, dst, element, 1);
}


IplImage *detectBalls (IplImage **_src)
{
    IplImage *src = *_src;
    CvSize size = cvGetSize(src);
    IplImage *hsv = cvCreateImage(size, IPL_DEPTH_8U, 3);
    cvCvtColor(src, hsv, CV_BGR2HSV);  

    CvMat *mask = cvCreateMat(size.height, size.width, CV_8UC1);
    cvInRangeS(hsv, cvScalar(14, 135, 139, 0),
                    cvScalar(30, 1.00*256, 1.00*256, 0), mask);
    cvReleaseImage(&hsv);

    IplConvKernel *se21 = cvCreateStructuringElementEx(21, 21, 10, 10, CV_SHAPE_RECT, NULL);
    IplConvKernel *se11 = cvCreateStructuringElementEx(11, 11, 5,  5,  CV_SHAPE_RECT, NULL);
    cvClose(mask, mask, se21); // See completed example for cvClose definition
    cvOpen(mask, mask, se11);  // See completed example for cvOpen  definition
    cvReleaseStructuringElement(&se21);
    cvReleaseStructuringElement(&se11);

    /* Copy mask into a grayscale image */
    IplImage *hough_in = cvCreateImage(size, 8, 1);
    cvCopy(mask, hough_in, NULL);
    cvSmooth(hough_in, hough_in, CV_GAUSSIAN, 15, 15, 0, 0);

    /* Run the Hough function */
    CvMemStorage *storage = cvCreateMemStorage(0);
    CvSeq *circles = cvHoughCircles(hough_in, storage,
        CV_HOUGH_GRADIENT, 4, size.height/10, 100, 40, 0, 0);
    cvReleaseMemStorage(&storage);

    int i;
    for (i = 0; i < circles->total; i++) {
             float *p = (float*)cvGetSeqElem(circles, i);
         CvPoint center = cvPoint(cvRound(p[0]),cvRound(p[1]));
         CvScalar val = cvGet2D(mask, center.y, center.x);
         if (val.val[0] < 1) continue;
             cvCircle(src,  center, 3,             CV_RGB(0,255,0), -1, CV_AA, 0);
             cvCircle(src,  center, cvRound(p[2]), CV_RGB(255,0,0),  3, CV_AA, 0);
             cvCircle(mask, center, 3,             CV_RGB(0,255,0), -1, CV_AA, 0);
             cvCircle(mask, center, cvRound(p[2]), CV_RGB(255,0,0),  3, CV_AA, 0);
    }

        cout << "Number of circles: ";
        cout << circles->total;
        cout << "\n";   



    return hough_in;
}

int main()
{
    cvNamedWindow("out", 0);
    cvNamedWindow("img", 0);
    CvCapture* capture = cvCaptureFromCAM(1);  //Capture using any camera connected to your system
    while(1){ //Create infinte loop for live streaming

        IplImage *frame = cvQueryFrame(capture); //Create image frames from capture
        IplImage *frameOut = detectBalls(&frame);
        cvShowImage("img", frame);   //Show image frames on created window
        cvShowImage ("out", frameOut);
        key = cvWaitKey(10);     //Capture Keyboard stroke
        if (char(key) == 27){
            break;      //If you hit ESC key loop will break.
        }
    }
    cvReleaseCapture(&capture); //Release capture.
    cvDestroyWindow("img"); //Destroy Window
    cvDestroyWindow("out");
    return 0;
}

Can someone help me ?

Kind regards,

Zahir M