尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

make-sense 图像标注全流程:格式导出、校验与团队协作避坑

make-sense 图像标注全流程:格式导出、校验与团队协作避坑 选图像标注工具这件事我踩过一次很难受的坑团队用某平台标了两周导出时发现格式跟训练脚本对不上坐标口径也不一致最后靠人肉写脚本转换还丢了一批多边形的实例。从那以后我评估任何一个标注工具第一件事不是看它支持几种画框方式而是看数据能不能完整、无损、可逆地拿回来。make-sense 就是在这个标准下被我留下来的一个工具——它是一个跑在浏览器里的开源图像标注工具打开网页就能用不用注册账号图片全程在本地浏览器里处理不往外传。适合的人群很明确手上有一批图片要做目标检测或实例分割想快速出一版数据集跑通训练流程的算法工程师预算有限但数据又比较敏感的小团队以及想在自己电脑上搭一套离线标注环境、连内网都不出的人。这篇就把我从图片整理、标签设计、动手标注、格式导出到团队协作的完整过程摊开讲一遍重点放在那些文档里不会写、但一上手就会撞上的细节。1. 挑标注工具时我为什么先看数据能不能拿回来1.1 一次返工让我把导出格式提到了评估第一位很多人在选工具时会先比较界面好不好看、画框顺不顺手、有没有智能预标注这些东西确实影响手感但它们只影响效率不影响成败。真正会让人返工的是另外三件事导出的坐标口径和你训练框架的输入要求是否一致、类别索引的映射关系是否稳定、标注状态能不能保存和恢复。我那个被坑的项目就是这样标注环节大家干得挺快问题出在最后一公里——平台导出的 COCO JSON 里category_id从 1 开始而我们的训练脚本按 0 开始读同时多边形被降级成了外接矩形分割任务直接作废。返工的两周里重新画框的时间占三成剩下七成全是核对、转换、抽查和吵架。所以我现在评估标注工具会按这个顺序排优先级导出格式覆盖度 状态可保存 操作效率 协作能力 界面美观。make-sense 在这条链上的表现比较均衡它支持矩形、多边形、点、线四种标注形态导出侧覆盖 YOLO、COCO JSON、Pascal VOC XML、CSV 以及它自己的工程 JSON最后这个工程 JSON 是关键——它能把当前整个项目状态序列化下来包括图片列表、标签定义和所有标注结果下次可以接着干。这个可续接的能力比什么花哨功能都值钱。1.2 make-sense 的定位一个跑在浏览器里的开源图像标注工具它的运行方式跟传统桌面标注软件不太一样。你打开页面把图片拖进去浏览器在本地把图片解码、渲染到画布上你在画布上画框画多边形所有数据都留在当前页面的内存里。整个过程没有上传动作服务端不需要接收你的图片这一点对数据敏感的团队来说很实用。也因为这样它的能力边界很明显它是一个单机、单页、手动为主的标注工具不是一个带任务分发、账号权限、进度统计的标注平台。你要多人协作得靠人肉分工加规范约束而不是靠工具本身的任务队列。它还有几个我觉得挺聪明的设计。一是标签面板和快捷键绑定数字键可以直接切换当前激活的标签画一个框按一下数字键就换类别手不用离开键盘区域二是上一个/下一个图片和撤销的组合箭头键翻图、CtrlZ 回退连续标注的节奏能保持住三是它支持把工程导出的 JSON 再导回来这等于自带了一个极简的版本管理——我习惯每标完一百张就导一份工程 JSON 出来命名带上日期和批次号。1.3 和 LabelImg、Labelme、CVAT 放在一张表里对比这几个工具我都用过各有各的适用面。把它们的差异摊在一张表里比看任何评测文章都直观工具运行方式主要标注形态导出格式更适合的场景make-sense浏览器在线或本地部署矩形、多边形、点、线YOLO、COCO、VOC、CSV、工程 JSON快速起量、单人/小团队、格式多样LabelImg桌面客户端矩形YOLO、VOC纯目标检测、老项目维护Labelme桌面客户端多边形、矩形、点COCO、VOC、自有 JSON实例分割、像素级轮廓CVAT服务端部署矩形、多边形、点、线、轨迹多格式有人力管理需求的团队、视频标注我的实际组合是做目标检测就用 make-sense因为矩形标注加 YOLO 导出的链路最短做像素级分割、需要跟着轮廓描边的时候会切回 Labelme 或者继续用 make-sense 的多边形视频和多人任务分发才上 CVAT。工具没有绝对优劣关键看你这一批数据的最终形态是什么。先确定训练框架要吃什么格式再倒推选工具这个顺序千万别反过来。2. 打开页面之前先把图片和标签体系理清楚2.1 图片预处理清单文件名、尺寸、EXIF、重复项标注开始之前的准备工作决定了后面会不会返工。我现在的固定动作有四项每次都不例外。第一是文件名唯一化。make-sense 在导出时会用图片的文件名作为标签文件的主名比如IMG_0231.jpg对应IMG_0231.txt。如果你从两个不同文件夹拖进来两张同名图片导出时就会互相覆盖而且这个过程是静默的不报错。我的做法是统一重命名为场景_序号的形式比如workshop_0001.jpg只用英文、数字和下划线绝对不用中文和空格——中文文件名在部分工具链里会出现编码问题虽然不一定每次都炸但排查起来很浪费生命。第二是统一分辨率或至少心里有数。超过 4000 像素宽的大图在浏览器里缩放标注会比较吃力画框时的拖拽会有轻微延迟而且缩放到 30% 以下时人眼对边界位置的判断精度会下降同一张图两个人标出来的框可能差十几个像素。如果原图分辨率远高于模型输入尺寸我会先做一次等比缩放到长边 1920再拿去标注。这个选择是有代价的小目标会被缩掉。所以原则是——先看你的目标最小像素尺寸如果缩放后目标仍然大于 32 像素就可以缩否则保留原图标注时配合页面缩放功能放大到 100% 以上再画。第三是处理 EXIF 方向信息。手机拍的图片常常带一个旋转标记浏览器渲染时可能自动转正但画布取到的像素坐标是按原始方向算的。这种看起来是正的、导出来是歪的问题非常隐蔽往往要等到训练时可视化标注框才发现整张图错位。稳妥的做法是在预处理阶段统一转正并剥掉 EXIF用一条命令批量搞定# 依赖 imagemagick-auto-orient 按 EXIF 转正profile * 剥掉元信息 mkdir -p normalized for f in raw/*.jpg; do convert $f -auto-orient -resize 1920x1920 profile * normalized/$(basename $f) done第四是去重和剔废。模糊的、纯色背景的、明显重复的图标注时浪费时间训练时还可能带偏分布。我一般先按文件大小排序把几十 KB 的异常小的图挑出来看一眼再随机抽 20 张确认画质。这批工作花半小时能省掉后面几小时的无效标注。2.2 标签体系设计粒度、互斥、层级标签体系最容易犯的错是边标边加。今天觉得应该区分戴帽子的行人和没戴帽子的行人明天又觉得没必要于是标签列表越改越乱早期标的数据全得改。我的经验是在标第一张图之前拿十张有代表性的图把标签列表定死之后只允许在列表末尾追加不允许插入和重排。定标签时我会问自己三个问题。第一粒度我要区分的是车还是轿车/卡车/巴士如果下游任务只需要知道这里有车就没必要细分细分会让每个类别的样本数变少长尾问题更严重。第二互斥性一个目标会不会同时属于两个类别比如骑电动车的人是标成人加电动车还是标成一个骑手这两种方案都行但必须全队统一。我的偏好是能拆就拆标成人和电动车两个框因为这样模型学到的是两个独立概念后面可以复用。第三层级有没有父子关系比如交通标志下面分限速标志禁止标志如果有我建议先在标注阶段平铺成三个独立标签等训练时再在代码里做合并映射比在标注阶段做层级更灵活。还有一点值得单独提背景类和忽略类。有些目标模糊到你自己都判断不了这时候别硬标。要么定义一个ignore标签专门收这类训练时在 loss 里屏蔽掉要么干脆不标但要保证全队一致——最怕的是张三遇到模糊目标就标李四遇到就不标模型收到的是自相矛盾的信号最后学出来一堆高置信度的错检。2.3 用文件命名承载元信息可选但很香如果你的数据来自多个来源比如三个不同厂区、两种相机、白天和夜间我强烈建议把这些信息写进文件名或者至少维护一张文件名 - 场景的映射表。原因是训练集划分必须按场景分层不能纯随机——同一段连续视频抽出来的帧如果被拆到训练集和验证集验证指标会虚高得离谱线上直接打脸。命名成siteA_day_0001.jpg这种形式后面用脚本按前缀分层抽样就非常省事。这个习惯我在好几个项目里都吃过亏才养成的早期混着随机划分验证集 mAP 报 0.85上线实测掉到 0.5排查了一周才发现是数据泄漏。3. 四种标注形态的适用边界与手动操作细节3.1 矩形框目标检测的主力矩形框是使用频率最高的形态操作也最直接在图片上按住鼠标从左上拖到右下松开后框就生成了然后在标签面板选中对应类别或者用快捷键切类别。这里有几个细节值得说。框的松紧度。新手容易把框画得比较紧贴着目标边缘甚至切掉一点。这在训练时其实是有影响的如果框太紧目标的边缘特征被截断模型对边界的学习会偏如果框太松框里混进大量背景正样本区域被稀释。我的一般标准是框略大于目标可见轮廓留出大约目标尺寸 2% 到 5% 的余量对于被遮挡的目标框只覆盖可见部分不要凭想象补全。这个标准要在规范文档里写成一句话再配两张示例图一张正确、一张错误比写五百字描述都管用。密集目标的处理。遇到拥挤场景比如一群人挨在一起框会大量重叠画的时候容易点到已经画好的框上变成拖动而不是新建。这时候有个小技巧先把图放大到 200% 以上从画面边缘开始画或者临时切换到只显示当前框的视图状态。另外重叠区域到底该归谁需要提前定规则——我的规则是谁的可见面积大就归谁被遮挡超过 70% 的不标这个阈值可以根据任务调整但必须写下来。小目标放大标注。小于 20 像素的目标直接按页面显示尺寸画框误差会非常大可能一个框偏了 5 个像素就是 25% 的相对误差。正确做法是放大到 300% 甚至 400% 再画画完之后缩回来看一眼整体效果。这一点在标注遥感图或者工业质检图时特别重要那类图里的小目标往往才是主角。3.2 多边形实例分割与不规则目标多边形适合轮廓不规则的目标比如缺陷区域、裂缝、医学影像里的器官边界。交互方式是沿着轮廓依次点击点与点之间自动连成直线最后回到起点闭合。用多边形的核心难点不在操作而在点的密度怎么把握。点太密一个轮廓上打三四十个点标注时间翻好几倍而且相邻点太近会让后续的轮廓平滑处理出问题点太稀轮廓退化成粗糙的多边形分割掩码和真实边界的 IoU 上不去。我的经验法则是在曲率大的地方点密一点直线段上只留两个端点。打个比方标注一个圆形的工件圆周上大概需要 12 到 16 个点而标注一个矩形箱子四到六个点就够了四个角加可能的两个转折点。按照这个密度一张中等复杂度的图大概 30 秒到 1 分钟能标完一个目标。还有一个很关键的坑多边形在导出时和矩形不是平等对待的。YOLO 格式本身只支持矩形框所以如果项目里混着多边形导出时多边形的处理方式不一定符合你的预期——有的版本会退化成外接矩形有的会直接跳过。我现在的做法是做检测任务的项目只画矩形做分割任务的项目只画多边形两种形态永远不混在同一个项目里。这多花几分钟建两个项目能省掉后面核对实例数量的几个小时。3.3 点与线关键点与线性结构点标注适合关键点任务比如人体姿态里的关节、零件的中心位置。操作就是单击一个像素级的点。这里的注意事项是点标注对精度极其敏感一定要放大到 400% 以上再点因为一个点的坐标误差在训练时会被直接放大成回归 loss。另外点的语义要靠标签区分比如左肩右肩必须分成两个标签不能靠顺序推断。线标注适合线性结构比如车道线、管道、线缆、道路中心线。交互是点两个端点生成一条线段也可以连续点多个点构成折线。线标注最有意思的地方在于它和后续处理方式的匹配——如果你下游要用霍夫变换或者做车道线拟合线标注的端点坐标可以直接用但如果你想训练分割模型线必须被渲染成有一定宽度的掩码这个宽度就是个超参数通常取 3 到 8 像素太小了在降采样后消失太大了会和相邻目标粘连。实际使用中点和线的使用频率远低于矩形和多边形但它们在特定任务里不可替代。我的建议是如果你的任务不涉及关键点或线性结构就别开启这两种工具因为工具栏上多两个按钮误操作的概率就会增加。3.4 快捷键与操作节奏效率提升最明显的地方标注是体力活一天标几百张图效率差异主要来自手指移动距离。make-sense 的快捷键设计比较合理我总结了一套自己的操作节奏数字键切换标签标完一个目标立刻按数字键切到下一个类别全程手不离键盘。标签面板的顺序会决定哪个类别绑定哪个数字键所以标签列表的排序要按使用频率排最常用的放前面。CtrlZ 撤销画歪了立刻撤销不要试图去微调那个框重新画一遍比修更快。方向键翻图标完一张直接按方向键进下一张不要用鼠标点缩略图那个操作要移动视线和光标累积起来很耗时。Delete 删除选中误标的目标直接删掉不要留着后面清理清理阶段你会忘记哪一个是误标。Esc 取消当前操作画多边形的过程中想放弃按一下就行不用一个个点回去。我还养成了一个习惯把浏览器窗口调成接近全屏关掉其他标签页和聊天工具。听着像废话但实测下来一天标 500 张图的场景里每次被打断后重新找回标注状态大概要 10 到 20 秒一天被打断二十次就是十分钟以上的纯损失还不算注意力碎片化的隐性成本。另外建议用有线鼠标无线鼠标在精细拖拽时的细微延迟会影响画框手感。4. 导出环节YOLO、COCO、Pascal VOC、CSV 的口径差异4.1 四种格式的坐标口径拆解这是全文最该记住的部分。同样是一个矩形框四种格式的表达方式完全不同搞错了就是一批数据白标。YOLO 格式是一图一文件图片名.txt每行代表一个实例五个字段类别索引 中心点x 中心点y 宽度 高度。这四个坐标值全部是归一化到 0 到 1 的相对值也就是除以图片的宽和高。类别索引从 0 开始而且是纯数字文件里不存类别名——这一点非常重要意味着你必须自己维护一份索引到类别名的映射清单否则过两个月你根本不知道索引 7 是哪个类。COCO JSON是单个大文件内部结构分成images、annotations、categories三块。bbox字段是[左上角x, 左上角y, 宽度, 高度]全部是绝对像素值如果标注里有多边形会额外出现在segmentation字段里格式是多边形所有顶点的扁平坐标数组。category_id通常从 1 开始而不是 0这是最容易踩的坑。Pascal VOC XML是一图一文件bndbox下面是xmin、ymin、xmax、ymax绝对像素值注意这里是右下角的坐标而不是宽高跟 COCO 相比多了一步减法。类别名以字符串形式直接存在 XML 里可读性最好。CSV是一张表通常一行一个实例包含文件名、类别、坐标等列。好处是可以在表格软件里直接打开抽查坏处是不同工具导出的列名和顺序不统一跨工具时不能直接混用。4.2 一张对照表训练框架与格式匹配把格式和下游框架对应起来选型的时候就不用猜了导出格式坐标口径类别标识主要适配YOLO归一化中心点宽高从 0 开始的数字索引Ultralytics 系列、darknetCOCO JSON绝对像素左上角宽高从 1 开始的数字 idDetectron2、MMDetection、torchvisionPascal VOC绝对像素左上右下字符串类别名较早的检测框架、部分评测脚本CSV依导出而定字符串类别名人工抽查、数据统计、格式转换中转我的常用策略是标注用 make-sense导出选 YOLO 或 COCO中间用脚本转换。原因是这两个格式的生态最完整几乎任何框架都能吃而且转换脚本遍地都是。VOC 一般只在我需要人工核对的时候导出一份因为 XML 结构可读性最好出问题一眼能看出来。4.3 导出后必做的三项校验附 Python 脚本导出完成不等于数据可用。我现在固定做三项校验一个都不能省。第一项是图片与标签的配对检查。有图没标签、有标签没图这两种情况都会让训练脚本报错或者静默跳过样本。import os img_dir datasets/images/train lbl_dir datasets/labels/train img_exts {.jpg, .jpeg, .png, .bmp, .webp} imgs {os.path.splitext(f)[0] for f in os.listdir(img_dir) if os.path.splitext(f)[1].lower() in img_exts} lbls {os.path.splitext(f)[0] for f in os.listdir(lbl_dir) if f.endswith(.txt)} print(有图无标签:, len(imgs - lbls), sorted(imgs - lbls)[:10]) print(有标签无图:, len(lbls - imgs), sorted(lbls - imgs)[:10])第二项是标签内容的合法性检查。重点看类别索引有没有越界、归一化坐标有没有跳出 0 到 1、宽高有没有为 0 或者负数。类别索引越界这个问题特别隐蔽——如果你的映射清单里只有 8 个类但标签文件里出现了索引 9训练脚本可能不报错直接把这一行当背景处理你损失了一批正样本还不知道。import os, glob CLASS_NUM 8 # 按你的类别总数改 def check(label_dir, class_numCLASS_NUM): problems [] for f in glob.glob(os.path.join(label_dir, *.txt)): lines [l.strip() for l in open(f, encodingutf-8) if l.strip()] if not lines: problems.append((f, 空标签文件)) continue for i, line in enumerate(lines, 1): p line.split() if len(p) ! 5: problems.append((f, f第{i}行字段数{len(p)})) continue try: cid, vals int(p[0]), [float(x) for x in p[1:]] except ValueError: problems.append((f, f第{i}行解析失败)) continue if not (0 cid class_num): problems.append((f, f第{i}行类别越界: {cid})) if any(v 0 or v 1 for v in vals): problems.append((f, f第{i}行坐标越界: {vals})) if vals[2] 0 or vals[3] 0: problems.append((f, f第{i}行宽高非正)) return problems for item in check(datasets/labels/train)[:30]: print(item)第三项是抽样可视化。前两项只能查出格式错误查不出框错了位置这类语义错误。我的做法是写一个脚本随机抽 20 张图把标注框画到图上拼成一张网格图肉眼扫一遍。这一步能抓到很多脚本抓不到的问题比如某几张图的框整体偏移了一个固定距离通常是图片尺寸记录错误或者某个标签系统性标错了位置。import random from PIL import Image, ImageDraw import os img_dir, lbl_dir datasets/images/train, datasets/labels/train names [os.path.splitext(f)[0] for f in os.listdir(img_dir)][:200] sample random.sample(names, 20) cells [] for n in sample: img Image.open(os.path.join(img_dir, n .jpg)).convert(RGB) w, h img.size d ImageDraw.Draw(img) lp os.path.join(lbl_dir, n .txt) if os.path.exists(lp): for line in open(lp, encodingutf-8): p line.split() if len(p) ! 5: continue _, cx, cy, bw, bh p[0], *map(float, p[1:]) x1, y1 (cx - bw / 2) * w, (cy - bh / 2) * h x2, y2 (cx bw / 2) * w, (cy bh / 2) * h d.rectangle([x1, y1, x2, y2], outline(255, 0, 0), width3) img.thumbnail((400, 400)) cells.append(img)这三项加起来大概十分钟但它拦住的是几小时甚至几天的返工。5. 部署与协作把单机工具变成团队流水线5.1 本地起服务Docker 与源码两种方式用在线版本最省事但对两类团队不适用一类是数据不能出内网的另一类是网络环境不稳定的。这两种情况都可以自己部署一份。源码方式适合想改代码的人Docker 方式适合只想要一个能用的服务。源码跑起来大致是这样git clone https://github.com/SkalskiP/make-sense.git cd make-sense npm install npm start # 开发模式默认监听 3000 端口如果只是要部署给团队用生产构建会更好npm run build # 产物在 build 目录 # 用任意静态服务器托管 build 目录即可 python3 -m http.server 8080 --directory build因为它是纯前端应用构建产物就是一堆静态文件扔到任意一台内网机器上起个静态服务就行不需要数据库、不需要后端接口运维成本基本为零。想用 Docker 的话仓库里通常带了 Dockerfile流程是构建镜像再挂端口docker build -t make-sense:local . docker run -d --name make-sense -p 3000:3000 make-sense:local这里有几个实操注意点。一是端口以 Dockerfile 里暴露的为准跑起来访问不通就用docker ps看实际映射。二是如果放在共享服务器上给多人用它本质上还是各人各的浏览器会话服务端不存储任何标注状态所以不要指望它能做多人同时标同一批图、进度共享——这个能力它没有硬上会撞墙。三是修改默认配置比如你们团队有一套固定的标签体系可以在代码里把默认标签列表改掉这样每个人打开页面就已经有了正确的标签省掉手动添加和顺序不一致的问题。这是个很小的改动但对标注一致性的帮助非常大。5.2 多人分标时怎么保证一致性既然工具本身不做任务分发一致性就得靠流程。我们的做法是三步。第一步是按图片分人不按目标分人。同一张图必须由同一个人标完因为一张图内部的标注标准是连贯的如果两个人各标一半交界处的标准差异会非常明显。分工时按批次切比如 A 标 0001 到 0500B 标 0501 到 1000。第二步是交叉复核而不是各标各的。每人标完之后随机抽 10% 的图交给另一个人复核复核的人只做两件事删掉明显多余的框、补上明显漏掉的框。这里不要做微调框的位置这种操作会引发无休止的争论。第三步是算一致率。抽一批图让两个人独立标同一批数据然后计算匹配上的框占总数量的比例。低于 90% 就说明标签规范里有歧义要回去改文档高于 95% 就可以放心放大规模。这个指标的绝对值不重要重要的是趋势——如果某个批次的复核删除率突然升高说明这个批次的数据本身就模糊可能需要重新采集。5.3 标注规范文档该写什么我见过太多口头约定式的标注规范结果就是一周后没人记得当初怎么说的。一份能用的规范文档我建议至少包含这几块标签定义表每个标签的名称、含义、典型示例图、明确排除的情况。比如行人标签下面写清楚只标站立或行走的人坐着的、躺着的、骑车的不算。边界规则遮挡多少算不标、截断在画面边缘的目标标不标、超过多少像素才算有效目标。这些数字必须写死。多边形的点密度示例放两张图一张是密度合适的一张是点太少的比文字描述有用十倍。导出流程导出哪种格式、文件怎么命名、存放在哪个目录、命名规则是什么。注意这里要写清类别索引的映射清单最好直接把清单文件一起放进版本管理。常见错误案例这个部分是最有价值的随着项目推进不断往里加。每次发现新的错误类型就补一条配图说明。三个月后这份文档就成了团队最有价值的资产之一。规范文档不要求长我的经验是控制在两三页配上十来张示例图反而比长篇大论更容易被执行。6. 我踩过的坑和几条不太正规但好用的技巧6.1 关掉标签页就等于白干这条必须放在第一位。浏览器端运行的一个直接后果是标注状态保存在页面内存里关掉标签页或者刷新页面没导出的标注就没了。我在最开始用的时候花了一下午标了两百多张顺手关了浏览器去看个邮件回来打开页面一片空白那种感觉不用多描述。所以现在我的习惯是批次导出。具体的节奏是每标完 100 张导出一份工程 JSON命名成project_20240315_batch03.json同时把当前这批图片和标签导出到对应目录。这样即使浏览器崩了最多损失 100 张的进度。另外用隐私模式、清理浏览器数据、切到别的设备这些操作都会让状态丢失团队协作时要在规范里写清楚。还有一点导出的工程 JSON 一定要和图片放在一起或者至少记录清楚它对应的是哪一批图片。我试过一次工程文件找回来了、图片批次搞混了的情况最后靠文件名前缀一点点对回来非常痛苦。6.2 类别顺序一旦定下就别乱动YOLO 格式里类别是纯数字索引索引和类别名的对应关系完全靠你自己维护。这意味着标签列表的顺序就是类别索引的顺序。如果你标了 5000 张图之后在标签列表中间插入了一个新类别那后面所有类别的索引全部后移一位已经导出的标签文件全部失效。这种错误不会报错只会让模型学得一塌糊涂。我的做法是三条第一标签列表的顺序按使用频率和重要性排定下来就锁死第二新类别只能追加到末尾第三维护一份classes.txt或labels.json文件明确写出索引到名称的映射放进代码仓库一起做版本管理每次改标签都提交一次这样至少能追溯。6.3 浏览器内存与分批策略一次性往页面里拖几百张高分辨率图片浏览器会很吃力表现为滚轮缩放卡顿、画框拖拽延迟、翻图时白屏一两秒。这不是工具的问题是浏览器渲染几百张图的必然结果。我的分批策略是每批 100 到 300 张具体看图片大小1080p 左右的分辨率可以到 300 张4000 万像素的原图控制在 50 到 100 张。分批还有一个额外好处就是天然形成了导出节奏每批标完就导一次进度可控、损失可控。标注顺序上我习惯先把简单图快速标完攒信心再啃困难样本因为困难样本容易打断节奏、消耗时间放在精力最好的时段集中处理效率更高。6.4 常见问题速查表最后把经常被问到的几个问题整理成一张表撞上问题可以直接对号入座现象最可能的原因处理方式导出的框整体偏移或旋转图片带 EXIF 方向信息渲染与像素读取不一致预处理阶段统一转正并剥掉 EXIF标签文件互相覆盖、数量对不上存在同名图片标注前统一重命名按批次命名避免重名训练时类别全乱标签列表顺序被改动索引映射错位恢复类别顺序维护映射清单并纳入版本管理多边形数据在导出后消失项目里混用了矩形和多边形目标格式不支持多边形检测与分割分项目标注导出后核对实例数量页面卡顿、翻图延迟单批图片数量或分辨率过高按 100 到 300 张分批大图先等比缩放昨天的进度找不到了页面状态只存在内存中未导出工程文件建立每 100 张导出一次的节奏说到底make-sense 是个很好用的图像标注工具但它的强项是轻、快、格式全不是管人、管任务、管进度。把它放在正确的位置上配合清晰的标签规范、固定的导出节奏和一套校验脚本一个两三个人的小团队完全可以在几天内产出一份质量靠得住的目标检测数据集。我个人的体会是标注这件事的成本从来不在画框这个动作上而在前面想清楚、后面验清楚这两头——工具帮你省的是中间那一小段别把整个流程的成败都押在工具上。另外再分享一个小心得把标签映射清单和标注规范文档放在代码仓库里跟训练脚本一起版本管理半年后回头看你会庆幸当初多花了这十分钟。
返回列表