Mosaic数据增强的实现

mosaic数据增强是一种在YOLOv4中首次引入的数据增强技术,它可以将4张训练图像以一定的比例合并成一张。这样可以让模型学习如何在比正常更小的尺度上识别物体,也可以在训练中显著减少对大批量大小的需求。

 

mosaic数据增强的优势主要有以下几点:

  • 它可以丰富一张图像上的信息,让模型学习到更多的场景和目标。
  • 它可以减少对大批量大小的依赖,因为一张图像上包含了四张图像的信息。
  • 它可以提高模型对小目标的检测能力,因为将四张图像拼接成一张,相当于缩小了目标的尺寸。
  • 它可以提高模型的泛化能力,因为它可以增加图像背景的复杂度,防止模型过拟合。

Mosaic的一种具体的实现方法如下:

  1. 从数据集中随机挑选四张图片。
  2. 对每张图片进行放大、缩小、平移等几何变换和平滑、模糊、对比度、亮度等像素变换。
  3. 随机从四张图片中各裁剪出一部分区域,进行拼接得到一张固定大小的图片如640x640。
  4. 对每张图片的GT框进行同样的几何变换,同时去除那些裁剪后小于某一阈值的标注框。
class MosicDataset(Dataset):

    def __init__(self, size=(640, 640)):
        super(MosicDataset, self).__init__()
        self.src_data = VocDataset()  # 一个DataSet类,每次返回一个图片,以及对应的标注框
        self.dst_size = size

    def __getitem__(self, idx):
        scale_ratio = (0.6, 1.4)
        src_img, src_boxes, _ = self.src_data[idx]
        img_indexs = np.random.choice(np.arange(self.__len__()), size=3)
        datas = [(src_img, src_boxes)]
        # 随机取出三张图片加上固定的一张一共四张
        for i in img_indexs:
            img, boxes, _ = self.src_data[i]
            datas.append((img, boxes))
        random.shuffle(datas)  # 打乱图片
        h, w = self.dst_size
        # 在640X640大小的背景上随机确定一点,过此点做垂直于四条边的线,将图片分为四部分
        cy, cx = random.randint(h // 4, w * 3 // 4), random.randint(h // 4, w * 3 // 4)
        cys = [cy, h - cy, 0]  # 分别是第一部分的高度,第二部分的高度,最后一个为0,方便循环
        cxs = [cx, w - cx, 0]
        new_images = np.ones(shape=(h, w, 3), dtype=np.uint8) * 114
        new_boxes = []
        for i in range(2):
            for j in range(2):
                img, boxes = datas[i * 2 + j]
                H, W, _ = img.shape
                sr = np.random.uniform(scale_ratio[0], scale_ratio[1])  # 随机缩放图片
                img = cv2.resize(img, (int(sr * W), int(sr * H)), interpolation=cv2.INTER_LINEAR)
                H, W, _ = img.shape
                # 随机在每张图片上进行裁剪
                excursion_x, excursion_y = random.randint(0, max(H - cxs[i], 0)), random.randint(0, max(W - cys[j], 0))
                # 将裁剪后的图片复制到画布上
                new_images[cxs[i - 1]: cxs[i - 1] + min(cxs[i], H - excursion_x),
                cys[j - 1]: cys[j - 1] + min(cys[j], W - excursion_y)] = img[
                                                                         excursion_x: excursion_x + min(cxs[i],
                                                                                                        H - excursion_x),
                                                                         excursion_y: excursion_y + min(cys[j],
                                                                                                        W - excursion_y)]
                for box in boxes:
                    # 对标注框进行放缩
                    xmin, ymin, xmax, ymax = box[:4] * sr
                    # 确保标注框不会出界
                    xmin = np.clip(xmin - excursion_y, a_min=0, a_max=cys[j])
                    ymin = np.clip(ymin - excursion_x, a_min=0, a_max=cxs[i])
                    xmax = np.clip(xmax - excursion_y, a_min=0, a_max=cys[j])
                    ymax = np.clip(ymax - excursion_x, a_min=0, a_max=cxs[i])
                    # 排除裁剪后和裁剪前相比剩余部分较小的标注框:这里既可以用比例,也可以指定面积。
                    if ((ymax - ymin) * (xmax - xmin)) / ((box[3] - box[1]) * (box[2] - box[0]) * sr * sr) > 0.3:
                        # 将标注框还原到画布
                        new_boxes.append(
                            [xmin + cys[j - 1], ymin + cxs[i - 1], xmax + cys[j - 1], ymax + cxs[i - 1], box[-1]])

        new_boxes = np.array(new_boxes, dtype=np.float32)
        trans = transforms.Compose([transforms.ToTensor(),
                                    transforms.ColorJitter(0.2, 0.2, 0.2),
                                    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])
        # new_images = trans(new_images)
        # new_boxes = paddle.to_tensor(new_boxes, dtype=paddle.float32)
        return new_images, new_boxes

    def __len__(self):
        return self.src_data.__len__()

诸事不顺,幸得二月初春,忽见嫩芽新发,才不致满面愁容。最后以白居易的一首诗结尾吧:

春风先发苑中梅,樱杏桃梨次第开。荠花榆荚深村里,亦道春风为我来。 — 唐代·白居易《春风》

posted @ 2023-03-07 22:08  人间别久不成悲  阅读(919)  评论(0编辑  收藏  举报