Ali Ünsal
Ali Ünsal

Reputation: 11

OpenCV Annulus region of interest

I defined annulus ROI selection function and i would like to find contours in this area. But contours pixel values are neighbors to the zero and out of masked areas equal to zero. Therefore contours couldn't be catch thresholded image.

How can i define annulus ROI or find the contours if function is ok

    def annulusROI(img, center, innerR, outerR):
        """
        img: Image matrix
        center: ROI center point [px] (x,y tuple)
        innerR: ROI inner radius [px]
        outerR: ROI outer radius [px]
        mode: Mask selection for white (255, 255, 255), for black (0, 0, 0) [BGR tuple]
    
        return roi matrix and left-top start point coordinate
        """
        outRoi, rectC = rectangleROI(img, center, outerR*2, outerR*2)
        mask1 = np.zeros_like(outRoi)
        mask2 = np.zeros_like(outRoi)
        mask1 = cv2.circle(mask1, (round(outerR),round(outerR)), innerR, (255, 255, 255), -1)
        mask2 = cv2.circle(mask2, (round(outerR),round(outerR)), outerR, (255, 255, 255), -1)
        mask = cv2.subtract(mask2, mask1)
        roi = cv2.bitwise_and(outRoi, mask)
    
        return roi, (center[0]-outerR, center[1]-innerR)

contour

thresholded roi returned image

Upvotes: 0

Views: 304

Answers (2)

jeremy_rutman
jeremy_rutman

Reputation: 5788

You had the right idea! You just had the circle centers wrong:

mask1 = cv2.circle(mask1, center, innerR, (255, 255, 255), -1)
mask2 = cv2.circle(mask2, center, outerR, (255, 255, 255), -1)

will do the trick.

Upvotes: 0

Markus
Markus

Reputation: 6298

After thresholding and before getting the contours you can separate the region of interest from the outer area. Or even better you can cut your region of interest after thresholding, not before. Finally you can filter out the releavant contours by area size.

import cv2


# get image threshold
img = cv2.imread("img.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray, 64, 255, 0)

# separate annulus from outer area
h, w, _ = img.shape
center = (round(w / 2), round(h / 2))
innerR = 246
outerR = 306

cv2.circle(thresh, center, innerR, 255)
cv2.circle(thresh, center, outerR, 255)

# filter contours by relevant area size
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cc = [c for c in contours if 100 < cv2.contourArea(c) < 5000]
cv2.drawContours(img, cc, -1, (0, 0, 255))

cv2.imwrite("out.png", img)

Result:

output

Upvotes: 0

Related Questions