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

Python如何对二值图边界xy坐标二维数组按顺时针排序优化绘图

你当前得到的bw数组是逐行逐列扫描得到的边界点集合,点的存储顺序是行优先排列,和轮廓上的相邻位置顺序无关,所以直接连线时会出现路径交叉、穿过1值区域的问题。只需要把边界点按轮廓相邻的顺时针顺序重新排列即可解决。

顺时针重排实现代码

def sort_boundary_clockwise(boundary_points, origin):
    # 移除末尾重复的闭合原点,得到去重边界点集合
    points = boundary_points[:-1].tolist()
    # 定义8邻域顺时针搜索的偏移顺序(行偏移量,列偏移量)
    search_order = [(-1, 1), (0, 1), (1, 1), (1, 0), (1, -1), (0, -1), (-1, -1), (-1, 0)]
    sorted_points = [origin.tolist()]
    current_point = origin.tolist()
    points.remove(current_point)

    while points:
        found = False
        # 按顺时针顺序查找当前点的相邻边界点
        for dy, dx in search_order:
            next_candidate = [current_point[0] + dy, current_point[1] + dx]
            if next_candidate in points:
                sorted_points.append(next_candidate)
                points.remove(next_candidate)
                current_point = next_candidate
                found = True
                break
        if not found:
            # 无相邻点时直接追加剩余点(单连通边界场景下不会触发)
            sorted_points.extend(points)
            break
    # 追加原点形成闭合轮廓
    sorted_points.append(origin.tolist())
    return np.array(sorted_points)

调用方法

在原有代码基础上新增如下逻辑即可:

# 顺时针重排边界点
sorted_bw = sort_boundary_clockwise(bw, origin)
# 绘制重排后的轮廓
plt.plot(sorted_bw[:,1], sorted_bw[:,0])
plt.gca().invert_yaxis()
plt.axis('equal') # 保持坐标轴比例一致,避免轮廓变形
plt.show()

可选优化(消除锯齿)

如果需要进一步得到顺滑无锯齿的轮廓,可以对重排后的坐标做样条平滑处理,示例如下(需要安装scipy库):

from scipy.interpolate import splprep, splev

# 取除了末尾重复原点的点做插值
tck, u = splprep([sorted_bw[:,1], sorted_bw[:,0]], s=0.5, per=1)
u_new = np.linspace(0, 1, 1000)
x_smooth, y_smooth = splev(u_new, tck)
plt.plot(x_smooth, y_smooth)
plt.gca().invert_yaxis()
plt.axis('equal')
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 21:45:03