基於python的兩張圖片RGBA alpha 透明度混合實現
最近在做關於基於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)