opencv实现mosaic数据增强

mosaic数据增强:将四个图片随机缩放,放在一个大的图片中
原理:
方法步骤:

  1. 随机选取图片拼接基准点坐标(xc,yc),另随机选取四张图片。
  2. 四张图片根据基准点,分别经过 尺寸调整 和 比例缩放 后,放置在指定尺寸的大图的左上,右上,左下,右下位置。
  3. 根据每张图片的尺寸变换方式,将映射关系对应到图片标签上。
  4. 依据指定的横纵坐标,对大图进行拼接。处理超过边界的检测框坐标。
    这里原先没有限定四个图,所以加上了对第四个图的退出
    opencv实现mosaic数据增强_第1张图片
def mosaic(imgs, labels, img_size=640):
    labels4 = []
    s = img_size
    mosaic_border = [-s // 2, -s // 2]
    # 从点A(s/2, s/2)和点B(3s/2, 3s/2)限定的矩形内随机选择一点作为拼接点
    yc, xc = (int(random.uniform(-x, 2 * s + x)) for x in mosaic_border)  # mosaic center x, y
    for i in range(len(imgs)):
        img = imgs[i]
        h, w = img.shape[:2]
        # place img in img4
        if i == 0:  # top left
            # 创建马赛克图像 [1280, 1280, 3]=[h, w, c] base image with 4 tiles
            img4 = np.full((s * 2, s * 2, imgs[0].shape[2]), 114, dtype=np.uint8)
            # xmin, ymin, xmax, ymax (large image)
            # 计算马赛克图像中的坐标信息(将图像填充到马赛克图像中)
            # 马赛克图像【大图】:(x1a,y1a)左上角,(x2a,y2a)右下角
            x1a, y1a, x2a, y2a = max(xc - w, 0), max(yc - h, 0), xc, yc
            # xmin, ymin, xmax, ymax (small image)
            # 计算截取的图像区域信息(以xc,yc为第一张图像的右下角坐标填充到马赛克图像中,丢弃越界的区域)
            # 要拼接的图像【小图】:(x1b,y1b)左上角 (x2b,y2b)右下角
            x1b, y1b, x2b, y2b = w - (x2a - x1a), h - (y2a - y1a), w, h
        elif i == 1:  # top right
            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
        elif i == 2:  # bottom left
            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)
        elif i == 3:  # bottom right
            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)
        # 由于马赛克的数据增强需要四个数据加在一起,所以多一个就会出错,0-3四个结束之后就会结束
        else:
            break
        # img4[ymin:ymax, xmin:xmax]
        # 将截取的图像区域填充到马赛克图像的相应位置   img4[h, w, c]
        # 将图像img的【(x1b,y1b)左上角 (x2b,y2b)右下角】区域截取出来填充到马赛克图像的【(x1a,y1a)左上角 (x2a,y2a)右下角】区域
        # 辉:
        """ img_0=cv2.resize(img[::,0], img4[::,0].shape)
        img_1=cv2.resize(img[::,1], img4[::,1].shape)
        img_2=cv2.resize(img[::,2], img4[::,2].shape)
        img[::,0]=img_0
        img[::,1]=img_1
        img[::,2]=img_2 """
        # img=cv2.resize(img,img4.shape[0],img4.shape[1])
        """ if(y2b-y1b>img.shape[0]):
            img4[y1a:y2a-1, x1a:x2a] = img[y1b:y2b-1, x1b:x2b]  # img4[ymin:ymax, xmin:xmax]
        else:
            img4[y1a:y2a, x1a:x2a] = img[y1b:y2b, x1b:x2b] """
        """ if(y2b-y1b==img.shape[0]+1):
            img=cv2.resize(img, (x2b-x1b,y2b-y1b)) """
        img4[y1a:y2a, x1a:x2a] = img[y1b:y2b, x1b:x2b]

        # 计算小图填充到大图时所产生的偏移 用来计算mosaic数据增强后 标签框的位置
        padw = x1a - x1b
        padh = y1a - y1b

        # 处理图像的labels信息
        label = labels[i].copy()
        if label.size:
            # normalized xywh to pixel xyxy format
            label[:, 1:] = xywhn2xyxy(label[:, 1:], w, h, padw, padh)
        labels4.append(label)

    # Concat/clip labels
    # 把label4中4张小图的信息整合到一起
    labels4 = np.concatenate(labels4, 0)
    for x in (labels4[:, 1:]):
        np.clip(x, 0, 2 * s, out=x)  # clip when using random_perspective()

    return img4, labels4

你可能感兴趣的:(每日总结,opencv,计算机视觉,图像处理)