Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Removing circles inside larger circles


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;
        cap >> frame; 

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


        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)

    cout << "Closing the camera" << endl;
    cout << "bye!" <<endl;
    return 0;