VisDrone2019数据集COCO格式转换实战:代码解析与避坑指南

张开发
2026/4/10 2:43:46 15 分钟阅读

分享文章

VisDrone2019数据集COCO格式转换实战:代码解析与避坑指南
1. VisDrone2019数据集与COCO格式简介VisDrone2019是无人机视角下的目标检测与跟踪基准数据集包含10,209张图片6,471张训练集、548张验证集、3,190张测试集标注了行人、车辆等11类目标。但它的原生标注格式与主流框架如MMDetection、Detectron2默认支持的COCO格式存在显著差异标注文件差异VisDrone使用每张图片对应一个.txt文件每行表示一个物体标注x_min,y_min,width,height,score,category_id...而COCO使用单个.json文件集中存储所有标注坐标系统差异VisDrone采用左上角坐标宽高表示法COCO同样使用该表示法但需要额外处理边界框越界情况类别定义差异VisDrone的11个类别需要与COCO的80类做映射或独立保留我在实际项目中使用MMDetection训练模型时发现框架自带的COCO数据加载器无法直接处理VisDrone原始格式。手动转换时还遇到过边界框越界导致训练报错、类别ID不连续引发索引错误等问题。下面通过完整代码解析帮你避开这些坑。2. 环境准备与目录结构2.1 必要依赖安装转换脚本需要以下Python库pip install opencv-python tqdm numpy建议使用Python 3.7环境实测在Ubuntu 20.04和Windows 10上均可运行。2.2 数据集目录规范原始VisDrone2019-DET解压后应保持如下结构VisDrone2019/ ├── VisDrone2019-DET-train/ │ ├── annotations/ # 存放每个图片的.txt标注文件 │ └── images/ # 训练集图片 ├── VisDrone2019-DET-val/ │ ├── annotations/ # 验证集标注 │ └── images/ # 验证集图片 └── VisDrone2019-DET-test-dev/ # 测试集无标注注意部分版本解压后可能包含视频序列文件夹检测任务只需关注上述DET目录3. 核心转换代码解析3.1 类别定义与初始化首先定义与VisDrone原始类别完全对应的categories列表categories [ {id: 0, name: ignored regions}, {id: 1, name: pedestrian}, {id: 2, name: people}, {id: 3, name: bicycle}, # ...完整类别见原始代码 ]这里保持原始ID不变避免后续模型输出与可视化时产生混淆。实测发现若重新编号如从0开始连续会导致评估指标计算错误。3.2 标注文件解析关键步骤处理单个.txt标注文件时的核心逻辑for line in f.readlines(): line line.replace(\n, ) if line.endswith(,): # 处理标注行末尾多余的逗号 line line.rstrip(,) line_list [int(i) for i in line.split(,)] # 转换为COCO需要的bbox格式[x,y,width,height] bbox_xywh [line_list[0], line_list[1], line_list[2], line_list[3]] # 边界框越界检查关键 if bbox_xywh[0] bbox_xywh[2] width: bbox_xywh[2] width - bbox_xywh[0] if bbox_xywh[1] bbox_xywh[3] height: bbox_xywh[3] height - bbox_xywh[1]这个越界处理特别重要我在最初版本中漏掉后训练时出现了Bounding box is outside image的报错。3.3 COCO JSON结构构建最终生成的JSON需包含三个关键字段dataset_dict { images: [ # 所有图片信息列表 { file_name: img_00001.jpg, height: 1080, width: 1920, id: img_00001 # 使用文件名作为唯一ID }, # ... ], annotations: [ # 所有标注对象列表 { image_id: img_00001, # 关联对应图片 bbox: [x,y,width,height], category_id: 1, id: 0, # 标注全局唯一ID area: width*height, iscrowd: 0 # VisDrone均为单个对象 }, # ... ], categories: categories # 前文定义的类别 }4. 常见问题与解决方案4.1 边界框越界处理VisDrone中存在部分标注框超出图像边界的情况这会导致COCO评估时抛出异常。除了前文的基础检查外更健壮的做法是def clamp_bbox(bbox, img_width, img_height): x1 max(0, bbox[0]) y1 max(0, bbox[1]) x2 min(img_width, bbox[0] bbox[2]) y2 min(img_height, bbox[1] bbox[3]) return [x1, y1, x2-x1, y2-y1] # 返回修正后的[x,y,w,h]4.2 特殊字符处理部分图片文件名包含括号等特殊字符直接读取可能报错。建议统一处理import re def sanitize_filename(name): return re.sub(r[\\/*?:|], _, name)4.3 大内存消耗优化当处理完整训练集时内存占用可能超过16GB。可以通过分块处理解决chunk_size 1000 # 每处理1000张图片保存一次 for i, img_file in enumerate(image_files): # ...处理逻辑... if i % chunk_size 0: save_partial_json()5. 完整使用流程下载数据集后解压到指定目录运行转换脚本示例python convert_visdrone_to_coco.py \ --input_dir /path/to/VisDrone2019 \ --output_dir /path/to/output验证生成的文件import json with open(VisDrone2019-DET_train_coco.json) as f: data json.load(f) print(fTotal images: {len(data[images])}) print(fTotal annotations: {len(data[annotations])})转换完成后即可在MMDetection等框架中通过标准COCO数据加载器使用# MMDetection配置示例 data dict( traindict( typeCocoDataset, ann_filepath/to/VisDrone2019-DET_train_coco.json, img_prefixpath/to/VisDrone2019-DET-train/images, # ... ) )实际部署时发现由于无人机视角的特殊性建议将默认的anchor尺寸调整为更适合小目标的设置。可以先用转换后的数据训练一个基线模型然后通过k-means重新计算anchor尺寸。

更多文章