2024-05-20 15:45:30
提取开放曲线轮廓顶点并保持遍历顺序的问题
我需要提取下图中开放曲线的轮廓顶点,且顶点必须按沿轮廓遍历的顺时针/逆时针顺序排列,用于后续计算。

尝试1:使用OpenCV的cv2.findContours()
调用该方法提取轮廓时,返回的是闭合轮廓,存在明显的折返问题:

我尝试仅保留唯一坐标,但这样会破坏顶点的遍历顺序(忽略图中红线):

对应的代码片段:
dirPictures = os.listdir(sourcePath) for path in dirPictures: if '.' in path and path.split('.')[-1].lower() in acceptedFileTypes: # 重置绘图默认尺寸 plt.rcParams["figure.figsize"] = plt.rcParamsDefault["figure.figsize"] plt.gca().invert_yaxis() # 提取轮廓 img = cv2.imread(sourcePath + '/' + path, cv2.IMREAD_GRAYSCALE) cont, hier = cv2.findContours(img, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
尝试2:np.where()结合排序
原本以为这种方法可行,但在部分案例中失效——因为轮廓顶点并非从边缘开始,排序方案不适用:

预期的最终效果:
尝试3:使用Potrace库提取SVG路径
使用Potrace库尝试提取路径,同样失败:
对应的代码片段:
# 提取轮廓 img = cv2.imread(sourcePath + '/' + path, cv2.IMREAD_GRAYSCALE) img = np.array(img) # 从数组创建位图 bmp = potrace.Bitmap(img) # 追踪位图生成路径 path = bmp.trace() # 遍历路径曲线 x = [] y = [] for curve in path: print("start_point =", curve.start_point) for segment in curve: print(segment) end_point_x, end_point_y = segment.end_point.x, segment.end_point.y if segment.is_corner: c_x, c_y = segment.c.x, segment.c.y else: c1_x, c1_y = segment.c1.x, segment.c1.y c2_x, c2_y = segment.c2.x, segment.c2.y x.append(c1_x) y.append(c1_y) x.append(c2_x) y.append(c2_y) # 转换为坐标对数组 [[x,y]...] k = np.stack((x,y), axis=-1) # 保留有序的唯一点 _, idx = np.unique(k, axis=0, return_index=True) k = k[np.sort(idx)] plt.plot(k[:,0], k[:,1], 'g.-') plt.show()
内容的提问来源于stack exchange,提问作者user22034139
相关产品推荐
相关产品推荐

