最近在做关于基于yolo的目标检测,由于yolo目标检测中有时候会检测到不需要或者说和需要检测的目标不相匹配的其它额外小目标,因此在训练yolo模型的时候,有必要对训练数据进行数据增强操作,由程序对训练数据随机增加一些额外的小目标物体。如果只是把小目标图片直接叠加到原图中,则会出现周围像素不匹配等问题,所以写个博客记录一下呗。
本次要做的就是将如下第一张图片和第二张图片进行融合,效果如第三张图片。
网上没有找到现成的python代码实现,只能看c++的实现代码并用python做一个简单实现。
图二代表你要嵌入的小图片
图一代表你的一张大的背景图
由于我的图二大小是100*100的。所以如下代码中指定的长宽都是100,至于要显示在图片上的那个位置由自己指定。
img = cv2.imread("图二.png")
co = cv2.imread("图一.png", -1)
scr_channels = cv2.split(co)
dstt_channels = cv2.split(img)
b, g, r, a = cv2.split(co)
for i in range(3):
dstt_channels[i][100:200,300:400] = dstt_channels[i][100:200,300:400]*(255.0-a)/255
dstt_channels[i][100:200,300:400] += np.array(scr_channels[i]*(a/255), dtype=np.uint8)
cv2.imwrite("img_target.png", cv2.merge(dstt_channels))
以下是我在项目中添加该部分数据增强时候的代码:
h, w, c = image.shape
#animal angumention
# cv2.imwrite('1_result.png', cv2.flip(img,-1))
# cv2.imwrite('1_result.png', cv2.resize(img, None,fx=0.2,fy=2, interpolation = cv2.INTER_CUBIC))
if cfg.animal_augment and random.uniform(0, 1) >= 0.4:
animal_sample = []
choices = random.sample(self.animal_aug_list, random.randint(1,4))
# print(choices)
for e in choices:
animal_sample.append(os.path.join(cfg.animal_aug_dir, e))
for i_idx, img_path in enumerate(animal_sample):
# print(img_path)
i = cv2.imread(img_path, -1)
# if len(i) != 4:
# continue
if random.uniform(0, 1) > 0.5:
i = cv2.flip(i, random.choice([0, 1, -1]))
if random.uniform(0, 1) > 0.5:
coor_rate = round(random.uniform(0.5, 1.2), 1)
i = cv2.resize(i, None, fx=coor_rate, fy=coor_rate, interpolation = cv2.INTER_CUBIC)
i_h, i_w, i_c = i.shape
dstt_channels = cv2.split(image)
scr_channels = cv2.split(i)
if len(scr_channels) != 4:
# print("pass")
continue
b, g, r, a = cv2.split(i)
# print(i.shape)
if random.uniform(0, 1) >= 0.5:
coor_xmin = random.randint(5, w//2-i_w)
else:
coor_xmin = random.randint(w//2+i_w, w-i_w)
coor_ymin = random.randint(10, h-i_h)
for j in range(3):
dstt_channels[j][coor_ymin:(coor_ymin+i_h), coor_xmin:(coor_xmin+i_w)] = dstt_channels[j][coor_ymin:(coor_ymin+i_h), coor_xmin:(coor_xmin+i_w)]*(255.0-a)/255
dstt_channels[j][coor_ymin:(coor_ymin+i_h), coor_xmin:(coor_xmin+i_w)] += np.array(scr_channels[j]*(a/255), dtype=np.uint8)
image = cv2.merge(dstt_channels)