Closed38

Kinectronを使って見る

にー兄さんにー兄さん

kinectronというプロジェクトがある
ElectronクライアントでAzureKinectとかKinect v2のセンサーデータをブロードキャストして
SDKを使ったWebクライアントで受信できるらしい

https://kinectron.github.io/#/

にー兄さんにー兄さん

なんとなくやってみたいのが、babylon.jsでkinectronから受信した深度情報や色情報から点群を生成したい
ん-できるのかな

にー兄さんにー兄さん

そのためにはまず、kinectron serverからColorとdepthを送信して
それをクライアントで取得して
それらのデータから点群を生成して
その点群をパーティクルなりシェーダなりで表示しなくてはいけない

というのをまとめる

  1. Kinectron serverからColorとdepthを送信(もしかしたらFOVとかXYTableが必要かも)
  2. colorとdepthを受信
  3. 点群を生成
  4. 点群を表示
にー兄さんにー兄さん

ところでKinectronサーバー、GitHubじゃなくてなんでDropBoxで配布するんだとおもったら
バイナリ3.6GBあって草

にー兄さんにー兄さん

どんなデータが送信できるのか、colorとdepth、RawDepth 、RGBD
https://kinectron.github.io/#/server/azure?id=single-frame

RGBDってどんな感じだろうと思ったら、
Alphaに8bitでdepthが入ってる、depthにアラインされたcolorらしい
でも8bitってどういうことだ......
流石に256mmだけしか測れないことはなさそうなので、16bit→8bitにマップされてるはずなんだけど
これがsqrtなのか線形補完なのかワカラン

にー兄さんにー兄さん

近い方が色が濃くなっている、ということはAlphaが近いほど1で遠いほど0か
[0-65,536)→[1-0]へのマップかな

にー兄さんにー兄さん

AzureKinectのWFOV 2x2Binnedは512x512でFOVが120d x 120dのdepthカメラ
おそらくこれにマッピングされているんだろう
xytableとかは取得できなさそうだし、z値から自前計算で点群復元かな

にー兄さんにー兄さん

DepthとRawDepthとDepthKeyという3つのDepthデータがある

まずDepthの説明

"Depth" returns a webp of the depth mapped to a grayscale (0-255) image.

次にRawDepth

"Raw Depth" returns an array of values ranging from 0 - 3860. The values correspond to depth in millimeters. It displays a lossless webp image in the application for testing and feedback.

そしてDepthKey

"Depth Key" returns an array of raw depth values corresponding to the tracked bodies. The values range from 0 - 3860. The values correspond to depth in millimeters. It displays a lossless webp image in the application for testing and feedback.

にー兄さんにー兄さん

Depthは画像化するために0-255にマッピングされたデータらしい
白黒の画像になっている

RawDepthはそのままの値?(でも上限は65,536ではないっぽい)の配列らしい

DepthKeyはボディトラッキングの文脈も絡んでくるんだとか

にー兄さんにー兄さん

本当はRGBDを使いたいんだけど、なんとなくrawDepth or DepthKeyが扱いやすそうな気がしてきた

にー兄さんにー兄さん

RawDepthの時、枠が丸ではなく六角形だった
ということはRGBDとは異なりDepthのモードはNFOVということになり、
またexampleを見た感じだと、NFOV 2x2 binnedだと思われる

にー兄さんにー兄さん

depthデータから点群復元の式、こんな感じだろうか

にー兄さんにー兄さん

dのところ、なんか違和感感じるなと思ったら3次元的な位置関係を忘れてた
dはさらにd_xd_yに分かれる。

にー兄さんにー兄さん

(y座標とz座標の)導出の流れとしては、

  1. まずFOVから焦点距離(相対値)fが分かる。これは定数
  2. 同時に投影面座標系における位置(UV座標っぽいもの)である(x_f,y_f)が分かる
  3. すると、投影面までの距離がd_f=\sqrt{x_f^2+y_f^2}とわかるd_fはピクセルごとの定数なので最初だけ計算すればよい
  4. 次に相似によって焦点から(0,y,z)までの距離がd_y=d \frac{d_{fy}}{d_f}だとわかる。ここでd_{fy}=\sqrt{f^2+y_f^2}である
  5. 最後に相似によってy=y_f \frac{d_y}{d_{fy}}, z=f \frac{d_y}{d_{fy}}とわかる
  6. 同様にx座標も計算できる
にー兄さんにー兄さん

お風呂に入りながら間違えを発見した

検算としてd^2 = x^2+y^2+z^2となるはずなんだけど
多分このままだとならない

理由はd_f=\sqrt{x_f^2+y_f^2+f^2}のところをd_f=\sqrt{x_f^2+y_f^2}
としてしまっていたらしい

にー兄さんにー兄さん

今思ったけど、これ前提として縦横のサイズが違った場合にも[-1, 1]に正規化してるので
なんか縮尺変じゃね......?
どうすればよいんだろ、-1,1を縦に適用して、横は横長の場合1.2とかそういう感じでやるのがいいのかな

にー兄さんにー兄さん

それでいい気がしてきた
縮尺が違うのが問題なのであって、数値的にはもともとピクセル単位でもよかったわけだし

にー兄さんにー兄さん

ちょっと詰まったけど、無事depth maoからpoint cloudにするためのコアロジックも実装できた
コード書きながら思ったのが、今回は画像の縦幅を基準に正規化しているので、
焦点距離を求める時も鉛直方向のFoVから計算しないとおかしくなるよなぁと思った

にー兄さんにー兄さん

最終的に、思っていたようなものができました
点群構成のロジックもあってたみたいで:嬉しい:

このスクラップは2022/03/29にクローズされました