换脸特效

目录

摘要

实验步骤

关于应用到视频上


摘要

抖音上很多脸部特效很好玩,都可以一一实现来玩玩。下面介绍的是换脸特效。效果图如下,

这是最近比较流行的一个效果。其实很简单。

原文:http://matthewearl.github.io/2015/07/28/switching-eds-with-python/,不过需要对其中代码进行修改。

原文给的是人脸,上图用的是狗脸融合,可以通过自己标准68个点,对应人脸的位置。

实验步骤

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

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

dlib确定68个点是通过 “ 用回归树,一毫秒搞定人脸对齐。”, 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

关于应用到视频上

1 用C++写代码,

2 不用68个点,取其中主要的点,减少计算量。

 

 

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值