抠图技术中三分图(trimap) 被普遍用到,这里记录下基于图像分割技术得到的粗分割结果生成三分图的 python 实现及图片合成实现.
1. 生成三分图trimap
import random
import numpy as np
import cv2
def gen_trimap(alpha):
k_size = random.choice(range(1, 5)) # 随机选择核大小
iterations = np.random.randint(1, 20)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (k_size, k_size))
dilated = cv2.dilate(alpha, kernel, iterations)
eroded = cv2.erode(alpha, kernel, iterations)
trimap = np.zeros(alpha.shape)
trimap.fill(128)
trimap[eroded >= 255] = 255
trimap[dilated <= 0] = 0
return trimap
if __name__ == "__main__":
alpha = xxxx
assert (np.unique(alpha_np) == [0, 255]).any()
alpha = alpha * 255
gen_trimap(alpha)
2. 合成图片composite4
由背景、前景、前景alpha 合成新图像.
import math
import cv2
import numpy as np
def composite4(fg, bg, a, w, h):
fg = np.array(fg, np.float32)
bg_h, bg_w = bg.shape[:2]
x = 0
if bg_w > w:
x = np.random.randint(0, bg_w - w)
y = 0
if bg_h > h:
y = np.random.randint(0, bg_h - h)
bg = np.array(bg[y:y + h, x:x + w], np.float32)
alpha = np.zeros((h, w, 1), np.float32)
alpha[:, :, 0] = a / 255.
im = alpha * fg + (1 - alpha) * bg
im = im.astype(np.uint8)
return im, a, fg, bg
def process(fg_file, alpha_file, bg_file):
im = cv2.imread(fg_file)
a = cv2.imread(alpha_file, 0)
h, w = im.shape[:2]
bg = cv2.imread(bg_file)
bh, bw = bg.shape[:2]
wratio = w / bw
hratio = h / bh
ratio = wratio if wratio > hratio else hratio
if ratio > 1:
bg = cv2.resize(src=bg, dsize=(math.ceil(bw * ratio), math.ceil(bh * ratio)), interpolation=cv2.INTER_CUBIC)
return composite4(im, bg, a, w, h)
if __name__ == "__main__":
#
fg_file = 'fg.jpg'
alpha_file = 'fg_alpha.png'
bg_file = 'bg_file.jpg'
img, alpha, fg, bg = process(fg_file, alpha_file, bg_file)
# trimap
trimap = gen_trimap(alpha)
# 翻转
if np.random.random_sample() > 0.5:
img = np.fliplr(img)
trimap = np.fliplr(trimap)
alpha = np.fliplr(alpha)
5 comments
您好,在trimap中alpha_np并没有定义呢
嗯,这行代码可以忽略下,alpha 实际上就是分割出来的二值图,前景为1,背景为0.
您好,在trimap中alpha_np并没有定义呢,能把您的代码使用的图片发一下吗
您好,请问‘生成三分图trimap’部分的‘ alpha = xxxx’需要怎么改呀? 万分感谢了
分割出来的前景背景图.