【iOS ARKit】BlendShapes

BlendShapes 基础介绍

      利用前置摄像头采集到的用户面部表情特征,ARKit 提供了一种更加抽象的表示面部表情的方式,这种表示方式叫作 BlendShapes,BlendShapes 可以翻译成形状融合,在3ds Max 中也叫变形器,这个概念原本用于描述通过参数控制模型网格的位移,苹果公司借用了这个概念,在ARKit 中专门用于表示通过人脸表情因子驱动模型的技术。

      BlendShapes 在技术上是一组存储了用户面部表情特征运动因子的字典,共包含52 组特征运动数据,ARKit会根据摄像机采集的用户表情特征值实时地设置对应的运动因子。利用这些远动因子可以驱动2D 或者3D人脸模型,这些模型即可呈现与用户一致的表情。

      ARKit实时提供全部52组运动因子,这52组运动因子中包括7组左眼运动因子数据、7组右眼运动因子数据、27组嘴与下巴运动因子数据、10组眉毛脸颊鼻子运动因子数据、1组舌头运动因子数据。1在使用时可以选择利用全部或者只利用其中的一部分,如只关注眼睛运动,则只利用眼睛相关运动因数据即可。

     每一组运动因子表示一个 ARKit识别的人脸表情特征,每一组运动因子都包括一个表示人脸特定表情的定位符与一个表示表情程度的浮点类型值,表情程度值的的围为[0,1],其中0表示没有表情,1表示完全表情。

    ARKit 会实时捕提到这些运动因子,利用这些运动因子我们可以驱动 2D、3D人脸模型,这些模型会同步用户的面部表情,当然,我们可以只取其中的一部分所关注的运动因子,但由于人脸表情通常与著干组表情因子相关联,如果想精确地模拟用户的表情,建议使用全部运动因子数据。

BlendShapes 技术原理

     在 ARKit 中,对人脸表情特征信息定义了52组运动因子数据,其使用 BlendShapeLocation 作为表情定位符,表情定位符定义了特定表情,如 mouthSmileLeft、mouthSmileRight 等,与其对应的运动因子则表示表情程度,这 52 组运动因子数据如下表 所示。

区域

表情定位符

描述

Left Eye(7)

eyeBlinkLeft

左眼眨眼

eyeLookDownLeft

左眼目视下方

eyeLookInLeft

左眼注视鼻尖

eyeLookOutLeft

左眼向左看

eyeLookUpLeft

左眼目视上方

eyeSquintLeft

左眼眯眼

eye WideLeft

左眼睁大

区域

表情定位符

描述

Right Eye (7)

eyeBlinkRight

右眼眨眼

eyeLookDownRight

右眼目视下方

eyeLookInRight

右眼注视鼻尖

eyeLookOutRight

右眼向左看

eyeLookUpRight

右眼目视上方

eyeSquintRight

右眼眯眼

eye WideRight

右眼睁大

Mouth and Jaw(27)

jaw Forward

努嘴时下巴向前

jawLeft

撇嘴时下巴向左

jawRight

撇嘴时下巴向有

jawOpen

张哦时下巴向下

mouthClose

闭嘴

mouthFunnel

稍张嘴并双唇张开

mouthPucker

抿嘴

mouthLeft

向左撇嘴

mouthRight

向右撇嘴

mouthSmileLeft

左撇嘴笑

mouthSmileRight

右撇嘴笑

mouthFrownLeft

左嘴唇下压

mouthFrownRight

右嘴唇下压

mouthDimpleLeft

左嘴唇向后

mouthDimpleRight

右嘴唇向后

mouthStretchLeft

左嘴角向左

mouthStretchRight

右嘴角向右

mouthRollLower

下嘴唇卷向里

mouthRollUpper

下嘴唇卷向上

mouthShrugLower

下嘴唇向下

mouthShrug Upper

上嘴脣向上

mouthPressLeft

下嘴唇压向左

mouthPressRight

下嘴唇压向右

mouthLowerDownLeft

下嘴唇压向左下

mouthLowerDownRight

下嘴唇压向右下

mouthUpperUpLeft

上嘴唇压向左上

mouthUpperUpRight

上嘴唇压向右上

Eyebrowa (5)

browDownLeft

左眉向外

browDownRight

右眉向外

browinnerUp

蹙眉

brow OuterUpLeft

左眉向左上

brow OuterUpRight

右眉向有上

Cheeks (3)

cheekPuff

脸颊向外

cheekSquintLeft

左脸颊向上并回旋

cheekSquintRight

右脸颊间上并回旋

区域

表情定位符

Nose (2)

noseSneerLeft

左蹙鼻子

noseSneerRight

右蹙鼻子

Tongue (1)

tongueVut

吐舌头

       需要注意的是,在表中表情定位符的命名是基于人脸方向的,如 eyeBlinkRight 定义的是人脸右眼眨眼,但在呈现3D模型时我们镜像了模型,看到的人脸模型右眼其实在左边。有了表情特征运动因子后,就可以使用 SceneKit 中的SCNMorpher. SetWeight()方法进行网格融合,该方法原型为:setWeight(_ weight: CGFloat, forTargetNamed targetName: Int) ;该方法有两个参数,for TargetNamed 参数需要融合的网格变形器名,即上文中的 BlendShapeLocation 名;weight 参数为需要设置的BlendShape 权重值,取值范围为[0,1]。

BlendShapes 代码示例

      使用 ARKit 的 BlendShapes 功能需要满足两个条件:第一是有一个配备有深度相机或者 A12 及以上处理器的移动设备;第二是有一个 BlendShapes 已定义好的模型,为简化操作,这个模型的 BlendShapes 名称定义应与表5-5完全对应。为模型添加 BlendShapes 可以在3ds Max 软件中定义变形器,并做好对应的网格变形。在满足以上两个条件后,使用 BlendShapes 就变得相对简单了,实现的思路如下:

(1)获取 ARKit 表情特征运动因子。这可以通过检查 ARFaceAnchor 获取相应数据,在检测到人脸时,ARFaceAnchor 会返回一个 blendShapes 集合,该集合包含所有52组表情特征运动因子数据。

(2)绑定 ARKit 的表情特征定位符与模型中的变形器,使其保持一致。

(3)当人脸 ARFaceAnchor 发生更新时,实时更新所有与表情特征运动因子相关联的模型变形器。

核心示例代码如下:

//
//  BlendShapeView.swift
//  ARKitDeamo
//
//  Created by zhaoquan du on 2024/1/25.
//import SwiftUI
import ARKit
import RealityKitstruct BlendShapeView: View {var body: some View {BlendShapeViewContainer().edgesIgnoringSafeArea(.all).navigationTitle("BlendShape")}
}struct BlendShapeViewContainer :UIViewRepresentable{func makeUIView(context: Context) -> ARSCNView {let arSCNView = ARSCNView(frame: .zero)return arSCNView}func updateUIView(_ uiView: UIViewType, context: Context) {guard ARFaceTrackingConfiguration.isSupported else {return}let config = ARFaceTrackingConfiguration()config.isWorldTrackingEnabled = falseconfig.isLightEstimationEnabled = trueconfig.maximumNumberOfTrackedFaces = 1config.providesAudioData = falseuiView.delegate = context.coordinatoruiView.autoenablesDefaultLighting = trueuiView.allowsCameraControl = trueuiView.session.run(config, options: [])}func makeCoordinator() -> Coordinator {Coordinator()}class Coordinator: NSObject, ARSCNViewDelegate{var contentNode: SCNReferenceNode? = nilprivate lazy var head = contentNode?.childNode(withName: "head", recursively: true)func modelSetup() {if let filePath = Bundle.main.path(forResource: "BlendShapeFace", ofType: "scn") {let referenceURL = URL(fileURLWithPath: filePath)self.contentNode = SCNReferenceNode(url: referenceURL)self.contentNode?.load()self.head?.morpher?.unifiesNormals = trueself.contentNode?.scale = SCNVector3(0.01,0.01,0.01)self.contentNode?.position.x += 0.2}}func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {guard anchor is ARFaceAnchor else{return}modelSetup()if let contentNode = contentNode {node.addChildNode(contentNode)}}func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {guard let faceAnchor = anchor as? ARFaceAnchor else { return }DispatchQueue.main.async {for (key, value) in faceAnchor.blendShapes {if let fValue = value as? Float {self.head?.morpher?.setWeight(CGFloat(fValue), forTargetNamed: key.rawValue)}}}}}}

   实现 BlendShapes 核心逻辑很清晰,即使用检测到的人脸表情驱动模型对应的表情,因此人脸表情与模型变形器(BlendShapes)必须建立一一对应关系,我们可以选择手动逐个绑定,也可以在建模时将变形器名与 ARKit 中的BlendShapeLocation 定位符名按表5-5所示完全对应以简化手动绑定。为实现实时驱动的效果,需要实时地更新 ARKit 检测到的人脸表情因子到模型变形器。

    运行本示例,AR应用启动后会自动开启前置摄像头,当检测到人脸时就会在该人脸位置挂载虚拟头像,当人脸表情发生变化时,虚拟头像模型对应表情也会发生变化,BlendShapes 效果如上图 所示。

具体代码地址:https://github.com/duzhaoquan/ARkitDemo.git

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/649722.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu18编译jdk8源码

环境 系统 ubuntu18 Linux ubuntu 5.4.0-150-generic #167~18.04.1-Ubuntu SMP Wed May 24 00:51:42 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux jdk源码openjdk-8u41-src-b04-14_jan_2020.zip bootJdk jdk-8u391-linux-x64.tar.gz ps -e|grep ssh sudo apt-get install ssh…

【MATLAB第92期】基于MATLAB的集成聚合多输入单输出回归预测方法(LSBoost、Bag)含自动优化超参数和特征敏感性分析功能

【MATLAB第92期】基于MATLAB的集成聚合多输入单输出回归预测方法(LSBoost、Bag)含自动优化超参数和特征敏感性分析功能 本文展示多种非常用多输入单输出回归预测模型效果。 注:每次运行数据训练集测试集为随机,故对比不严谨&…

京东广告算法架构体系建设--在线模型系统分布式异构计算演变 | 京东零售广告技术团队

一、现状介绍 算法策略在广告行业中起着重要的作用,它可以帮助广告主和广告平台更好地理解用户行为和兴趣,从而优化广告投放策略,提高广告点击率和转化率。模型系统作为承载算法策略的载体,目前承载搜索、推荐、首焦、站外等众多广…

Word插入音乐视频文件快速方法 exe zip doc apk txt pdf bat等

需求: Word插入文件有哪些极限操作?如何快速插入音乐视频等文件 问题解决: 使用拖动进行文件快速插入(PPT Excle 同理) 操作 1.让文件和word界面处于同一屏幕,可以使用分屏 2.鼠标选中文件左键或者使用笔…

一些反序列化总结

1 反序列化漏洞原理 如果反序列化的内容就是那串字符串,是用户可以控制的(即变量的值),且后台不正当的使用了PHP中的魔法函数,就会导致反序列化漏洞,可以执行任意命令。Java 序列化指 Java 对象转换为字节序…

Flink问题解决及性能调优-【Flink根据不同场景状态后端使用调优】

Flink 实时groupby聚合场景操作时,由于使用的是rocksdb状态后端,发现CPU的高负载卡在rocksdb的读写上,导致上游算子背压特别大。通过调优使用hashmap状态后端代替rocksdb状态后端,使吞吐量有了质的飞跃(20倍的性能提升…

2024年,你是否还在迷茫?

2024年,你是否还在迷茫? 别担心!鸿蒙来了,这个未来技术的制高点,为你提供了答案! 诸多大厂疯抢、24年预计鸿蒙相关的岗位需求将达到百万级、就业均薪达到19K,全国高校开课…… 种种现象都在表…

VirtualBox安装Ubuntu22.04

目录 1、新建虚拟机 1.1、设置内存大小 1.2、创建虚拟硬盘 2、虚拟机设置 2.1、设置启动顺序​编辑 2.2、选择iso镜像文件 2.3、设置网络(桥接网卡) 3、启动 3.1、设置语言环境 3.2、系统更新安装(不更新) 3.3、选择键盘布局(默认即可) 3.4、选择安装类型 3.5、网…

硬件知识(1) 手机的长焦镜头

#灵感# 手机总是配备好几个镜头,研究一下 目录 手机常配备的摄像头,及效果举例 长焦的焦距 焦距的定义和示图: IPC的焦距和适用场景: 手机常配备的摄像头,及效果举例 以下是小米某个手机的摄像头介绍&#xff1a…

EXCEL VBA抓取网页JSON数据并解析

EXCEL VBA抓取网页JSON数据并解析 链接地址: https://api.api68.com/CQShiCai/getBaseCQShiCaiList.do?lotCode10036&date2024-01-26 Sub test() On Error Resume Next Sheet.Select Sheet1.Cells.ClearContents [a1:g1] Split("preDrawIssue|preDrawTi…

用Visual Studio Code创建JavaScript运行环境【2024版】

用Visual Studio Code创建JavaScript运行环境 JavaScript 的历史 JavaScript 最初被称为 LiveScript,由 Netscape(Netscape Communications Corporation,网景通信公司)公司的布兰登艾奇(Brendan Eich)在 …

mysql 存储过程学习

存储过程介绍 1.1 SQL指令执行过程 从SQL执行的流程中我们分析存在的问题: 1.如果我们需要重复多次执行相同的SQL,SQL执行都需要通过连接传递到MySQL,并且需要经过编译和执行的步骤; 2.如果我们需要执行多个SQL指令,并且第二个SQL指令需要…

Topaz Video AI:无损放大,让你的视频更清晰!

在当今的数字时代,视频内容的重要性越来越受到人们的关注。无论是在社交媒体上分享生活片段,还是在商业领域中制作宣传视频,人们都希望能够展现出更高质量的视频内容。 然而,由于各种原因,我们经常会面临一个问题&…

C++版QT:分割窗口

目录 mainwindow.h mainwindow.cpp main.cpp Qt的分割窗口功能允许用户将一个窗口分割成多个区域,每个区域可以独立地显示不同的内容。这种功能在许多应用程序中非常有用,例如编辑器、浏览器和IDE等。 理解Qt的分割窗口,需要从以下几个方面…

音频格式之AAC:(2)AAC封装格式ADIF,ADTS,LATM,extradata及AAC ES存储格式

系列文章目录 音频格式的介绍文章系列: 音频编解码格式介绍(1) ADPCM:adpcm编解码原理及其代码实现 音频编解码格式介绍(2) MP3 :音频格式之MP3:(1)MP3封装格式简介 音频编解码格式介绍(2) MP3 :音频格式之MP3&#x…

IDEA jdk版本切换问题

打开 IntelliJ IDEA 的 Project Structure(快捷键通常是 Ctrl Alt Shift S)。 转到 Project Settings > Modules。 选择相应的模块,然后在 Sources 标签页下,查看 Language level 是否设置为 自己需要的jdk版本语言。 接…

20240125-边界外路径

题目要求 有一个m*n的网格,网格中有一个小球。小球初始位置位[startRow,startColumn]。您可以将小球移动到网格中相邻的四个单元格之一(可能会越过网格边界移出网格)。最多可以对小球进行maxMove移动。 给定 m、n、maxMove、sta…

uniapp导入uView组件库

目录 准备工作 1. 新建一个项目 2. 导入uview组件库 3. 关于SCSS 配置步骤 1. 引入uView主JS库 2. 在引入uView的全局SCSS 3. 引入uView基础样式 4. 配置easycom组件模式 添加效果实验运行即可成功 准备工作 1. 新建一个项目 2. 导入uview组件库 在进行配置之前&#x…

TensorFlow2实战-系列教程2:神经网络分类任务

🧡💛💚TensorFlow2实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Jupyter Notebook中进行 本篇文章配套的代码资源已经上传 1、Mnist数据集 下载mnist数据集: %matplotlib inline from pathlib imp…

使用代码取大量2*2像素图片各通道均值,存于Excel文件中。

任务是取下图RGB各个通道的均值及标签(R, G,B,Label),其中标签由图片存放的文件夹标识。由于2*2像素图片较多,所以将结果放置于Excel表格中,之后使用SVM对他们进行分类。 from PIL import Image import os …