Kinect for Windows v2入門 ― C++プログラマー向け連載(7)
Kinect v2プログラミング(C++) - AudioBeam編
Kinect v2では、Microphoneアレイにより水平面音源方向の推定(AudioBeam)や音声認識(Speech Recognition)などが行える。今回はAudioBeamを取得する方法を解説する(正式版に合わせて改訂)。
前回までは、Kinect for Windows v2(以下、Kinect v2)のColorカメラやDepthセンサーからKinect for Windows SDK v2(以下、Kinect SDK v2)を用いてデータを取得する方法を紹介した。
今回は、KinectのMicrophoneアレイからAudioBeam(=水平面音源方向推定)を取得する方法を紹介する。
Microphoneアレイ
連載 第1回で紹介したように、KinectにはColorカメラやDepthセンサーの他にMicrophoneアレイが搭載されている。
Microphoneアレイは異なる間隔で搭載された4つのMicrophoneから構成されており、水平面音源方向の推定(AudioBeam)や、話者の推定(AudioBody)、音声認識(Speech Recognition)などを行える。Audioデータは、16bit/16kHzのフォーマットで4つのMicrophone(4channel)から入力される。
サンプルプログラム
Kinect SDK v2を用いてAudioBeamを取得してコンソールに表示するサンプルプログラムを示す。連載 第2回で紹介したデータを取得するステップごとに抜粋して解説する。このサンプルプログラムの全容は、以下のページで公開している。
また、Kinect SDK v1で同様にAudioBeamを取得、表示するサンプルプログラムは、筆者の書籍『Kinect for Windows SDK プログラミングガイド』を参照していただきたい。
「Sensor」
Sensor
を取得する。
// Sensor
IKinectSensor* pSensor; //……1
HRESULT hResult = S_OK;
hResult = GetDefaultKinectSensor( &pSensor ); //……2
if( FAILED( hResult ) ){
std::cerr << "Error : GetDefaultKinectSensor" << std::endl;
return -1;
}
hResult = pSensor->Open(); //……3
if( FAILED( hResult ) ){
std::cerr << "Error : IKinectSensor::Open()" << std::endl;
return -1;
}
|
- 1Kinect v2を扱うためのSensorインターフェース。
- 2デフォルトのSensorを取得する。
- 3Sensorを開く。
「Source」
Sensor
からSource
を取得する。
// Source
IAudioSource* pAudioSource; //……1
hResult = pSensor->get_AudioSource( &pAudioSource ); //……2
if( FAILED( hResult ) ){
std::cerr << "Error : IKinectSensor::get_AudioSource()" << std::endl;
return -1;
}
|
- 1Audio系の機能のためのSourceインターフェース。
- 2SensorからSourceを取得する。
「Reader」
Source
からReader
を開く。
// Reader
IAudioBeamFrameReader* pAudioReader; //……1
hResult = pAudioSource->OpenReader( &pAudioReader ); //……2
if( FAILED( hResult ) ){
std::cerr << "Error : IAudioSource::OpenReader()" << std::endl;
return -1;
}
|
- 1AudioBeamフレームのためのReaderインターフェース。
- 2SourceからReaderを開く。
「FrameList」~「Data」
Reader
から最新のFrameList
を取得する。FrameList
から有効なFrame
を取得、そこからデータ
を取り出す。
while( 1 ){
// Frame List
IAudioBeamFrameList* pAudioFrameList = nullptr;
hResult = pAudioReader->AcquireLatestBeamFrames( &pAudioFrameList ); //……1
if( SUCCEEDED( hResult ) ){
UINT count = 0;
hResult = pAudioFrameList->get_BeamCount( &count ); //……2
if( SUCCEEDED( hResult ) ){
for( int index = 0; index < count; index++ ){
// Frame
IAudioBeamFrame* pAudioFrame = nullptr;
hResult = pAudioFrameList->OpenAudioBeamFrame( index, &pAudioFrame ); //……3
if( SUCCEEDED( hResult ) ){
// Get Beam Angle and Confidence
IAudioBeam* pAudioBeam = nullptr;
hResult = pAudioFrame->get_AudioBeam( &pAudioBeam ); //……4
if( SUCCEEDED( hResult ) ){
FLOAT angle = 0.0f;
FLOAT confidence = 0.0f;
pAudioBeam->get_BeamAngle( &angle ); // radian [-0.872665f, 0.872665f] //……5
pAudioBeam->get_BeamAngleConfidence( &confidence ); // confidence [0.0f, 1.0f] //……5
// Convert from radian to degree : degree = radian * 180 / Pi //……6
if( confidence > 0.5f ){
std::cout << "Index : " << index << ", Angle : " << angle * 180.0f / M_PI << ", Confidence : " << confidence << std::endl;
}
}
SafeRelease( pAudioBeam );
}
SafeRelease( pAudioFrame );
}
}
}
SafeRelease( pAudioFrameList );
// Input Key ( Exit ESC key )
if( GetKeyState( VK_ESCAPE ) < 0 ){
break;
}
}
|
- 1Frameのリストを取得する。
- 2リストに含まれるFrameの数を取得する。
現在は常に「1」を返すが、今後は同時に複数の音源方向を取得できるようになる可能性がある。 - 3リストからFrameを取得する。
- 4FrameからAudioBeamを取得する。
- 5水平面音源方向とその信頼値を取得する。
音源方向はラジアンで取得できる。
信頼値は0.0f~1.0fの範囲で、数値が大きいほど音源方向の推定結果が信頼できる - 6ラジアン(弧度法)を度(度数法)に変換してコンソールに出力する。
取得できる音源方向はKinect v2の中心正面を0°として水平面方向左右に+/-50°の範囲で取得できる。
取得した音源方向の角度単位は「ラジアン(弧度法)」のため、式1を利用して「度(度数法)」に変換する。
|
実行結果
このサンプルプログラムを実行すると図5のように音声などの音源の角度(Angle)と推定の信頼値(Confidence)が表示される。
もしMicrophoneアレイの反応が過度に敏感であったり鈍感であったりするようならば、OSの録音デバイスの設定を調整するといいだろう([コントロールパネル]-[サウンド]-[録音]で表示される録音デバイスの中にある「マイク配列Xbox NUI Sensor」のプロパティからレベルを調整する)。
まとめ
今回はKinect SDK v2でAudioBeamを取得するサンプルプログラムを紹介した。
Kinect SDK v1と比べるとMicrophoneアレイからのAudioデータの取得プロセスが非常に簡単かつシンプルに書けるようになっていることが分かるだろう。
この連載では、Kinect v2の概要と基本的なデータを取得するプログラムを紹介してきた。その他に応用的なデータ(Fusion、Face、HDFaceなど)を取得するプログラムも公開しているので参考にしてほしい。
※以下では、本稿の前後を合わせて5回分(第3回~第7回)のみ表示しています。
連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。
4. Kinect v2プログラミング(C++) - BodyIndex編
Kinect SDK v2で、BodyIndex(人物領域)を取得する方法を、サンプルコードを示しながら説明する(正式版に合わせて改訂)。
5. Kinect v2プログラミング(C++) - Body編
Kinect SDK v2に実装されている主要な機能の紹介は、一通り完了。今回は、Body(人物姿勢)を取得する方法を説明する(正式版に合わせて改訂)。