基于Unity尝试唇同步/LipSync/OVRLipSync(附Demo及源码)

 在视频创作的时候,这个小破站的审核制度有点气人。所以想着写一个工具,以相对较小的成本,尽可能快的加工视频。算是在唇同步技术上的一个小尝试。

目的和初步的想法

基于Unity3D开发语音输入与3D模型开发唇同步软件,以此来丰富个人视频创作的内容,解决个人创作资源相对匮乏的局面,让个人可以把更多的精力投入到内容的组织上去,是这个软件所要解决的问题。

在Unity3D中加载已经组织好的视频,利用Oculus Lipsync视频中的音频所拥有的面部动作,并在选中的模型上播放该动作,并逐帧录制导出视频。软件提供提供两种模式,一个是视频识别,流程大致为选中模型-导入视频-播放识别-导出视频。另一个是麦克风识别,流程大致为选中模型-导入视频-语音录入识别-导出视频。

通过识别音频波形或语音图像中分析出特有的面部数据,并以此在3D模型上模拟相应的面部的动画是实现唇同步技术常用的方案,这项技术已被应用在虚拟主播、动画制作、游戏开发等领域。传统的唇同步的实现方案大多是根据一段段语音制作对应的面部动画库,然后根据具体的业务逻辑对面部动画进行拼接融合。这种识别模拟的唇同步技术成本和效率要远远优于传统的唇同步技术。

开发环境

环境配置:.Net Standard 2.0,开发引擎:Unity3D 2019.4.1f1,代码编辑:Visual Studio 2019。

唇同步技术应用的现状

唇同步技术多半是有由语音来驱动三维人脸动画,这种技术用途非常广泛,如影视创作、虚拟主播、游戏开发、人机交互等领域,无论是哪种用途,最后都需要涉及三个技术环节,人物建模、语音来源、识别与动画关键帧匹配。

人物建模环节主要是决定基础外观模型,支撑指定面部动作的骨骼动画又或者是面部参数。不同的唇同步技术实现都会预先选定一些固定的音素,不同的语种所对应的音素也会有差异,然后在模型中预制这些预选音素的动画片段或者是面部参数。

语音来源,顾名思义就是语音的来源,一般有两种,一是真人配音,语音自由度最大,真实度最好。另一个是通过语音合成技术(Text To Speech,简称TTS),在时间、空间以及实现成本上有很大优势。在语音驱动人脸动画领域,有一个重要的步骤——获取基于时间轴的音素序列,真人配音很难直接获取准确的基于时间轴的音素序列,通过TTS技术产生语音序列的同时获得序列相对来说很容易。

识别与动画关键帧匹配。识别是指在语音波段中识别音素,所谓音素是构成音节的最小单位,又或者说是最小语音片段,以汉语为例,每个独立的声母,单韵母都是一个独立的音素,普通话中声母有23个,单韵母有10个,鼻辅音2个,在英文中有20个元音和28个辅音,地位同汉语中声韵母相当。识别出的音素之后调用人物模型中有对应的动画或者是面部参数

在虚拟人脸图像动画生成方面,主要存在两种技术,一是通过技术合成三维人物,其面部表情主要通过建模时制作好的渐变动画实现,通过动画参数来驱动,具有实时性和可操作性好的特点;第二种是通过从真人视频语料库中提取所需嘴形以及神态的片段,拼接成视频的合成技术,这种技术具有真实感强的特点。现有的唇同步技术多使用基于MPEG-4视频编码标准中的人脸动画参数。

唇同步中所需音素的特点与局限

音素的合适与否直接影响着面部动画的真实及其自然程度,选定的语素过多会增加识别算法的计算量,识别精度也会大打折扣,语素过少,则会导致唇同步的面部表情不流畅,不自然,真实度也会大大折扣,在保证一定真实度的情况下,可以剔除一些口形相近的语素,一般情况下,7-15个基础语素就可以满足唇同步技术的需要。不同语种的一些基础音素的口形上有一定相似性,因此在一些对真实感要求不高的情况下,基础语素组可以跨语种使用的,即同一种唇同步技术可以跨语种使用。

前面提到真人配音很难直接获取准确的基于时间轴的音素序列,识别音素需要先确定每个基础语素所对应的特征参数,然后根据特征参数去语音波形中识别中语素序列。这种方案有很大的局限性,不同的情况下,很有可能识别的结果也不一样,如在环境是否噪杂,说话快慢,不同的语境,声音高低,甚至是不同的人。

解决识别误差的问题一般会采取两个方案,一个是利用机器学习针对具有同一文字的语言做大量的训练,或者是针对具有口形的视频语言片段做大量训练,以此来保证识别结果的真实度。另一个则是利用完全不真实动画,如卡通,二次元等,通过夸张,另类的面部表情,让看到的人不再考虑真实感的问题。

口形数据的识别

1. 从音频中计算出一个变化的权重值

这种方案相对简单,效率高,但真实感差,它只需要识别出口形大小的线性权重数值,然后制定不同区间下的面部动画,如定义权重区间为[0-10],规定区间[0-2]播放动画A,区间(2-4]播放动画B…… Salsa Lip Sync就是这种方案的实现之一。

2.从音频中识别音素的特征参数

这种方案比较复杂,效率高,但真实感差。该技术的实现主要有三部分,语音信号的预处理和特征提取、特定语种下的语素的特征录制、利用BP神经网络来做音素分类算法分析。识别结果受训练数据的影响比较大,比如以经济为训练材料的技术实现,对经济内容识别结果会比较好,但对文学内容的识别结果就会比较差。如Oculus的OVRLipSync。

开发构想

此软件的定位为唇同步技术在个人视频创作方向上的应用的一种实现,主要是面向在知识类演讲类的视频的创作。希望软件操作简单,学习使用低时间成本。用户导入自己喜欢的一个视频,提供实时录制语音识别和视频音频识别两种语音识别模式。用户可以选择自己喜欢的人物模型,自定义大小和位置,录制完即导出视频。软件需要开发热更功能,以此来实现对人物模型的增加与维护,使得用户有更多的选择方案来实现。该软件的开发为Window平台软件。

功能设计

唇同步的软件主要分为以下几个大的模块热更资源、UI交互、资源处理、视频处理、唇同步识别。

热更资源

热更资源主要包括资源差异检查和资源下载两个业务实现。如图1 热更资源业务图

在Unity3d的开发当中,文件差异比对一般是使用md5码来处理。在资源打包阶段,每一个AssetBundle文件都会获取其对应的md5码,每个更新迭代版本都用一个单独的文件用于存储所有AssetBundle文件的md5码。

当软件打开后,软件会先从资源服务器下载最新的md5码列表文件,然后读取本地的md5码列表文件,对比并获取二者的差异列表。如果远端列表与本地列表同一文件下的md5码出现差异,则认为该文件需要更新,如果远端列表中出现了本地列表没有的文件及其md5码,认为该文件为新增,需要更新。如果差异列表为空,则认为不需要更新,进入下一步。如果差异列表不为空,则进入资源下载的步骤,下载完成之后,进入下一步。如图2 热更业务流程图。

图1 热更资源业务图

图2 热更业务流程图

UI交互

UI交互是一个软件必不可少的部分,它直观的向用户展示出软件所拥有的功能。UI交互模块向用户提供了行为有选择角色、选择视频,选择麦克风音频输入源、选择视频音频输入源、开始录制。如图3 UI交互业务图。

进入软件主界面时,会将配置的所有角色展示,并由用户决定角色大小和位置,视频时,角色的位置和大小不开放调整。选择角色之后,需要用户选择导入准备好的背景视频,背景视频的格式支持mp4、avi两种格式。选择视频之后,需要用户选择音频的录制源,软件提供麦克风、视频音频两种方式。完成以上设置,最后是开始录制。

图3  UI交互业务图

资源处理

资源处理模块包括AssetBundle打包、AssetBundle上传资源服务器、本地资源加载三个业务。如图4 资源模块业务图。

图4 资源模块业务图

AssetBundle是Unity中的一种资源包,这种资源包可以是游戏内要用到的几乎所有资源,例如:模型、纹理、预设、场景等大部分文件更新,并且可以在运行时动态加载。AssetBundle是可以多个文件一起打包(如图5),例如将要打包的资源做成预设后再进行打包,这样可以将预设上面附带的组件、纹理、子对象等一并打包,加载后直接实例化就能直接使用了。AssetBundle 可以选择压缩后再进行网络传输,提升传输效率,减少包体大小等。AssetBundle支持3中格式的压缩选择,分别是LZMA,LZ4,无压缩。默认是LZMA格式的压缩,但是这样虽然可以使资源文件大小大大缩小,利于下载,但是也有不利的一面,在使用时会先解压再使用,所以会造成加载时间过长。它的主要用途有实现资源的热更、减少初始包体大小、做分包处理、可以利用二进制文件做资源加密等等。

图5 AssetBundle原理示意图

AssetBundle打包为后台维护业务,当发布新包或者更新新的版本的时候,需要根据打包规则将软件所需包设置成多个AssetBundle包,并将所有AssetBundle包的md5码列表写到一个单独的文件。之后将打包的AssetBundle包和md5码列表上传到资源服务器,当软件重新打开时,会通过热更模块将资源更新至目标客户端。本地资源加载,显示将对应AssetBundle加载至内存,然后再从内存中的AssetBundle中加载所需资源。

视频处理模块

视频处理模块分为加载视频文件、播放视频文件、视频的录制与导出。如图6 视频处理业务。视频处理支持mp4、avi视频两种格式,导出只会导出mp4视频格式。导出视频与导入视频分辨率相同,时长相同。由于Unity3D在视频录制方面不是太过理想,且官方也没有给出比较合理的解决方案,所以视频录制和导出业务则使用Unity AssetStore中的AV Pro Video插件来处理

图6 视频处理业务图

AV Pro Video是一款强大的是视频支持插件在Unity3D中几乎是可以全平台Window,Ios,Android,Web进行视频的录制保存播放等同时也提供了对直播视频流的支持之所欲选用AV Pro Video,是因为Unity3D官方没有提供相关技术支持,所以使用Unity开发视频一直没有一个比较同一的官方性的答案在Unity中录制视频的方案一般为每个控制帧截图保存到本地,最后按照对应格式的标准将所有的截图合成视频文件AV Pro Video的方案与此方案类似先是逐帧截图随机把对应的截图压入视频文件中即随截随写。这种录制视频的方式与传统的视频制作软件有一个明显的差异即导出的视频受硬件的影响比较大通俗的来讲就是在不同硬件上Uinty3D录制的视频帧率有可能也不尽相同而视频制作软件导出的视频其帧率固定导出耗时不同例如假如目标视频的帧率设定为30而unity的运行帧率只有19那么最终导出的视频的帧率为19

唇同步识别

唇同步识别模块的业务主要有麦克风音频输入、视频音频输入、音频的识别、播放面部动画、表情系统等。如图7唇同步识别业务图。音频识别业务使用Oculus Lipsync来处理Oculus Lipsync的识别结果只有处理了唇部部分如果唇同步动画只有唇部动作则会显得角色面部呆滞语言僵硬为了面部动画看起来自然协调则引入表情系统唇同步进行工作时表情系统则随机处理眉毛眼球眨眼唇同步不工作达一定时间后则随机处理眉毛眼球眨眼微笑具体的面部动作的优先级参考表2,不同等级按照高优先级执行同等级的按照时间先后优先执行后触发动作

图7 唇同步识别业务图

Oculus发布的Oculus Lipsync,它是一款优秀的唇同步技术支持组件,可以通过任何口语来实时驱动面部动画。Oculus Lipsync是一种Unity集成,语音内容同步至虚拟角色的唇部动作。提供离线和实时分析音频输入两个部分,Oculus Lipsync选定了15个视觉音素sil,PP,FF,TH,DD,kk,CH,SS,nn,RR,aa,E,ih,oh和ou。

最初通过SDK 1.16.0推出的原版Oculus Lipsync采用一个小而浅薄的神经网络来学习一小段语音音频输入和音素(构成人类语音的声音单位)之间的映射。尽管这个模型在英语方面的效果相当好,但它在其他语言方面效果不佳,而且容易受背景噪音的影响。作为研究和产品之间的合作,Oculus投资了更新的机器学习模型,即时间卷积网络(TCN)。对于时间卷积网络,它们已经能够在其他领域的任务中实现显著更高的性能和稳定性,如视觉和语言。在内部测试中,这种TCN模型能够将英语语音的视素准确度提高30%以上,并且在重口音和大量背景噪音方面优于先前的模型。

 面部动作优先级

面部动作

优先级数值大的优先级高

唇同步所需动作

3

眉毛

2

眼球

2

眨眼

2

微笑

1

唇同步软件的程序开发

热更资源模块的实现

图8 热更资源模块的类定义

资源处理模块的实现

图10  AssetRequest以及派生类

图11 Assets资源加载管理类

视频处理模块的实现

图12 视频处理模块管理类定义

唇同步识别模块的实现

唇同步对语音的识别主要是分析利用Oculus Lipsync来完成,主要的实现类有

LipSync

识别算法的核心接口,主要负责从Oculus Lipsync封装的程序集中导入唇同步所需的接口,字段VisemeCount定义的是是使用音素的数量。方法CreateContext负责建立音源与识别的联系并返回一个独有的id,以便于多音源识别的实现。方法ProcessFrame负责将识别结果转换成后续使用的Frame对象,ResetContext为重置识别接口。

OVRLipSyncMicInput

主要是负责对麦克风的监听预注册,将麦克风捕捉的语音流输出到audioSource上。字段audioSouce为语音播放所需的组件。方法StartMircrophone负责激活Unity提供的麦克风服务,相应的StopMircrophone为关闭当前麦克风的方法。

LipSyncContextMorphTarget

这个是唇同步动画处理部分,主要是负责根据LipSync识别的语素内容实时调用模型的面部动画。这里使用的更改BlendShape参数的形式来实现唇同步动画的播放,字段skinnedMeshRenderer为模型的蒙皮网格渲染器,上面带有唇同步所需要的BlendShape参数。

OVRLipSyncContextTextureFlip

这里同样是唇同步动画处理部分,但这里播放唇同步动画的实现是对15种语素的贴图实现不同比例的设置。字段Textures存储的就是15个语素图片。方法SetVisemeToTexture的操作是实现唇同步识别结果Frame到语素图片的显示的对接。

LipSyncContext

主要是负责音源数据的获取和调制。OnAudioFilterRead这个是Unity封装的语音数据的回调,当对应的节点上的AudioSource组件有声音输出时,对应的数据会通过这个接口传递进来。组件会在Awake时,从LipSycn中获取唯一识别对象content,然后当有Unity端有音频数据传递时,调用分析接口,将分析结果封装到字段frame中,对应模型播放动画时通过GetCurrentPhonemeFrame接口来获取保存识别结果的frame对象。

图13 唇同步模块的主要类实现

使用步骤及效果预览

1.开启资源服务器

我用的是python3.6.8自带的http服务

python -m http.server

2.打开exe程序

 3.按照提示往下点,到选中视频 

4.设置模型大小和位置

5.开始录制。视频播放完毕或者退出程序,即视为录制结束。

源码地址

 demo源码【码云】

关于这个demo,存在的一些问题和自我反省。

做demo的最主要的目的是了解和学习LipSync唇同步,所以对于一些周边的功能,搬运和魔改的操作比较多,且又是业余时间来处理,所以说时间上也是非常有限,所以有些问题,细节就比较随意,标准就是能用就行。从了解技术,到demo,再到文章,大约是花了两个月的业余时间。

当然我也有意识到,有些阐述受自身水平的限制,难免会出现错误。我认为错误恰恰是一个改善自我的机会,所以我一直是通过这种方式训练自己,提升自己。如有错误,还请指针。

参考文献

[1] 梁晓昀. 语音驱动三维唇形动画算法研究[D].北京理工大学,2016.

[2] 杨明敏. 基于深度学习的唇语识别数据库构建和算法研究[D].华中科技大学,2019.

[3]何珊,袁家斌,陆要要.基于中文发音视觉特点的唇语识别方法研究[J/OL].计算机工程与用:1-7[2021-02-27]

http://kns.cnki.net/kcms/detail/11.2127.TP.20210203.0957.006.html

[4] SALSA LipSync Suite - Online Documentation

https://crazyminnowstudio.com/docs/salsa-lip-sync/

[5] Oculus Lipsync for Unity Development

https://developer.oculus.com/documentation/unity/audio-ovrlipsync-unity/

[6] Unity User Manual (2019.4 LTS)

https://docs.unity3d.com/Manual/index.html

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值