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
相关产品推荐
相关产品推荐

