记录--从AI到美颜全流程讲解

打印 上一主题 下一主题

主题 1017|帖子 1017|积分 3051

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助


美颜和短视频

美颜相关APP可以说是现在手机上的必备的软件,例如抖音,快手,拍出的“照骗”和视频不加美颜效果,估计没有人敢传到网上。很多人一直好奇美颜类APP是如何开发出来的。本文就大致讲一下在Android上如何实现实时修改唇色效果。其它功能例如美白,腮红都是类似的原理
下图的唇色修改效果就是想实现的功能
 
 
美颜原理

美颜是的基本原理就是深度学习加计算机图形学。深度学习用来人脸检测和人脸关键点检测。计算机图形学用来磨皮,瘦脸和画妆容。一般在Android上使用OpenGLES,IOS为Metal。由于计算机图形学概念较多和复杂,本文中用Android的Canvas替代。
人脸检测 & 人脸关键点


  • 人脸检测指的是对图片或者视频流中的人脸进行检测,并定位到图片中的人脸。
  • 人脸关键点检测是对人脸中五官和脸的轮廓进行关键点定位,一般情况下它紧接在人脸检测后。
 
 
我们将使用TengineKit来实现实时大红唇效果。
TengineKit

免费移动端实时人脸212关键点SDK。是一个易于集成的人脸检测和人脸关键点SDK。它可以在各种手机上以非常低的延迟运行。
github.com/OAID/Tengin…
 
 
实现口红效果

配置 Gradle

Project中的build.gradle添加
  1.     repositories {
  2.         ...
  3.         mavenCentral()
  4.         ...
  5.     }
  6.     allprojects {
  7.         repositories {
  8.             ...
  9.             mavenCentral()
  10.             ...
  11.         }
  12.     }
复制代码
主Module中的build.gradle添加
  1.     dependencies {
  2.         ...
  3.         implementation 'com.tengine.android:tenginekit:1.0.5'
  4.         ...
  5.     }
复制代码
配置 manifests
  1.     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  2.     <uses-permission android:name="android.permission.INTERNET"/>
  3.     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  4.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  5.     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
复制代码
相对于上篇用摄像头来做效果,本文用gif图来代替摄像头的输入的视频流,如果想用摄像头实现,可以参考:
用开源212点人脸关键点实现Android人脸实时打码 zhuanlan.zhihu.com/p/161038093
处理Gif传过来的图片流

首先我们先初始化TengineKit:

  • 选用normal处理模式
  • 打开人脸检测和人脸关键点功能
  • 设置图片流格式为RGBA
  • 设置输入图片流的宽高,此处为gif图的预览宽高
  • 设置输出图片流的宽高,此处为GifImageView的宽高,此处和gif一致,所以用gif图的宽高代替
  1.     com.tenginekit.Face.init(getBaseContext(),
  2.         AndroidConfig.create()
  3.                 .setNormalMode()
  4.                 .openFunc(AndroidConfig.Func.Detect)
  5.                 .openFunc(AndroidConfig.Func.Landmark)
  6.                 .setInputImageFormat(AndroidConfig.ImageFormat.RGBA)
  7.                 .setInputImageSize(facingGif.getGifWidth(), facingGif.getGifHeight())
  8.                 .setOutputImageSize(facingGif.getGifWidth(), facingGif.getGifHeight())
  9.     );
复制代码
通过关键点得到嘴唇的形状
  1.     Path getMouthLandmarks(FaceLandmarkInfo fi){        Path outPath = new Path();        outPath.moveTo(fi.landmarks.get(180).X,fi.landmarks.get(180).Y);        for(int i = 180; i < 189; i++){            outPath.lineTo(    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  2.     <uses-permission android:name="android.permission.INTERNET"/>
  3.     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  4.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  5.     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>fi.landmarks.get(i).X,    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  6.     <uses-permission android:name="android.permission.INTERNET"/>
  7.     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  8.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  9.     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>fi.landmarks.get(i).Y            );        }        for(int i = 204; i >= 196; i--){            outPath.lineTo(    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  10.     <uses-permission android:name="android.permission.INTERNET"/>
  11.     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  12.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  13.     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>fi.landmarks.get(i).X,    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  14.     <uses-permission android:name="android.permission.INTERNET"/>
  15.     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  16.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  17.     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>fi.landmarks.get(i).Y            );        }        outPath.close();        Path inPath = new Path();        inPath.moveTo(fi.landmarks.get(180).X,fi.landmarks.get(180).Y);        for(int i = 195; i >= 188; i--){            inPath.lineTo(    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  18.     <uses-permission android:name="android.permission.INTERNET"/>
  19.     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  20.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  21.     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>fi.landmarks.get(i).X,    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  22.     <uses-permission android:name="android.permission.INTERNET"/>
  23.     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  24.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  25.     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>fi.landmarks.get(i).Y            );        }        for(int i = 204; i  80) {            alpha = (int) (alpha * 0.9f + 0.5f);        }        alpha = (int) (Color.alpha(color) * ((float) alpha / 255))  0){                faceLandmarks = faceDetect.landmark2d();                if(faceLandmarks != null){    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  26.     <uses-permission android:name="android.permission.INTERNET"/>
  27.     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  28.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  29.     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>for (int i = 0; i < faceLandmarks.size(); i++) {    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  30.     <uses-permission android:name="android.permission.INTERNET"/>
  31.     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  32.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  33.     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>    Path m_p = getMouthLandmarks(faceLandmarks.get(i));    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  34.     <uses-permission android:name="android.permission.INTERNET"/>
  35.     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  36.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  37.     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>    LipDraw.drawLipPerfect(canvas, m_p, Color.WHITE, 100);    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  38.     <uses-permission android:name="android.permission.INTERNET"/>
  39.     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  40.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  41.     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>}                }            }            return out_bitmap;        }    });
复制代码
效果对比


 
 

https://juejin.cn/post/6855129006367309832

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

民工心事

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表