上一篇文章介绍了“看脸”的世界背后的技术,很多人会好奇那些萌萌的兔耳朵,猫胡须是怎么贴到脸上并且还有各种萌萌哒动画的,现在就为你揭晓谜题。拓幻科技不仅让幻想不止于此,也让程序猿鸽鸽的技能变得不那么神秘,吼吼吼~

Faceu,B612刷爆朋友圈,因为他们在拍照、拍视频时加入了动态贴纸的功能之后,妹子们拍照已经不满足于仅仅瘦脸、磨皮、大眼等对图片的处理。于是一个不能加萌萌哒贴纸的拍照软件,都不好意思上架了。那么如何快速让自己的相机快速拥有图一这种加猫耳朵的神奇秘术呢?

网上很流行的贴纸挡脸软件(不仅看脸还要更萌)(1)

图1 拓幻科技贴纸demo示意图

在上一篇文章中我们介绍过,这些图像美化技术之前都会有人工智能AI技术保驾护航。这就是人脸检测和追踪,AI为其提供了底层技术框架。据程序猿葛葛说,这个技术也有很多是开源的,只是效率和效果上达不到商用级别,感兴趣的童鞋自己尝试则完全没问题的,比如OpenCV,dlib,flandmark。这个技术也是一般做特效相机软件的门槛,没有这个技术,就没有实时贴纸,当然也不能把脸变小把眼睛变大啦,科科。我们拓幻科技是基于自己研发的人脸检测追踪器,实时检测大家帅气的面庞的哦。人脸追踪器会检测人脸关键点的位置信息,并且实时跟踪,不管你侧脸,张嘴还是闭眼。

拿到这些关键点信息后,就是AR渲染了。这个步骤必须配合设计师完成,设计师会设计好猫耳朵的原始样貌,然后会设计很多张不同形态下连续的图片,连起来播放就像是猫耳朵在动啦,是不是很眼熟?就像小时候在一本书每一页的边缘画上不同动作的相同小人,快速翻书就像在看动画一样。然后程序员葛葛会根据设计师设计的贴纸,页数以及人脸追踪器标准点位置等参数,生成相应的参数文件,告诉代码这个猫耳朵该放在什么位置,以及多少张形成一个连续的动画。接下来就是渲染了,如果只是自己尝试,建议试试使用GPUImage等开源库,功能也是十分强大。以下的话,都是程序猿葛葛看不下去,抢过我的键盘,自己敲的。

OK,各位,切入正题。贴纸效果是可以基于GPUImage实现的,文章末尾我会放上一些demo以供参考。贴纸效果其实就是在人脸上贴一些图片,同时这些图片是跟随着人脸的位置改变的。其实可以这么理解,如果我们不强调贴图的位置,这就是一个简单的水印需求。根据人脸检测的结果动态调整水印贴纸的位置,加上刚刚商务小妹说的那些,即可实现简单的实时动态贴纸效果。添加水印的方法,在GPUImage的官方demo中就已经有文字水印的实现:

GPUImageFilter *filter = [[GPUImageFilter alloc] init]; [self.videoCamera addTarget:filter]; GPUImageAlphaBlendFilter *blendFilter = [[GPUImageAlphaBlendFilter alloc] init]; blendFilter.mix = 1.0; NSDate *startTime = [NSDate date]; UIView *temp = [[UIView alloc] initWithFrame:self.view.frame]; UILabel *timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, 240.0f, 40.0f)]; timeLabel.font = [UIFont systemFontOfSize:17.0f]; timeLabel.text = @"Time: 0.0 s"; timeLabel.textAlignment = UITextAlignmentCenter; timeLabel.backgroundColor = [UIColor clearColor]; timeLabel.textColor = [UIColor whiteColor]; [temp addSubview:timeLabel]; uiElementInput = [[GPUImageUIElement alloc] initWithView:temp]; [filter addTarget:blendFilter]; [uiElementInput addTarget:blendFilter]; [blendFilter addTarget:filterView]; __unsafe_unretained GPUImageUIElement *weakUIElementInput = uiElementInput; [filter setFrameProcessingCompletionBlock:^(GPUImageOutput * filter, CMTime frameTime){ timeLabel.text = [NSString stringWithFormat:@"Time: %f s", -[startTime timeIntervalSinceNow]]; [weakUIElementInput update]; }];

首先要熟悉一下GPUImageAlphaBlendFilter和GPUImageUIElement。

GPUImageUIElement继承GPUImageOutput类,作为响应链的源头。通过CoreGraphics把UIView渲染到图像,并通过glTexImage2D绑定到outputFramebuffer指定的纹理,最后通知targets纹理就绪。它作用是把一个视图的layer通过CALayer的renderInContext:方法把layer转化为image,然后作为OpenGL的纹理传给GPUImageAlphaBlendFilter。而GPUImageAlphaBlendFilter则是一个blend filter,它需要两个输入, 它的第一个输入是摄像头数据,第二个输入则是刚刚提到的GPUImageUIElement的数据,GPUImageAlphaBlendFilter将这两个输入做alpha blend,可以简单的理解为将第二个输入叠加到第一个的上面。

那么这样就可以实现简单的贴纸和视频帧的叠加了。

通过以上的方法,就可以简单实现一个实时贴纸效果的demo啦。当然渲染方法也可以不用GPUImage库,可以使用自己的渲染方法,本文只是个例子。这个demo只是实现功能,如果想要向拓幻科技一样进行商用,那当然需要进一步做优化的,比如渲染方法,效率等等都是需要考虑的。

附上经典demo源码地址,大家可以学习哦。

最后再给大家看看我们公司的萌妹纸和程序猿葛葛吧,将“黑”朋友进行到底,尽在拓幻科技~~~

网上很流行的贴纸挡脸软件(不仅看脸还要更萌)(2)

图2 背景替换示意图 妹纸总嫌不是瓜子脸,这下够了吧,哈哈哈

网上很流行的贴纸挡脸软件(不仅看脸还要更萌)(3)

图3 被哈哈镜玩坏了的程序猿葛葛

希望下班可以安全回家,不会被他们拖出去打死~~~ 好啦,小伙伴们,我们下期再见!也可以关注我们官方微信公众号,请搜索微信公众号,拓幻科技告诉我们你们最想了解什么技术,我们会在这里为你解答~

网上很流行的贴纸挡脸软件(不仅看脸还要更萌)(4)

,