声明:本文中特征多针对Kinect for windows 1.0,新版的Kinect Sensor可能有部分数值或方法有一定变化,请知晓。
Kinect的声音来自下方的4个麦克风组成的麦克风阵列。传感器内含数字信号处理器,可以用来强化接受声音的清晰度同时处理噪声,根据4个麦克风接收音量的强弱,Kinect可以分析出声音的来源,但这种分析受限于水平方向,垂直方向上的具体位置,Kinect则无法分辨。另外,Kinect对前后方的声音判断也是不敏感的,即接收到声音后它默认判断是从前方声源发出,且会自动将麦克风阵列对准环境中声音最大的来源位置。
Kinect的声音接收覆盖角度为100度,即大致以右边两个摄像头的中点(也相当于Kinect的中心点)为中心,左右各延伸50度。
开发者可以通过API,让麦克风阵列锁定特定来源区域的声音,比如通过用户的骨骼位置锁定声音检测区域。但是要注意Kinect每次仅能锁定区间范围为10度的区域作为接收范围,这样可以增强该用户的声音识别精确度。
Kinect的声音采样频率为16kHz,采样位数为16位(2Byte,即声音分级为2的16次方)。一般音乐CD为44kHz,但那是高频的音乐质量,16kHz进行语音识别或者语音通信已经很足够了。
我们可以打开之前我们打开过的Kinect Explorer-WPF,在下方就是声音的检测,我们可以发出声音,Kinect会输出我们声源的相关信息。如下图所示,这是我在Kinect的一侧咳嗽了一声后,Kinect Explorer反馈给我的结果。
Beam Angle是麦克风阵列对准声音来源的角度即当前麦克风阵列朝向并重点采集声音的角度;Source Angle是经过Kinect内部算法处理后,计算出的声源角度;而最后一个confidence属性,是用来判断声音强弱或者声音远近的标识。如果要确定声源方向的话,Source Angle更加准确一些。
下面我们使用Visual Studio来写一个侦测声音来源方向的程序。
先贴出代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Kinect;namespace KinectListener
{class Program{static KinectAudioSource AudioSourceSetup(KinectAudioSource source) {//对我们的KinectAudioSource对象进行初始化source.NoiseSuppression = true;//开启抑制噪声功能source.AutomaticGainControlEnabled = true;//自动增益控制功能source.BeamAngleMode = BeamAngleMode.Adaptive;//设置BeamAngleMode为adaptive属性,适合环境噪声大的环境return source;}static void SoundTracking(KinectAudioSource source) {source = AudioSourceSetup(source);//对传入的KinectAudioSource对象初始化source.BeamAngleChanged += audioSource_BeamAngleChanged;source.SoundSourceAngleChanged += audioSource_SoundSourceAngleChanged;//初始化后,注册时间处理函数source.Start();//启动KinectAudioSource对象}static void audioSource_BeamAngleChanged(object sender, BeamAngleChangedEventArgs e) {//事件处理函数 取得麦克风阵列最新对准的方向string output = "侦测到Beam Angle :"+ e.Angle.ToString();Console.WriteLine(output);}static void audioSource_SoundSourceAngleChanged(object sender, SoundSourceAngleChangedEventArgs e) {//事件处理函数 取得当前声音来源方向string output = "侦测到Source Angle:" + e.Angle.ToString() + ", Source Confidence :" + e.ConfidenceLevel.ToString();Console.WriteLine(output);}static void Main(string[] args){KinectSensor sensor = KinectSensor.KinectSensors[0];//获得传感器sensor.Start();//启动传感器KinectAudioSource source = sensor.AudioSource;//要使用Kinect的声音功能,必须从KinectSensor对象中取出AudioSensor对象SoundTracking(source);//追踪声音Console.WriteLine("退出请按空格键");string maxmin1 = ",最大Beam Angle :" + KinectAudioSource.MaxBeamAngle + ",最小Beam Angle :" + KinectAudioSource.MinBeamAngle;string maxmin2 = ",最大Source Angle :" + KinectAudioSource.MaxSoundSourceAngle + ",最小Source Angle :" + KinectAudioSource.MinSoundSourceAngle;Console.WriteLine(maxmin1);Console.WriteLine(maxmin2);while (Console.ReadKey().Key != ConsoleKey.Spacebar) { }sensor.Stop();}}
}
首先还是和上次一样,在解决方案资源管理器中要先添加Kinect引用,然后添加Microsoft.Kinect的命名空间。
要使用Kinect的声音API,首先必须从KinectSensor对象中取出 AudioSource对象;同时对于声音方向,微软提供了BeamAngle和SoundSourceAngle属性;对于音量的大小,则有SoundSourceAngleConfidence属性。
简单讲解一下这个程序:
一开始是AudioSourceSetup方法,它有一个形式参数,需要我们传入一个KinectAudioSource对象,然后方法进行初始化后将这个对象返回。
后面是SoundTracking方法,也就是声音追踪,它同样有一个KinectAudioSource类型的形参,对这个传入的KinectAudioSource对象首先执行AudioSourceSetup(),然后方法中注册了两个事件处理函数,这两句话是告诉系统,一旦侦测到SoundSourceAngle和BeamAngle的数值改变,那就调用这里注册的事件处理函数。
source.BeamAngleChanged += audioSource_BeamAngleChanged;
source.SoundSourceAngleChanged += audioSource_SoundSourceAngleChanged;
接下来,就是我们的事件函数。第一个用于取得麦克风阵列最新对准的方向;第二个用于获取当前声音来源方向,它们会输出当前准确的数值。
Main方法就很简单了,最后设计了一个空格退出的while循环。
我们可以运行这个程序来发出声音,看看返回给我们的数值。当你在同一个地方发出声响的时候,他是只会提示SoundSourceAngle的变化的,如果你换一个位置,它才会再次显示BeamAngle的数值。而且当你一段时间内不发出任何声音的时候,SoundSource会逐渐变化归零。
备注:代码修改自《Kinect体感程序设计入门》
2015.4.6 17:21
By Mr.Losers