我定义了环形 ROI 选择函数,我想找到该区域的轮廓。但轮廓像素值与零相邻,并且遮蔽区域之外的像素值等于零。因此轮廓无法捕捉阈值图像。
如果功能正常,我如何定义环形 ROI 或找到轮廓
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)
阈值化之后和获取轮廓之前,您可以将感兴趣的区域与外部区域分开。或者更好的是,您可以在阈值化之后而不是之前切割您的兴趣区域。最后可以根据面积大小过滤出相关轮廓。
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)
结果:
你的想法是对的!你只是圆心错了:
mask1 = cv2.circle(mask1, center, innerR, (255, 255, 255), -1)
mask2 = cv2.circle(mask2, center, outerR, (255, 255, 255), -1)
会成功的。