如何使用skimage的regionprops获取不规则形状的内部中心点
不规则形状物体内部中心点获取方法
你用regionprops默认返回的centroid是区域所有像素的坐标均值,对于凹形等不规则物体确实很容易落在区域外,下面是几种可直接落地的实现方案:
方案1:最大内切圆圆心(推荐,适配绝大多数场景)
这个点是物体内部可容纳的最大圆形的圆心,100%落在物体内部且尽可能远离边缘,非常适合文本标注的场景,实现方式如下:
import cv2 import numpy as np from skimage.measure import regionprops # 输入参数:mask是单物体的二值掩码,前景值为1/255,背景为0 mask = mask.astype(np.uint8) # 第一步:计算距离变换,每个前景像素的值等于其到最近背景像素的距离 dist_transform = cv2.distanceTransform(mask, cv2.DIST_L2, 5) # 第二步:取距离变换的最大值对应的坐标,就是最大内切圆圆心 min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(dist_transform) # 输出的max_loc是(x,y)格式,直接兼容OpenCV的putText坐标要求 inner_center = max_loc
如果你的scikit-image版本≥0.24,也可以直接调用regionprops的内置属性获取:
props = regionprops(mask)[0] # 直接返回(y,x)格式的最大内切圆圆心,转成OpenCV的(x,y)格式即可 inner_center = (int(props.centroid_weighted[1]), int(props.centroid_weighted[0]))
方案2:骨架中点(适配长条/弯管状不规则物体)
如果你的物体是细长型结构,最大内切圆圆心可能偏置在较粗的一端,用骨架中点效果更好:
from skimage.morphology import skeletonize import numpy as np # 提取物体骨架 skeleton = skeletonize(mask.astype(bool)) # 取所有骨架像素坐标的中位数,避免端点干扰 y_list, x_list = np.where(skeleton == 1) inner_center = (int(np.median(x_list)), int(np.median(y_list)))
方案3:质心校正(适配低计算资源的轻量场景)
如果对精度要求不高,也可以直接对落在外部的质心做快速校正:
from skimage.measure import regionprops import numpy as np props = regionprops(mask.astype(int))[0] centroid_y, centroid_x = props.centroid centroid_x, centroid_y = int(centroid_x), int(centroid_y) # 判断质心是否落在物体内部 if mask[centroid_y, centroid_x] == 0: # 找到距离质心最近的前景像素作为替代中心点 y_coords, x_coords = np.where(mask == 1) dist_arr = (x_coords - centroid_x)**2 + (y_coords - centroid_y)**2 nearest_idx = np.argmin(dist_arr) inner_center = (x_coords[nearest_idx], y_coords[nearest_idx]) else: inner_center = (centroid_x, centroid_y)
内容的提问来源于stack exchange,提问作者Adam Boyher
相关产品推荐
相关产品推荐

