如何从NumPy布尔网格中提取多边形的外部坐标?
从NumPy布尔网格提取多边形外部坐标的解决方案
我来帮你搞定这个问题!从布尔网格里提取多边形的外部坐标,本质就是找出True区域的轮廓边界,这里有几个实用的方法,你可以根据自己的开发环境选合适的:
方法一:用OpenCV快速提取轮廓
OpenCV的轮廓检测功能非常成熟,处理这类网格简直是小菜一碟,步骤很清晰:
- 先把布尔数组转换成OpenCV能处理的格式:把
True转成255(白色),False转成0(黑色),并改成uint8类型。 - 调用
findContours函数,指定只找最外层轮廓(RETR_EXTERNAL),同时用CHAIN_APPROX_SIMPLE压缩轮廓点,避免冗余。 - 提取轮廓坐标,调整格式到你需要的样子。
直接上代码示例:
import numpy as np import cv2 # 你的16x16布尔网格示例(补全部分行方便测试) grid = np.array([ [False, False, False, False, False, False, True, True, True, True, False, False, False, False, False, False], [False, False, False, False, False, True, True, True, True, True, True, False, False, False, False, False], [False, False, False, False, False, False, False, False, False, False, True, True, False, False, False, False], [False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False], [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] ]) # 转换为OpenCV兼容的8位图像格式 binary_img = (grid * 255).astype(np.uint8) # 查找最外层轮廓,忽略内部小轮廓 contours, _ = cv2.findContours(binary_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 提取第一个轮廓(假设只有一个目标多边形),squeeze去掉多余维度,得到(N,2)的坐标数组 external_coords = contours[0].squeeze() # 注意:OpenCV返回的坐标是(列,行),如果需要和NumPy的(行,列)索引一致,交换一下顺序 external_coords = external_coords[:, [1, 0]] print("提取的外部坐标(行, 列):") print(external_coords)
小提示
如果你的网格里有多个独立的True区域,contours会是一个列表,每个元素对应一个区域的轮廓,你可以遍历列表逐个处理。
方法二:用scikit-image提取轮廓
如果你更习惯用scikit-image这个图像处理库,它的find_contours函数也能轻松搞定,而且返回的坐标直接是(行,列)格式,不用额外转换:
import numpy as np from skimage.measure import find_contours # 同样用示例网格 grid = np.array([ [False, False, False, False, False, False, True, True, True, True, False, False, False, False, False, False], [False, False, False, False, False, True, True, True, True, True, True, False, False, False, False, False], [False, False, False, False, False, False, False, False, False, False, True, True, False, False, False, False], [False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False], [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] ]) # 查找轮廓,level=0.5是因为我们把布尔数组转成浮点后,True是1,False是0,0.5刚好是分界值 contours = find_contours(grid.astype(float), level=0.5) # 提取第一个外部轮廓 external_coords = contours[0] print("提取的外部坐标(行, 列):") print(external_coords)
小提示
这个方法返回的坐标是连续的浮点数,如果需要整数坐标,直接用external_coords.astype(int)转换就行。
手动实现思路(适合理解原理)
如果你不想依赖第三方库,也可以手动找边界点:遍历网格里所有True的点,判断它的邻域(上下左右或8个方向)是否有False的点,这类点就是边界点。不过手动把这些边界点按顺序排列成多边形会比较麻烦,需要用排序算法(比如按顺时针/逆时针),所以还是推荐用上面的现成库方法,省事儿又高效。
内容的提问来源于stack exchange,提问作者Eduardo
相关产品推荐
相关产品推荐

