简单的复制粘贴数据增强

本文介绍如何通过下标操作在目标检测任务中,从一个图像的候选目标mask中选择并转移标签到其他图片,同时强调了使用segmentation标签的重要性。作者给出了详细步骤和示例代码,讨论了操作的局限性和改进方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思想:利用下标值操作

首先抠出原图中的候选目标的mask

这里有几点需要注意:

  1. 我们是通过下标操作,所以我们不需要得到原图的像素值。 仅仅得到原图对应像素值的下标即可
  2. 得到下标的同时需要进行判断是否超出边界。
  gt_box_i = batched_inputs[select_image]['instances'].gt_boxes.tensor[i]         # 这是已经转换了的box,coco数据集可能原始的是x,y,w,h格式
  ori_mask = torch.zeros_like(batched_inputs[select_image]['image'][0,:,:])       # 得到和清晰度相同的0矩阵

  mask_h, mask_w = ori_mask.shape
  ori_mask[max(0, int(gt_box_i[0])): min(mask_w, int(gt_box_i[2])),
      max(0, int(gt_box_i[1])): min(mask_h, int(gt_box_i[3]))] = 1                # 将挑选出来的bbox的mask值置为一
  idx_all = torch.nonzero(ori_mask == 1, as_tuple=True)                           # 得到下标为1的位置(x, y)

在上述操作中,我们得到了下标为1的位置保存在idx_all中。 注意到在ori_mask中我们对相应的边界做了判断防止越界。

将结果贴到需要转换的图片上面

这一步十分的简单,直接使用下标值进行复制就可以了。结合后面的一起说明。

完整代码

images = [x["image"].to(self.device) for x in batched_inputs]
images = [(x - self.pixel_mean) / self.pixel_std for x in images]

images = ImageList.from_tensors(images,
                                self.backbone.size_divisibility)
if not self.training:
    return images
select_image = random.randint(0, 0xfffffff) % len(batched_inputs)
select_Num = random.randint(0, 0xfffffff)

for i in range(len(batched_inputs[select_image]['instances'].gt_boxes.tensor)):
    if i << 1 & select_Num:
        # 把这个目标贴到其他的图上面去
        gt_box_i = batched_inputs[select_image]['instances'].gt_boxes.tensor[i]         # 这是已经转换了的box
        ori_mask = torch.zeros_like(batched_inputs[select_image]['image'][0,:,:])       # 得到和清晰度相同的0矩阵

        mask_h, mask_w = ori_mask.shape
        ori_mask[max(0, int(gt_box_i[0])): min(mask_w, int(gt_box_i[2])),
            max(0, int(gt_box_i[1])): min(mask_h, int(gt_box_i[3]))] = 1                # 将挑选出来的bbox的mask值置为一
        idx_all = torch.nonzero(ori_mask == 1, as_tuple=True)                           # 得到下标为1的位置(x, y)
        label_rgb = images.tensor[select_image]
        label_id = batched_inputs[select_image]['instances'].gt_classes[i]
        for img_idx in range(len(batched_inputs)):
            if img_idx == select_image:
                continue
            rand_num = random.randint(0, 0xffffffff)
            h, w = images.tensor[img_idx, ...].shape[-2:]
            trans_x = idx_all[0] + rand_num % w        # (x0, x1)
            trans_y = idx_all[1] + rand_num % h        # (y0, y1)
            trans_x, trans_y = trans_x[trans_x >= 0], trans_y[trans_x >= 0]
            trans_x, trans_y = trans_x[trans_x < w], trans_y[trans_x < w]
            trans_x, trans_y = trans_x[trans_y >= 0], trans_y[trans_y >= 0]
            trans_x, trans_y = trans_x[trans_y < h], trans_y[trans_y < h]
            if trans_x.shape[0]> 10:
                images.tensor[img_idx][:, trans_y, trans_x] = label_rgb[:, trans_y - rand_num % h, trans_x - rand_num % w]
                gt_box_i = torch.Tensor([gt_box_i[0] + rand_num % w, gt_box_i[1] + rand_num % h,
                                      gt_box_i[2] + rand_num % w, gt_box_i[3] + rand_num % h])
                ious = box_iou(batched_inputs[img_idx]['instances'].gt_boxes.tensor, gt_box_i.unsqueeze(0))
                batched_inputs[img_idx]['instances'].gt_boxes.tensor = batched_inputs[img_idx]['instances'].gt_boxes.tensor[(ious < 0.9).squeeze(1)]
                batched_inputs[img_idx]['instances'].gt_classes = batched_inputs[img_idx]['instances'].gt_classes[
                    (ious < 0.9).squeeze(1)]
                batched_inputs[img_idx]['instances'].gt_boxes.tensor = torch.cat((batched_inputs[img_idx]['instances'].gt_boxes.tensor, gt_box_i.unsqueeze(0)))
                batched_inputs[img_idx]['instances'].gt_classes = torch.cat((batched_inputs[img_idx]['instances'].gt_classes, label_id.unsqueeze(0)))
return images

关于这个代码有几点需要说明一下:

  1. 对于输入进行了减去均值除以方差的操作
  2. 如果没有在训练时(即验证)不进行下面的操作直接返回。

流程说明:

  • 首先我们从输入的batch中随机挑选出一张照片。通过生成一个随机数对batchsize取余得到select_image。
  • 然后我们从该图片的label中随机挑选出子集,贴到其他的图片上面。通过生成随机数然后与i<<1判断是否选中。
  • 在得到了原图中label的下标值之后,通过随机数rand_num得到其他图像的偏移。
  • 最后判断得到的下标是否越界。
  • 最后判断iou是否大于设定的阈值(0.9),来更新对应图片的label.

缺点:

  • 由于笔者是做目标检测的,对于目标检测的评价指标可能比较熟悉一点。事实上,在得到原图label对应下标的时候用segmentation的标签比较好。可以防止大量背景信息导入。

在这里插入图片描述

图1 原始图片
图2 贴图

可以看到,转换时把背景信息也提取出来了。所以用segmentation作为label的下标比较好。(这里我屏蔽了第一步的减去均值除以方差的操作)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值