実践!照度差ステレオ<実画像編>
前回のシミュレーション編に続き、現実の物体に対して照度差ステレオを適用します。
撮影システム
自動で撮影できるシステムを組みました。
撮影から処理までの流れは全てpythonで管理されています。一部の処理にはコマンドラインツールを利用していますがsubprocessで呼び出しています。
光源
光源は白色チップLED(白亜化学工業 NSSW157T)を使いました。光量を確保するためLEDを3個並べて1つの光源としました。
LEDの点灯はマイコン(mbed LPC1114)を用いて制御しています。マイコンとPCはシリアル通信で通信でき、PC側から送信する信号によって最大8個までのLEDの点灯を制御できるようにしました。
Woodhamの照度差ステレオでは平行光源を仮定しています。そのためチップLEDを被写体に対して十分に離れた距離に配置することで平行光源として近似できるようにしました。また光源の強さを同じにするために、被写体とLEDの距離が等しくなるように配置しました。
カメラ
カメラはCanon EOS 6D、レンズはEF40mm F2.8 STMを使いました。gphoto2を使ってPC側からカメラのシャッターを制御できるようにしました。
カメラは平行投影に近づけるために望遠レンズを使って撮影することが望ましいですが、手元にあるレンズのうちで焦点距離が1番長いレンズが40mmしかなかったのでこれを使いました。
RAWデータの処理
一般的なカメラは、入射光強度をカメラ応答関数で非線型な変換をして画素値に対応させています。照度差ステレオでは入射光強度を扱っているため、入射光強度と画素値は線形な関係である必要があります。そこでRAW画像で撮影して、線形になるように現像しました。現像にはdcrawを使いました。オプションを"-4 -T"にすると線形で現像されたTIFF形式のデータを出力してくれます。
光源方向の推定
光源方向の推定のための鏡面反射成分を持つ球としてボール球を使いました。完全な球ではないのですが安価に手に入ったのでこれを使いました。(追記(2018/12/25):最近、鏡面球を手に入れました。これからはそちらを使うつもりです。)
実験
3つの光源で撮影された3枚の画像から照度差ステレオを実行しました。 撮影対象は3Dプリンターで印刷した物体(ABS樹脂)と石です。
結果
実験結果です。左の図が撮影対象、中の図が法線マップ、右の図が反射率マップです。
実践!照度差ステレオ<シミュレーション編>
照度差ステレオとは
照度差ステレオ(photometric stereo)は陰影を情報として画像の法線情報を得ることができる手法です。Woodhamが提案したランバート面における照度差ステレオ*1は、3つの異なる平行光源で撮影された3枚の画像から法線マップを求めることができます。
単位光源ベクトルを、物体表面の単位法線ベクトルを、物体表面の反射率をとするとき、その点での明るさは以下のように表せられます。
3つの異なる光源で撮影するとき、明るさは以下のような行列式で書き表すことができます。
この式を解くことにより法線ベクトルと反射率を求めることができます。
また3つ以上の光源で撮影された画像を用いる場合は、以下の式を最小二乗法で解くことによって求めることもできます。
データセットの準備
照度差ステレオのデータセットはPOV-Rayを使って合成しました。今回対象とする物体は下の図のような、2つの木の球がくっついたような物体です。地面に対して垂直となる方向から物体を撮影した画像をデータセットとして使いました。
2次元画像での法線の取り扱いについて
2次元画像における法線の取り扱いについて説明します。法線マップはRGBの3チャンネルに対して法線方向xyzを対応させています。下の画像は球の法線マップです。法線方向が-1.0から1.0の値を法線マップでは0から255に変換しています。
光源方向の推定
光源方向の推定を行い、光源ベクトルを求めます。推定には鏡面反射成分を持つ球使います。
撮影した球の画像から画像中のハイライトの位置を求めます。球の形状は既知なので中心位置と半径がわかれば、画像中の球の各点での法線が求まります。ハイライトの位置の法線ベクトルを、撮影した方向を表す視線ベクトルをとすると、光源ベクトルは以下の式で求めることができます。
視線ベクトルはカメラの方向なのでとなります。
結果
下のシーンで照度差ステレオをやってみました。データセットに8つの光源で撮影した8枚の画像を使いました。
法線マップです。
反射率マップです。(修正(2018/12/22):グレイスケールだったので、カラーに差し替えました)
プログラム
使用したプログラムをGitHubに置いておきます.
参考資料
http://pages.cs.wisc.edu/~lizhang/courses/cs766-2008f/syllabus/10-09-shading/shading.pdf
コンピュータビジョン最先端ガイド5 (CVIMチュートリアルシリーズ)
- 作者: 松下康之,古川泰隆,川崎洋,古川亮,佐川立昌,八木康史,斎藤英雄
- 出版社/メーカー: アドコム・メディア
- 発売日: 2012/12/05
- メディア: 単行本
- この商品を含むブログ (1件) を見る
コンピュータビジョン: 広がる要素技術と応用 (未来へつなぐデジタルシリーズ)
- 作者: 米谷竜,斎藤英雄
- 出版社/メーカー: 共立出版
- 発売日: 2018/06/28
- メディア: 単行本
- この商品を含むブログを見る
POV-RayでCG制作してみる
POV-Rayとは
POV-Rayはレイトレーシングによって3次元CGを制作できるソフトウェアです。シーンファイルを記述し、レンダリングすることでシーンの画像を得ることができます。オープンソースであるなどの理由から研究ツールとしてもよく用いられているらしいです。
今回は以下の本を参考にして進めました。
POV-Rayによる3次元CG制作 -モデリングからアニメーションまで-
- 作者: 鈴木広隆,倉田和夫
- 出版社/メーカー: 画像情報教育振興協会
- 発売日: 2016/09/20
- メディア: 単行本
- この商品を含むブログを見る
やってみる
GUI用のソフトもありますが、MacであればHomebrewでインストールできます。これでコマンドライン上でレンダリングを実行することができます。
まずは適当なエディタで、シーンファイルを記述します。シーンファイルは基本的にカメラ・照明・物体の3つで構成されています。
このシーンファイルをレンダリングします。
すると記述したシーンの画像を得ることができます。
今回は球と床だけの簡単なシーンだけでした。繰り返しや条件分岐をすることでいくつかの物体を並べたり、模様や質感を設定することでフォトリアリスティックなCGを制作することができます。
作品
宙に浮いているプリズムに上から光を当ててみました。
while文で作った螺旋階段です。照明を階段の上の方に配置したらなんだか神々しくなりました。
惑星を光沢のある石っぽくしてみました。
直接成分と大域成分の分離をやってみた
概要
Nayarら*1の手法を用いて、シーン中の直接成分と大域成分の分離をやってみました。
CAVE | Projects: Fast Separation of Direct and Global Images
はじめに
光源で照らされたシーンの輝度を観測した時に、直接成分(direct component)と大域成分(global component)の2つの成分に分けることができます。直接成分は光源から出た光が直接照らしている成分です。大域成分はシーンの他の点が間接的に照らしている成分です。Nayarらは照明としてプロジェクターで白と黒を交互に配した市松模様を投影することで、2つの成分を分離する方法を提案しました。
実験
撮影対象は色画用紙で作った多面体です。オレンジ色の棚の上に置いて、後ろの背景にホワイトボードを設置しています。
市松模様のサイズは8×8ピクセルの正方形で、3ピクセルずつ動かしました。プロジェクターの解像度に合わせて1280×800の市松模様の画像を合計30枚投影しました。カメラはCanon EOS 6DでレンズはEF40mm F2.8 STMを使いました。ISOは100、f値は8、露光時間は1/128です。
結果
撮影して処理した結果を下の図に示します。左の図が撮影したシーン、中の図が直接成分のみのシーン、右の図が大域成分のみのシーンです。
多面体の凹んだ部分に注目すると、大域成分が強く観測できます。これは凹んだ部分同士の相互反射による間接光で照らされているためだと考えられます。
ホワイトボードの薄い緑色の部分に注目すると、直接成分は緑色の部分がなく、大域成分だけに現れています。これは、ホワイトボードなどから反射した光が、多面体で反射してホワイトーボードに返って照らしているためだと考えられます。
このように、シーンから直接成分と大域成分に分離することができました。(ただし、多面体の右上のホワイトボードにあるスペキュラは白トビしてしてしまっているので、この部分の処理結果は正しくありません。)
カメラのフレームレートを3倍に上げてみた
カラーカメラの色情報を引き換えにフレームレートを3倍に上げてみました。
原理
一般的なカラーカメラは色の3原色(RGB)に相当する光の情報を計測するために、1つの撮像素子の場所ごとに異なる色フィルタが貼り付けられています。
ここで暗室でボールが動くシーンを考えます。このシーンをカメラで撮影するとき、露光中にストロボのように一瞬だけ光を発光させると、発光させた瞬間のボールを撮影することがきます。照明を赤・緑・青の光にして、露光中に一瞬だけ別々のタイミングで順番に発光させます。すると、赤色の光を発光させた瞬間はRチャンネルにだけシーンが記録され、G・Bには記録されません。緑・青についても同様に対応したチャンネルだけにシーンが記録されます。撮影されたカラー画像を各チャンネルに分解すると3枚の連続したグレースケール画像になります。
この方法を動画に適用することで色の情報を失う代わりにフレームレートを擬似的に3倍にすることができます。
実験
実際にやってみます。
RGB照明には各色のLEDを使いました。発光の制御はマイコンで行なっています。
撮影するカメラはiPhone SEです。マニュアル撮影するためにMusemageというアプリを使いました。フレームレートは30fpsで露光時間は1/30に設定しました。
結果
結果は以下のようになりました。
分解した画像をみてみるとB→R→Gの順でボールの位置が変化してる様子が記録できていることがわかります。
動画にも適用しました。最初のカラー映像が入力映像で、次のモノクロ映像が処理した結果です。
滑らかになりましたね。やったぜ。