Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
Kinect for Windows v2入門 ― C++プログラマー向け連載(7)

Kinect for Windows v2入門 ― C++プログラマー向け連載(7)

Kinect v2プログラミング(C++) - AudioBeam編

2014年12月30日 改訂 (初版:2014/07/03)

Kinect v2では、Microphoneアレイにより水平面音源方向の推定(AudioBeam)や音声認識(Speech Recognition)などが行える。今回はAudioBeamを取得する方法を解説する(正式版に合わせて改訂)。

杉浦 司(Microsoft MVP for Kinect for Windows)
  • このエントリーをはてなブックマークに追加

 前回までは、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)から入力される。

図1 Kinect v2のMicrophoneアレイ
図2 Kinect SDK v2のサンプルプログラム(AudioBasics)

サンプルプログラム

 Kinect SDK v2を用いてAudioBeamを取得してコンソールに表示するサンプルプログラムを示す。連載 第2回で紹介したデータを取得するステップごとに抜粋して解説する。このサンプルプログラムの全容は、以下のページで公開している。

図3 Kinect SDK v2のデータ取得の流れ(再掲)

 また、Kinect SDK v1で同様にAudioBeamを取得、表示するサンプルプログラムは、筆者の書籍『Kinect for Windows SDK プログラミングガイド』を参照していただきたい。

「Sensor」

 Sensorを取得する。

C++
// 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;
}
リスト1.1 図3の「Sensor」に該当する部分(再掲)
  • 1Kinect v2を扱うためのSensorインターフェース。
  • 2デフォルトのSensorを取得する。
  • 3Sensorを開く。

「Source」

 SensorからSourceを取得する。

C++
// Source
IAudioSource* pAudioSource;  //……1
hResult = pSensor->get_AudioSource( &pAudioSource );  //……2
if( FAILED( hResult ) ){
  std::cerr << "Error : IKinectSensor::get_AudioSource()" << std::endl;
  return -1;
}
リスト1.2 図3の「Source」に該当する部分
  • 1Audio系の機能のためのSourceインターフェース。
  • 2SensorからSourceを取得する。

「Reader」

 SourceからReaderを開く。

C++
// Reader
IAudioBeamFrameReader* pAudioReader;  //……1
hResult = pAudioSource->OpenReader( &pAudioReader );  //……2
if( FAILED( hResult ) ){
  std::cerr << "Error : IAudioSource::OpenReader()" << std::endl;
  return -1;
}
リスト1.3 図3の「Reader」に該当する部分
  • 1AudioBeamフレームのためのReaderインターフェース。
  • 2SourceからReaderを開く。

「FrameList」~「Data」

 Readerから最新のFrameListを取得する。FrameListから有効なFrameを取得、そこからデータを取り出す。

C++
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;
  }
}
リスト1.5 図3の「Frame」、「Data」に該当する部分
  • 1Frameのリストを取得する。
  • 2リストに含まれるFrameの数を取得する。
    現在は常に「1」を返すが、今後は同時に複数の音源方向を取得できるようになる可能性がある。
  • 3リストからFrameを取得する。
  • 4FrameからAudioBeamを取得する。
  • 5水平面音源方向とその信頼値を取得する。
    音源方向はラジアンで取得できる。
    信頼値は0.0f~1.0fの範囲で、数値が大きいほど音源方向の推定結果が信頼できる
  • 6ラジアン(弧度法)を度(度数法)に変換してコンソールに出力する。

 取得できる音源方向はKinect v2の中心正面を0°として水平面方向左右に+/-50°の範囲で取得できる。

図4 音源方向の検出範囲(+/-50°)

 取得した音源方向の角度単位は「ラジアン(弧度法)」のため、式1を利用して「度(度数法)」に変換する。

  • ラジアン(radian)→ 度(degree): degree=radian×180÷π
  • 度(degree) → ラジアン(radian): radian=degree×π÷180
式1 ラジアン(弧度法)から度(度数法)に変換する

実行結果

 このサンプルプログラムを実行すると図5のように音声などの音源の角度(Angle)と推定の信頼値(Confidence)が表示される。

 もしMicrophoneアレイの反応が過度に敏感であったり鈍感であったりするようならば、OSの録音デバイスの設定を調整するといいだろう([コントロールパネル]-[サウンド]-[録音]で表示される録音デバイスの中にある「マイク配列Xbox NUI Sensor」のプロパティからレベルを調整する)。

図5 実行結果

コンソールに音源方向の角度と推定の信頼値が表示される。

まとめ

 今回はKinect SDK v2でAudioBeamを取得するサンプルプログラムを紹介した。

 Kinect SDK v1と比べるとMicrophoneアレイからのAudioデータの取得プロセスが非常に簡単かつシンプルに書けるようになっていることが分かるだろう。

 この連載では、Kinect v2の概要と基本的なデータを取得するプログラムを紹介してきた。その他に応用的なデータ(Fusion、Face、HDFaceなど)を取得するプログラムも公開しているので参考にしてほしい。

※以下では、本稿の前後を合わせて5回分(第3回~第7回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

Kinect for Windows v2入門 ― C++プログラマー向け連載(7)
3. Kinect v2プログラミング(C++) - Depth編

Kinect SDK v2プレビュー版で、Depthデータを取得する方法を説明する(改訂版)。

Kinect for Windows v2入門 ― C++プログラマー向け連載(7)
4. Kinect v2プログラミング(C++) - BodyIndex編

Kinect SDK v2で、BodyIndex(人物領域)を取得する方法を、サンプルコードを示しながら説明する(正式版に合わせて改訂)。

Kinect for Windows v2入門 ― C++プログラマー向け連載(7)
5. Kinect v2プログラミング(C++) - Body編

Kinect SDK v2に実装されている主要な機能の紹介は、一通り完了。今回は、Body(人物姿勢)を取得する方法を説明する(正式版に合わせて改訂)。

Kinect for Windows v2入門 ― C++プログラマー向け連載(7)
6. Kinect Studioとは?

Kinectアプリ開発支援ツール「Kinect Studio」の機能や使い方を解説する。データを記録/再生できるので、開発&デバッグが簡単に。

Kinect for Windows v2入門 ― C++プログラマー向け連載(7)
7. 【現在、表示中】≫ Kinect v2プログラミング(C++) - AudioBeam編

Kinect v2では、Microphoneアレイにより水平面音源方向の推定(AudioBeam)や音声認識(Speech Recognition)などが行える。今回はAudioBeamを取得する方法を解説する(正式版に合わせて改訂)。

サイトからのお知らせ

Twitterでつぶやこう!