opencvimage-processingcontourconvex-hull

Opencv - Close a specific contour


I'm dealing with an image and I need your help. After a lot of image processing I get this from a microscopic image. This is my pre-final thresholded image:

unclosed contour

As you can see there's a big C in the upper left corner. This should not be an open blob, it must be a closed one.

How can I achieve that with out modifying the rest? I was thinking on applying Convex Hull to that contour, but I don't know how to apply to that and only that contour, with out even touching the others.

I mean, maybe there's a "meassure" I can use to isolate this contour from the rest. Maybe a way to tell how convex/cancave it is or how big is the "hole" it delimits.

In further works maybe appears some other unclosed contours that I'll need to close, so don't focus it this particular case I'll need something I can use or adapt to other similar cases.

Thanks in advance!


Solution

  • While Jeru's answer is correct on the part where you want to close the contour once you have identified it, I think OP also wants to know how he can automatically identify the "C" blob without having to find out manually that's it the 29th contour.

    Hence, I propose a method to identify it : compute the centroids of each shape and check if this centroid is inside the shape. It should be the case for blobs (circle) but not for "C"s.

    img=cv2.imread(your_image,0)
    if img is None:
         sys.exit("No input image") #good practice
    res=np.copy(img) #just for visualisation purposes    
    
    #finding the connectedComponents (each blob)
    output=cv2.connectedComponentsWithStats(img,8)
    #centroid is sort of the "center of mass" of the object.
    centroids=output[3]
    #taking out the background
    centroids=centroids[1:]
    
    
    #for each centroid, check if it is inside the object
    for centroid in centroids:
        if(img[int(centroid[1]),int(centroid[0])]==0):
            print(centroid) 
            #save it somewhere, then do what Jeru Luke proposes
    
        #an image with the centroids to visualize
        res[int(centroid[1]), int(centroid[0])]=100
    

    This works for your code (I tried it out), but caveat, may not work for every "C form" especially if they are "fatter", as their centroid could well be inside them. I think there may be a better measure for convexity as you say, at least looking for such a measure seems the right direction for me.

    Maybe you can try something like computing ConvexHull on all your objects (without modifying your input image), than measure the ratio between the object's area and the "convex hull around it"'s area, and if that ratio is under a certain threshold then you classify it as a "C" shape and modify it accordingly.