2026/4/16 22:19:38
网站建设
项目流程
关于医院网站建设的通知,哪里有做推文的网站,中国航发网上商城app下载,外贸soho自己建站DAMO-YOLO实操手册#xff1a;导出检测结果为COCO格式并用于下游训练流程
1. 为什么需要把DAMO-YOLO的检测结果转成COCO格式
你刚跑通DAMO-YOLO#xff0c;看着界面上跳动的霓虹绿框#xff0c;心里挺美——人、车、猫、椅子全被框得明明白白。但很快问题来了#xff1a;…DAMO-YOLO实操手册导出检测结果为COCO格式并用于下游训练流程1. 为什么需要把DAMO-YOLO的检测结果转成COCO格式你刚跑通DAMO-YOLO看着界面上跳动的霓虹绿框心里挺美——人、车、猫、椅子全被框得明明白白。但很快问题来了你想拿这些检测结果去微调另一个模型比如训练一个更专精的工业缺陷检测器或者想把标注数据喂给Label Studio做人工校验又或者要接入MMDetection做模型对比实验……这时候你会发现DAMO-YOLO默认输出的JSON结构和主流训练框架认的COCO格式压根对不上。不是它不好是它“太完整”了——带UI状态、带渲染参数、带时间戳、还带赛博朋克配色配置。而COCO只要干净的三样东西图片信息、类别定义、检测框坐标归一化或绝对像素加置信度。这篇手册不讲原理、不画架构图就干一件事用最少的代码把DAMO-YOLO跑出来的原始结果变成下游训练工具能直接读、能直接训、不报错的COCO JSON文件。整个过程不需要重装环境不改源码不碰前端只在后端Python层加一个轻量转换脚本。实测从拿到原始输出到生成标准COCO文件5分钟内搞定。2. 理解DAMO-YOLO的原始输出结构在动手前先看清它到底吐出了什么。当你上传一张test.jpgDAMO-YOLO后端Flask路由返回的JSON长这样{ status: success, timestamp: 2026-01-26T13:48:22.105Z, image_info: { filename: test.jpg, width: 1920, height: 1080, format: JPEG }, detections: [ { category: person, bbox: [124.5, 89.2, 312.8, 456.7], score: 0.923, id: 1 }, { category: car, bbox: [782.1, 210.4, 1120.6, 598.3], score: 0.871, id: 2 } ], ui_config: { threshold: 0.5, color: #00ff7f, render_mode: neon } }注意几个关键点bbox是[x_min, y_min, x_max, y_max]格式单位是像素不是归一化值category是字符串但COCO要求所有类别必须映射到整数IDperson1, car2…detections里没有图片ID字段而COCO的annotations数组必须关联到images里的idimage_info里有宽高但COCO的images数组需要file_name、width、height、id四个字段没有全局的categories定义——这是COCO最核心的元信息必须手动补全。所以转换不是简单复制粘贴而是做三件事① 构建标准images和categories列表② 把每个detection转成COCO的annotation格式加image_id、category_id、area、iscrowd等③ 保证所有ID连续、无重复、可追溯。3. 实现COCO导出三步走代码全贴我们不新建项目直接复用DAMO-YOLO已有的Python环境。所有代码都放在/root/ai-models/iic/cv_tinynas_object-detection_damoyolo/目录下新建一个coco_exporter.py文件。3.1 第一步定义COCO类别映射表COCO官方80类顺序是固定的。DAMO-YOLO支持全部80类但它的category字符串和COCO官方命名完全一致比如都是person、bicycle、car所以我们可以直接按字母序生成ID。但为保险起见还是显式定义——这样以后增删类别也方便。# coco_exporter.py COCO_CATEGORIES [ {id: 1, name: person, supercategory: person}, {id: 2, name: bicycle, supercategory: vehicle}, {id: 3, name: car, supercategory: vehicle}, {id: 4, name: motorcycle, supercategory: vehicle}, {id: 5, name: airplane, supercategory: vehicle}, {id: 6, name: bus, supercategory: vehicle}, {id: 7, name: train, supercategory: vehicle}, {id: 8, name: truck, supercategory: vehicle}, {id: 9, name: boat, supercategory: vehicle}, {id: 10, name: traffic light, supercategory: outdoor}, # ... 中间省略50行保持到80类 {id: 80, name: hair drier, supercategory: accessory} ] # 建立 name → id 的快速查找字典 NAME_TO_ID {cat[name]: cat[id] for cat in COCO_CATEGORIES}小技巧如果你只用其中10个类别比如只检人、车、狗、包就把COCO_CATEGORIES列表剪裁成这10个并重新编号为1~10。下游训练时显存和速度都会明显提升。3.2 第二步写核心转换函数这个函数接收DAMO-YOLO原始JSON路径输出标准COCO JSON路径。逻辑清晰每行都有注释import json import os from pathlib import Path def damoyolo_to_coco(damoyolo_json_path: str, output_coco_path: str): 将DAMO-YOLO单次推理的JSON输出转换为标准COCO格式 Args: damoyolo_json_path: DAMO-YOLO返回的原始JSON文件路径 output_coco_path: 输出的COCO JSON文件路径 # 1. 读原始JSON with open(damoyolo_json_path, r, encodingutf-8) as f: raw json.load(f) # 2. 初始化COCO结构 coco { info: { description: DAMO-YOLO COCO Export, version: 1.0, year: 2026, contributor: Wuli-Art Visual Lab, date_created: raw.get(timestamp, 2026-01-01T00:00:00Z) }, licenses: [{id: 1, name: MIT, url: https://opensource.org/licenses/MIT}], images: [], annotations: [], categories: COCO_CATEGORIES # 直接复用上面定义的 } # 3. 处理单张图片信息 → images数组 img_info raw[image_info] image_id 1 # 单图场景固定为1多图批量处理时用循环自增 coco_image { id: image_id, file_name: img_info[filename], width: img_info[width], height: img_info[height], date_captured: raw.get(timestamp, ), license: 1 } coco[images].append(coco_image) # 4. 处理所有检测框 → annotations数组 annotation_id 1 for det in raw[detections]: # bbox转COCO格式[x,y,width,height] x1, y1, x2, y2 det[bbox] width round(x2 - x1, 1) height round(y2 - y1, 1) x round(x1, 1) y round(y1, 1) # 计算area必须是正数 area max(1.0, width * height) # category映射 category_id NAME_TO_ID.get(det[category], 0) if category_id 0: print(f 警告未知类别 {det[category]}已跳过) continue annotation { id: annotation_id, image_id: image_id, category_id: category_id, bbox: [x, y, width, height], area: area, segmentation: [], # DAMO-YOLO不输出mask留空 iscrowd: 0 } # 可选添加score作为annotation的额外字段非COCO标准但部分训练框架支持 if score in det: annotation[score] round(det[score], 3) coco[annotations].append(annotation) annotation_id 1 # 5. 写入文件 with open(output_coco_path, w, encodingutf-8) as f: json.dump(coco, f, indent2, ensure_asciiFalse) print(f 已生成COCO格式文件{output_coco_path}) print(f 图片数{len(coco[images])}标注数{len(coco[annotations])}) # 示例调用测试用 if __name__ __main__: damoyolo_to_coco( damoyolo_json_path/root/ai-models/iic/cv_tinynas_object-detection_damoyolo/output/test_result.json, output_coco_path/root/ai-models/iic/cv_tinynas_object-detection_damoyolo/output/test_coco.json )3.3 第三步批量处理与自动化集成实际工作中你不会只导一张图。DAMO-YOLO通常会把一批图片的检测结果存在/output/目录下文件名如img_001.json、img_002.json……这时只需加个循环def batch_export(input_dir: str, output_dir: str): 批量转换整个目录下的DAMO-YOLO JSON input_path Path(input_dir) output_path Path(output_dir) output_path.mkdir(exist_okTrue) json_files list(input_path.glob(*.json)) print(f 找到 {len(json_files)} 个JSON文件) for i, json_file in enumerate(json_files, 1): # 生成对应COCO文件名img_001.json → img_001_coco.json coco_name json_file.stem _coco.json coco_path output_path / coco_name try: damoyolo_to_coco(str(json_file), str(coco_path)) except Exception as e: print(f 处理 {json_file.name} 失败{e}) print(f 批量导出完成COCO文件已保存至{output_dir}) # 在__main__里调用 if __name__ __main__: batch_export( input_dir/root/ai-models/iic/cv_tinynas_object-detection_damoyolo/output/, output_dir/root/ai-models/iic/cv_tinynas_object-detection_damoyolo/coco_annotations/ )运行后你会得到一个标准COCO JSON文件开头长这样{ info: { description: DAMO-YOLO COCO Export, version: 1.0, year: 2026, contributor: Wuli-Art Visual Lab, date_created: 2026-01-26T13:48:22.105Z }, licenses: [...], images: [ { id: 1, file_name: test.jpg, width: 1920, height: 1080, date_captured: 2026-01-26T13:48:22.105Z, license: 1 } ], annotations: [ { id: 1, image_id: 1, category_id: 1, bbox: [124.5, 89.2, 188.3, 367.5], area: 69172.5, segmentation: [], iscrowd: 0 } ], categories: [...] }完全符合pycocotools、MMDetection、Detectron2等所有主流框架的输入要求。4. 下游训练实测用导出的COCO数据微调YOLOv8光有COCO文件还不够得验证它真能训。我们用最轻量的方式——用Ultralytics的YOLOv8在RTX 4090上微调3个epoch看是否报错、是否收敛。4.1 准备训练目录结构COCO标准要求数据集按以下结构组织coco_dataset/ ├── annotations/ │ └── instances_train2017.json ← 你的导出文件放这里 ├── train2017/ │ └── test.jpg ← 原始图片必须同名放这里 └── ...所以你需要把test.jpg复制到coco_dataset/train2017/把test_coco.json重命名为instances_train2017.json放进coco_dataset/annotations/4.2 一行命令启动训练确保已安装Ultralyticspip install ultralytics然后执行yolo detect train \ datacoco_dataset \ modelyolov8n.pt \ epochs3 \ imgsz640 \ batch16 \ namedamoyolo_finetune训练日志里如果出现Class names: [person, bicycle, car, ...] Found 1 images in train2017 Loaded 1 labels from coco_dataset/annotations/instances_train2017.json说明COCO文件被正确加载。3个epoch后你就能得到一个基于DAMO-YOLO检测结果微调的新模型专门适配你的场景。实测提示如果训练卡在Loading annotations...90%是JSON里file_name和图片实际文件名不一致比如大小写、空格、扩展名.JPGvs.jpg用ls -l核对即可。5. 常见问题与避坑指南5.1 “KeyError: category” 错误原因DAMO-YOLO某些版本在无检测目标时detections数组为空但代码仍尝试遍历。修复很简单# 在damoyolo_to_coco函数里处理detections前加判断 if detections not in raw or not raw[detections]: print(f {damoyolo_json_path} 中无检测结果跳过) # 仍生成空COCO结构images有annotations为空保证格式合法 coco[annotations] [] return5.2 导出的bbox坐标错位现象COCO文件里框的位置和DAMO-YOLO界面上显示的不一致。原因DAMO-YOLO前端做了图像缩放比如把1920x1080图缩放到800px宽显示但后端返回的bbox是原始尺寸坐标。而你的图片如果被预处理过比如resize、pad就必须在导出前做逆变换。解决确认你传给DAMO-YOLO的图片就是原始尺寸。如果必须缩放记录缩放比例在导出时反向计算# 假设你上传前把图resize到了640x360原始是1920x1080 scale_x 1920 / 640 scale_y 1080 / 360 x1, y1, x2, y2 [v * scale_x if i % 2 0 else v * scale_y for i, v in enumerate(det[bbox])]5.3 类别ID对不上下游框架现象训练时报错category_id 81 is out of range。原因你的COCO JSON里categories写了80类但下游框架比如MMDetection默认只加载前20类。解决两种方式任选其一①推荐在导出脚本里只保留你实际用到的类别比如只检人、车、狗COCO_CATEGORIES只写这3个ID为1/2/3② 修改下游配置在MMDetection的config里加num_classes 80并确保classes列表和你的categories顺序严格一致。5.4 如何把COCO结果再可视化回DAMO-YOLO风格你导出了COCO训好了新模型现在想看看效果不用重写UI。直接用OpenCV读COCO JSON画霓虹绿框import cv2 import json def draw_coco_on_image(coco_json: str, image_path: str, output_path: str): with open(coco_json) as f: coco json.load(f) img cv2.imread(image_path) # 遍历annotations画框 for ann in coco[annotations]: x, y, w, h map(int, ann[bbox]) cv2.rectangle(img, (x, y), (xw, yh), (0, 255, 127), 2) # Neon Green: BGR(0,255,127) cv2.imwrite(output_path, img) print(f 可视化结果已保存{output_path}) draw_coco_on_image( coco_json/root/.../test_coco.json, image_path/root/.../test.jpg, output_path/root/.../test_visualized.jpg )6. 总结一条从检测到训练的闭环链路这篇手册没讲TinyNAS怎么搜索、没讲BFloat16怎么加速、也没讲赛博朋克UI的CSS动画怎么实现。它只聚焦一个工程师每天都会遇到的真实断点检测结果如何变成训练数据。你现在拥有了一份开箱即用的coco_exporter.py5分钟接入现有DAMO-YOLO部署清晰的三步转换逻辑映射→构建→写入可读、可调、可debug批量处理能力支撑小规模数据集构建下游训练实测路径证明导出结果100%可用四个高频问题的解决方案覆盖90%的落地报错。真正的AI工程不在于模型多炫酷而在于让数据在不同环节之间零损耗、零歧义、零摩擦地流动。DAMO-YOLO的霓虹绿框今天是你眼中的结果明天它就是另一个模型进步的起点。--- **获取更多AI镜像** 想探索更多AI镜像和应用场景访问 [CSDN星图镜像广场](https://ai.csdn.net/?utm_sourcemirror_blog_end)提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。