Android平台美颜相机/Camera实时滤镜/视频编解码/影像后期/人脸技术探索——1.1 工程思路与难点_Martin20150405的博客-程序员秘密

技术标签: 实时滤镜  Android平台美颜相机、实时滤镜、人脸技术探秘  android  美颜相机  安卓开发  人脸识别  

回到目录

本文主要探讨搭建一款Android平台下美颜相机可能需要填的坑,内容会不断更新。。

相机框架

相机框架相对比较简单,现有的开源代码很多,可以很容易的实现拍照和录像的功能。

预览尺寸选择

预览尺寸就是相机显示纹理的尺寸,也是每一帧原始数据的尺寸,一般相对拍照尺寸较低(1080P就算比较高的预览尺寸了)

拍照尺寸选择

拍照尺寸只在拍照时起作用,往往可以调的很高,而且获取数据非常快(例如1300万像素,相当于1080P数据的7倍左右)

拍照:已被弃用的Camera API可以提供takePicture进行拍照,在onPictureTaken(final byte[] data, final Camera camera)中可以获得包括了Exif数据的图片,直接写入到文件就是一张没有做过任何处理的照片,也可以转成bitmap再做处理(图片尺寸就是拍照尺寸),但是很容易出现OOM的问题,例如1300万像素的照片至少占内存50M,分分钟死给你看。

录像:使用MediaRecorder可以进行录像,相机需要在录像模式和预览模式之间切换,使用较为方便

获取每一帧数据:onPreviewFrame(byte[] data, Camera camera)中可以获取到每一帧的原始数据,如果处理不及时下一帧就会被丢弃,帧率并不是固定的(也就是可能比相机预览的速度慢很多),这里的图像大小和设定的预览尺寸相同

Camera2 API

后期会切换到这个API,ImageReader类确实封装的很好,虽然我还没搞清楚怎么获取原始数据

实时滤镜

用CPU来处理图像真的太慢慢慢慢慢慢了,尤其是在移动平台下,因此一定要用GPU来加速处理。
由于是图像处理,OpenGL尚能够胜任,而且兼容性和通用性都比较好,所以不考虑RenderScript和OpenCL,相机的数据可以直接利用GL_TEXTURE_EXTERNAL_OES进行GPU加速的格式转换,在显示层面不需要自己再做YUV420SP/YUV420P到RGB的转换,之后就可以使用GL_TEXTURE_2D来进行各种处理。GPU相对CPU要快很多,举个例子:在Mali400MP1这种渣渣GPU上,高斯模糊可以在720P的图像上连续处理6次依然丝般润滑毫无卡顿之感。

叠加特效后拍照/截屏/离屏渲染

在叠加了滤镜、面具、面部贴纸后,如果要拍照,有两种可能的解决方案:
拍照后离屏渲染:效率较高,但是较为复杂,需要自行管理一个工作线程,因为照片的尺寸远大于预览的纹理尺寸,而且内存开销较大,适合于软件定位为图像处理/专业相机应用时的情况,拍完照片后不影响后续拍照,用户体验可以做的很棒(例如各大国产ROM自带的滤镜功能,拍完后不会感觉到任何卡顿)
直接对Surface截屏:这是最简单粗暴的方法,代码简单,非常鲁棒,内存占用也低(毕竟屏幕分辨率2K已经算高了,也才200万像素),经过测试,Snow相机和FaceU都是采用的这种方法,特点是方便快捷,但是生成的图片尺寸较小(一般就是屏幕分辨率),适合于软件定位为偏社交相机应用的情况,拍完照直接编辑预览。

录屏录像

录屏在Android 5.0之前是没有提供接口的(需要root),如果是5.0及以上版本录屏(直播)就会非常方便,但是如果只是录制相机的预览区域就不同了(对于Surface进行录制)
硬编:硬件编码的CPU占用低,码率可以拉的很高,不卡顿,MediaRecorder可以直接录制视频,但是没法实时处理,在5.0及以上版本也可以录制Surface了,但是封装的太好,使用并不自由。
MediaCodec是一个相对“野生”的API,最常用的硬编格式是”video/avc”,也就是喜闻乐见的h264格式,目前大部分手机都支持硬编(Snow相机、FaceU以及各大直播软件都首选此方案),虽然要求API在4.3以上才能够比较完美的运行,但是不能硬编的手机真的太少了(除了我的破手机)
MediaCodec可以直接对Surface进行录制(参考 Google的grafika),因为我们直接使用了SurfaceTexture做预览,不需要每次都获取原始数据在用BufferQueue喂数据,这也就意味着我们可以很容易的让预览结果和录制视频的结果不同,分辨率也可以不同,例如视频中可以实时打水印,但是预览不显示水印之类的(当然一般是相同的)
软编:软编就是用CPU来进行编码,常见的例如FFMpeg软编,资源占用高,可能卡顿,增大APK体积,但是兼容性很好,还可以一直兼容到原始社会(Android2.3)

图像后期

如果定位专业相机软件,那么图像后期的功能就多了去了,完全可以把整个PS都搬过来,如果是偏向社交的软件,那么后期主要是一些美化,加文字、贴图的效果(当然一键分享到朋友圈是一定一定一定要有的功能)

视频后期/转码

视频后期其实和实时录制比较类似,就是一个解码,加特效再编码的过程,当然分辨率和码率就可以很高很高啦,毕竟不是实时的应用

人脸相关应用

实际上,稳定高效的人脸检测、对齐才是在做一款美颜类APP是会碰到的最大的问题。市场上主流的软件也都是采用第三方的解决方案,例如商汤(ST)、虹软(ArcSoft)、Face++、优图(Tencent)等,虽然实时的人脸识别技术历史悠久,但是最近的直播热好像又让她焕发了新生。
现在人工智能大热,不管什么方向好像深度学习都能取得非常优异的成绩,也正兴起着一股把神经网络搬到移动平台上来的风潮(OpenCL、RenderScript、Vulkan、Metal等,当然也有直接上CPU跑的),神经网络用来处理图像,识别物体的App大家应该也都见过不少。
然而,如果要在线处理,就要保证算法足够高效,在移动平台上好像还没有公认的很好的公开解决方案。OpenCV的LBP做人脸检测其实很好,但是还有待调教,其他的像JDA、npd等都可以考虑。
在Github上转了一圈,找到不少开源项目,有C语言的,Java封装的,Python封装的,居然还有.so语言的,真是让我大开眼界。
个人感觉国内这一块的风气并不是很好,稍微有点小成果就拿去圈钱(@于仕琪老师,多向山老师学学),当然这也好理解,毕竟难度远高于拿着别人的轮子自己调调UI做一个App上线,大家都不容易嘛。

有了人脸的特征点就可以做很多很多事情了,例如换脸肯定就建立在高效的人脸特征点跟踪上,剩下的就是贴个图的事情(例如OpenGL的Blend),如果是脸部贴纸就更轻松了。当然,”美颜2.0”也是建立在人脸识别的基础上(例如大眼小脸),如果没有人脸检测,就只能做做肤色、光线调整什么的,或者来个哈哈镜,功能就会大受限制。

直播推流

直播推流有很多现有的解决方案,可能也并不是美颜相机的重点(是直播App的重点呢,哈哈),但是直播App和美颜相机用到的技术有很大的交集,因此直播推流也会成为后期探索的内容之一(例如硬编录屏推流,软编录像等等)。
回到目录

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Martin20150405/article/details/55271855

智能推荐

golang的gitlab-ci配置 Docker搭建GitLab-runner_golang .gitlab-ci.yml vendor_熊猫卡洛斯的博客-程序员秘密

介绍GitLab-runner环境搭建获取镜像 执行以下命令,获取gitlab-runner 镜像docker pull gitlab/gitlab-runnerdocker pull启动 执行以下命令启动gitlab-ruunersudo docker run -d /--name gitlab-runner /--restart always /-v /...

图灵、图灵机和图灵测试_九三智能控v的博客-程序员秘密

关注:灰质,有趣有料的AI技术分享说到人工智能就不得不提到图灵,大家现在手头使用的智能手机、计算机都可以说是一种图灵机,即通过对输入进行计算得到输出的机器,图灵最早给出了这种机器形式化的定...

java表单框架_Java框架之SpringMVC 04-视图解析-Spring表单-JSON-上传下载_IBEANI的博客-程序员秘密

SpringMVC视图解析请求处理方法(controller方法)执行完成后,最终返回一个ModelAndView对象,即使出现异常也会返回一个 ModelAndView对象。对于那些返回 String,View 或 ModeMap 等类型的处理方法,Spring MVC 也会在内部将它们装配成一个 ModelAndView 对象,它包含了逻辑名和模型对象的视图,由视图解析器解析视图,然后,...

TPLink路由器登陆密码怎么破解_tplinkwar1200l密码字典_acmdream的博客-程序员秘密

转自:http://jingyan.baidu.com/article/375c8e19b89b4125f2a2298c.htmlTPLink路由器登陆密码忘记了怎么办?由于路由器设置通常只是偶尔进行,因此时间长了可能就忘记了路由器登陆密码。当路由器登陆密码忘记后,我们可以采用暴力破解登陆路由器,也可以通过恢复路由器出厂设置来清除登陆密码。以下小编就为大家分享一下具体破解TPLink路由器

Vue 2.0使用sass_vue 2.0项目中使用sass_Faith_ZL的博客-程序员秘密

如何在Vue 2.0中使用sass在项目中使用sass,less等css预处理器语言方便我们更快捷高效的开发。但是在Vue 2.0cli安装sass的时候会报错。最终已经解决,现在贴出我的解决方法。首先安装所需的模块。npm i node-sass style-loader [email protected]安装sass-loader的时候一定要指定版本,如果sass的版本太高,webp...

随便推点

phpdoc注释文档生成_已迁移_weixin_33829657的博客-程序员秘密

为什么80%的码农都做不了架构师?>>> ...

GPS信息JT/T808协议的0200位置关键信息_解析jt808地址0200_微蓝极光的博客-程序员秘密

GPS信息JT/T808协议的0200位置关键信息7E 起始标志 002 00 命令字 1 200 3A 短消息,不加密 3 404 01 3F 68 79 67 终端号 5 6 7 8 9 10(BCD8421码)3F 3F 消息流水号 11 1200 00 00 00 报警标志 13 14 15 1600 00 00 02 状态 17 18 19 2002 27 7A 30 纬度 21 22 23 24 (转10进制再0.000001)06 3F 3F

springboot 实现Mysql使用MD5进行密码加密_springboot hex_小花皮猪的博客-程序员秘密

项目开发中为了保护用户隐私安全,一般都会用MD5进行密码加密以下就简单举例SpringBoot 实现Mysql使用MD5进行密码加密做一个简单的例子看下数据库,这边简单做了用户表进行测试pom.xml添加依赖引用<!--MD5加密 对注册的密码进行加密操作--> <dependency> <groupId>commons-codec</groupId> <artifactId&gt

python怎么用pandas查找指定字符串_Python Pandas:通过搜索子字符串查找表_weixin_39691968的博客-程序员秘密

我有一个数据框,其中包含app user-agents列.我需要做的是从这个专栏中识别特定的应用程序.例如,NewWordsWithFriendsFree / 2.3 CFNetwork / 672.1.15 Darwin / 14.0.0将被分类为Words With Friends.iPhone3,1; iPhone OS 7.1.2; com.fingerarts.sudoku2; 1434...

python读取odb进行abaqus结果显示_用python读取Abaqus结果的重音'S'_小红帽的灰灰狼的博客-程序员秘密

晚上好我已经做了一个脚本来获取模型并生成结果。我试图用同一个脚本编写一种读取应力值的方法,但是python说:" File "C:/Users/TFG", line 250, in RegionTen=odb.rootAssembly.noseSets['Set-1'] KeyError: Set-1 "我知道Set-1不会退出,但那不是真的。我希望有人能帮助我。在我创建集合1:^{p...

keySet()与entrySet()遍历的性能比较_hehefefe的博客-程序员秘密

在做项目的时候有邮件发送方面的业务.对邮件的收发的业务不是很清楚,这几天重点在恶搞JavaMail.邮件系统的开发在一般的项目中都会用到,可以看出这一块的知识点用到的频率很高,所以必须来掌握它.这是老大写的一个邮件接口实现类(项目中的真实代码):[code="java"]package com.tq.platform.service.core.impl;import java.util...

推荐文章

热门文章

相关标签