Skip to content

LabelForge v2.0.0

Choose a tag to compare

@github-actions github-actions released this 18 Oct 11:44
· 55 commits to main since this release

LabelForge v2.0.0 — ONNX 图片推理、视频与滑窗区域推理

本版跨越三个新功能域:图片推理、视频、滑窗/区域推理。项目由 PasteLabel 更名为 LabelForge,界面框架由 PyQt5 迁到 PySide6,许可协议由 MIT 改为 LGPL-3.0-only。

✨ 新功能与改进

• ONNX 图片推理:支持 YOLOv5 / YOLOv8 / YOLO11 / YOLO26 四种导出,可对当前图片或整批数据集推理,结果写成 LabelMe 标注
• 模型格式自动识别:从输出形状与模型自带 metadata 判断,歧义形状直接报错要求显式指定格式,不猜(猜错会静默产出错误标注)
• 端到端模型(YOLO26)自动跳过 NMS:其导出已内置 NMS,再跑一遍会静默吞掉重叠框(实测 25 框变 22 框);界面把 NMS 输入框置灰并说明「该模型已内置 NMS,此项不生效」
• 兼容带辅助输出头的第三方自训练导出:按形状挑出主检测头(只看形状不看输出名,因为第三方输出名毫无规律);分割 / 姿态 / OBB 导出会明确拒绝而非瞎挑
• 推理设置行:工具栏四个图标(参数行、▶ 单图、⚡ 批量、漏斗筛选),设置行可关闭,关闭即停止推理但模型保持已加载;阈值与输入尺寸直接写入已加载的模型,调参不再重载模型
• 置信度显示与保存:写入 LabelMe 顶层 score 字段(手工框写 null 占位),画布可显示(固定两位小数,存储保留原始精度),新增「显示置信度」复选框与快捷键 Y 切换
• 类别筛选:可滚动勾选列表,支持全选 / 全不选,按钮上显示 (已选/总数);筛选只作用于本次推理写入的框,不动已有标注
• 推理进度窗:每行带北京时间戳(固定 UTC+8、精确到毫秒)、文件名、该图框数与单张耗时,最新在最上;向上翻历史时不会被新结果拽回底部
• 推理范围:可选全图 / 滑窗 / 区域三种模式,默认全图
• 滑窗推理:参数实时回显、窗口网格在画布上绘出并给每个窗口标 r1c1 式编号,跨窗结果按模型行的 NMS 阈值合并去重,并按可见度过滤过低的框
• 区域推理:画布内联绘制区域、列出区域坐标并带删除按钮、逐区域锁定、四角与边手柄调整、滚轮编辑、缩放感知的命中区域
• 视频抽帧:把视频按时间采样导出为图片数据集(按时间点采样而非固定帧步长整除,29.97 FPS 抽 2 FPS 也能得到准确的 2 FPS),每张图配映射记录写入 video_manifest.json
• 视频合成:把抽帧图片连同各自的标注合成为一段视频,输出原子发布(先写 .partial.mp4,校验通过再改名),失败不留看似成功的输出
• 推理成片:把原视频逐帧跑模型、将框烧进每一帧再编码成新视频,帧数 / 分辨率 / 帧率 / 时长与源视频完全一致,支持叠加标签与滑窗、区域推理
• 视频标签叠加:可勾选类别、类别名、置信度,默认与画布显示一致;标签字号可调并带可展开预览
• 视频功能支持中文路径:Windows 上 cv2 的 imread/imwrite 完全不支持中文路径(imwrite 返回 False 且不写文件),全部改用 imencode / imdecode 绕开
• 新增快捷键 Ctrl+Shift+Z:画布聚焦时删除当前图片的标注
• 参数行新增「批量目标」输入框,默认值为最后一张图
• 设置窗口显示版本号,「恢复默认设置」按钮移到保存旁边
• 画布:在图像任意位置按下即可平移(此前只在缩放后生效),拖出复制改为按鼠标移动触发,区域改为手型光标
• 界面圆角统一:选项弹窗、按钮与输入框统一为 4px,进度条样式抽成统一的主题方法供多处共用
• 推理进度窗时间戳去掉年月日:一次批量推理不跨天,日期是纯噪声,去掉后文件名这一列看得更清
• 画布清空后删除该图的 sidecar json:空 json 会让「从未标注」和「标注后删空」无法区分
• 应用图标重做:橙→品红的 F,SVG 绘制后按每个尺寸单独渲染,资源管理器与任务栏不再靠放大糊掉的 PNG
• 改名不停用旧设置:启动时若发现 ~/.pastelabel.json 且没有新的配置文件,就复制成 ~/.labelforge.json(旧文件保留),环境变量 PASTELABEL_CONFIG_PATH 同样回退

🔧 修复

• 修复加载数据集时静默销毁标注:渐进式加载器对每张图写入空框列表,而缓存命中判定是「键是否存在」——空列表被视为合法的「已加载、结果为零框」,于是加载器替所有还没读过的图标了「没有标注」
• 修复切换图片后旧检测框被写回缓存:缓存命中判定用「列表非空」,导致空结果不被识别为已缓存,切到该图时会重读磁盘并把已清掉的旧框写回
• 修复删除仍有内容的 json:空判断用的是内存中的框列表,漏掉两类实际有内容的文件
• 修复不同类别的框在保存时被当作重复而丢掉:去重只看几何形状,而模型常为一个区域给出多个类别提议,纯几何去重会静默丢掉其中一个
• 修复通过画布右键重命名时改掉所有同名框:该菜单调用的是整类重命名,现在只改当前这一个框
• 修复画布完全空白且无任何报错:绘制时取值写错了变量名,异常被 paintEvent 的兜底 except 吞掉(未捕获异常会让 Qt 直接终止进程)
• 修复删除已加载的背景文件夹后刷新,界面仍在撒谎:列表仍指向不存在的文件、画布仍显示最后一张图
• 修复设置窗口里放大器的四个选项在中英文界面都显示中文(侧边 / 鼠标中心 / 窗口放大器尺寸 / 放大器显示位置):这些键中文表里也缺失,取值失败时回退到键本身,编辑时看着正常
• 修复标注质检的小目标判据与标定前提不符:原判据各轴各比各的,而预处理是等比缩放,短边的缩水被抹掉;改为原图与框一起等比换算到 640 输入空间判断
• 修复打包版一点「数据增强」或「格式转换」就崩(AttributeError: 'QTextCursor' object has no attribute 'End'):光标枚举原来取在实例上,PyQt5 允许、PySide6 不允许,迁移时漏改了两处日志框
• 修复关键点落在检测框内时,画布右键弹出的是检测框的菜单:左键的命中顺序是「关键点在最上层」,右键却按列表顺序取第一个命中的框,两者口径不一致
• 修复统计窗的图表再也回不到 1:1:等高归一化只在「四个面板堆成一列」时才执行,而默认排布是 2×2 两列,于是同一列上下被拖成 1:2 后就无人纠正;拖分隔条也只改几何、不发 dockLocationChanged,连触发都等不到。现在行内等宽、列内等高,拖完左右比例一并回到默认
• 修复切换工作视图后已标注图片的圆点变回灰色:视图切换只重建列表行、不重启后台扫描,状态要等下次切图才补上
• 修复统计窗的表格、表头、面板标题与颜色按钮四角是直角,统一为项目一致的 4px 圆角

📦 其他变更

• 项目更名 PasteLabel → LabelForge:包目录、配置文件、CLI 名称、文档同步,旧配置自动沿用
• 界面框架由 PyQt5 换成 PySide6(Qt6)
• 许可协议由 MIT 改为 LGPL-3.0-only:换绑定并不能回避 Qt 的 LGPL,PyQt 的 wheel 里带的也是 LGPL 版 Qt;一文件打包的 exe 无法满足 4(d)(1),采用 4(d)(0) 路线(开放源码 + 可替换的 Qt),LICENSE 与 THIRD-PARTY.md 随源码仓库提供
• Linux 包照常提供,但构建基线由 Ubuntu 18.04 上调到 20.04(glibc 2.31):PySide6 需要 glibc ≥ 2.28,18.04 装不上;同时把 PySide6 上限钉在 <6.10,因为 6.10 的 Linux wheel 要求 glibc 2.34,会在无人察觉的情况下再把门槛抬高
• 依赖版本以 requirements.txt 为唯一出处,CI 直接读它,避免两处各钉一份
• 新增运行时依赖 cv2,钉到 opencv-python-headless>=4.10,<4.11(只用 headless,不要与其它 OpenCV 发行版混装)
• 内部重构:画布滚轮处理、主题样式表、统计健康面板等拆成小函数;框命中判定、并发扫描、关闭处理收敛到共享实现(行为不变,为后续修改降低出错面)