C#でAzure Kinect / Femto Boltを使う

## はじめに

[Azure Kinect](https://azure.microsoft.com/products/kinect-dk)には[Azure-Kinect-Sensor-SDK](https://github.com/microsoft/Azure-Kinect-Sensor-SDK)が、[Femto Bolt](https://www.orbbec.com/products/tof-camera/femto-bolt)には[OrbbecSDK](https://github.com/orbbec/OrbbecSDK)または[OrbbecSDK-K4A-Wrapper](https://github.com/orbbec/OrbbecSDK-K4A-Wrapper)があります。
しかし、これらはいずれもC/C++で使う必要があります。

https://github.com/bibigone/k4a.net

これを利用すれば、Azure KinectやFemto BoltをC#で使えます。

:::note

Microsoftの公式Azure Kinect向けパッケージには[Microsoft.Azure.Kinect.Sensor](https://www.nuget.org/packages/Microsoft.Azure.Kinect.Sensor)、[Microsoft.Azure.Kinect.BodyTracking](https://www.nuget.org/packages/Microsoft.Azure.Kinect.BodyTracking)があります。
Orbbecには[OrbbecSDK_CSharp](https://github.com/orbbec/OrbbecSDK_CSharp)や[OrbbecUnitySDK](https://github.com/orbbec/OrbbecUnitySDK)がありますが、NuGetパッケージはありません。

いずれにせよ、統一的な公式C#インターフェースはないようです。

:::

## k4a.netの使い方

まずはNuGetパッケージを追加します。

https://www.nuget.org/packages/K4AdotNet

https://www.nuget.org/packages/K4AdotNet-Femto

そしてソリューションファイルの`Any CPU`の部分を`x64`に置き換えます

あとは[Azure Kinectのドキュメント](https://learn.microsoft.com/previous-versions/azure/kinect-dk)を見たり、リポジトリの`K4AdotNet.Samples.*`を見たり、入力補完に頼ったりすればいけます。

### RGBカメラを開始して終了する例

```csharp
using K4AdotNet.Sensor;

var deviceCount = Device.InstalledCount;
Console.WriteLine($"Device Count: {deviceCount}");

if (deviceCount == 0)
{
    throw new Exception("Not found: Kinect Device");
}

using (var device = Device.Open())
{
    Console.WriteLine($"Serial Number: {device.SerialNumber}");

    var deviceConfig = new DeviceConfiguration
    {
        CameraFps = FrameRate.Thirty,
        ColorFormat = ImageFormat.ColorBgra32,
        ColorResolution = ColorResolution.R720p,
        DepthMode = DepthMode.Off
    };

    device.StartCameras(deviceConfig);

    Console.WriteLine("Camera started and stopping...");

    device.StopCameras();
}
```

### Body Trackingで人数を数える例

```csharp
using K4AdotNet.Sensor;
using K4AdotNet.BodyTracking;

var deviceCount = Device.InstalledCount;
Console.WriteLine($"Device Count: {deviceCount}");

if (deviceCount == 0)
{
    throw new Exception("Not found: Kinect Device");
}

using (var device = Device.Open())
{
    Console.WriteLine($"Serial Number: {device.SerialNumber}");

    var deviceConfig = new DeviceConfiguration
    {
        CameraFps = FrameRate.Thirty,
        DepthMode = DepthMode.NarrowViewUnbinned,
        ColorResolution = ColorResolution.Off
    };
    device.StartCameras(deviceConfig);

    device.GetCalibration(deviceConfig.DepthMode, deviceConfig.ColorResolution, out var calibration);

    var trackerConfig = TrackerConfiguration.Default;
    using (var tracker = new Tracker(calibration, trackerConfig))
    {
        using (var capture = device.GetCapture())
        {
            tracker.EnqueueCapture(capture);
        }

        using (var bodyFrame = tracker.PopResult())
        {
            Console.WriteLine($"Timestamp: {bodyFrame.DeviceTimestamp}");
            Console.WriteLine($"Body Count: {bodyFrame.BodyCount}");
        }

        tracker.Shutdown();
    }

    device.StopCameras();
}
```

`device.GetCalibration`は`device.StartCameras`の前でも呼び出せるはずです