利用opencv实现抖音最强变脸术 | 您所在的位置:网站首页 › 抖音上变换天气的特效 › 利用opencv实现抖音最强变脸术 |
最近一个“最强变脸术”又火爆抖音啦,还不知道的朋友建议先打开抖音,搜索“最强变脸术”看个十来个视频再回来看这篇文章。视频看起来炫酷,其实本质就是图像的各种变换组合到一块的结果。那我们能不能也搞出一个来玩玩?我利用周末刷了两天抖音,不停的暂停、继续… 最终在尝试了仿射变换和透视变换两种方案后,搞出了一个“低配版最强变脸术”。首先先来看看最终实现的效果(忽略gif颜色问题),也可以到http://www.iqiyi.com/w_19saz1z92h.html查看完整视频,然后从数学原理、opencv代码实现入手一步步的搞一个“最强变脸术”。 人脸关键点识别看过“最强变脸术”的都知道,这个效果最基础的技术就是人脸识别。都2020年了,人脸识别当然不是多难的事了,可以选择的技术也很多,比如可以利用深度学习自己训练一个,也可以和我一样使用dlib这个三方库。 dlib用起来很简单,下面直接上代码了。 img = cv2.imread("./imgs/2.jpg") dets = detector(img, 1) shape = predictor(img, dets[0]) landmarks = [] for p in shape.parts(): landmarks.append(np.array([p.x, p.y])) for idx, point in enumerate(landmarks): cv2.putText(img, str(idx), (point[0], point[1]), fontFace=cv2.FONT_HERSHEY_SCRIPT_SIMPLEX, fontScale=0.3, color=(0, 255, 0)) cv2.imshow("--", img) cv2.waitKey()运行上面的代码可以看到这样的结果: 请注意上面图中36、45、29三个数字的位置,因为在下面仿射变换的版本中我们要用到。 版本一:仿射变换实现人脸关键点搞定后的第一次尝试,我是用的图像仿射变换来实现的。通过不断观察,我拆解出了一下三种变换方式: 平移 缩放 旋转 平移需要平移,是因为我们需要把两张图片上的人脸叠放到一块。平移的变换操作矩阵是: [ 1 0 t x 0 1 t y ] \left[ \begin{matrix} 1 & 0 & tx \\ 0 & 1 & ty \end{matrix} \right] [1001txty] 例如我们要向右平移100个像素,向下平移50个像素,那么变换矩阵就应该是: [ 1 0 100 0 1 50 ] \left[ \begin{matrix} 1 & 0 & 100 \\ 0 & 1 & 50 \end{matrix} \right] [100110050] 对应的运算是: [ x ′ y ′ ] = [ 1 0 100 0 1 50 ] ∗ [ x y 1 ] \left[ \begin{matrix} x' \\ y' \\ \end{matrix} \right]=\left[ \begin{matrix} 1 & 0 & 100 \\ 0 & 1 & 50 \end{matrix} \right]*\left[ \begin{matrix} x \\ y \\ 1 \end{matrix} \right] [x′y′]=[100110050]∗⎣⎡xy1⎦⎤ 即 { x ′ = 1 ∗ x + 0 ∗ y + 100 ∗ 1 y ′ = 0 ∗ x + 1 ∗ y + 50 ∗ 1 \begin{cases} x'=1*x+0*y+100*1 \\ y'=0*x+1*y+50*1 \end{cases} { x′=1∗x+0∗y+100∗1y′=0∗x+1∗y+50∗1 所以平移操作的本质就是对每个像素加上一个偏移量。下面是使用opencv对图像进行平移操作的代码: img = cv2.imread("./imgs/2.jpg") M = np.float32( [ [1, 0, 100], [0, 1, 50] ] ) dst = cv2.warpAffine(img, M, (img.shape[1], img.shape[0])) cv2.imshow("", dst) cv2.waitKey()运行上面的代码可以看到这样的结果: 缩放需要缩放,是因为我们在人脸对齐的时候需要尽可能的保证两张人脸大小一致。缩放的变换操作矩阵是: [ f x 0 0 0 |
CopyRight 2018-2019 实验室设备网 版权所有 |