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

PyQt5图像标注扩展:实现多闭合单元格可编辑多边形功能

核心选型结论
  • 原生QGraphicsPolygonItem无法直接满足多闭合单元格标注需求:该类仅支持维护单个闭合多边形的点集,没有内置多子区域、跨区域共享节点/边的拓扑管理逻辑,强行改造需要额外维护大量关联关系,开发成本高、后续扩展难。
  • 不需要完全基于QPainterPath从零开发,最优方案是自定义拓扑数据层+QPainterPath渲染层的组合结构,原有可编辑多边形的顶点交互逻辑可以直接复用,灵活度远高于硬套原生图元。
具体实现路径

1. 先搭独立的拓扑数据层,和渲染逻辑解耦

不要把业务数据存在原生图元对象里,自己维护三层核心数据结构:

  • 节点:存储每个顶点的全局唯一ID、场景坐标,同时记录该节点关联的所有边ID;做节点吸附判定时,设置3-5像素的距离阈值,鼠标点击位置和节点距离小于阈值即判定为选中已有节点,满足新增多段线起止点必须落于已有节点的要求。
  • 边:存储每条边的两个端点ID、所属单元格ID,按无向边逻辑存储,避免重复记录不同单元格共享的分割边。
  • 单元格:存储每个闭合标注区域的边ID列表、有序点序列,对应最终输出的标注单元。

原有参考代码里的顶点拖拽、选中高亮逻辑可以直接复用,只需要把交互句柄和你自定义的节点对象绑定,而非绑定QGraphicsPolygonItem的内置点。

2. 扩展交互逻辑

保留原有代码的多边形选中、顶点拖拽能力,新增分割多段线的绘制流程:

  • 初始绘制/导入外轮廓多边形时,自动把所有顶点注册到节点层,外轮廓边注册到边层,生成第一个初始单元格。
  • 新增「绘制分割线」交互模式,可通过工具栏按钮或快捷键触发,模式下的交互逻辑:
    • 首次点击必须吸附到已有节点作为多段线起点,吸附成功后显示随鼠标移动的临时橡皮线
    • 绘制过程中点击空白画布可添加中间顶点,新顶点自动注册到节点层,相邻顶点自动生成临时边
    • 结束绘制时最后一次点击必须吸附到另一个已有节点作为终点,自动完成本次多段线录入
  • 多段线绘制完成后自动更新拓扑:以新生成的边为分割边界,通过环遍历算法(从新边端点出发,沿邻接边按固定顺/逆时针方向遍历直到回到起点)自动拆分出被分割的新单元格,同步更新节点、边、单元格三层的关联关系。

3. 渲染层实现

不需要重写全套绘制逻辑:

  • 遍历拓扑数据动态拼接QPainterPath:每个闭合单元格对应路径里的一个闭合子路径,共享边只绘制一次,避免多图元叠加导致的重影、锯齿问题,单元格数量较多时渲染性能远高于多个独立QGraphicsPolygonItem叠加。
  • 顶点编辑句柄单独实现为QGraphicsEllipseItem子类,拖拽句柄时同步更新关联节点坐标、关联边和单元格的路径数据,触发视图重绘即可。
  • 需要做单元格选中高亮时,直接给对应单元格的子路径设置单独的高亮画刷/画笔即可,不需要额外做图元拾取判断。
标注数据提取

不需要从渲染图元反向解析数据,直接从自定义的拓扑数据层导出即可:

  • 点数据:遍历所有节点,输出节点ID、对应场景坐标
  • 边数据:遍历所有边,输出边的两个端点ID、端点坐标、关联的单元格ID
  • 单元格数据:遍历所有单元格,输出单元格的有序点序列、包含的边列表,直接满足标注结果的导出要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 06:30:46