CCPD数据集高效转换为YOLO格式:技术实现与避坑指南

1次阅读
没有评论

共计 2239 个字符,预计需要花费 6 分钟才能阅读完成。

image.webp

背景介绍

CCPD(Chinese City Parking Dataset)是目前国内最全面的车牌检测数据集之一,包含了不同天气、光照条件下的车牌图像,非常适合用于训练鲁棒的车牌检测模型。而 YOLO(You Only Look Once)作为当前流行的目标检测算法,其数据格式要求与 CCPD 原始标注格式存在较大差异,因此需要进行格式转换。

CCPD 数据集高效转换为 YOLO 格式:技术实现与避坑指南

YOLO 格式的基本要求是:

  • 每个图像对应一个.txt 文件,文件名相同
  • 每行表示一个目标,格式为:class_id x_center y_center width height
  • 坐标和尺寸都是相对于图像宽高的归一化值(0- 1 之间)

技术难点

CCPD 原始标注与 YOLO 格式的主要差异体现在:

  1. 坐标系统不同:CCPD 使用绝对坐标,YOLO 需要相对坐标
  2. 标注方式不同:CCPD 使用四点坐标表示车牌,YOLO 使用中心点 + 宽高
  3. 文件结构不同:CCPD 标注集中在一个文件,YOLO 需要每个图像单独标注
  4. 类别表示不同:CCPD 没有显式类别 ID,YOLO 需要明确类别编号

实现方案

下面是一个完整的 Python 转换脚本,实现了从 CCPD 到 YOLO 格式的转换:

import os
import cv2
import json
from pathlib import Path

def convert_ccpd_to_yolo(ccpd_annotation_path, output_dir, class_id=0):
    """
    将 CCPD 标注转换为 YOLO 格式
    :param ccpd_annotation_path: CCPD 标注文件路径
    :param output_dir: YOLO 格式输出目录
    :param class_id: 类别 ID(车牌默认为 0)"""
    # 确保输出目录存在
    os.makedirs(output_dir, exist_ok=True)

    with open(ccpd_annotation_path, 'r') as f:
        annotations = json.load(f)

    for img_name, points in annotations.items():
        try:
            # 读取图像获取尺寸
            img_path = os.path.join(os.path.dirname(ccpd_annotation_path), img_name)
            img = cv2.imread(img_path)
            if img is None:
                print(f"警告:无法读取图像 {img_path}")
                continue

            img_h, img_w = img.shape[:2]

            # 计算边界框(四点坐标转矩形)x_coords = [p[0] for p in points]
            y_coords = [p[1] for p in points]
            x_min, x_max = min(x_coords), max(x_coords)
            y_min, y_max = min(y_coords), max(y_coords)

            # 转换为 YOLO 格式(归一化中心坐标和宽高)x_center = (x_min + x_max) / 2 / img_w
            y_center = (y_min + y_max) / 2 / img_h
            width = (x_max - x_min) / img_w
            height = (y_max - y_min) / img_h

            # 写入 YOLO 格式文件
            output_path = os.path.join(output_dir, Path(img_name).stem + '.txt')
            with open(output_path, 'w') as f:
                f.write(f"{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}\n")

        except Exception as e:
            print(f"处理 {img_name} 时出错: {str(e)}")

# 使用示例
if __name__ == "__main__":
    convert_ccpd_to_yolo("ccpd_annotations.json", "yolo_labels")

性能优化

当处理大规模 CCPD 数据集时,可以考虑以下优化策略:

  1. 内存管理:
  2. 使用生成器逐批处理图像,避免一次性加载所有数据
  3. 及时释放不再需要的图像内存

  4. 并行计算:

  5. 使用 Python 的 multiprocessing 模块实现多进程处理
  6. 将数据集分片,每个进程处理一部分数据

  7. IO 优化:

  8. 使用 SSD 存储加速读写
  9. 合并小文件写入操作

避坑指南

在实际转换过程中,常见的错误及解决方案包括:

  1. 坐标归一化错误:
  2. 错误:忘记将坐标除以图像宽高
  3. 解决:确保所有坐标都转换为 0 - 1 之间的值

  4. 图像路径问题:

  5. 错误:图像路径拼接不正确
  6. 解决:使用 os.path.join 保证跨平台兼容性

  7. 四点坐标顺序混乱:

  8. 错误:四点坐标不是顺时针或逆时针顺序
  9. 解决:对点坐标进行排序后再计算边界框

  10. 图像加载失败:

  11. 错误:图像损坏或路径错误
  12. 解决:添加异常处理,跳过问题图像

  13. 类别 ID 冲突:

  14. 错误:多类别场景下类别 ID 定义混乱
  15. 解决:建立明确的类别映射表

扩展思考

本方案可以轻松适配到其他自定义数据集,主要修改点包括:

  1. 解析不同的原始标注格式
  2. 调整坐标转换逻辑
  3. 扩展多类别支持

对于其他四点标注的数据集,只需修改边界框计算部分;对于其他坐标表示的数据集,调整归一化计算方式即可。

实践任务

建议读者尝试以下实践:

  1. 下载 CCPD 数据集(至少 1000 张图像)
  2. 使用提供的脚本进行格式转换
  3. 使用 YOLOv5 或 YOLOv8 验证转换结果
  4. 尝试训练一个简单的车牌检测模型

通过实际动手操作,可以更深入地理解数据格式转换的关键点,为后续的模型训练打下坚实基础。

正文完
 0
评论(没有评论)