You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

含障碍物多维地图的路径区域识别:求地图转多边形的Python实现方案

解决方案:从栅格地图提取区域多边形并判断路径点归属

可用Python库及实现方案

1. OpenCV(推荐,与现有代码兼容)

你已经在用OpenCV生成地图,直接用它的轮廓检测功能就能提取区域多边形,无需额外依赖,性能也足够应对小规模地图。

实现步骤:

  • 提取区域轮廓:用cv2.findContours检测地图中值为1的连通区域轮廓,每个轮廓对应一个区域的多边形顶点。
  • 判断点归属:用cv2.pointPolygonTest判断路径点是否在多边形内(返回值≥0表示在内部或边界上)。

示例代码:

import cv2
import numpy as np

def get_polygons_from_map(map_array):
    # 寻找最外层轮廓,适配独立区域
    contours, _ = cv2.findContours(map_array, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    # 将轮廓转换为多边形顶点数组
    polygons = [cnt.reshape(-1, 2) for cnt in contours]
    # 为每个区域命名
    area_names = [f"Area{i+1}" for i in range(len(polygons))]
    return area_names, polygons

# 示例地图
map = np.array([
    [1,1,1,1],
    [0,0,0,0],
    [0,0,1,1],
    [0,1,1,0]
], dtype=np.uint8)

# 获取命名区域和对应多边形
area_names, polygons = get_polygons_from_map(map)

# 路径点归属判断
path = [(0,0), (1,0), (1,1), (2,1), (2,2)]
areas = []
for point in path:
    # 转换坐标:原路径点是(row,col),OpenCV用(col,row)格式
    cv_point = (point[1], point[0])
    matched_area = None
    for idx, poly in enumerate(polygons):
        if cv2.pointPolygonTest(poly, cv_point, False) >= 0:
            matched_area = area_names[idx]
            break
    areas.append(matched_area)

print(areas)  # 输出: ['Area1', None, None, None, 'Area2']

2. scikit-image

适合偏向图像处理的场景,通过标记连通区域再提取轮廓的方式获取多边形。

示例代码片段:

from skimage import measure
import numpy as np

def get_polygons_from_map(map_array):
    # 标记所有连通区域
    labeled_regions = measure.label(map_array, connectivity=2)
    region_props = measure.regionprops(labeled_regions)
    
    area_names = []
    polygons = []
    for i, region in enumerate(region_props):
        # 提取区域轮廓坐标
        contour = measure.find_contours(labeled_regions == region.label, 0.5)[0]
        # 转换为整数栅格坐标
        contour = np.round(contour).astype(int)
        polygons.append(contour)
        area_names.append(f"Area{i+1}")
    return area_names, polygons

# 后续点归属判断可结合shapely或自定义点-in-多边形算法实现

3. shapely(专业几何处理)

如果需要更灵活的几何操作,shapely提供了原生的多边形、点归属判断能力。

示例代码:

from shapely.geometry import Point, Polygon
from shapely.ops import unary_union
from skimage.measure import label
import numpy as np

def get_polygons_from_map(map_array):
    # 获取所有值为1的栅格坐标(row, col)
    all_coords = np.argwhere(map_array == 1)
    # 标记连通区域
    labeled_regions = label(map_array, connectivity=2)
    unique_regions = np.unique(labeled_regions[labeled_regions != 0])
    
    area_names = []
    polygons = []
    for i, region_id in enumerate(unique_regions):
        # 筛选当前区域的所有坐标
        region_coords = all_coords[labeled_regions[all_coords[:,0], all_coords[:,1]] == region_id]
        # 转换为shapely支持的(x,y)格式(col, row)
        poly_coords = [(c[1], c[0]) for c in region_coords]
        # 生成区域多边形
        polygon = unary_union([Point(p) for p in poly_coords]).convex_hull
        polygons.append(polygon)
        area_names.append(f"Area{i+1}")
    return area_names, polygons

# 路径点归属判断
path = [(0,0), (1,0), (1,1), (2,1), (2,2)]
areas = []
area_names, polygons = get_polygons_from_map(map)
for point in path:
    p = Point(point[1], point[0])
    matched_area = None
    for idx, poly in enumerate(polygons):
        if p.within(poly) or p.touches(poly):
            matched_area = area_names[idx]
            break
    areas.append(matched_area)

print(areas)  # 输出: ['Area1', None, None, None, 'Area2']

性能说明

你的地图元素数量不多,上述三种方案的性能都完全够用:

  • OpenCV的轮廓检测基于C++实现,速度最快;
  • scikit-image和shapely在小规模数据下的耗时可忽略不计。

内容的提问来源于stack exchange,提问作者Leon0402

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 16:36:22