

[Azure Kinect DK] Quickstart: Build your first Azure Kinect application (C#版)
ソリューション開発部 中川です。
Azure Kinect DK がいよいよ日本でも 2020年3月27日(金) に発売されました。
早速ソリューション開発部でも入手し、技術調査を始めています。
本体を入手したらまずはAzure Kinect DK documentationを読み込むところから始まります。クイックスタートとしてQuickstart: Build your first Azure Kinect applicationが用意されていますが、英語のみ、かつCのコードしか掲載されていません。
Azure Kinect Sensor SDK はC#対応に更新されている(一部の機能を除く)ので、今回は「 Quickstart: Build your first Azure Kinect application 」をC#コードでまとめてみます。
Azure Kinectアプリのプロジェクト作成を行い、 Azure Kinect との接続、Azure Kinectカメラからカラー画像を取得・保存するところがゴールです。
Quickstart: Build your first Azure Kinect application C#版
Azure Kinect DKを使い始めたい? このクイックスタートでデバイスを起動してみよう!
(本文ではAzureサブスクリプションを作成するよう促していますが、とりあえず起動するだけなら不要です。)
以下のFunctionをカバーしています:
- Microsoft.Azure.Kinect.Sensor.Device.GetInstalledCount()
- Microsoft.Azure.Kinect.Sensor.Device.Open()
- Microsoft.Azure.Kinect.Sensor.Device.StartCameras()
- Microsoft.Azure.Kinect.Sensor.Device.StopCameras()
前提条件
- Azure Kinect DK をセットアップしてください。
- Azure Kinect Sensor SDKをダウンロードしてインストールしてください。
Visual Studio プロジェクトの準備
Visual Studioからコンソールアプリの新規プロジェクトを作成してください。
「 ツール 」 ⇒ 「 Nugetパッケージマネージャー 」 ⇒ 「 パッケージマネージャーコンソール 」 を開いてください。
Azure Kinect Sensor SDKの追加
PM> Install-Package Microsoft.Azure.Kinect.Sensor -Version 1.4.0
System.Drauwingの追加 (Kinectから取得した画像処理のため)
PM> Install-Package System.Drawing.Common -Version 4.7.0
ヘッダー
using Microsoft.Azure.Kinect.Sensor;
Azure Kinect DK デバイスを見つける
複数の Azure Kinect DK デバイスを接続できます。まず最初に何台接続されているかを Microsoft.Azure.Kinect.Sensor.Device.GetInstalledCount() を使用して確認します。
このメソッドは特別なセットアップはなしですぐに動作します。
int count = Device.GetInstalledCount();
デバイスが接続されていることが確認出来たら、Microsoft.Azure.Kinect.Sensor.Device.Open() を使用して接続します。その際、接続する機器のIndexを指定できます。1台目に接続する場合は、0 を指定します。
//1台目に接続
Device device = Device.Open(0);
デバイスをOpen したあと、不要になったら忘れずに破棄するようにしましょう。
device.Dispose();
カメラを起動する
デバイスに接続したら、Microsoft.Azure.Kinect.Sensor.DeviceConfigurationオブジェクトでカメラ設定を定義する必要があります。カメラ設定にはさまざまなオプションがあるので、用途に合った設定を選びましょう。
//カメラを起動する
device.StartCameras(new DeviceConfiguration
{
ColorFormat = ImageFormat.ColorBGRA32, //RGBカラーイメージ
ColorResolution = ColorResolution.R720p, //解像度720p
DepthMode = DepthMode.NFOV_Unbinned, //深度モード:NFOV Unbinned
SynchronizedImagesOnly = true, //DepthイメージとColorイメージのシンクロされたイメージを取得
});
// ...Camera capture and application specific code would go here...
// カメラを停止する
device.StopCameras();
エラーハンドリング
注)この部分は原文の翻訳ではありません。
SDKを確認した限り用意されているExceptionは以下の通りです。
AzureKinectOpenDeviceException
AzureKinectStartCamerasException
AzureKinectStartImuException
AzureKinectException
OpenDevice, StartCameras, StartImu はそれぞれの操作に対応しています。その他のErrorはAzureKinectExceptionで返されるのではないかと思われます。
まだ十分に確認できていませんが、Exceptionに含まれるDescriptionは「 K4A_FAILED
」としか書かれていないことも多く、うまくいかなかった時の原因の特定が難しい印象です。
この辺は今後の拡充に期待したいところです。
StartCameras() 後に適切にStopCameras() しないままエラーなどでプロセスが落ちてしまうと、Kinectカメラが起動したままになってしまい、他のプロセスからアクセスできなくなりUSBケーブルを抜き差しする必要があるので注意しましょう。
カメラからRGBイメージを取得する
注)この部分は原文の翻訳ではありません。
原文は「// …Camera capture and application specific code would go here…」と省略されており、カメラを起動して停止するだけのコードとなっています。
でもこれだけでは寂しいので、KinectからRGBイメージを取得してローカルディスクに保存するコードを追加します。
Kinect.ImageからBitMapへの変換はtks_yoshinagaさんの下記のブログ記事を参考にさせていただきました。
tks_yoshinagaさんの「 C#で始めるAzure Kinect開発 」シリーズはとても読みやすくわかりやすいのでおススメです。
コード
//カラー画像を取得して保存
var transform = device.GetCalibration().CreateTransformation();
var colorWidth = device.GetCalibration().ColorCameraCalibration.ResolutionWidth;
var colorHeight = device.GetCalibration().ColorCameraCalibration.ResolutionHeight;
Console.WriteLine("Get Capture.");
using (var transformedDepth = new Image(ImageFormat.Depth16, colorWidth, colorHeight, colorWidth * sizeof(UInt16)))
using (Capture capture = device.GetCapture())
{
Console.WriteLine("Captured !!");
transform.DepthImageToColorCamera(capture, transformedDepth);
unsafe
{
//カラー画像を取得
var colorImage = capture.Color;
//画像のメモリのアドレスを取得
using (System.Buffers.MemoryHandle pin = colorImage.Memory.Pin())
{
try
{
//Bitmap画像を作成
var colorBitmap = new System.Drawing.Bitmap(
colorImage.WidthPixels, //カラー画像の横幅
colorImage.HeightPixels,//カラー画像の縦幅
colorImage.StrideBytes, //横一列のバイト数(width*4)
System.Drawing.Imaging.PixelFormat.Format32bppArgb,//カラーフォーマット(RGBA)
(IntPtr)pin.Pointer); //各ピクセルの色情報
//ファイルに保存
colorBitmap.Save(@"保存したいパス\" + System.DateTime.Now.ToString("yyyyMMddhhmmss") + ".png", System.Drawing.Imaging.ImageFormat.Png);
}
catch (Exception ex)
{
Console.WriteLine("Failed to Save Image!");
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace.ToString());
}
}
}
}
unsafeコードを使用するので、プロジェクトでアンセーフビルドを許可する設定を行います。プロジェクトプロパティの「ビルド」タブにて「アンセーフコードの許可(E)」にチェックを入れます。


FullCode
using System;
using Microsoft.Azure.Kinect.Sensor;
namespace SensorQuickStart
{
class Program
{
static void Main(string[] args)
{
//接続されている機器の数をチェック
int count = Device.GetInstalledCount();
if (Device.GetInstalledCount() == 0)
{
Console.WriteLine("No k4a devices attached!");
Console.ReadKey();
return;
}
Device device = null;
// Open the first plugged in Kinect device
try
{
//1台目に接続
device = Device.Open(0);
}
catch (AzureKinectOpenDeviceException ex)
{
Console.WriteLine("Failed to open k4a device!!");
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace.ToString());
Console.ReadKey();
return;
}
//カメラを起動
try
{
device.StartCameras(new DeviceConfiguration
{
ColorFormat = ImageFormat.ColorBGRA32, //RGBカラーイメージ
ColorResolution = ColorResolution.R720p, //解像度720p
DepthMode = DepthMode.NFOV_Unbinned, //深度モード:NFOV Unbinned
SynchronizedImagesOnly = true, //DepthイメージとColorイメージのシンクロされたイメージを取得
});
}
catch (AzureKinectStartCamerasException ex)
{
Console.WriteLine("Failed to open k4a device!!");
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace.ToString());
device.Dispose();
Console.ReadKey();
return;
}
//カラー画像を取得して保存
var transform = device.GetCalibration().CreateTransformation();
var colorWidth = device.GetCalibration().ColorCameraCalibration.ResolutionWidth;
var colorHeight = device.GetCalibration().ColorCameraCalibration.ResolutionHeight;
Console.WriteLine("Get Capture.");
using (var transformedDepth = new Image(ImageFormat.Depth16, colorWidth, colorHeight, colorWidth * sizeof(UInt16)))
using (Capture capture = device.GetCapture())
{
Console.WriteLine("Captured !!");
transform.DepthImageToColorCamera(capture, transformedDepth);
unsafe
{
//カラー画像を取得
var colorImage = capture.Color;
//画像のメモリのアドレスを取得
using (System.Buffers.MemoryHandle pin = colorImage.Memory.Pin())
{
try
{
//Bitmap画像を作成
var colorBitmap = new System.Drawing.Bitmap(
colorImage.WidthPixels, //カラー画像の横幅
colorImage.HeightPixels,//カラー画像の縦幅
colorImage.StrideBytes, //横一列のバイト数(width*4)
System.Drawing.Imaging.PixelFormat.Format32bppArgb,//カラーフォーマット(RGBA)
(IntPtr)pin.Pointer); //各ピクセルの色情報
//ファイルに保存
colorBitmap.Save(@"保存したいパス\" + System.DateTime.Now.ToString("yyyyMMddhhmmss") + ".png", System.Drawing.Imaging.ImageFormat.Png);
}
catch (Exception ex)
{
Console.WriteLine("Failed to Save Image!");
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace.ToString());
}
}
}
}
// Shut down the camera when finished with application logic
device.StopCameras();
device.Dispose();
}
}
}
デフォルトの構成オプション「AnyCPU」では動作できないので、「x64」に切り替えて実行してください。指定したパスにpng画像ファイルが保存されます。
Next Step
これでAzure Kinectアプリの基本中の基本を実装できることができました。次のステップとしておススメなのは、公式のGitHubに公開されているサンプルを読み込むことです。
「 build2019/csharp 」の下にC#でのサンプルが用意されています。
次回は Azure Kinect Body Tracking SDK を使用して、「Quickstart: Build an Azure Kinect body tracking application」のC#版を投稿します。