RGB-Depthセンサを自作しよう【4-構造化光法編】

15 の nomo ( @nomotech )です。

この記事はrogy Advent Calender 2020 23日目の記事です。

RGB-Depthセンサを自作しよう【3-キャリブレーション編】の続きです。
今回はついに構造化光法についてです。
絶対位相の計算とカラーの計算までを解説します。


構造化光法とは

構造化光法とはプロジェクタなどによってパターン光を投影し、その反射光をカメラで撮像して解析することによって3次元形状を計測する手法です。

RealSense D435 でもIRステレオカメラの補助としてこの構造化光法を使っています。
RealSenseでは以下のようなドットパターンを投影しています。

(RealSense公式より)

しかしこのドットパターンでは解像度の面と、高速化の面で問題があります。

プロジェクタを使って複数枚のパターンを投影することによって解像度の問題を解消することができます。例えば前回キャリブレーションで使ったグレーコードパターンを使えば高精度に深度計測ができます。
しかしグレーコードパターンの場合投影枚数が多くなる(キャリブレーションで使ったのは47枚)という問題があります。
そこで今回は 6 枚のパターンを使う位相シフト法という手法を採用します。

RGB位相シフト法

位相シフト法には以下の大きなメリットがあります。

  • すべての処理が画素単位で並列に計算できる
  • 比較的少ないパターン枚数で計算できる
  • サブピクセル精度で計算できる

位相シフト法も様々な派生手法がありますが、今回採用する位相シフト法は以下のような位相計算用の正弦波パターン 3 枚と位相接続用のグレーコードパターン 3 枚の合計 6 枚を使います。
ハードウェアは第2回で紹介した通りです。

以下の図のように① ~ ⑥のパターンを 60 Hz で更新しながら投影し、それを 120 fpsで 撮像した ① ~ ⑫ の合計 12 枚を使って位相シフト法をします。

ここで高速化のためにカメラからは RGB8 ではなくデモザイキング前の BayerRG8 フォーマットで画像を取得します。これによって画像のデータサイズが 1 / 3 になり転送時間が早くなります。
代わりに ByaerRG8 から RGB に変換するデモザイキング処理は PC 側の GPU で並列処理します。

新しく撮像するたびに 12 枚のうち古い 1 枚が pop され、新しい 1 枚を push するので、完全に更新するまで 12 フレームかかります。つまり直近 12 枚分の残像が出てしまいます。(もしプロジェクタが 120 Hzで更新できれば残像は 6 枚)

この撮像したパターンを以下の図に示すプロセスで処理して深度とRGBを計算します。

位相計算

プロジェクタから投影する 3 枚の正弦波パターンの各画像の画素 (u, v) における輝度は以下の式で表されます。

\begin{aligned} I_0(u, v) &= I_d + I_m \cos(2 \phi(u, v) - \frac{2}{3} \pi) \\ I_1(u, v) &= I_d + I_m \cos(2 \phi(u, v)) \\ I_2(u, v) &= I_d + I_m \cos(2 \phi(u, v) + \frac{2}{3} \pi) \end{aligned}

ここで、 \phi(u, v) は画素 (u, v) における正弦波の位相、 I_d は直流成分、 I_m は正弦波の振幅成分です。これらはそれぞれ以下の式で求められます。

\begin{aligned} I_d(u, v) &= \frac{I_0 + I_1 + I_2}{3} \\ I_m(u, v) &= \frac{\sqrt{3(I_0 - I_2)^2 + (2I_1 - I_0 - I_2)^2}}{3} \\ \phi^{\prime}(u, v) &= \arctan\left(\frac{\sqrt3(I_0 - I_2)}{2I_1 - I_0 - I_2}\right) \end{aligned}

以下の画像は 3 枚の正弦波パターンから計算された(相対)位相 \phi^{\prime}(u, v) です。

位相接続

ここまでで(相対)位相 \phi^{\prime}(u, v) を求めることができましたが、これでは何周期目の波なのかがわかりません。

上から数えて何番目の波なのかを数えれば周期数がわかりますが、画像全体を参照しないといけなくなり、画素ごとに並列処理ができなくなってしまいます。
そこで何周期目か画素ごとに特定できるグレーコードパターンを追加で投影します。


(グレーコードから求めた周期数)

この周期数を使ってる位相接続をおこない、絶対位相を求めます。
以下が位相接続の結果です。

\begin{aligned} \phi(u, v) = \phi^{\prime}(u, v) + k \times 2 \pi \\ \end{aligned}


この後この絶対位相を使って三角測量をすれば深度が計測できます。
三角測量は次回。

カラー

今回は高速化のためにデモザイキングをしていない BayerRG8 フォーマットで画像を取得していたので、GPU内でデモザイキングをしてカラーを復元します。このデモザイキングは GPU で並列化することによって高速に実行できます。

今回はグレーコードパターン 3 枚のみを使ってカラーを復元しました。
(正弦波パターンからも復元できるはずですが、やってみたら正弦波の縞模様の影響が目立ったのでグレーコードだけでカラー化しました。原因は分かってるけど今回はスキップ)

次回は三角測量をやっていきます。
続きはこちら

RGB-Depthセンサを自作しよう【1-基礎知識編】
RGB-Depthセンサを自作しよう【2-同期撮像編】
RGB-Depthセンサを自作しよう【3-キャリブレーション編】
RGB-Depthセンサを自作しよう【4-構造化光法編】
RGB-Depthセンサを自作しよう【5-深度計算編】

コメントを残す

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