How to Convert k4a::image to cv::Mat

Azure Kinect Sensor SDKではk4a::image(またはk4a_image_t)という型で各データを取得できます。
これをOpenCVで扱うためにはcv::Matに変換しますが、データフォーマットによって変換する方法が変わってきます。
Azure KinectではColor、Depth、Infrared、Point Cloud、Body Index Mapと様々なデータを扱います。また、ColorだけでもMotionJPEG、NV12、YUY2、BGRA32と4つのフォーマットがあります。
この記事ではこのような様々なデータフォーマットのk4a::image(またはk4a_image_t)をOpenCVのcv::Matに変換するユーティリティを関数を公開します。

Sample Program

サンプルプログラムはこちらにあります。
変換ユーティリティ(util.h)をダウンロードして利用してください。
変換ユーティリティはCおよびC++の各サンプルプログラムに含まれています。

・Convert k4a::image to cv::Mat

k4a::imageからcv::Matに変換するにはk4a::get_mat()を利用します。
(C APIのk4a_image_tからcv::Matに変換するにはk4a_get_mat()を利用します。)

// Convert k4a::image to cv::Mat
cv::Mat mat = k4a::get_mat( image );

・Output Data Format

変換ユーティリティは内部でデータフォーマットごとに変換をしてcv::Matを返します。
すべてのデータフォーマットに対応しているため、k4a::imageの中身を気にする必要はありません。
k4a::get_mat()(およびk4a_get_mat())では以下のフォーマットのcv::Matに変換されます。

Azure Kinect Image FormatOpenCV Mat Format
Color
(MJPG、NV12、YUY2、BGRA32)
CV_8UC4
(BGRA)
Depth
(DEPTH16)
CV_16UC1
Infrared
(IR16)
CV_16UC1
Body Index Map
(CUSTOM8)
CV_8UC1
Point Cloud
 (CUSTOM) 
CV_32FC3
(XYZ)

・Deep Copy or Shallow Copy

k4a::get_mat()(およびk4a_get_mat())はデフォルトではディープコピーで動作します。
新しくメモリを確保したcv::Matにデータが格納されるため、cv::Matに処理をしても変換元のk4a::image(またはk4a_image_t)には影響しません。

// Deep Copy (k4a::image and cv::Mat have deferent memory)
cv::Mat mat = k4a::get_mat( image, true );

k4a::get_mat()(およびk4a_get_mat())の第二引数deep_copyfalseを設定するとシャローコピーで動作します。
変換元のk4a::image(またはk4a_image_t)とメモリを共有するため、cv::Matに処理をすると変換元のk4a::image(またはk4a_image_t)のデータも変わります。

// Shallow Copy (share memory between k4a::image and cv::Mat)
cv::Mat mat = k4a::get_mat( image, false );

シャローコピーを応用することで、たとえばAzure Kinect Body Tracking SDKで人物を検出する範囲を限定することができます。

  1. k4a::get_mat()でシャローコピーを指定してInfraredのk4a::imagecv::Matに変換する。
  2. Infraredのcv::Matに対して検出したくない範囲を0にマスク処理する。このときメモリを共有している変換元のk4a::imageのデータも書き換えられる。
  3. k4abt::tracker::enqueue_capture()k4a::captureを渡す。

コメントをどうぞ

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です