抠图技术中三分图(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 合成新图像.

Matting - 更换主体背景的实现 - AIUAI

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)

3. 相关

[1] - Python - OpenCV 之图像形态学(膨胀与腐蚀) - AIUAI

[2] - Matting - 更换主体背景的实现 - AIUAI

Last modification:November 21st, 2020 at 03:11 pm