• Yolo v8数据马赛克数据增强代码详解


    目标检测: 一文读懂 Mosaic 数据增强_mosaic数据增强_大林兄的博客-CSDN博客     有图更加详细生动。

    pad可参考博客:目标检测的Tricks | 【Trick7】数据增强——Mosaic(马赛克)_Clichong的博客-CSDN博客

      马赛克数据增强:将四张图片随即进行裁剪之后,在拼接到一张图上做训练数据。丰富了图片的背景,并将四张图片拼接,提高了batch_size.

    1.随机选择一个坐标作为拼接中心的坐标(xc,yc)

     yc, xc = (int(random.uniform(-x, 2 * s + x)) for x in self.mosaic_border)  # mosaic center x, y

     random.uniform(a,b):生成指定范围内的随机数大于等于a,小于等于b。

    2.生成四张拼接图象的索引。

    indices = [index] + random.choices(self.indices, k=3)

    random.choice(seq,k)从非空序列中随机选择一个数据并返回。序列可以是list、tuple、str、set。返回结果是列表。

    3.random.shuffle(indices)随机打乱数据顺序,如果是多维矩阵,只对第一个维度进行打乱顺序。

    4.enumerate将一个可遍历的数据对象组合成一个索引序列,同时列出数据和数据下标。

    5.返回resize之后的图像、原图、resize之后的h.w。

    img, _, (h, w) = self.load_image(index)

     6.创建马赛克图像

    1. # place img in img4
    2. if i == 0: # top left
    3. img4 = np.full((s * 2, s * 2, img.shape[2]), 114, dtype=np.uint8) # base image with 4 tiles
    4. x1a, y1a, x2a, y2a = max(xc - w, 0), max(yc - h, 0), xc, yc # xmin, ymin, xmax, ymax (large image)
    5. x1b, y1b, x2b, y2b = w - (x2a - x1a), h - (y2a - y1a), w, h # xmin, ymin, xmax, ymax (small image)
    6. elif i == 1: # top right
    7. x1a, y1a, x2a, y2a = xc, max(yc - h, 0), min(xc + w, s * 2), yc
    8. x1b, y1b, x2b, y2b = 0, h - (y2a - y1a), min(w, x2a - x1a), h
    9. elif i == 2: # bottom left
    10. x1a, y1a, x2a, y2a = max(xc - w, 0), yc, xc, min(s * 2, yc + h)
    11. x1b, y1b, x2b, y2b = w - (x2a - x1a), 0, w, min(y2a - y1a, h)
    12. elif i == 3: # bottom right
    13. x1a, y1a, x2a, y2a = xc, yc, min(xc + w, s * 2), min(s * 2, yc + h)
    14. x1b, y1b, x2b, y2b = 0, 0, min(w, x2a - x1a), min(y2a - y1a, h)

    np.full()返回一个给定大小和类型并且以指定数字全部填充的新数组。

    img4 = np.full((s * 2, s * 2, img.shape[2]), 114, dtype=np.uint8)

    img4为从[512,512,3]---->[1024,1024,3]全部元素为114的图像。 分为图片超出画布和图片不超出画布两种情况,具体可参考开头博客的内容,非常详细,好理解。

    i=0时,左上角的范围:x1a, y1a, x2a, y2a,马赛克图像的左上角和右下角。

    x1b, y1b, x2b, y2b,截取的图像区域的坐标信息,左上角和右下角。

    x1a, y1a, x2a, y2a = max(xc - w, 0), max(yc - h, 0), xc, yc  # xmin, ymin, xmax, ymax (large image),确定画布区域

     x1b, y1b, x2b, y2b = w - (x2a - x1a), h - (y2a - y1a), w, h  # xmin, ymin, xmax, ymax (small image),确定图片区域

     i=1时,右上角的范围:

    x1a, y1a, x2a, y2a = xc, max(yc - h, 0), min(xc + w, s * 2), yc

    x1b, y1b, x2b, y2b = 0, h - (y2a - y1a), min(w, x2a - x1a), h

    i=2时,左下角的范围:

    x1a, y1a, x2a, y2a = max(xc - w, 0), yc, xc, min(s * 2, yc + h)

    x1b, y1b, x2b, y2b = w - (x2a - x1a), 0, w, min(y2a - y1a, h)

    i=3时,右下角的范围:

    x1a, y1a, x2a, y2a = xc, yc, min(xc + w, s * 2), min(s * 2, yc + h)

    x1b, y1b, x2b, y2b = 0, 0, min(w, x2a - x1a), min(y2a - y1a, h)

    7.将截取出的图像区域信息填充到马赛克图像区域。填充可能右三种情况,需要计算进行判断。

    img4[y1a:y2a, x1a:x2a] = img[y1b:y2b, x1b:x2b]

    8.4张图片进行拼接时候边缘情况的判断:

    padw = x1a - x1b

    padh = y1a - y1b

    9.将标签中的(x,y,w,h)坐标转换为,(w,h,padw,padd)为相对于resize之后图像的数据,该函数的功能是将(x,y,w,h)坐标转换为标签的左上角和右下角坐标。

    1. def xywhn2xyxy(x, w=640, h=640, padw=0, padh=0):
    2. # Convert nx4 boxes from [x, y, w, h] normalized to [x1, y1, x2, y2] where xy1=top-left, xy2=bottom-right
    3. y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x)
    4. y[..., 0] = w * (x[..., 0] - x[..., 2] / 2) + padw # top left x
    5. y[..., 1] = h * (x[..., 1] - x[..., 3] / 2) + padh # top left y
    6. y[..., 2] = w * (x[..., 0] + x[..., 2] / 2) + padw # bottom right x
    7. y[..., 3] = h * (x[..., 1] + x[..., 3] / 2) + padh # bottom right y
    8. return y

    10.np.clip(x, 0, 2 * s, out=x)  # clip when using random_perspective()

    np.clip(a,a_min,a_max,out)截取数组中小于或大于某值的部分,并使截取部分等于固定值。从输入矩阵a中将所有比a_min小的值都强制变为a_min,比a_max大的值都变为a_max。out用于指定输出矩阵的对象。

  • 相关阅读:
    【数据结构】线性结构——数组、链表、栈和队列
    JS中字符串一些常用的方法
    【香橙派4B】6、测试串口
    论文阅读——BERT
    #力扣:136. 只出现一次的数字@FDDLC
    R语言使用xts包表示时间序列数据(time series data)
    Unity项目迁移
    hibernate跨数据库,columnDefinition不可移植性改造方案
    Android studio Build Log乱码+错误: 找不到符号符号
    Java中作为数据库某个表的实体类为什么一定要实现Serializable接口
  • 原文地址:https://blog.csdn.net/laner__gg/article/details/133172704