Finding the centroid of very irregular image

I’m very new to using opencv, so it’s likely the case that I’m just going about this wrong.

I have several irregularly shaped objects in an image, and need to find the centers an minimum enclosing circle. But, I end up finding centers all along the contours I find.

Any guidance here?

The python snippet I am using…

    # Convert to binary image
    ret,thresh = cv.threshold(self._cartooned,127,255,0)
    self.show("binary", thresh)

    # find contours in the binary image
    #im2, contours, hierarchy = cv.findContours(thresh,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    contours, hierarchy = cv.findContours(thresh,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    for c in contours:
        # calculate moments for each contour
        M = cv.moments(c)

        if M["m00"] != 0:
            cX = int(M["m10"] / M["m00"])
            cY = int(M["m01"] / M["m00"])
        else:
            cX, cY = 0, 0
        # calculate x,y coordinate of center
        # cX = int(M["m10"] / M["m00"])
        # cY = int(M["m01"] / M["m00"])
        cv.circle(self._image, (cX, cY), 5, (255, 255, 255), -1)
        cv.putText(self._image, "centroid", (cX - 25, cY - 25),cv.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)

    self.show("centers", self._image)
    cv.waitKey()

The source image

binary

I would attach the result, but it looks like I am limited to including only one image.

Thanks,
-Evan-

The result:
centers

please post original full-resolution data, not plots.

you probably have many more contours, than you expected, so you would need to filter the contours for size/area (and keep only the largest few) before trying to find the center

The binary image I’m working on:

The source

Unfortunately, I don’t know in advance how large the objects are or how many of them there are, so it seems like filtering them based on area would be a bit of a challenge here.

dilation / erosion

get rid of the small, noisy (artificial) blobs in your binary image, before finding contours

Thanks – works much better now.

your threshold level is rubbish (127 is usually not!), or the input to threshold is rubbish.

see this? those squares are from jpeg compression (of the input to a threshold), but they should usually not be this noticeable.

image

what exactly is the data in self._cartooned? show it to us.