AnnotationCheck

April 17, 2026 · View on GitHub

双模态(可见光 + 红外光)图像序列标注审核工具,支持逐帧对照文本编辑、违规自动检测与问题标记,欢迎Star和PR🎉

teaser


0. 更新日志

V1.2

  • 全新功能:Paraphrase 批量改写:新增针对 HALLUCINATION 帧的一键批量改写能力(按钮入口 + Ctrl+R 快捷键)
  • 新功能请求链路paraphrase 统一走 Anthropic SDK(MiniMax Anthropic 兼容端点),自动解析返回中的 text content block
  • 新功能配置项:新增并启用 paraphrase 相关配置(paraphrase_modelminimax_api_keyopenai_base_urlopenai_api_keyopenai_model
  • Prompt 长度约束增强:改写结果新增硬性要求 不超过 30 词,并尽量控制在 20 词以内
  • 改写结果流转:改写成功后自动移除 HALLUCINATION 并写入 AI_GENERATED 标记,同时刷新违规检测与问题列表
  • 标记帧稳定性修复:修复 FLAG_TYPES 与弹窗文案不一致导致的“标记帧卡死/退出”问题(补齐 AI_GENERATED 并增加兜底文案)
  • 幻觉队列实时同步:手动新增/取消 HALLUCINATION 后,批量改写队列立即更新,不再出现“当前序列没有幻觉帧”的误提示
  • 鼠标侧键翻帧:支持 XButton1/XButton2 直接切换上一帧/下一帧
  • 文本编辑体验优化
    • 拖拽选区按“整词边界”吸附,减少截断单词
    • 编辑区字号和行间距增大,降低误选到下一行
    • 每次编辑后自动压缩连续空格(保留换行),避免删除后出现双空格/多空格

V1.1

  • 自动保存:修改当前帧文本后,切换帧(键盘/按钮/表格点击)时自动保存当前修改,无需手动点击保存
  • 修改标记:编辑后的帧在右侧问题列表中自动添加绿色 MODIFIED 标记,会覆盖该帧原有的其他手动标记
  • 下一修改导航:新增「下一修改 ▶」按钮,快速定位到下一个修改过的帧
  • 翻译额度警示:开通翻译功能说明中加入每月免费额度(100万字符)及额度监控链接

目录

  1. 更新日志
  2. 数据组织格式
  3. 环境配置
  4. 启动方式
  5. 界面布局
  6. 核心操作流程
  7. 编辑与保存逻辑
  8. 备份机制
  9. 违规自动检测
  10. 问题帧标记
  11. 审核进度管理
  12. 快捷键参考
  13. 文件结构
  14. 阿里云翻译功能
  15. Paraphrase 批量改写功能
  16. 常见问题

1. 数据组织格式

目录结构

data/
├── visual/                          # 图像数据(由 ZIP 包解压而来)
│   └── {序列名}/                    # 序列目录
│       ├── visible/                 # 可见光图像:v000001.jpg, v000002.jpg ...
│       └── infrared/               # 红外光图像:i000001.jpg, i000002.jpg ...

├── text/                            # 文本标注(与图像序列一一对应)
│   ├── {序列名}.txt                 # 每行对应一帧,与 visible/infrared 帧数严格对应
│   ├── backup/                     # 自动备份(每序列最多保留 10 份)
│   │   └── {序列名}/
│   │       └── {序列名}_20260414_153022.txt   # 时间戳备份
│   └── translations/               # 译文缓存(自动生成)
│       └── {序列名}_translations.json          # 各帧译文,格式 {帧序号: "译文"}

└── review/                         # 审核状态记录
    ├── progress.json                # 所有序列的审核进度
    └── {序列名}_flags.json          # 该序列的问题帧标记

文件命名规则

类型命名格式示例
可见光帧v + 6 位序号v000001.jpg
红外帧i + 6 位序号i000001.jpg
文本标注序列名 .txtbus.txt
图像序列目录二级同名目录bus/bus/

文本标注格式

  • 编码:UTF-8
  • 换行:Unix LF\n),末行无末尾换行符
  • 每行对应一帧,read().splitlines() 解析,行号从 1 开始(帧号从 1 开始)
  • 标注内容要求:
    • 标准长度 ≤ 20 词,建议不超过 30 词(绝对上限)
    • 纯英文,禁止中英混杂
    • 相邻帧描述不得完全相同
    • 不得含乱码字符

2. 环境配置

依赖

版本要求说明
Python≥ 3.8推荐 3.9
PyQt5≥ 5.15GUI 框架
Pillow≥ 9.0图像解码(绕过 Qt JPEG 插件问题)
natsort≥ 8.4自然排序(文件名 1, 2, 10 正确排列)
alibabacloud_alimt20181012= 1.1.0阿里云机器翻译 SDK
anthropic≥ 0.40.0Paraphrase(Anthropic 兼容 API)

安装

# 激活 conda 环境
conda activate p39

# 安装依赖
pip install PyQt5==5.15.7 Pillow==9.5.0 natsort==8.4.0 alibabacloud_alimt20181012==1.1.0

注意:本项目使用的 conda 环境 p39 中 PyQt5 缺少内置 JPEG 解码插件, 程序通过 Pillow 解码图像并转换为 Qt 可处理的格式,完全不依赖 Qt 的 JPEG 插件, 在任何环境下均可正常运行。


3. 启动方式

方式一:直接运行源码(开发/调试用)

conda activate p39
cd 项目根目录
python main.py

方式二:运行打包后的 exe(推荐最终用户使用)

dist/AnnotationCheck.exe   ← 双击直接运行,无需安装 Python 环境

打包版本已将 conda Qt 运行时 DLL 和插件目录嵌入 exe,单文件分发,无需任何依赖。


4. 界面布局

┌──────────────────────────────────────────────────────────────────────────┐
│  菜单栏:文件  视图  编辑  工具  帮助                                       │
├──────────────────────────────────────────────────────────────────────────┤
│  [打开数据集] [保存] │ [切换模态 Tab] │ [|◀][◀]  47/113  [▶][▶|] │ [标记帧 F] │
├────────────┬─────────────────────────────┬───────────────────────────────┤
│            │                              │  标注审核工具 — bus             │
│  序列列表   │    可见光(主/大窗格)       │  第 47 / 113 帧   │  ● 3 个错误 │
│            │                              │                               │
│  ● bus    │  [图像帧号徽章]               │  ┌─────────────────────────┐  │
│  ● black  │                              │  │  当前帧标注预览(大窗格) │  │
│    bagbike│                              │  │  A person in white...  │  │
│  ⚠ 4four  │─────────────────────────────── │  │  21 词  [◀ 上一帧][下一帧▶]│  │
│            │    红外光(次/小窗格)        │  │  [保存 Ctrl+↵] [取消]  │  │
│  [筛选…]  │                              │  └─────────────────────────┘  │
│            │                              │                               │
│            │                              │  # │ 标注内容            │词数│  │
│            │                              │ 45 │ A person in white… │ 8w │  │
├────────────┴─────────────────────────────┤  46 │ A person in a whit…│22w │  │
│  状态栏: bus  │  第 47/113 帧 │  违规: 3 │  47 │ The bus is large…  │31w │  │
│  │ 行帧差: 0 │  标记: 2  │  已保存 ✓     │                             │
└──────────────────────────────────────────────────────────────────────────┘

四大区域说明

区域位置说明
工具栏顶部打开数据集、保存、切换模态、标记帧
序列列表左侧停靠栏所有序列列表,支持按名称过滤,双击进入
图像窗格左侧中央上部大窗格=主模态,下部小窗格=次模态,Tab 键一键切换
标注窗格右侧顶部大预览框(可编辑当前帧)+ 下方表格(浏览全部帧)
问题列表右侧停靠栏手动标记 + 自动检测到的违规,双击跳转

5. 核心操作流程

5.1 加载数据集

  1. 点击工具栏「打开数据集
  2. 在弹出的目录选择框中选择 data/ 目录(包含 visual/text/ 子目录的那个)
  3. 左侧「序列列表」自动填充所有序列
  4. 双击序列名(如 bus)进入审核

程序会自动检测:

  • 可见光帧数 vs 红外帧数是否一致(不一致时弹出警告)
  • 文本行数 vs 图像帧数是否一致(不一致时状态栏红色提示)

5.2 逐帧浏览

  • 键盘 / (或 A / D)逐帧切换;Ctrl+← / Ctrl+→ 跳 10 帧
  • 鼠标:拖动进度滑块实时预览
  • 点击:直接点击右侧表格任意行,跳转到对应帧
  • 跳转:帧号输入框直接输入帧号回车跳转

5.3 查看标注

当前帧的标注自动显示在右侧顶部的大预览框中,包括:

  • 完整标注文本(可完整阅读所有字符)
  • 词数统计(实时更新)
  • 左侧彩色边框颜色表示违规级别(见下节)

下方表格可快速浏览全部帧,违规行自动着色:

颜色含义
红色背景超出 30 词上限(错误)
橙色背景超出 20 词建议值(警告)
蓝色背景与相邻帧完全重复(错误)
黄色背景与相邻帧高度相似(>90%,警告)
紫色背景含中文字符或乱码(错误)
蓝色边框(当前帧)当前正在审核的帧

6. 编辑与保存逻辑

6.1 编辑流程

  1. 在顶部预览框中直接修改文本
  2. 词数实时显示,超过限制自动变色
  3. 点击「保存 Ctrl+↵」或按 Ctrl+Enter 保存当前帧
  4. 状态栏短暂显示「已保存 ✓」

6.2 撤销与重做

  • Ctrl+Z 撤销(最多保留 50 步历史)
  • Ctrl+Y 重做

6.3 保存时机

操作是否保存
Ctrl+S / 保存按钮立即保存
Ctrl+Enter(预览框)保存当前帧
切换序列弹出确认框(保存 / 放弃 / 取消)
每 3 分钟(自动保存)静默保存主文件(不产生新备份)
程序退出自动保存 + 记录审核进度

6.4 写回文件格式

保存时严格还原原始格式(UTF-8\n 分隔,末行无末尾换行), 与原始标注文件格式完全一致,不会引入额外换行符。


7. 备份机制

每次手动保存时,程序自动在以下位置创建时间戳备份:

data/text/backup/{序列名}/{序列名}_20260414_153022.txt
  • 每个序列最多保留 10 个最新备份
  • 自动清理超出配额的旧版本
  • 自动保存不产生新备份(仅覆写主文件)
  • 备份文件为完整文本内容,非增量

8. 违规自动检测

程序在加载序列时对全部帧执行一次违规扫描,结果缓存并实时更新。

检测项目

违规类型级别检测方式规范依据
超出上限错误词数 > 30标注长度规范
超出建议值警告词数 > 20 且 ≤ 30标注长度规范
完全重复错误与相邻帧逐字比较多样性规范
高度相似警告与相邻帧相似度 > 90%多样性规范
语言混杂错误正则检测中文字符 / 乱码语言纯净规范

注意:幻觉(HALLUCINATION)、语法错误(GRAMMAR)、视觉不准确(VISUAL) 属于需要人工判断的违规类型,程序无法自动检测,请在审核过程中手动标记。


9. 问题帧标记

标记方式

F 键或工具栏「标记帧」按钮,弹出问题类型选择框:

类型含义
幻觉(HALLUCINATION)标注描述了图像中不存在的内容
语法错误(GRAMMAR)拼写 / 时态 / 冠词等语法问题
视觉不准确(VISUAL)目标 / 颜色 / 动作与图像不符
其他(OTHER)其他类型问题
已修改(MODIFIED)当前帧文本被手动编辑后自动标记
AI改写(AI_GENERATED)该帧文本由批量 paraphrase 改写生成

支持填写备注。

查看与管理

  • 右侧「问题列表」停靠栏显示所有手动标记 + 自动检测违规
  • 双击任意条目跳转到对应帧
  • 点击「导出」可输出 JSON 问题报告

10. 审核进度管理

程序自动维护 data/review/progress.json,记录每个序列的:

  • 审核状态pending(未开始)/ in_progress(进行中)/ done(已完成)
  • 最后审核帧号:下次打开自动从该帧继续
  • 违规数量 / 手动标记数量
  • 完成时间

点击工具栏「标记完成」可将序列标为已完成(需先处理所有错误级违规)。


11. 快捷键参考

导航

快捷键功能
/ A上一帧
/ D下一帧
Ctrl+←跳回 10 帧
Ctrl+→跳进 10 帧
鼠标侧键 XButton1上一帧
鼠标侧键 XButton2下一帧
Home跳到第 1 帧
End跳到末帧
Ctrl+F聚焦搜索框

编辑

快捷键功能
Ctrl+S保存当前标注
Ctrl+Z撤销
Ctrl+Y重做
Ctrl+Enter在预览框中保存当前帧
Ctrl+[跳转到上一问题帧
Ctrl+]跳转到下一问题帧

查看

快捷键功能
Tab切换主显示模态(可见光 ↔ 红外光)
F标记 / 取消标记当前帧
[跳转到上一个手动标记帧
]跳转到下一个手动标记帧

图像操作(鼠标)

操作功能
Ctrl + 滚轮缩放图像
按住左键拖拽平移图像
双击图像全屏预览

翻译

快捷键功能
翻译 按钮手动重新翻译当前帧(文本修改后需点击)

批量改写(Paraphrase)

快捷键功能
Ctrl+R对当前序列候选帧(HALLUCINATION / DUPLICATE / SIMILAR)执行批量 paraphrase 改写

12. 文件结构

AnnotationCheck/
├── main.py                      # 程序入口,DLL 路径配置

├── core/                        # 核心业务逻辑
│   ├── config_manager.py        # 用户配置持久化(JSON,含阿里云 AK/SK)
│   ├── sequence_loader.py       # 序列扫描与路径解析
│   ├── annotation_manager.py    # 标注读写、撤销/重做、备份、译文持久化
│   ├── annotation_validator.py  # 违规检测引擎
│   ├── image_loader.py          # Pillow 解码 → QPixmap(跨平台图像加载)
│   └── review_manager.py        # 问题帧标记、审核进度持久化

├── ui/                          # GUI 界面
│   ├── main_window.py           # 主窗口,布局编排,信号总线,菜单栏
│   ├── image_panel.py           # 双模态图像窗格(缩放/平移/全屏)
│   ├── nav_bar.py               # 帧导航栏
│   ├── text_panel.py            # 标注预览框 + 译文显示框 + 表格 + 搜索
│   ├── sequence_panel.py        # 序列列表侧边栏
│   ├── flag_panel.py            # 问题帧汇总面板
│   └── flag_dialog.py           # 标记问题帧类型对话框

├── resources/
│   └── icons/
│       └── bitbug_favicon.ico   # 应用图标

├── dist/
│   └── AnnotationCheck.exe       # 打包后的可执行文件(单文件,~795MB)

├── config.json                  # 用户配置(自动生成,含 SDK 凭证)
├── requirements.txt             # Python 依赖列表
├── DESIGN.md                   # 技术设计文档
└── README.md                   # 本文档

13. 阿里云翻译功能

程序集成阿里云机器翻译 SDK,可在审核过程中实时查看英文标注的中文译文, 无需手动复制粘贴。所有译文自动缓存,关闭或切换序列后依然有效。

开通翻译功能

阿里云翻译功能需要自行注册阿里云账号,访问 https://mt.console.aliyun.com/basic 可以开通机翻翻译通用版,每个主账号每月有一百万字符的免费额度, 1,000,000字符约160,000英文单词,使用时请注意额度限制,避免大量计费!!! 额度监控请访问:https://mt.console.aliyun.com/monitor 注册后可以通过 SDK 使用软件内翻译功能。

13.1 首次配置

首次启动应用时,会自动弹出 阿里云 SDK 凭证配置 对话框。

如果需要手动配置或修改:

  • 菜单栏 → 配置阿里云 SDK 设置…
  • 输入 Access Key ID 和 Access Key Secret
  • 点击确定保存

获取凭证地址:https://ram.console.aliyun.com/manage/ak

注意:凭证保存在 config.json 中(程序同级目录),请勿泄露给他人。

13.2 界面说明

右侧标注面板分为两个区域:

区域位置说明
英文标注编辑框上方(约25%高度)可编辑的原始英文标注,Consolas 等宽字体,左边框颜色表示违规级别
中文译文显示框下方(约25%高度)只读,深蓝背景,雅黑字体,显示当前帧的自动翻译结果

控制行中的 [翻译] 按钮用于手动重新翻译(文本修改后必须点击)。

13.3 自动翻译机制

  • 翻页触发:每次跳转到新帧,自动对当前帧发起翻译请求
  • 语言检测:程序自动判断标注语言(含中文 → 英译,含其他字符 → 中译)
  • 预取缓存:同时在后台预取 ±1、±2、±3 相邻帧的译文,存入内存缓存
  • 译文持久化:每次翻译结果实时写入 data/text/translations/{序列名}_translations.json,下次打开该序列时自动恢复缓存,无需重复调用 API
  • 非阻塞:所有翻译请求均在后台线程执行,不影响窗口响应

13.4 手动重新翻译

修改英文标注后,需要点击 [翻译] 按钮手动重新翻译当前帧(因为自动翻译仅在翻页时触发,不会主动重新翻译已缓存的内容)。

状态标签含义:

状态颜色含义
✓ 已翻译绿色译文已缓存并显示
翻译中…灰色API 请求进行中
翻译失败红色认证失败或网络错误,请检查 SDK 配置
未配置 SDK红色尚未填写 AK/SK,请通过菜单配置

13.5 译文文件格式

data/text/translations/{序列名}_translations.json 结构:

{
  "0": "一个人穿着白色上衣和深色裤子走在人行道上。",
  "1": "A bus is driving on the road.",
  "2": "..."
}
  • Key:帧序号(从 0 开始)
  • Value:该帧标注的译文
  • 手动修改可能导致覆盖,以程序保存为准

14. Paraphrase 批量改写功能

V1.2 新增能力。用于对候选问题帧(HALLUCINATION / DUPLICATE / SIMILAR)执行批量改写,自动生成更稳健的替代表达。

14.1 功能定位

  • 该功能是新增模块,在 V1.1 及更早版本中不存在。
  • 目标:对同一序列中的候选问题帧文本(幻觉/重复/相似),自动生成更可靠的 paraphrase。
  • 改写完成后:
    • HALLUCINATION 标记会被移除
    • 自动替换为 AI_GENERATED 标记
    • 文本写入当前帧并参与后续违规检测

14.2 入口与触发方式

入口位置说明
批量改写按钮右侧「问题列表」底部对当前序列候选帧(幻觉/重复/相似)批量执行改写
Ctrl+R全局快捷键弹出确认框后执行批量改写

执行前置条件:

  1. 当前已加载序列;
  2. 当前序列存在至少一个候选改写帧(HALLUCINATION / DUPLICATE / SIMILAR);
  3. 已在「配置 → paraphrase 设置」中填写可用的 API Key。

14.3 配置项说明

paraphrase 相关配置保存在 config.json(程序根目录):

{
  "paraphrase_model": "minimax",
  "minimax_api_key": "",
  "minimax_api_secret": "",
  "openai_base_url": "",
  "openai_api_key": "",
  "openai_model": "gpt-4o-mini"
}

说明:

  • 当前版本底层统一采用 Anthropic SDK 请求链路;
  • 现有配置字段出于兼容性保留(历史命名不影响使用);
  • 至少需要可用 API Key 才能发起改写请求。

14.4 请求链路(端到端)

  1. 用户点击批量改写(或 Ctrl+R)。
  2. ui/main_window.py 收集当前序列候选帧索引(幻觉/重复/相似)并启动 _RewriteThread(后台线程)。
  3. 线程内按帧处理:
    • 从当前帧向前回溯,提取最多 5 条“非幻觉、非 AI 生成”的参考 caption;
    • 额外收集前 5 帧(任意类型)的非空标注,作为差异化约束邻居集;
    • 若某帧 caption 包含 No visible target in current frame(大小写不敏感),该帧会被标记为运行时自动类型 NO_TARGET
    • NO_TARGET 帧不会参与改写候选,也不会作为参考或邻居约束文本(该类型仅运行时存在,不写入 review 文件);
    • 调用 core/paraphrase_model.py 的模型实现执行 paraphrase;
    • 请求使用 Anthropic 兼容接口,返回后自动提取 text content block;
    • 若与邻居集任一文本相似度 >= 0.85,触发自动重试(最多 3 次)。
  4. 主线程收到进度信号后:
    • 写回新文本到 AnnotationManager
    • 将该帧标记从 HALLUCINATION 更新为 AI_GENERATED
    • 更新进度条与问题列表
  5. 批处理完成后:
    • 重新执行违规校验
    • 刷新文本表格、问题列表、状态栏
    • 保持为“已修改未保存”状态,等待用户保存

14.5 Prompt 规则(当前生效)

paraphrase 使用统一系统提示词,核心约束包括:

  1. 主体不变(不得替换/新增/删除主语义目标);
  2. 仅重述表达,不得编造参考内容之外的信息;
  3. 保持事实性,不增加未经支持的动作/属性细节;
  4. 基于 1~5 条同序列参考语句融合生成单句结果;
  5. 硬性长度限制:输出绝对不得超过 30 词
  6. 建议长度:尽量控制在 20 词以内
  7. 差异化要求:与前 5 帧邻居文本保持明显措辞差异

14.6 结果解析与文本落盘

  • 响应解析策略:
    • 仅提取 Anthropic 响应中的 text 块;
    • 自动忽略 thinking/工具调用等非文本块;
    • 若包含 <think>...</think> 片段,会先剔除再解析;
    • 取首条有效文本作为最终改写结果。
  • 重试与通过判定:
    • 每次生成后计算与前 5 帧邻居文本的最大相似度;
    • 当最大相似度 >= 0.85 时,向模型反馈“过于相似”并重试;
    • 最多重试 3 次,仍不满足则该帧记为失败并跳过。
  • 回写策略:
    • 改写文本直接写入当前序列对应帧;
    • UI 立即更新;
    • 后续按正常保存流程写入 data/text/{seq}.txt

14.7 标记流转规则

阶段标记状态
改写前HALLUCINATION 或自动违规候选(DUPLICATE / SIMILAR
改写成功若原为 HALLUCINATION 则移除该标记;统一新增 AI_GENERATED
改写失败/跳过保持原状态(手动标记/自动违规均不改变)

14.8 失败与排查

常见失败原因:

  • 未配置 API Key;
  • 当前帧无法找到有效参考 caption(会跳过);
  • 网络异常或服务端返回异常;
  • 响应中无可解析 text 块。

排查建议:

  1. 先检查 config.json 中 paraphrase 配置是否完整;
  2. 确认问题帧列表里确实有候选改写帧(幻觉/重复/相似);
  3. 查看终端日志中的 [Anthropic paraphrase] / [批量改写] 输出;
  4. 先对少量帧试跑,确认链路正常后再全量执行。

15. 常见问题

Q1:打开数据集后图像显示为黑色

确认选择的是 data/ 目录(含 visual/text/ 子目录)。 如果 exe 在没有 conda 环境的机器上运行,图像加载不依赖 Qt JPEG 插件, 由 Pillow 负责解码,不会出现黑色问题。

Q2:标注文件与图像帧数不一致

程序会在状态栏显示行帧差(红色),并允许正常浏览和编辑。 请在审核后联系项目负责人处理源头数据。

Q3:如何恢复误改的标注?

data/text/backup/{序列名}/ 目录下有每次保存的时间戳备份, 手动将备份文件内容复制到主文件即可。

Q4:程序异常退出,未保存的修改会丢失吗?

程序退出前自动保存当前状态,审核进度(最后帧号)也会持久化。 但两次自动保存(间隔 3 分钟)之间的修改可能丢失,建议每隔几分钟手动保存一次。

Q5:序列列表没有显示序列?

请确认选择的目录包含 data/visual/ 子目录。 程序会自动扫描该子目录下的所有子目录作为序列列表。

Q6:打包 exe 分发时需要安装 Python 吗?

不需要。dist/AnnotationCheck.exe 是单文件打包,已内嵌 Python 解释器和全部依赖, 可直接在目标机器双击运行,无需安装任何环境。