YOLO数据集增强、扩充

YOLO数据集增强、扩充

介绍

yolo已标注数据集增强扩充,已标注的.txt格式的数据集增强,包含旋转、平移、裁剪、翻转、调整亮度和增加噪声6种方式,随意组合,每张图片增强至5张。

核心代码

translation_range = np.random.randint(10, 50)  
rotation_angle_range = np.random.randint(10, 30)  
crop_range = np.random.randint(10, 30)  
brightness_range = (np.random.uniform(0.5, 1.5), np.random.uniform(1.5, 2.5))  
noise_stddev = np.random.randint(5, 20)  

# 获取图像文件和标注文件的路径
img_paths = [os.path.join(src_img_dir, f) for f in os.listdir(src_img_dir) if f.endswith(('.jpg', '.jpeg', '.png'))]
txt_paths = [os.path.join(src_txt_dir, f) for f in os.listdir(src_txt_dir) if f.endswith('.txt')]

for img_path, txt_path in zip(img_paths, txt_paths):
    # 读取图像
    image = cv2.imread(img_path)
    h, w, _ = image.shape

    # 读取标注数据
    with open(txt_path, 'r') as txt_file:
        lines = txt_file.readlines()

    augmentations = np.random.choice(['mirror', 'translate', 'rotate', 'brightness', 'noise', 'crop', 'flip'], size=5, replace=False)

    for i, aug in enumerate(augmentations):
        image_augmented = image.copy()
        lines_augmented = list(lines)

        if aug == 'mirror':
            image_augmented = cv2.flip(image_augmented, 1)
            for j, line in enumerate(lines_augmented):
                values = line.strip().split(' ')
                if len(values) == 5:
                    x, y, width, height = map(float, values[1:5])
                    x = 1 - x
                    lines_augmented[j] = f"{values[0]} {x} {values[2]} {values[3]} {values[4]}\n"

        if aug == 'translate':
            tx = np.random.randint(-translation_range, translation_range)
            ty = np.random.randint(-translation_range, translation_range)
            M = np.float32([[1, 0, tx], [0, 1, ty]])
            image_augmented = cv2.warpAffine(image_augmented, M, (w, h))

            for j, line in enumerate(lines_augmented):
                values = line.strip().split(' ')
                if len(values) == 5:
                    x, y, width, height = map(float, values[1:5])
                    x += tx / w
                    y += ty / h
                    lines_augmented[j] = f"{values[0]} {x} {y} {values[2]} {values[3]}\n"

        if aug == 'rotate':
            angle = np.random.randint(-rotation_angle_range, rotation_angle_range)
            M = cv2.getRotationMatrix2D((w / 2, h / 2), angle, 1)
            image_augmented = cv2.warpAffine(image_augmented, M, (w, h))

            for j, line in enumerate(lines_augmented):
                values = line.strip().split(' ')
                if len(values) == 5:
                    x, y, width, height = map(float, values[1:5])
                    x_rot, y_rot = np.dot(M, np.array([x * w, y * h, 1]))
                    x_rot /= w
                    y_rot /= h
                    lines_augmented[j] = f"{values[0]} {x_rot} {y_rot} {values[2]} {values[3]}\n"

        if aug == 'brightness':
            brightness_factor = np.random.uniform(*brightness_range)
            image_augmented = cv2.convertScaleAbs(image_augmented, alpha=brightness_factor, beta=0)

        if aug == 'noise':
            noise = np.random.normal(0, noise_stddev, image_augmented.shape).astype(np.uint8)
            image_augmented = cv2.add(image_augmented, noise)

        if aug == 'crop':
            x1 = np.random.randint(0, crop_range)
            y1 = np.random.randint(0, crop_range)
            x2 = w - np.random.randint(0, crop_range)
            y2 = h - np.random.randint(0, crop_range)
            image_augmented = image_augmented[y1:y2, x1:x2]
            for j, line in enumerate(lines_augmented):
                values = line.strip().split(' ')
                if len(values) == 5:
                    x, y, width, height = map(float, values[1:5])
                    x = (x - x1) / (x2 - x1)
                    y = (y - y1) / (y2 - y1)
                    lines_augmented[j] = f"{values[0]} {x} {y} {values[2]} {values[3]}\n"

        if aug == 'flip':
            image_augmented = cv2.flip(image_augmented, 0)
            for j, line in enumerate(lines_augmented):
                values = line.strip().split(' ')
                if len(values) == 5:
                    y = 1 - float(values[2])
                    lines_augmented[j] = f"{values[0]} {values[1]} {y} {values[2]} {values[3]}\n"

        # 保存增强后的图像
        img_name = os.path.basename(img_path)
        output_img_path = os.path.join(output_img_dir, f"{i}_{os.path.splitext(img_name)[0]}.png")
        cv2.imwrite(output_img_path, image_augmented)

        # 保存增强后的标注数据
        txt_name = os.path.basename(txt_path)
        output_txt_path = os.path.join(output_txt_dir, f"{i}_{txt_name}")
        with open(output_txt_path, 'w') as output_txt_file:
            output_txt_file.writelines(lines_augmented)

注意点

  • opencv-python的版本不能过高,否则报错
  • 本例中的版本为4.1.2.30

完整代码

YOLO(You Only Look Once)是一种常用的目标检测算法,其格式化的数据集常称为YOLO格式数据集。可用于训练的YOLO格式数据集包括一组图像和对应的标签文件。 YOLO格式数据集的图像通常是在计算机视觉领域收集的真实场景图像,包含各种常见物体或特定目标。这些图像要求具有高分辨率和多样性,以便训练出的模型具备良好的泛化能力。对于图像的预处理,可以进行尺寸调整、亮度调整、裁剪等操作,以满足训练的需求。 而标签文件则是对每个图像中的物体或目标进行框选和分类的结果。每个目标通常由一个边界框和一个类别标签来表示。边界框一般用矩形框选物体,并通过坐标表示框的位置和大小。类别标签则指定了该物体所属的类别,例如人、汽车、狗等。标签文件可以采用常见的格式,如txt、xml等,具体的格式要与训练算法的要求相匹配。 在使用YOLO格式数据集进行训练时,首先需要将图像和标签文件加载到训练环境中,并配合使用相应的训练算法进行模型的训练。模型的训练过程中,图像和标签会被输入模型中,通过反向传播算法进行权重的更新,从而逐步提高模型的准确性和鲁棒性。通过逐渐增加数据集的规模和多样性,可以进一步提升模型的性能。 综上所述,可用于训练的YOLO格式数据集是一组经过预处理的真实场景图像及其相应的标签文件,在训练过程中用于调整模型权重和学习目标检测任务。只有具备高分辨率、多样性和正确标注的数据集,才能充分发挥YOLO算法的优势,并得到准确且鲁棒的目标检测模型。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值