游戏中口型动画合成系统

您所在的位置:网站首页 日语u发音口型视频 游戏中口型动画合成系统

游戏中口型动画合成系统

2024-03-19 06:31| 来源: 网络整理| 查看: 265

近年来, 基于语音驱动的人脸动画技术在虚拟主持人、数字娱乐、人机交互以及远程会议等方面有广泛的应用。如何快速、高效的实现语音驱动的唇形自动合成,以及优化语音与唇形面部表情之间的同步是此项技术的关键。表情动画作为语音驱动人脸动画的一部分,在增加人脸动画逼真性方面起着重要的作用,但已有的工作没 有定量分析人脸表情动 画与语音之间的关系.

目前音视频模型主要集中在矢量量化的方法 (VQ)、神经网络(Neural Network,NN)、高斯混合模型 (Gaussian Mixture Mode1.GMM)、隐马尔可夫模型现代计算机2015.05中 (Hidden Markov ModeL HMM)和动态贝叶斯模型(Dv.namic Bayesian Network,DBN)的探索 ,而人脸模型主要集中在基于图像的模型、基于2D模型和基于3D模型的探索。

来自Annosoft公司的AutoLip-Sync语音-嘴唇动画

今天主要介绍的是两种语音口型动画的实现, 两种都是先从音频文件(.wav .mp3)提取出音素(主要是元音), 然后再根据不同的音素去制作不同的口型,最后不同口型之间差值得到连续的动作。

基于共振峰提取元音 基于神经网络提取音素 基于共振峰提取元音

这里先简单介绍一下人类发声的原理。

人在发声时,肺部收缩送出一股直流空气,经器官流至喉头声门处(即声带),使声带产生振动,并且具有一定的振动周期,从而带动原先的空气发生振动,这可以称为气流的激励过程。之后,空气经过声带以上的主声道部分(包括咽喉、口腔)以及鼻道(包括小舌、鼻腔),不同的发音会使声道的肌肉处在不同的部位,这形成了各种语音的不同音色,这可以称为气流在声道的冲激响应过程。

对于语音识别来说,重要的部分是第二个过程,因为口型就是声道形状的一部分。而这一冲激响应过程,在频谱上的表现为若干个凸起的包络峰。这些包络峰出现的频率,就被称为共振峰频率,简称为共振峰。

发前元音时舌的最高部位移向口腔前部并稍许拱起。后元音发音时舌后部向软腭抬起。舌面的位置和唇的形状是元音分类的一个标准。发音时从肺部呼出的气流通过起共鸣器作用的口腔,发出阻力极小并无摩擦声音的语音。尽管在一般情况下发元音时声带都振动,但也可使声带不振动,发成清音或耳语音。

元音的高低,取决于舌面与上腭的距离,而非嘴巴的张合大小,因为嘴巴的张合大小不一定可以引起舌面的高低。如发 [æ] 时,舌面与上腭的距离较 [ɛ]大

1. 从音频文件获取语音数据

从AudioSource处获取是实时匹配时采用的方法。AudioSource本身提供了一个GetOutputData函数,可以获取当前正在播放的语音数据段。 从AudioClip处获取是烘焙是采用的方法。AudioClip本身其实是对语音文件的一个封装,可以使用GetData函数直接获得语音数据。 这过程中也包含了分帧与窗口化的步骤。

2. 剔除无声帧

从信号处理的角度上说,这一步是一种时域分析方法。对数据帧中的所有值进行求和,如果结果大于用户预设的一个阈值(也就是AmplitudeThreshold),那么就认为这一帧是没有声音的,不对它进行后续处理。这可以节省不必要的分析过程。如果适当调高阈值,一定程度上可以降噪。

3. 获取语音数据的频域信息

你在使用一些音乐播放器时,有时候会看到一根根跳动的长条,这就是“频谱”的一种表现方式,频域信息指的就是频谱。这对于语音识别来说是非常重要的信息。 在Unity提供的API AudioSource的GetSpecturmData可以高效地获取当前播放的语音数据频谱。 如果你的项目使用了fmod的开发环境,可以使用如下获取声谱信息:

public StudioEventEmitter emiter; FMOD.DSP m_FFTDsp; FMOD.ChannelGroup master; FMOD.DSP mixerHead; void Start() { emiter.Play(); InitDsp(); } void InitDsp() { // 初始化均衡器 DSP RuntimeManager.CoreSystem.createDSPByType(FMOD.DSP_TYPE.FFT, out m_FFTDsp); m_FFTDsp.setParameterInt((int)FMOD.DSP_FFT.WINDOWTYPE, (int)FMOD.DSP_FFT_WINDOW.HANNING); m_FFTDsp.setParameterInt((int)FMOD.DSP_FFT.WINDOWSIZE, windowSize); RuntimeManager.CoreSystem.getMasterChannelGroup(out master); var m_Result = master.addDSP(FMOD.CHANNELCONTROL_DSP_INDEX.HEAD, m_FFTDsp); m_Result = master.getDSP(0, out mixerHead); mixerHead.setMeteringEnabled(true, true); } void Update() { string result = null; IntPtr unmanagedData; uint length; m_FFTDsp.getParameterData((int)FMOD.DSP_FFT.SPECTRUMDATA, out unmanagedData, out length); FMOD.DSP_PARAMETER_FFT fftData = (FMOD.DSP_PARAMETER_FFT)Marshal.PtrToStructure(unmanagedData, typeof(FMOD.DSP_PARAMETER_FFT)); if (fftData.spectrum != null && fftData.spectrum.Length > 0) { playingAudioSpectrum = fftData.spectrum[0]; //声谱信息,针对立体音 只获取0声道频谱 } }

语音信号一般在10ms到30ms之间,我们可以把它看成是平稳的。为了处理语音信号,我们要对语音信号进行加窗,也就是一次仅处理窗中的数据。因为实际的语音信号是很长的,我们不能也不必对非常长的数据进行一次性处理。明智的解决办法就是每次取一段数据,进行分析,然后再取下一段数据。

Hanning窗函数:

拿到声谱之后, 我们先使用一个高斯滤波器过滤掉噪音。通俗的讲,高斯滤波就是对整声谱进行加权平均的过程,每一个点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。

其中$\mu$, $\sigma(\sigma>0)$为常数, 则称X服从参数为$\mu$, $\sigma(\sigma>0)$的正态分布或者高斯分布。

对于离线处理的音频可以借助了一个数学工具——离散余弦变换(DCT),它可以用来获取一个时域信息段的频域信息。它与另一个著名的数学工具——傅里叶变换是等价的,所不同的是余弦变换只获取频率信息,而舍弃了相位信息。实际上这就够了,我们并不需要相位信息。

一维DCT变换:

其中,f(i)为原始的信号,F(u)是DCT变换后的系数,N为原始信号的点数,c(u)可以认为是一个补偿系数,可以使DCT变换矩阵为正交矩阵

二维DCT变换:

声音是不像图像, 是一维序列。因此这里应用的是一维DCT变换。 github示例工程里对应的代码如下:

public static float[] DiscreteCosineTransform(float[] data) { float[] result = new float[data.Length]; float sumCos; for (int m = 0; m


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3