变装之faceswap

程序整体思想分为以下几个部分,

 

(1)使用Dlib进行人脸检测和68个关键点定位

这里使用的是ERT方法,源自论文 One Millisecond Face Alignment with an Ensemble of RegressionTrees,算是一种比较老的方法了。但是效果很好。

(2)进行旋转,缩放,平移等变换,即aligement操作,使得第二个图和原始图相互吻合

这里使用的是普式变换(Ordinary Procrustes Analysis),最终结果是要使得变换过程满足下面式子最小化,简单的说,就是第一个图的68个点经过仿射变换(warp_affine)后,和第二个图的68个点的距离最小。

其中,R是2*2的旋转变换矩阵,S是一个线性缩放矩阵,T是一个二维平移向量,p,q分别为上面计算的2个人的68个点。

那么问题来了,现在只已经2个图的68个点,如何求解上面的S,R,T呢,这里使用奇异值SVD分解( Singular Value Decomposition),从而求出R。

U, S, Vt = numpy.linalg.svd(points1.T * points2)
R = (U * Vt).T

最终返回变换矩阵

return numpy.vstack([numpy.hstack(((s2 / s1) * R,
                                       c2.T - (s2 / s1) * R * c1.T)),
                         numpy.matrix([0., 0., 1.])])

有了该变换矩阵,就可以使用opencv的warpAffine函数,将第二张图片变为和第一种图片同样的空间位置。

(3)将第二个图的颜色匹配到第一个图

如果直接将第二个图覆盖到第一个图,会发现,在边缘地方2个人的肤色和关照等会出现明显的区别,这里使用了颜色平衡( RGB scaling colour-correction)的方法,这里主要进行的操作就是,分别对图片1,2进行高斯滤波,生成高斯滤波后的1,2图片,然后对第二个图片除以自己的高斯滤波后的图片,再乘以第一个图片的高斯滤波后的图片,从而生成最终变换后的图片。

这里高斯核的选择是一个重点,太小的话,会将第一个图的特征显示到第二个图上,太大又会将人脸以外的区域覆盖到第二个图上,这里选取0.6倍的瞳距。

im1_blur = cv2.GaussianBlur(im1, (blur_amount, blur_amount), 0)
im2_blur = cv2.GaussianBlur(im2, (blur_amount, blur_amount), 0)

# Avoid divide-by-zero errors.
im2_blur += 128 * (im2_blur <= 1.0)

return (im2.astype(numpy.float64) * im1_blur.astype(numpy.float64) /
                                                im2_blur.astype(numpy.float64))

(4)将第二个图的人脸特征,通过使用掩码的方式混合融合进第一个图

这里主要是要生成一个掩码,通过该掩码来进行图像融合,在掩码为1的地方显示图像2,掩码为1的地方显示图像1,掩码0-1之间的地方进行融合。

生成掩码的思路为,先通过人脸关键点生成一个凸包(convexHull),然后扣出凸包中的像素,进行高斯滤波,生成mask,然后将1,2两幅图的mask进行max操作,生成最终的mask。

最终通过一个阿尔法变换,用2个图片生成最终想要的结果。

output_im = im1 * (1.0 - combined_mask) + warped_corrected_im2 * combined_mask

当然这个并没有网上的H5的效果好,但是基本还是有模有样的。

实验效果如下,第一张是变换后的图,第二张是原图。

 

 

reference:

https://github.com/matthewearl/faceswap

http://matthewearl.github.io/2015/07/28/switching-eds-with-python/

https://github.com/hrastnik/FaceSwap

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值