Search code examples
pythonopencvmaskcontour

How to segment circle from contour?


GOAL: Locate ball in OpenCV

ISSUE: I have a mask I obtained with hsv bounds for my ball but some of the background is bleeding into my mask. How can I segment the circle I want from the background I don't? I suspect the issue is that I'm using minEnclosingCircle, but I don't know what else to use

I've tried eroding my mask to separate the circle, but it doesn't do me much good

Mask

mask

Resulting Circle

resulting circle


def draw_circle(orig,mask,name):
    cnts=cv2.findContours(mask.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    cnts=imutils.grab_contours(cnts)
    center=None
    if len(cnts)>0:
        c=max(cnts,key=cv2.contourArea)
        ((x,y),radius)=cv2.minEnclosingCircle(c)
        M=cv2.moments(c)
        center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))
        if radius > 10:
            cv2.circle(orig, (int(x), int(y)), int(radius),
                (0, 255, 255), 2)
            cv2.circle(orig, center, 5, (0, 0, 255), -1)
        #d=int(name.split(".JPG")[0])
        #expected_R=(231*1.6)/(2*d)
        #error=1.0-(radius/expected_R)
        #print "error is "+str(error)

    else:
        print "oops"
    cv2.imshow(str(name)+" circled",orig)
    cv2.imshow(str(name)+" mask",mask)
    cv2.waitKey(0)

Solution

  • First of all, I would recommend you to try using an edge detection algorithm, a simple Sobel Filter should be enough to provide you distinct features of the ball and afterwards perform thresholding to eliminate noise. You can use fitting ellipse or a minimum enclosing circle as you do now to better locate the ball. More details in this

    Another approach would be a Hough transform for circles, an algorithm customised for detecting circles, but in comparison to the prior presented approach, it is more computationally expensive. See the following link:

    As a note, if the scene presented in your image is just a mock up, not a dependency or a real use case, I would recommend you to use a different colour of the background, this ay your job would be much easier.