Ask Your Question
0

Removing circles inside larger circles

asked 2020-02-04 13:11:39 -0600

iwalther gravatar image

Hi,

so I am making a program that can detect a ball of a certain color. I pass the image through HSV, then threshold that image to only display objects in range of the color in the threshold i.e my ball. After doing that I pass the thresholded image through Canny to identify edges, then I find contours and then I write some code to draw circles based on what the thresholded image presents.

In my finalized image, which is shown in the window named "drawing" in the attached image, you can see that there are multiple circles drawn inside of the largest circle, which is my ball that I am trying to detect. This happens sometimes when the color of parts of the ball is outside the color threshold, and results in the program drawing a circle in the void. This happens even if I edit the threshold of which colors to detect.

So my question is: Is there a way to remove smaller circles inside of the largest one in an image?

PS: I have attached my code underneath the attached image.

image description

#include <stdio.h>
#include <cstring>

#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>


using namespace cv;
using namespace std;

int H_MIN = 0;
int H_MAX = 31;
int S_MIN = 17;
int S_MAX = 88;
int V_MIN = 102;
int V_MAX = 255;

int main(int argc, char** argv)
{
    VideoCapture cap(0); 
    if (!cap.isOpened())
    {
        cerr << "ERROR: Unable to open the camera" << endl;
        return 0;
    }

    Mat frame;
    Mat hsvFrame;
    Mat threshFrame;
    Mat dilateElement = getStructuringElement(MORPH_RECT, Size(10,10));

    cout << "Starting grabbing, press any key on the video feed window to terminate process" << endl;
    while(1)
    {
        cap >> frame; 

        if (frame.empty()) 
        {
            cerr << "ERROR: Unable to grab from the camera" << endl;
            break;

        }

        cvtColor(frame, hsvFrame, COLOR_BGR2HSV); 

        inRange(hsvFrame, Scalar(H_MIN, S_MIN, V_MIN), Scalar(H_MAX, S_MAX, V_MAX), threshFrame); 

        dilate(threshFrame, threshFrame, dilateElement);

        Mat canny_output;
        Canny( threshFrame, canny_output, 100, 100*2 );

        vector<vector<Point> > contours;
        findContours(threshFrame, contours, RETR_TREE, CHAIN_APPROX_SIMPLE);

        vector<vector<Point> > contours_poly( contours.size() );
        vector<Rect> boundRect( contours.size() );
        vector<Point2f>centers( contours.size() );
        vector<float>radius( contours.size() );

        for( size_t i = 0; i < contours.size(); i++ )
        {
            approxPolyDP( contours[i], contours_poly[i], 3, true );
            boundRect[i] = boundingRect( contours_poly[i] );
            minEnclosingCircle( contours_poly[i], centers[i], radius[i] );
        }

        Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );

        for( size_t i = 0; i< contours.size(); i++ )
        {
            Scalar color = Scalar( 49, 255, 255 );
            circle( drawing, centers[i], (int)radius[i], color, 2 );
        }

        imshow("Drawing", drawing);
        imshow("Threshold Feed",threshFrame);

        if (waitKey(30) >= 0)
        {
        break;
        }
    }

    cout << "Closing the camera" << endl;
    cap.release();
    destroyAllWindows();
    cout << "bye!" <<endl;
    return 0;
}
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
1

answered 2020-02-04 13:31:15 -0600

mvuori gravatar image

Use CV_RETR_EXTERNAL instead of CV_RETR_TREE

edit flag offensive delete link more

Comments

With contours you can somehow define that you are only interested in the outer boundary - if seen this code before. Most likely mvuoris comment is the solution for this.

holger gravatar imageholger ( 2020-02-04 15:34:25 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2020-02-04 13:07:12 -0600

Seen: 1,026 times

Last updated: Feb 04 '20