当前位置: 首页 > news >正文

目标检测中的数据增强:翻转、旋转、缩放、裁剪、亮度、模糊等【附完整源码】

《------往期经典推荐------》

一、AI应用软件开发实战专栏【链接】

项目名称项目名称
1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】
3.【手势识别系统开发】4.【人脸面部活体检测系统开发】
5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】
7.【YOLOv8多目标识别与自动标注软件开发】8.【基于YOLOv8深度学习的行人跌倒检测系统】
9.【基于YOLOv8深度学习的PCB板缺陷检测系统】10.【基于YOLOv8深度学习的生活垃圾分类目标检测系统】
11.【基于YOLOv8深度学习的安全帽目标检测系统】12.【基于YOLOv8深度学习的120种犬类检测与识别系统】
13.【基于YOLOv8深度学习的路面坑洞检测系统】14.【基于YOLOv8深度学习的火焰烟雾检测系统】
15.【基于YOLOv8深度学习的钢材表面缺陷检测系统】16.【基于YOLOv8深度学习的舰船目标分类检测系统】
17.【基于YOLOv8深度学习的西红柿成熟度检测系统】18.【基于YOLOv8深度学习的血细胞检测与计数系统】
19.【基于YOLOv8深度学习的吸烟/抽烟行为检测系统】20.【基于YOLOv8深度学习的水稻害虫检测与识别系统】
21.【基于YOLOv8深度学习的高精度车辆行人检测与计数系统】22.【基于YOLOv8深度学习的路面标志线检测与识别系统】
23.【基于YOLOv8深度学习的智能小麦害虫检测识别系统】24.【基于YOLOv8深度学习的智能玉米害虫检测识别系统】
25.【基于YOLOv8深度学习的200种鸟类智能检测与识别系统】26.【基于YOLOv8深度学习的45种交通标志智能检测与识别系统】
27.【基于YOLOv8深度学习的人脸面部表情识别系统】28.【基于YOLOv8深度学习的苹果叶片病害智能诊断系统】
29.【基于YOLOv8深度学习的智能肺炎诊断系统】30.【基于YOLOv8深度学习的葡萄簇目标检测系统】
31.【基于YOLOv8深度学习的100种中草药智能识别系统】32.【基于YOLOv8深度学习的102种花卉智能识别系统】
33.【基于YOLOv8深度学习的100种蝴蝶智能识别系统】34.【基于YOLOv8深度学习的水稻叶片病害智能诊断系统】
35.【基于YOLOv8与ByteTrack的车辆行人多目标检测与追踪系统】36.【基于YOLOv8深度学习的智能草莓病害检测与分割系统】
37.【基于YOLOv8深度学习的复杂场景下船舶目标检测系统】38.【基于YOLOv8深度学习的农作物幼苗与杂草检测系统】
39.【基于YOLOv8深度学习的智能道路裂缝检测与分析系统】40.【基于YOLOv8深度学习的葡萄病害智能诊断与防治系统】
41.【基于YOLOv8深度学习的遥感地理空间物体检测系统】42.【基于YOLOv8深度学习的无人机视角地面物体检测系统】
43.【基于YOLOv8深度学习的木薯病害智能诊断与防治系统】44.【基于YOLOv8深度学习的野外火焰烟雾检测系统】
45.【基于YOLOv8深度学习的脑肿瘤智能检测系统】46.【基于YOLOv8深度学习的玉米叶片病害智能诊断与防治系统】
47.【基于YOLOv8深度学习的橙子病害智能诊断与防治系统】48.【基于深度学习的车辆检测追踪与流量计数系统】
49.【基于深度学习的行人检测追踪与双向流量计数系统】50.【基于深度学习的反光衣检测与预警系统】
51.【基于深度学习的危险区域人员闯入检测与报警系统】52.【基于深度学习的高密度人脸智能检测与统计系统】
53.【基于深度学习的CT扫描图像肾结石智能检测系统】54.【基于深度学习的水果智能检测系统】
55.【基于深度学习的水果质量好坏智能检测系统】56.【基于深度学习的蔬菜目标检测与识别系统】
57.【基于深度学习的非机动车驾驶员头盔检测系统】58.【太基于深度学习的阳能电池板检测与分析系统】
59.【基于深度学习的工业螺栓螺母检测】60.【基于深度学习的金属焊缝缺陷检测系统】
61.【基于深度学习的链条缺陷检测与识别系统】62.【基于深度学习的交通信号灯检测识别】
63.【基于深度学习的草莓成熟度检测与识别系统】64.【基于深度学习的水下海生物检测识别系统】
65.【基于深度学习的道路交通事故检测识别系统】66.【基于深度学习的安检X光危险品检测与识别系统】
67.【基于深度学习的农作物类别检测与识别系统】68.【基于深度学习的危险驾驶行为检测识别系统】
69.【基于深度学习的维修工具检测识别系统】70.【基于深度学习的维修工具检测识别系统】
71.【基于深度学习的建筑墙面损伤检测系统】72.【基于深度学习的煤矿传送带异物检测系统】
73.【基于深度学习的老鼠智能检测系统】

二、机器学习实战专栏【链接】,已更新31期,欢迎关注,持续更新中~~
三、深度学习【Pytorch】专栏【链接】
四、【Stable Diffusion绘画系列】专栏【链接】
五、YOLOv8改进专栏【链接】持续更新中~~
六、YOLO性能对比专栏【链接】,持续更新中~

《------正文------》

目录

  • 引言
  • 数据增强重要性
  • 常见数据增强方式
  • 注意事项
  • 数据增强实现代码

引言

对象检测中的数据增强是一种通过对现有图像应用各种变换来人为增加训练数据集的大小和多样性的技术。这有助于提高我们的对象检测模型的鲁棒性和泛化能力,使其在看不见的数据上表现得更好。用于常规图像分类的图像增强与用于对象检测的图像增强之间的主要区别在于,还必须随图像一起增强边界框位置

数据增强重要性

为什么图像增强对目标检测很重要:

  1. 有限的数据: 对象检测数据集的创建可能既昂贵又耗时。增强有助于从现有数据中创建更多的训练数据,减少过度拟合并提高模型性能,特别是在数据有限的情况下。
  2. 对变化的鲁棒性: 真实世界的图像表现出很多变化(不同的照明,角度,大小,位置)。增强使模型在训练过程中暴露于这些变化,使其对这些变化更加鲁棒。
  3. 泛化: 通过在更多样化的数据集上进行训练,模型可以学习更好地泛化到看不见的图像。它不太可能偏向于训练集的特定特征。

常见数据增强方式

用于对象检测的常见图像增强技术:

  • 几何变换:
  • 旋转: 将图像旋转一定角度。边界框也必须相应地旋转。
  • 缩放(缩放): 放大或缩小图像。边界框必须按比例缩放。
  • 平移(平移): 水平或垂直移动图像。边界框必须移动相同的量。
  • 翻转: 水平或垂直翻转图像。边界框必须相应地翻转。在物体检测中,水平翻转比垂直翻转更常见。
  • 裁剪: 随机裁剪图像的一部分。如果边界框部分位于裁剪区域之外,则可能需要对其进行调整或将其丢弃。

光度变换:

  • 亮度调整: 改变图像的亮度。
  • 对比度调整: 改变图像的对比度。
  • 色调调整: 改变图像的色调。
  • 饱和度调整: 改变图像的饱和度。
  • 添加噪波: 向图像添加随机噪波

其他技术:

  • MixUp: 通过将两个图像混合在一起来创建新图像。边界框也相应地混合。
  • CutOut: 随机屏蔽图像的矩形区域。这可以帮助模型学习关注对象的不同部分。
  • **随机擦除:**类 似于剪切,但掩蔽区域填充随机值。

注意事项

目标检测增强的关键考虑因素:

  • 边界框调整: 最关键的方面是,每当你变换图像时,你也必须变换相应的边界框。如果我们旋转图像,你需要旋转边界框。如果我们缩放图像,您需要缩放边界框。如果我们裁剪图像,您可能需要调整或丢弃部分落在裁剪区域之外的边界框
  • 保持对象完整性: 小心可能会显著扭曲对象的增强。例如,过度旋转或缩放可能会使对象无法识别。
  • 数据增强库: Albumentations、Imgaug和TensorFlow的tf.image模块等库提供了在正确处理边界框的同时轻松应用这些增强的功能。

数据增强实现代码

import albumentations as A
import cv2
import os
import random

def augment_data(image_folder, annotation_folder, output_image_folder, output_annotation_folder, num_augmentations_per_image=3):
    """
    Augments images and their corresponding annotations for object detection.

    Args:
        image_folder: 包含图像的文件夹路径。
		annotation_folder: 包含标注文件的文件夹路径(.txt 文件,YOLO 格式)。
		output_image_folder: 保存增强后图像的文件夹路径。
		output_annotation_folder: 保存增强后标注文件的文件夹路径。
		num_augmentations_per_image: 每张图像生成的增强的次数。
    """

    if not os.path.exists(output_image_folder):
        os.makedirs(output_image_folder)
    if not os.path.exists(output_annotation_folder):
        os.makedirs(output_annotation_folder)

    # Define augmentations (customize as needed)
    transform = A.Compose([
        A.HorizontalFlip(p=0.5),
        A.RandomRotate90(p=0.5),
        A.ShiftScaleRotate(shift_limit=0.05, scale_limit=0.05, rotate_limit=15, p=0.5),
        A.RandomBrightnessContrast(p=0.3),
        A.RGBShift(r_shift_limit=20, g_shift_limit=20, b_shift_limit=20, p=0.2),  # Color shifts
        A.RandomCrop(width=400, height=400, always_apply=False, p=0.3), # Example crop. Adjust size.
        A.CLAHE(p=0.2), # Contrast Limited Adaptive Histogram Equalization
        A.Blur(blur_limit=3, p=0.2) # Add blur
    ], bbox_params=A.BboxParams(format='yolo', label_fields=['class_labels']))

    for filename in os.listdir(image_folder):
        if filename.lower().endswith(('.png', '.jpg', '.jpeg')):
            image_path = os.path.join(image_folder, filename)
            image = cv2.imread(image_path)

            if image is None:
                print(f"Warning: Could not read image {filename}. Skipping.")
                continue

            annotation_filename = os.path.splitext(filename)[0] + ".txt"
            annotation_path = os.path.join(annotation_folder, annotation_filename)

            if not os.path.exists(annotation_path):
                print(f"Warning: Annotation file {annotation_filename} not found for {filename}. Skipping.")
                continue

            try:
                with open(annotation_path, 'r') as f:
                    bboxes = []
                    class_labels = []  # Store class labels for each bounding box
                    for line in f:
                        parts = line.strip().split()
                        class_id = int(parts[0])
                        x_center = float(parts[1])
                        y_center = float(parts[2])
                        width = float(parts[3])
                        height = float(parts[4])
                        bboxes.append([x_center, y_center, width, height, class_id]) # Include class label
                        class_labels.append(class_id) # Append class label

                for i in range(num_augmentations_per_image):
                    augmented = transform(image=image, bboxes=bboxes, class_labels=class_labels)
                    augmented_image = augmented['image']
                    augmented_bboxes = augmented['bboxes']
                    augmented_class_labels = augmented['class_labels']

                    new_filename = f"{os.path.splitext(filename)[0]}_aug{i}.jpg" # Consistent jpg output
                    output_image_path = os.path.join(output_image_folder, new_filename)
                    cv2.imwrite(output_image_path, augmented_image)

                    new_annotation_filename = f"{os.path.splitext(filename)[0]}_aug{i}.txt"
                    output_annotation_path = os.path.join(output_annotation_folder, new_annotation_filename)

                    with open(output_annotation_path, 'w') as outfile:
                        for bbox, class_label in zip(augmented_bboxes, augmented_class_labels):
                            x_center, y_center, width, height, _ = bbox # Extract without class label
                            outfile.write(f"{class_label} {x_center} {y_center} {width} {height}\n")

            except FileNotFoundError:
                print(f"Warning: Annotation file {annotation_filename} not found. Skipping.")
            except ValueError:
                print(f"Warning: Invalid annotation format in {annotation_filename}. Skipping.")
            except Exception as e:
                print(f"An error occurred processing {filename}: {e}")


# Example usage:
image_folder = "path/to/your/image/folder"
annotation_folder = "path/to/your/annotation/folder"
output_image_folder = "path/to/output/augmented/images"
output_annotation_folder = "path/to/output/augmented/annotations"

augment_data(image_folder, annotation_folder, output_image_folder, output_annotation_folder)

print("Data augmentation complete.")

在这里插入图片描述

好了,这篇文章就介绍到这里,喜欢的小伙伴感谢给点个赞和关注,更多精彩内容持续更新~~
关于本篇文章大家有任何建议或意见,欢迎在评论区留言交流!

相关文章:

  • 用Python实现线性回归:从数学原理到代码实战
  • 【16】思科AireOS:创建使用 LWA 认证的 WLAN
  • CPT205 计算机图形学 OpenGL 3D实践(CW2)
  • 基于GFF3文件提取基因的位置信息
  • ram的使用——初始化很重要
  • 通过用户登录案例,详细说明线程的7种状态
  • 物联网 网络安全 概述
  • CloudberryDB(六)SPI拓展功能
  • 网络安全PPDR
  • Grafana——如何迁移Grafana到一台新服务器
  • 【人工智能】学会表达自己的需求是用好DeepSeek R1的关键
  • 优选算法《位运算》
  • C++ 虚表(Vtable)和虚基表(Vbtale)与 虚函数 和 虚继承
  • Linux网络 | 多路转接Poll
  • 轻松上手:2025年微服务教程
  • C++中常用的十大排序方法之3——插入排序
  • Redis 04章——持久化
  • PDF工具,个人作品,免费分享
  • sql语句的执行顺序
  • 【etcd】ubuntu22安装,与redis对比的区别
  • 出口管制不能将民用技术泛安全化,也不能破坏全球供应链稳定
  • 马克思主义理论研究教学名师系列访谈|薛念文:回应时代课题,才能彰显强大生命力
  • “五一”假期首日:国铁南宁局发送旅客81.7万人次
  • 全国台联原会长杨国庆逝世,享年89岁
  • 中国证券监督管理委员会党委委员、副主席王建军接受审查调查
  • 铁路上海站今日预计发送旅客65.8万人次,同比增长超16%