本项目将在Android上实现一种通过识别表情类别,从而给人脸戴上不同样式脸谱的AR软件,效果如下:

基于表情识别的脸谱换脸AR安卓APP效果演示

想要实现这样一个软件,核心就是两部分:
1)使用卷积神经网络训练一个人脸表情识别模型,
2)将训练好的模型移植到Android平台,同时在Android实现脸谱AR效果,并结合表情识别模型的识别结果,渲染不同的脸谱样式

本文讲第二部分,如何将卷积神经网络模型移植到Android,并在Android进行脸谱AR效果。

第一部分见:基于卷积神经网络的人脸表情识别应用–AR川剧变脸(一)



在第一部分中,我们训练了一个可以识别angry、disgust、fear、happy、sad、surprised、normal七种人脸表情的卷积神经网络模型,而且分析发现效果不错。

本文将建立在表情识别的基础上,设计一款AR变脸效果的软件,通过前置摄像头获取人脸图像,使用训练好的模型进行人脸表情识别,然后根据不同的表情,实现不同脸谱的渲染。

软件效果截图如下,首先右上角有按钮,FPS打开则显示当前帧数,Emotion打开则显示当前表情识别结果,Mask打开则渲染脸谱效果。

1、模型转换

我们的模型使用Keras训练,但是这样的模型是无法直接在Android移动端使用的,所以需要转换为Android可用的。

幸运的是TensorFlow的TensorFlow Lite(tflite)可以在Android上使用,如果能将模型转换为tflite,则就可以将模型移植到Android。

因为Keras以及被包含在TensorFlow里了,所以转换也非常方便:

from keras.models import Model,load_model
import tensorflow as tf# keras模型的文件按路径
model=load_model(r"keras.hdf5",compile=False)   # keras.hdf5是Keras训练好的模型converter =tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()open("output.tflite", 'wb').write(tflite_model)  # 转换成功后会得到output.tflite文件,这个就是转换后的模型,可以在Android中使用

2、Android部署

现在我们得到了模型文件,那么在Android部署还需要一个推理框架:tensorflow.lite

在Android中模型部署,将表情识别写成一个类:TFLiteClassificationUtil,在这个类里主要有两个方法,preProcess用于预处理:当我们从前置摄像头拿到人脸图像后,需要进行图像缩放、类型变换、维度变换、灰度变换等处理,让输入符合模型的要求,predict用于预测:也就是接收一个图像数据,使用我们的tflite模型进行预测得到结果并返回。

package com.google.ar.core.examples.java.augmentedfaces;import android.graphics.Bitmap;import org.tensorflow.lite.DataType;
import org.tensorflow.lite.Interpreter;
import org.tensorflow.lite.nnapi.NnApiDelegate;
import org.tensorflow.lite.support.tensorbuffer.TensorBuffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;import java.io.File;public class TFLiteClassificationUtil {private Interpreter tflite;private final TensorBuffer outputProbabilityBuffer;private static final int NUM_THREADS = 4;int[] imageShape;   //用以储存model的input_shape    [1,n,n,channel]/*** @param modelPath model path*/public TFLiteClassificationUtil(String modelPath) throws Exception {File file = new File(modelPath);if (!file.exists()) {throw new Exception("model file is not exists!");}try {Interpreter.Options options = new Interpreter.Options();// 使用多线程预测options.setNumThreads(NUM_THREADS);// 使用Android自带的API或者GPU加速NnApiDelegate delegate = new NnApiDelegate();
//            GpuDelegate delegate = new GpuDelegate();options.addDelegate(delegate);tflite = new Interpreter(file, options);// 获取输入,shape为{1, height, width, 3}String input="conv2d_input";String output="Identity";imageShape = tflite.getInputTensor(tflite.getInputIndex(input)).shape();DataType imageDataType = tflite.getInputTensor(tflite.getInputIndex(input)).dataType();// 获取输入,shape为{1, NUM_CLASSES}int[] probabilityShape = tflite.getOutputTensor(tflite.getOutputIndex(output)).shape();DataType probabilityDataType = tflite.getOutputTensor(tflite.getOutputIndex(output)).dataType();outputProbabilityBuffer = TensorBuffer.createFixedSize(probabilityShape, probabilityDataType);// 添加图像预处理方式//about input/output more info: https://www.tensorflow.org/lite/inference_with_metadata/lite_support} catch (Exception e) {e.printStackTrace();throw new Exception("load model fail!");}}private ByteBuffer preProcess(Bitmap bitmap) {// 设置想要的大小(也即是model的input shape)int newWidth = imageShape[1];int newHeight = imageShape[2];bitmap=Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, false);//buffer初始化    //定义一个Buffer,可以直接加载run()ByteBuffer inputBuffer = ByteBuffer.allocateDirect(4 * 1 * newWidth * newHeight * 1);inputBuffer.order(ByteOrder.nativeOrder());inputBuffer.rewind();// The bitmap shape should be 28 x 28int[] pixels=new int[newWidth * newHeight];bitmap.getPixels(pixels, 0, newWidth, 0, 0, newWidth, newHeight);for(int i =0;i<newWidth * newHeight;i++){int pixel = pixels[i];float avg = (((pixel >> 16) & 0xFF) * 38 + ((pixel >> 8) & 0xFF) * 75 + (pixel & 0xFF) * 15) >> 7;  //RGB图像转灰度图,pixels是多字节直接换算后的整数,所以还是用位运算更直接简便inputBuffer.putFloat(avg);}return inputBuffer;}// 执行预测float[] predict(Bitmap bmp) throws Exception {   //传入一张bitmap图ByteBuffer inputImageBuffer= preProcess(bmp);try {tflite.run(inputImageBuffer, outputProbabilityBuffer.getBuffer().rewind());   //开始推理} catch (Exception e) {throw new Exception("predict image fail! log:" + e);}float[] results = outputProbabilityBuffer.getFloatArray();int l = getMaxResult(results);return new float[]{l, results[l]};}// 获取概率最大的标签public static int getMaxResult(float[] result) {float probability = 0;int r = 0;for (int i = 0; i < result.length; i++) {if (probability < result[i]) {probability = result[i];r = i;}}return r;}}

3、脸谱AR

既然表情识别问题解决了,现在来解决脸谱AR的实现。

首先Android软件的整体框架:

其中AR使用Google ARCore框架实现,下图是ARCore的流程图,通过拿去摄像头图像数据、位置分析、渲染效果,不断重复,就感觉实现了AR效果。

结合本设计,最后设计的流程图如下所示:

Tflite模块就是表情识别。获取图像数据后,分析人脸表情,根据不同表情加载不同的脸谱样式,然后给人脸渲染上脸谱。

比如,下面的代码就是通过不同表情类别(0~6表示),渲染不同的脸谱

switch (maxIndex) {case 0:augmentedFaceRenderer_0.draw(projectionMatrix, viewMatrix, modelMatrix, colorCorrectionRgba, face);break;case 1:augmentedFaceRenderer_1.draw(projectionMatrix, viewMatrix, modelMatrix, colorCorrectionRgba, face);break;case 2:augmentedFaceRenderer_2.draw(projectionMatrix, viewMatrix, modelMatrix, colorCorrectionRgba, face);break;case 3:augmentedFaceRenderer_3.draw(projectionMatrix, viewMatrix, modelMatrix, colorCorrectionRgba, face);break;case 4:augmentedFaceRenderer_4.draw(projectionMatrix, viewMatrix, modelMatrix, colorCorrectionRgba, face);break;case 5:augmentedFaceRenderer_5.draw(projectionMatrix, viewMatrix, modelMatrix, colorCorrectionRgba, face);break;case 6:augmentedFaceRenderer_6.draw(projectionMatrix, viewMatrix, modelMatrix, colorCorrectionRgba, face);break;
}

4、演示效果

通过变换不同的表情,实现脸谱变脸:

脸谱AR演示_x264

代码资源:
链接:https://pan.baidu.com/s/1Gb_dQwF8yq1SL8Zg76iZZw?pwd=4c4w
提取码:4c4w

基于卷积神经网络的人脸表情识别应用--AR川剧变脸(二)相关推荐

  1. 基于卷积神经网络的人脸表情识别应用--AR川剧变脸(一)

    1.摘要 本项目将在Android上实现一种通过识别表情类别,从而给人脸戴上不同样式脸谱的AR软件,效果如下: 基于表情识别的脸谱换脸AR安卓APP效果演示 通过深度学习和Keras训练一个人脸表情识 ...

  2. 基于卷积神经网络的人脸表情识别(JAFFE篇)

    一.前言 人脸表情识别依然是计算机视觉中的研究重点,那就意味着它还有水文章的可能性.本专题将专门讨论各种表情识别的研究方法,当然我们从最简单的单一卷积网络开始.本文中的代码直接复制到电脑端(pytho ...

  3. 基于深度神经网络的人脸表情识别

    Preprocessing Fer2013 数据集 链接:fer2013.csv 提取码:mzvb 复制这段内容后打开百度网盘手机App,操作更方便哦 参考 下载fer2013数据集和数据的处理 基于 ...

  4. 基于卷积网络的人脸表情识别及其应用

    基于卷积网络的人脸表情识别及其应用 前言 一.人脸表情识别技术现状 二.卷积神经网络技术概述 1.卷积神经网络图像理解过程 2.卷积神经网络组成结构 3.卷积神经网络的优势 三.人脸表情识别卷积网络模 ...

  5. 卷积神经网络实现人脸表情识别

    文章目录 一.实现过程 1.1 下载数据集 1.2 根据猫狗数据集训练的方法来训练笑脸数据集 1.2 图片分类 1.3 作为健全性检查,计算一下在每个训练分割中我们有多少图片(训练/验证/测试): 1 ...

  6. 基于卷积神经网络的辛普森角色识别

    摘 要 基于深度学习在图像分类领域的优异性能,本文研究基于图像识别技术的辛普森角色自动识别方法.首先采集18个角色的16503幅辛普森角色图像数据集,然后在CNN模型框架下,修改最顶端的全连接层与分类 ...

  7. 博士论文——基于卷积神经网络的人脸识别研究 __张燕红

    论文题目 作者 年份 关键词 链接 备注 基于卷积神经网络的人脸识别研究 张燕红 2018 人脸识别:卷积神经网络:特征提取:分块策略:正则化 博士论文 摘要:随着信息技术的蓬勃发展,人们的学习和生活 ...

  8. 基于卷积神经网络的人脸识别(自我拍摄获取数据集)

    基于卷积神经网络的人脸识别 完整代码.数据请见:https://download.csdn.net/download/weixin_43521269/12837110 人脸识别,是基于人的脸部特征信息 ...

  9. python人脸识别系统界面设计_基于卷积神经网络的人脸识别系统的设计(Python)

    基于卷积神经网络的人脸识别系统的设计(Python)(论文10000字,外文翻译,参考代码,流程图,人脸图像库) 摘要:随着社会的进步与发展,个人信息的保护变得十分重要.传统的密码保护方式已经不再满足 ...

最新文章

  1. make: warning: file “xxx“ has modification time yyy s in the future 解决方法
  2. java impala_impala 概述
  3. python上传文件到linux服务器_python上传大文件到服务器报错
  4. python开发工具管理系统_Python开发桌面软件文档及网址管理工具,强迫症的福音...
  5. Keil(MDK-ARM-STM32)系列教程(六)Configuration(Ⅱ)
  6. 深度学习之学习(1-1) VGG16网络结构详解
  7. AdapterView.AdapterContextMenuInfo
  8. ipython 安装
  9. 【Android 逆向】Android 中常用的 so 动态库 ( libm.so 数学函数动态库 | liblog.so 日志模块动态库 | libselinux.so 安全模块动态库 )
  10. Delphi程序实现多语言功能
  11. 结对开发石家庄地铁查询系统
  12. java版精简搜狗皮肤
  13. 如何辨别电解电容正负极
  14. 如何转让个人股权?个人股权转让流程
  15. Ubuntu系统配置花生壳内网穿透
  16. springboot+maven+jwt学生信息增删查改
  17. 2023中国科学院大学计算机考研信息汇总
  18. winform程序内存不足或假死的问题
  19. 架构设计:微服务架构如何划分?这6个标准原则让你一目了然
  20. 量子信息 量子计算机的新闻,应用挑战知多少?美国学界公布量子信息路线图...

热门文章

  1. idea拉取并编译启动spring源码
  2. Idea中new project项目与new module项目区别与验证
  3. 《Java核心技术卷Ⅰ》没学过Java的再点进来看
  4. Unity访问Access数据库
  5. QT-编译调试时碰到“ ‘xxx’ file not found”-“The process was ended forcefully.”,“ Illegal byte sequence”等问题
  6. 一个好用的按键驱动模块
  7. 使用soapUI测试WebService
  8. 【python】利用python计算A类不确定度
  9. IIR滤波器设计代码(巴特沃斯+脉冲响应不变法/双线性变换法) Matlab代码
  10. (转)深度研究报告:108家基金公司都有独门武器,这是特色鲜明的十家公司