图像边缘处find_contours的轮廓闭合问题
解决find_contours处理跨边界物体时的开放轮廓闭合问题
针对目标物体超出图像边界时,measure.find_contours无法自动闭合开放轮廓的问题,提供以下几种实用解决思路:
1. 手动检测并闭合边界轮廓
遍历每个提取到的轮廓,判断其起点和终点是否位于图像边界,若均在边界上,直接将轮廓首尾相连完成闭合:
import numpy as np import matplotlib.pyplot as plt from skimage import measure r = masks[1]['segmentation'] h, w = r.shape contours = measure.find_contours(r, 0.8) # 处理开放轮廓 closed_contours = [] for contour in contours: start = contour[0] end = contour[-1] # 判断点是否在图像边界(上下左右边缘) def on_edge(point): y, x = point return y == 0 or y == h-1 or x == 0 or x == w-1 if on_edge(start) and on_edge(end): # 首尾相连闭合轮廓 closed_contour = np.vstack([contour, start]) closed_contours.append(closed_contour) else: closed_contours.append(contour) # 可视化结果 fig, ax = plt.subplots() ax.imshow(r, cmap=plt.cm.gray) for contour in closed_contours: ax.plot(contour[:, 1], contour[:, 0], linewidth=2) ax.axis('image') ax.set_xticks([]) ax.set_yticks([]) plt.show()
2. 扩展图像边界后提取轮廓
在原图像周围添加一圈背景像素,让跨边界的物体被完整包裹,此时find_contours会生成闭合轮廓,最后修正坐标对应原图像:
import numpy as np import matplotlib.pyplot as plt from skimage import measure r = masks[1]['segmentation'] # 上下左右各扩展1像素背景(0值) extended_r = np.pad(r, pad_width=1, mode='constant', constant_values=0) contours = measure.find_contours(extended_r, 0.8) # 修正轮廓坐标,减去扩展的1像素偏移 corrected_contours = [cnt - 1 for cnt in contours] # 可视化结果 fig, ax = plt.subplots() ax.imshow(r, cmap=plt.cm.gray) for contour in corrected_contours: ax.plot(contour[:, 1], contour[:, 0], linewidth=2) ax.axis('image') ax.set_xticks([]) ax.set_yticks([]) plt.show()
3. 结合regionprops与凸包生成闭合轮廓
利用regionprops获取区域信息,通过凸包算法补全跨边界部分,生成闭合轮廓:
import numpy as np import matplotlib.pyplot as plt from skimage import measure, label from skimage.morphology import convex_hull_image r = masks[1]['segmentation'] # 标记图像中的区域 label_img = label(r) region_props = measure.regionprops(label_img) fig, ax = plt.subplots() ax.imshow(r, cmap=plt.cm.gray) for prop in region_props: # 生成区域的凸包 hull = convex_hull_image(prop.image) # 提取凸包轮廓并转换到原图像坐标 hull_contours = measure.find_contours(hull, 0.5) for hull_cnt in hull_contours: # 加上区域的bbox偏移量,还原到原图像位置 contour = hull_cnt + prop.bbox[:2] ax.plot(contour[:, 1], contour[:, 0], linewidth=2) ax.axis('image') ax.set_xticks([]) ax.set_yticks([]) plt.show()
内容的提问来源于stack exchange,提问作者ewittry
相关产品推荐
相关产品推荐

