def find_concetric_circles(gray_img,min_ring_count=3, visual_debug=False):
# get threshold image used to get crisp-clean edges using blur to remove small features
edges = cv2.adaptiveThreshold(cv2.blur(gray_img,(3,3)), 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 5, 11)
_, contours, hierarchy = cv2.findContours(edges,
mode=cv2.RETR_TREE,
method=cv2.CHAIN_APPROX_NONE,offset=(0,0)) #TC89_KCOS
if visual_debug is not False:
cv2.drawContours(visual_debug,contours,-1,(200,0,0))
if contours is None or hierarchy is None:
return []
clusters = get_nested_clusters(contours,hierarchy[0],min_nested_count=min_ring_count)
concentric_cirlce_clusters = []
#speed up code by caching computed ellipses
ellipses = {}
# for each cluster fit ellipses and cull members that dont have good ellipse fit
for cluster in clusters:
if visual_debug is not False:
cv2.drawContours(visual_debug, [contours[i] for i in cluster],-1, (0,0,255))
candidate_ellipses = []
for i in cluster:
c = contours[i]
if len(c)>5:
if not i in ellipses:
e = cv2.fitEllipse(c)
fit = max(dist_pts_ellipse(e,c))
ellipses[i] = e,fit
else:
e,fit = ellipses[i]
a,b = e[1][0]/2.,e[1][1]/2.
if fit<max(2,max(e[1])/20):
candidate_ellipses.append(e)
if visual_debug is not False:
cv2.ellipse(visual_debug, e, (0,255,0),1)
if candidate_ellipses:
cluster_center = np.mean(np.array([e[0] for e in candidate_ellipses]),axis=0)
candidate_ellipses = [e for e in candidate_ellipses if np.linalg.norm(e[0]-cluster_center)<max(3,min(e[1])/20) ]
if len(candidate_ellipses) >= min_ring_count:
concentric_cirlce_clusters.append(candidate_ellipses)
if visual_debug is not False:
cv2.ellipse(visual_debug, candidate_ellipses[-1], (0,255,255),4)
#return clusters sorted by size of outmost cirlce biggest first.
return sorted(concentric_cirlce_clusters,key=lambda e:-max(e[-1][1]))
评论列表
文章目录