Last active
July 16, 2024 04:58
-
-
Save DIYer22/f82dc329b27c2766b21bec4a563703cc to your computer and use it in GitHub Desktop.
Get the maximum/largest inscribed circle inside mask/polygon/contours based on cv2. Support non-convex/hollow shape.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cv2 | |
import numpy as np | |
def get_test_mask(): | |
# Create an image | |
r = 100 | |
mask = np.zeros((4 * r, 4 * r), dtype=np.uint8) | |
# Create a sequence of points to make a contour | |
vert = [None] * 6 | |
vert[0] = (3 * r // 2, int(1.34 * r)) | |
vert[1] = (1 * r, 2 * r) | |
vert[2] = (3 * r // 2, int(2.866 * r)) | |
vert[3] = (5 * r // 2, int(2.866 * r)) | |
vert[4] = (3 * r, 2 * r) | |
vert[5] = (5 * r // 2, int(1.34 * r)) | |
# Draw it in mask | |
for i in range(6): | |
cv2.line(mask, vert[i], vert[(i + 1) % 6], (255), 63) | |
return mask | |
mask = get_test_mask() | |
""" | |
Get the maximum/largest inscribed circle inside mask/polygon/contours. | |
Support non-convex/hollow shape | |
""" | |
dist_map = cv2.distanceTransform(mask, cv2.DIST_L2, cv2.DIST_MASK_PRECISE) | |
_, radius, _, center = cv2.minMaxLoc(dist_map) | |
result = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR) | |
cv2.circle(result, tuple(center), int(radius), (0, 0, 255), 2, cv2.LINE_8, 0) | |
# minEnclosingCircle directly by cv2 | |
contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[-2:] | |
center2, radius2 = cv2.minEnclosingCircle(np.concatenate(contours, 0)) | |
cv2.circle(result, (int(center2[0]), int(center2[1])), int(radius2), (0, 255, 0,), 2) | |
cv2.imshow("mask", mask) | |
cv2.imshow("result", result) | |
cv2.waitKey(0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Red circle is max inscribed circle