? ? ? ?聲明:本文中特征多針對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