Touchdesignerで空間AIカメラ「OAK-D」シリーズ入門

![TDMovieOut.0 (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/4196c2a1-888b-6ea5-93c0-7d494d48b40e.gif)©具志堅用高氏

こんにちは。
[株式会社ワントゥーテン](https://www.1-10.com/)というところで空間演出エンジニアをやっているまるです。

TouchDesigner Advent Calendar 2024 24日目は、
「OAK-DカメラをTouchDesignerでの始め方講座」です！

軽く[去年の記事](https://qiita.com/malmal0v0/items/1f94d820cae53aa122e9#oak-device-chop--oak-select-top)でも概要に触れていましたが、まだ触ったことのない方へ向けて、OAK-Dカメラの魅力やTouchDesignerでの利用方法について詳しくご紹介していきます。

※記事内で使用されている画像や動画は全て引用元に著作権が帰属します。

## 1. OAK-Dとは？

**DepthAIプラットフォームの概要**
OAK-Dは、Luxonis社が開発したDepthAIプラットフォームを基盤とした空間AIカメラであり、深度データ、AI推論、RGBカメラ機能を一体化したデバイスです。
これにより、1台のカメラでさまざまなデータをリアルタイムで取得し、処理できるのが大きな特徴です。


### OAK-Dの主要機能
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/4a15048c-d1c4-59a7-faa8-d014cbe63fd6.png)
（[引用ースイッチサイエンス](https://www.switch-science.com/pages/luxonis)）

OAKカメラは主に以下の機能を備えています。


- **RGBカメラ**: 高解像度な映像を取得可能で、カラー映像と深度データを組み合わせた多様なアプリケーションに対応します。

- **ステレオデプス**: 左右のカメラからの映像を用いて高精度な深度マップをリアルタイムで生成します。この機能により、対象物の距離や形状を正確に把握可能です。


- **AI推論**: 内蔵されたMyriad X VPUにより、物体認識やポーズ推定などのAI推論をオンデバイスで実行します。これにより、外部サーバーに依存せずリアルタイム処理が可能です。

OAK-Dカメラはたくさんの種類がありますが、基本的に上記機能はどの製品にも備わっています。
その他、USB版以外にPoE版。広角レンズ版、ドットプロジェクター、低照度IR対応のPro版なども販売されています。


### ハードウェア比較表

以下が一般的なデバイスの比較表です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/de9e3d4a-5b9f-5214-e85a-7c9437ce73fd.png)
（[引用ースイッチサイエンス](https://www.switch-science.com/pages/luxonis)）

（追記）OAK-D Liteには9軸IMUは内蔵されていないはずです。
OAK-D LiteはOAK-Dと異なりRGBカメラも35fpsまでしか出ませんので、同列に併記してる辺り **「あくまでざっくりとした表」** と理解いただいたほうがいいかもです。

また、こちらの表には記載がないですが、ステレオデプスより震度情報を高精度で補足したいユースケースの為に、[ToF版](https://shop.luxonis.com/products/oak-d-sr-poe)も公式サイトでは販売されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/f5efc1fe-8593-f42e-96e3-7ea288838af1.png)


但し、後述のTouchdesignerで使えるオペレータとしては深度モデルをサポートするカメラの Time-of-Flight バージョンは、2024年現在開発中とのことです。

**会社で使う分には[Proシリーズ](https://www.switch-science.com/products/8269)、
個人で軽く触ってみたい方には[Liteシリーズ](https://www.switch-science.com/products/7650?_pos=1&_sid=3df58718b&_ss=r)がおすすめです。**

私は2021年に[KickStarter](https://www.kickstarter.com/projects/opencv/opencv-ai-kit-oak-depth-camera-4k-cv-edge-object-detection?lang=ja)で販売開始されたときにSuperEarlyで買っていたので、なんとこのLiteシリーズが1万円ちょっとで買えました。

今はスイッチサイエンスで2.7万円ほどになっていますが、それでも3万以下でこのカメラのエントリーモデルを変えてしまうのは本当に驚異的です。

具体的に何ができるのか、次項でみていきましょう。

## 2.すぐに使えるライブラリ群を一部紹介
OAK-Dには充実したライブラリがそろっている為、この空間AIカメラを購入するだけですぐにAI推論を使ったカメラ処理が可能になります。

以下に幾つかできることのサンプルを紹介していきます。

### ラベル付けされたオブジェクトの3次元座標認識
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/61ac216e-7b8e-b162-4a49-e3deee14d8b6.png)


### テキストOCR検出
![115358042-8d831100-a1bd-11eb-8782-415392c71a87.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/cabc8224-41dc-0fcf-7cb4-efb4f0af1f8c.png)

### ラベル付け人物推定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/18b65066-080c-d64e-3b51-abea1f1f478a.png)

### 年齢・性別推定
![106005496-954a8200-60b4-11eb-923e-b84df9de9fff.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/8ca08b42-d773-b359-9582-734f6bcc4c64.gif)


### 感情認識
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/28a694e1-27da-4080-737b-5b285f19fd33.png)

### ハンドトラッキング
![3d_visualization.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/6992c74c-c0ad-6267-c5cd-379129880d45.gif)

### ハンドジェスチャー認識
![toggle_light.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/e47d8ce7-302b-34ec-c5a8-b75d368b7c0d.gif)
![tetris.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/95cdefcf-5386-3e80-9358-715d74f23775.gif)

### 姿勢推定
![107493701-35f97100-6b8e-11eb-8b13-02a7a8dbec21.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/03ae776d-f726-1ae3-8c8f-35810d846100.gif)

### 人混み推定
![example.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/9507e59d-6427-01c4-6304-ead2a3e2b0a1.gif)

### 顔検出ぼかし
![139135932-b907f037-9336-4c42-a479-5715d9693c9c.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/f41d319b-c78d-f38b-fa88-b6df64f32bcb.gif)

### マスク着用検知
![112673778-6a3a9f80-8e65-11eb-9b7b-e352beffe67a (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/38dccb46-4401-d175-7450-d7d641cc5c0c.gif)

### ソーシャルディスタンス推定
![90741333-73f89500-e2cf-11ea-919b-b1f47dc55c4a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/f6b5a106-f833-58aa-c2ca-18f38deebfd5.gif)

### 火災検知
![fire_demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/3a38e66c-2fad-ffbd-a9f8-35bbf49ed3ce.gif)

はい。**めちゃくちゃありますね。**
ここに書いたものでもまだまだ一例ですが、デバイス一つ買うだけでこれだけのことがインスタレーションに組み込めるようになります。

ワクワクしてきませんか？
いいですね、では早速使い方をみていきましょう！

## 3. TouchDesignerで利用可能なOAK-D関連のOP

Touchdesignerでは、昨年2023年12月のTouchDesignerバージョン2023.11290アップデートで、OAK-D対応の新しいオペレーターたちが満を持して登場しました。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/ac337586-d69b-229f-14cc-aebecfd51bad.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/a84f031f-8b3e-210e-0cb1-5e884f23a307.png)

それまではdepthai-experimentsやdepthai-pythonといったライブラリ群を使ってコードベースで導入をするしかありませんでしたが、このアップデートによりノードベースで以下の機能が利用可能になりました：
- **OAK Device CHOP**: OAK-Dカメラからデータを取得し、リアルタイムで管理。
- **OAK Select CHOP**: 深度データやAI推論結果を選択し、TouchDesigner内で利用可能。
- **OAK Select TOP**: RGB映像や深度データをTexture Operatorとして扱い、映像処理に活用。


それぞれ詳しく見ていきましょう。

### 3-1. OAK Device CHOP
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/602d5ac0-3771-564e-5849-61ed9ee595be.png)

**概要**  
OAK Device CHOPは、TouchDesignerとOAK-Dカメラを接続するための基本的なオペレーターです。このCHOPを通じて、カメラデバイスを初期化し、データを取得します。後述の２つのOPに情報を渡すために、最初に使うやつになります。

#### **Parameters - OAK タブ**
1. **Active**
   - このパラメーターをオンにすると、OAK Device CHOPがアクティブになります。

2. **Sensor**
   - ドロップダウンリストから接続されているOAK Deviceを選択します。内部的にはMXIDという固有のデバイスIDや、IPアドレスによる指定も可能です。

3. **Refresh Sensor List**
   - 利用可能なセンサーのリストを更新します。新しく接続されたデバイスをリストに反映させる際に使用します。

4. **Initialize**
   - OAK Deviceを初期化します。このプロセスにより、デバイスが使用可能な状態になります。初期化に成功すると、createPipeline()コールバックが実行されます。

5. **Start**
   - デバイスのデータストリームを開始します。

6. **Play**
   - TouchDesignerがカメラからの新しいメッセージを処理するかどうかを切り替えます。

7. **Go to Done**
   -  特定のプロセスが完了した際にPulseされます。

8. **Callbacks DAT**
   - このOAK Device CHOPに関連付けられたコールバックを含むDATへのパスを指定します。OAK Device CHOP追加時に自動的に生成されます。

---

#### Parameters - Stream In タブ

**概要**  
Stream Inタブは、TouchDesignerからOAKカメラへ画像ストリームを送信する設定を行います。ここでは、送信するストリーム名、頻度、そして送信する画像のTOPオペレーターを指定できます。

1. **Name stream0name**
   - 送信するテクスチャのストリーム名を指定します。このストリームはDepthAIパイプライン内で、XLinkInノードを作成して初期化する必要があります。
   - 例: `stream0name` に「stream0」などの名前を指定し、この名前でテクスチャが受け取られるストリームを作成します。

2. **Frequency (Hz) stream0frequency**
   - 送信するテクスチャの送信頻度（Hz）を指定します。このパラメーターにより、画像がOAKカメラに送信される間隔が決まります。
   - 例: 30Hzに設定すれば、1秒間に30回画像が送信されることになります。

3. **TOP stream0top**
   - 送信する画像が含まれるTOPオペレーターを指定します。このTOPオペレーターにある画像が、指定された頻度でOAKカメラに送信されます。
   - 例: `stream0top` に「myTOP」と指定すれば、そのTOPオペレーターの画像が送信されます。

**注意事項**  
- ストリーム名が空欄の場合、画像は送信されません。
- TouchDesignerでは、送信前に自動的にBGR形式に画像を変換しますが、他の形式が必要な場合は、DepthAIパイプライン内のImageManipノードを使用して変換を行います。



---
### 3-2. OAK Select CHOP
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/7cc2ae70-2641-71df-d82e-ca26b405e0ed.png)

**概要**  
OAK Select CHOPは、OAK Device CHOPから取得された複数のデータストリームの中から特定の信号を選択して抽出するためのオペレーターです。
例えば、深度マップデータや物体検出結果をCHOP形式でTouchDesigner内に取り込む際に使用します。


#### **Parameters - OAK タブ**

1. **Active**  
   - このパラメーターをオンにすると、OAK Select CHOPがアクティブになります。  

2. **Device**  
   - データを取得する対象のOAK Device CHOPを指定します。 

3. **Signal Name**  
   - 抽出したいデータストリームの名前を指定します。 OAKD Device CHOPのCallbacksスクリプト内で記述されているhoge.setStreamName("depth_map")のようなストリーム名を指定します。

4. **Play**  
   - CHOPのデータ取得を再生または停止します。  

5. **Callbacks DAT**  
   - このOAK DSelect CHOPに関連付けられたコールバックを含むDATへのパスを指定します。OAK Select CHOP追加時に自動的に生成されます。

---
### 3-3. OAK Select TOP
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/b13d8b07-02ca-6259-eeda-e4e640fae636.png)


**概要**  
OAK Select TOPは、OAK Device CHOPから受信した映像のRGBフレームデータや深度マップなどの画像ストリームを選択し、TouchDesigner内で利用可能にするオペレーターです。

これにより、ビジュアルデータをTOPネットワークでそのまま処理することができます。

#### **Parameters - OAK タブ**

1. **Active**  
   - このパラメーターをオンにすると、OAK Select TOPがアクティブになります。  

2. **Device**  
   - データを取得する対象のOAK Device CHOPを指定します。  

3. **Stream Name**  
   - 抽出したいデータストリームの名前を指定します。 OAKD Device CHOPのCallbacksスクリプト内で記述されているhoge.setStreamName("rgb")のようなストリーム名を指定します。

4. **Cache Size**  
   - Queue Sizeパラメーターに相当します。2を選択すると、新しいデータを書き込みながらユーザーに画像を非同期的に表示できます。

5. **Output Index**  
   - Cache TOPのOutput Indexパラメーターを模倣しています。より複雑なDepthAIパイプライン（例: ハンドトラッキング）を使用する場合、トラッキングデータがRGB画像よりも遅れてTouchDesignerに届くことがあります。負の値を指定することで、画像を遅延させ、トラッキングデータと同期できます。

6, **Limit Max**  
   - ストリームが深度画像（かつストリーム名に"depth"が含まれる場合）である場合、最大の"z-depth"を制限するのに役立ちます。この値はメートルで測定されます。

7. **Output Format**  
   - TouchDesignerでDepthAIがまだ提供しない基本的な画像処理を適用できます。例えば、Output Formatが"Point Cloud"で、ストリームが深度ストリームかつストリーム名に"depth"が含まれる場合、OAK Selectで取得された画像は深度画像とカメラの内因性行列を基に生成された32ビットのXYZポイントクラウドになります。


## ４．基本的な使い方

サンプルのtoeはC:/Program Files/Derivative/TouchDesigner.2024.xxxxx/Samples/OAKに含まれています。
ここではOAK-D Liteを使って簡単な使い方を説明します。

試しに[具志堅用高](https://www.ohtapro.co.jp/talent/gushikenyoko.html)さんのボクシングの動画で姿勢推定を行ってみましょう。

![TDMovieOut.0 (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/4196c2a1-888b-6ea5-93c0-7d494d48b40e.gif)

今回使うのはこちらの blazeposeSkeleton です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/e4c1a698-1481-0c88-fddb-a2e6794ffbd7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/cccd49c2-5103-3f25-169f-64106a6b4ec0.png)

### 4-1.デバイスを接続する

USBケーブル（もしくはPoE）にてPCにOKA-Dカメラが接続されていると、sensorにデバイスのリストが表示されます。繋がっているはずなのに表示されない場合は、再接続してRefreshしましょう。

cameraのデバイスが選べたら、Startを押します。
Initializeは押さなくてもStartを押したら一緒に動いてくれます。

初めて押すときは、以下のような形でblobファイルのダウンロードが行われます。
blobファイルは、YOLOなどのNNモデルデータになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/6dd2ddd7-c4b3-fdf0-b5b8-a59aca758578.png)

Touchdesigner上でOPをポチポチやるだけで必要なモデルデータをDLしてくれるのは有難いですね。

お手持ちのPyTorch (ONNX) / TensorFlow / Caffe / OpenVINO ZOO モデルなどがあれば、[こちら](https://blobconverter.luxonis.com/)のサイトでOAK-Dカメラに使えるblobファイルにWeb上でConvertしてくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/a2606be9-235d-ada5-97e1-678a7644c34d.png)
### 4-2.デバイスの初期化とストリーミングを行う

作業に戻りましょう。
Startボタンを押すと、まず最初に左下に黄色の文字でINITIALIZINGと表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/37476acf-70cb-f0ae-fe22-0230e083f962.png)


少し待つと緑色のRUNNNING(playing)に切り替わります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/afce5103-8893-d871-b010-ff5653215ac6.png)

何も表示されないように見えますが、中ではしっかりとうごいています。
In TOPで処理したい映像を渡してあげる必要があるので、再生したいTOPを繋ぎます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/3fc7f5f8-e3a4-e83e-d0d9-0c7ed6513ba3.png)

出てきましたね。
たったこれだけです。簡単でしょ？

## 5．中身の説明

blazeposeSkeleton COMPの中身は以下のようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/46eab475-53d5-f8d5-1c84-c33d798c5efd.png)

多少の違いはありますが、大まかな流れは一緒なのでこれを使って軽く説明します。

### 5-1.デバイスまわりの設定

まず、左の赤枠部分でデバイスの設定を行っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/e1938d13-5b92-f6e0-8008-2f454d032dd0.png)

元ソースは[こちら](https://github.com/geaxgx/depthai_blazepose)のgeaxgx氏のリポジトリにありますが、同じ処理をOAK Devic CHOPのCallbacks DATに絡める形で追記されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/a5da5a16-886b-3669-7021-a84fc8dd1077.png)

入力されたソースを、指定された解像度にダウンスケーリングして処理させています。
defaultの値は1152x648になっています。
4Kなどで行いたいときには、それなりの[CuDA](https://developer.nvidia.com/cuda-toolkit)対応GPU搭載PCが必要になります。

### 5-2.姿勢データの取得

続いて真ん中の赤枠部分で、主に姿勢座標の推定や変換を行っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/7cabeda7-5277-5c8f-5581-29d48318bb89.png)

manager_outというストリームを取得し、
元のサンプルから⑤番目のサンプルごとに取得して5個のチャンネルに分けて形成しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/1537bf05-de46-94c1-c54f-64e50d52913a.png)

上から、順にtx,ty,tz,presence,visibilityをあらわしますが、visibikityは使われていません。
レンダリング時に使用されている値は4つです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/820fb9f0-bb90-163f-6114-7184873575ed.png)

### 5-3.合成し最終結果を出力

最後に、アウトプット処理です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/57128d2d-0c7e-d008-7f41-c1d0d9d2330f.png)

元の動画フレームと合算させています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/1d836240-83f3-6a57-57d3-f1ff831ed2c1.png)

同様の手順で、他のCOMPも試せます。まずはいろいろ弄ってみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/d8d2b501-7fba-e988-a2c8-353b458ff7cb.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/44c57b00-abc2-6812-602d-dac76082889c.png)

慣れてくると、[この辺り](https://docs.luxonis.com/software/depthai/examples/)のドキュメントを参考にcallbacks DATの中を自分で弄りまわすのがオススメです。

いろいろ組み合わせてみると楽しいです。


![6mb.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/9af84ebd-78bb-5081-507a-c5802bc50f0a.gif)
（職場の同期友情出演）


## 6．みんなも空間センシングやろうぜ

ということで、今回はTouchdesignerでのOAK-Dカメラを利用してみようチュートリアルでした。

今年のアドカレもイブ狙ったらまさかの比嘉さんとTsumikiRoomさんに挟まれて緊張したけど、どなたかのお役に立ちましたなら幸いです。

また、ワントゥーテンでは一緒に面白いものをつくってくれるクリエイティブエンジニアの方を[募集](https://www.1-10.com/career/)しています！

私のいる部署は執筆時点では求人が出ていませんが、面白い人いたら特別枠でとってもらえるので我こそはという方おりましたらご連絡ください！お繋ぎします😊

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217271/87e3ae78-4294-2a7f-92fa-ab9823571f47.png)

ということで明日はうちの上司、TsumikiRoom先輩の記事になります！乞うご期待✨

お読みいただきありがとうございました～。