ultralytics-yolov8的数据增强

因为项目上想做光照增强,在ultralytics-yolov8中在Config.yaml中的配置中没有找到,想做自己加一个,我进入到data/augment中发现了,发现了隐藏的Albumentations,太惊讶了,藏大太深了,必须得看代码

一、ultralytics-yolov8中在Config.yaml中配置的数据增强理解

1、hsv_h, hsv_s, hsv_v

可以这样理解,hsv中的h 是指什么颜色,S是指这个颜色浓不浓,V是值颜色亮不亮。

  • H=0是,大致对应红色,H=30时可能在黄色或橙色附近,H=60,可能变成绿色。顺序就是红、橙、黄、绿、青、蓝、紫;
  • S=255的时候,就是非常鲜艳的红色,S=100时,红色没有那么鲜艳,S=0时,完全没有颜色;
  • V=100时,当把V提高到150图片变亮,把V减少为50的时候,图片变暗

下面是ultralytics-yolov8中RandomHSV中的核心操作,

python 复制代码
        if self.hgain or self.sgain or self.vgain:
            dtype = img.dtype  # uint8

            r = np.random.uniform(-1, 1, 3) * [self.hgain, self.sgain, self.vgain]  # random gains
            x = np.arange(0, 256, dtype=r.dtype)
            # lut_hue = ((x * (r[0] + 1)) % 180).astype(dtype)   # original hue implementation from ultralytics<=8.3.78
            lut_hue = ((x + r[0] * 180) % 180).astype(dtype)
            lut_sat = np.clip(x * (r[1] + 1), 0, 255).astype(dtype)
            lut_val = np.clip(x * (r[2] + 1), 0, 255).astype(dtype)
            lut_sat[0] = 0  # prevent pure white changing color, introduced in 8.3.79

            hue, sat, val = cv2.split(cv2.cvtColor(img, cv2.COLOR_BGR2HSV))
            im_hsv = cv2.merge((cv2.LUT(hue, lut_hue), cv2.LUT(sat, lut_sat), cv2.LUT(val, lut_val)))
            cv2.cvtColor(im_hsv, cv2.COLOR_HSV2BGR, dst=img)  # no return needed

关键是操作比例:

python 复制代码
r_h ∈ [-hgain, +hgain]
r_s ∈ [-sgain, +sgain]
r_v ∈ [-vgain, +vgain]

和三个公式:

python 复制代码
H' = (H + r_h × 180) % 180
S' = clip(S × (1 + r_s), 0, 255)
V' = clip(V × (1 + r_v), 0, 255)

比如 随机出来r = 0, -0.2, +0.4,H = H, S = 0.8 *S, V = 1.4 X V

2、degree, translate, scale, shear, perspective

想要理解这些数据增强对图片的影响,必须知道这些背后是怎么操作的

2.1 这几种是怎么共同作用的

这几个是叠加执行,不是随机选择一个的

python 复制代码
 affine = RandomPerspective(
        degrees=hyp.degrees,
        translate=hyp.translate,
        scale=hyp.scale,
        shear=hyp.shear,
        perspective=hyp.perspective,
        pre_transform=None if stretch else LetterBox(new_shape=(imgsz, imgsz)),
    )

2.1 degrees 旋转

degrees 参数是图像旋转的度数,(+/- deg)

python 复制代码
a = random.uniform(-degrees, degrees)

2.2 scale:缩放

python 复制代码
s = random.uniform(1 - scale, 1 + scale)

2.3 translate:平移

python 复制代码
Δx∈[−translate⋅W,+translate⋅W]
Δy∈[−translate⋅H,+translate⋅H]

2.4 box处理

不直接对 bbox 的 (x1,y1,x2,y2) 做变换,而是先取 bbox 的 4 个角点 → 对 4 个角点做和图片完全一样的 M 变换 → 再用变换后的 4 个点重新计算一个能包住目标的最小 xyxy 框。

二、ultralytics-yolov8中数据增强的思考

  • 这种数据增强会导致目标框切割,但是YOLO会把bbox裁剪到图像范围内,也就是目标框还剩多少,全靠随机值,一种是目标框完全在图像外面,这张样本就变成了无目标框的背景;一种情况是,目标被切成了一个条条,已经完全和目标外形不一样了;
  • ultralytics-yolov里面的数据增强,包括mosaic、mixup、cutmix等是适合coco类型的图片的,在图像中目标本身可能出现在任意位置、大小变化比较大、部分遮挡、部分出画面、视角变化比较大,所以比较强的Mosaic、RandomPerspective、MixUp、CopyPaste、CutMix、scale、translate通常是比较有价值的;

三、实际应用

我的应用场景是固定摄像头、固定角度、目标位置范围有效、目标大小范围有效、目标形态基本固定,光照影响比较大;

3.1 第一阶段:使用 Ultralytics YOLOv8 内置的数据增强方式

  • MixUp、CopyPaste、CutMix关闭;
  • 轻微degrees=0~2、translate=0.02-0.05、scale=0.05-0.1,shear和perspective关闭;
  • H = 0.015 S = 0.2

3.2 第二阶段:使用 Ultralytics YOLOv8 中增加额外的亮度增强,增加 RandomBrightness

亮度增强有三种,brightness,gamma, contrast三种,不是叠加,而是每次选择一种;brightness,RGB三个通道增加或者减去一个相同的值;gamma, contrast

python 复制代码
return Compose(
        [
            pre_transform,
            MixUp(dataset, pre_transform=pre_transform, p=hyp.mixup),
            CutMix(dataset, pre_transform=pre_transform, p=hyp.cutmix),
            Albumentations(p=1.0, transforms=getattr(hyp, "augmentations", None)),
            RandomHSV(hgain=hyp.hsv_h, sgain=hyp.hsv_s, vgain=hyp.hsv_v),
            RandomBrightness(p=0.5),
            RandomFlip(direction="vertical", p=hyp.flipud, flip_idx=flip_idx),
            RandomFlip(direction="horizontal", p=hyp.fliplr, flip_idx=flip_idx),
        ]

3.3 第三个阶段:扩展到其他摄像头的角度,增加 RandomTranslate

目标在当前摄像头下的角度和形态是不变化的,但是目标同时也会出现在其他摄像头的角度下,发现,如果不把其他摄像头下的目标加入训练时,其他摄像头下的目标分值很低,在0.3~0.4左右,所以尝试用数据增强将模型扩展到其他摄像头角度下,增加模型的扩展性。第三阶段只针对translate,把translate的平移限制增加box的限制,不切割box

python 复制代码
return Compose(
        [
            pre_transform,
            MixUp(dataset, pre_transform=pre_transform, p=hyp.mixup),
            CutMix(dataset, pre_transform=pre_transform, p=hyp.cutmix),
            Albumentations(p=1.0, transforms=getattr(hyp, "augmentations", None)),
            RandomHSV(hgain=hyp.hsv_h, sgain=hyp.hsv_s, vgain=hyp.hsv_v),
            RandomTranslate(translate=1.0, p=0.2),
            RandomBrightness(p=0.5),
            RandomFlip(direction="vertical", p=hyp.flipud, flip_idx=flip_idx),
            RandomFlip(direction="horizontal", p=hyp.fliplr, flip_idx=flip_idx),
        ]

之前在别的摄像头角度下的目标,分数都很低,训练的时候加入RandomTranslate后,其他角度下的目标分数值增加到0.8~0.9.

3.4 如何在Config.yaml中对自己增加的增强,例如RandomBrightness和RandomTranslate,进行参数控制

如果直接在配置文件中写入random_translate: 0.3 的概率,程序报错,random_translate is not a valid YOLO argumnets .

  • 在 ultralytics/cfg/default.yaml中增加 random_translate:0.3 #probability random_brightness:0.3 #probability,default.yaml 只是一个模板,告诉你都有哪些配置参数;
  • 在你配置中加入这两个参数,然后再代码中使用,如下
python 复制代码
return Compose(
       [
           pre_transform,
           MixUp(dataset, pre_transform=pre_transform, p=hyp.mixup),
           CutMix(dataset, pre_transform=pre_transform, p=hyp.cutmix),
           Albumentations(p=1.0, transforms=getattr(hyp, "augmentations", None)),
           RandomHSV(hgain=hyp.hsv_h, sgain=hyp.hsv_s, vgain=hyp.hsv_v),
           RandomTranslate(translate=1.0, p=hyp.random_translate),
           RandomBrightness(p=hyp.random_brightness),
           RandomFlip(direction="vertical", p=hyp.flipud, flip_idx=flip_idx),
           RandomFlip(direction="horizontal", p=hyp.fliplr, flip_idx=flip_idx),
       ]
相关推荐
7177774 分钟前
能源行业 DevOps 平台选型与 Gitee 企业版适配性梳理
人工智能·gitee
宁渡AI大模型2 小时前
河南宁渡科技有限公司|宁渡课堂 AI 全栈面试分享,RAG 项目面试深挖问题解析
人工智能·机器学习·rag
锋行天下8 小时前
LangGraph 1.2+ 新特性:set_node_defaults,批量统一节点策略
人工智能
找方案8 小时前
AI+人力资源:AI招聘面试的兴起与争议
人工智能·面试·职场和发展
日常通勤穿搭8 小时前
2026 电商 AI 作图工具推荐|淘宝抖音跨境商品主图 AI 生图测评
人工智能·aigc·ai工具·电商美工
ZhengEnCi8 小时前
L2A-一个域名如何访问多台云服务器-子域名、路径前缀与Nginx反向代理选型指南
linux·人工智能
2601_963749108 小时前
越华环保集团污水站曝气系统边缘闭环控制架构与能耗优化实现
人工智能·架构
工业涂料百问9 小时前
【生产施工】系列(六)工业涂料固化方式怎么选?自然干 / UV / 电子束原理与选型实战
人工智能
葡萄城技术团队9 小时前
活字格 12.1 新特性解密:禁用自动回复后,AI 对话单元格也能流式输出了
人工智能
东风破_9 小时前
从 RAG 到 Agentic RAG:第一步,让模型决定「要不要检索」
人工智能