根据原图和对应的alpha图提取前景并且合成新图(基于python+opencv)

目前主流的抠图算法在最后生成的是一张alpha图像,该图像用来指明前景对应的透明度。比如下面两幅图所示:

根据原图和对应的alpha图提取前景并且合成新图(基于python+opencv)_第1张图片       根据原图和对应的alpha图提取前景并且合成新图(基于python+opencv)_第2张图片

那么如何根据原图以及alpha图提取最终的前景图呢,下面就来解决这个问题。

基本环境配置:

python 3.6.1

opencv-python==3.4.2 

numpy==1.15.0

代码如下所示:

import cv2
import numpy as np

img = cv2.imread("1.jpg")
mask = cv2.imread("2.jpg", 0) #读取灰度图像

height,width,channel=img.shape

b, g, r = cv2.split(img)

#-----------------1.获取透明的前景图像-----------
dstt = np.zeros((4,height,width),dtype=img.dtype)

dstt[0][0:height,0:width] = b
dstt[1][0:height,0:width] = g
dstt[2][0:height,0:width] = r
dstt[3][0:height,0:width] = mask
cv2.imwrite("fore.png", cv2.merge(dstt))

#-----------------2.与新背景图像合成-----------
bg= np.zeros((3,height,width),dtype=img.dtype)  #生成背景图像
bg[2][0:height,0:width] = 255 #背景图像采用红色

dstt = np.zeros((3,height,width),dtype=img.dtype)

for i in range(3):
    dstt[i][:,:] = bg[i][:,:]*(255.0-mask)/255
    dstt[i][:,:] += np.array(img[:,:,i]*(mask/255), dtype=np.uint8)
cv2.imwrite("merge.png", cv2.merge(dstt))

上述代码主要完成两件事:

(1)根据alpha图和原图提取前景人物,通过生成四通道的png图对多余背景进行剔除。

显示效果如下:

 

根据原图和对应的alpha图提取前景并且合成新图(基于python+opencv)_第3张图片

(2)将前景图和新的背景图进行合成,此处新的背景图为了简单直接采用纯红色背景,实现替换背景效果。最终效果如下:

 

根据原图和对应的alpha图提取前景并且合成新图(基于python+opencv)_第4张图片

代码链接:   https://download.csdn.net/upload/10976341

最后补充:如何从原图中生成alpha图则是一个难点并且也是最核心的模块,这个任务也叫抠图。具体的可以参照一些经典的抠图论文比如KNN等,也可以参考最新的一些利用深度学习进行抠图的论文(deep image matting)。后续我会重点介绍一些这方面的内容。

你可能感兴趣的:(语义分割,人像抠图)