【iOS ARKit】BlendShapes

news/2024/7/20 23:00:17 标签: ios

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 RealityKit


struct 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 = false
        config.isLightEstimationEnabled = true
        config.maximumNumberOfTrackedFaces = 1
        config.providesAudioData = false
        
        uiView.delegate = context.coordinator
        uiView.autoenablesDefaultLighting = true
        uiView.allowsCameraControl = true
        uiView.session.run(config, options: [])
        
        
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator()
    }
    
    class Coordinator: NSObject, ARSCNViewDelegate{
        var contentNode: SCNReferenceNode? = nil
        private 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 = true
                self.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.niftyadmin.cn/n/5348039.html

相关文章

前端工程化之:webpack1-1(构建工具)

一、浏览器端的模块化 1.问题 效率问题:精细的模块划分带来了更多的 JS 文件,更多的 JS 文件带来了更多的请求,降低了页面访问效率;兼容性问题:浏览器目前仅支持 ES6 的模块化标准,并且还存在兼容性问题&…

音频筑基:窄带、宽带、超宽带、全带一次说透

音频筑基:窄带、宽带、超宽带、全带一次说透 窄带、宽带、超宽带、全带定义参考资料 音频信号中,经常遇到窄带、宽带等说法,本文进行一个小结归类。 窄带、宽带、超宽带、全带定义 窄带、宽带到全带,总体来说是,指对音…

HTML — 区块元素

HTML 通过各种标签将元素组合起来。 一. 区块元素 大多数 HTML 元素被定义为块级元素或内联元素。块级元素在浏览器显示时&#xff0c;通常会以新的行开始。例如&#xff1a;<div>、<h1>、<p>、<ul>等。 它们在使用时会独自占据一行&#xff0c;称为块…

25考研每日的时间安排

今天要给大家分享一下25考研每日的时间安排。 没有完美的计划&#xff0c;只有合适的计划。 仅供参考 很多人说复习不要只看时长而是要看效率&#xff0c;所以学多长时间不重要&#xff0c;重要的高效率完成任务。 完美的计划 这个计划看起来很完美&#xff0c;从早到晚有学习…

计算机毕业设计选题参考 算法方向机器学习深度学习预测(博文底部xv获取)

基于深度学习的农业病虫害识别基于U-Net模型的细胞图像分割检测基于bert的旅游文本情感分析研究基于bert的经济文本情感分析基于Python OpenCV的车牌定位追踪识别系统医学图像识别&#xff1a;基于卷积神经网络的病癌细胞识别基于word2vectextcnn的微博评论情感分析研究基于线性…

Vite+Electron快速构建一个VUE3桌面应用(三)——打包

一. 简介 上一篇文章ViteElectron快速构建一个VUE3桌面应用(二)——动态模块热重载完成了开发时的动态模块热重载功能&#xff0c;现在是时候来看看怎么完成最后一步——打包了。 二. 思路 先说结论&#xff0c;重点还是在于mainWindow.loadURL()。 打包后还是加载http://lo…

ARP安全针对欺骗攻击的解决方案

针对欺骗攻击的解决方案 ARP表项固化 使能ARP表项固化功能后&#xff0c;设备在第一次学习到ARP之后&#xff0c;不再允许用户更新此ARP表项或只能更新此ARP表项的部分信息&#xff0c;或者通过发送ARP请求报文的方式进行确认&#xff0c;以防止攻击者伪造ARP报文修改正常用户…

ART: Automatic multi-step reasoning and tool-use for large language models 导读

ART: Automatic multi-step reasoning and tool-use for large language models 本文介绍了一种名为“自动推理和工具使用&#xff08;ART&#xff09;”的新框架&#xff0c;用于解决大型语言模型&#xff08;LLM&#xff09;在处理复杂任务时需要手动编写程序的问题。该框架可…