2D→3D復元技術で使われる用語まとめ

2次元の画像から3次元の情報を復元するプログラムを本格的に実装してみようと思って、まずはOpenGVから触り始めたんだけど、オイラの基礎知識が乏し過ぎて苦戦中。



まだOpenGVに同梱されているtestコードをいじってみている段階。オイラはこの分野の基本的な用語の知識が欠けているので、OpenGV独自の抽象化APIで使われる言葉との区別もつかず、公式ドキュメントを読むだけでだいぶ苦労する。(ドキュメント自体はそれほど文量多くないけど)

ということで、まずはこの分野で使われる言葉の意味をちゃんと知っておこうと思います。この分野は「エピポーラ幾何(Epipolar geometry)」とか「エピ極線幾何学」って呼ぶんですかね。
ライブラリの公式ドキュメントは英語なので、英語表記と日本語表記の対応もちゃんとおさえておく。OpenMVG公式の機能一覧cameras, multiviewの解説と図がシンプルで分かりやすかったので引用しながらまとめる。
openMVG:複数視点画像から3次元形状を復元するライブラリ
最近、この手の2D→3D復元系のライブラリを色々と調べている。何となく、自分で3D復元ツールを作ってみたくてね。 この間のOpenGVは複数画像からカメラ(視点)の3次元位置・姿勢を推定するライブラリだった↓ こっちのopenMVG(Mul...


数学的な定義よりも画像処理での用途寄りに書いていきますが、間違ってたらごめんなさい。(ご指摘いただけると有難い)


スポンサーリンク

Pinhole Camera Model:ピンホールカメラモデル

カメラは図のようなピンホールカメラモデルと呼ばれる単純な投影モデルで近似することができ、2D→3D復元の様々なアルゴリズムは基本的にこのモデルに基づいている。
ピンホールカメラモデルでは、カメラの射影行列(3D→2D)をintrinsic parameters(内部パラメータ)extrinsic parameters(外部パラメータ)の2つの行列で表す。内部パラメータは3D→2Dの投影関係、外部パラメータはカメラの3D空間での位置・向きを定義する。
上の図は、3Dのワールド座標をカメラで撮影することで2Dのスクリーン座標へ投影する様子を表している。

Homography:ホモグラフィ

画像認識におけるHomographyとは、2D空間同士の射影変換のこと。
(一般的には、射影変換全般をHomographyと呼ぶ)

図で赤く示されているような3D空間上のある平面について、2つのカメラO_LO_Rから撮影した画像では、同じ頂点でも2枚の撮影画像上ではそれぞれ別の2D空間の座標となる。この2つのカメラ画像の2D座標の対応関係は2Dの射影変換(平面を別の平面へ射影する)で表すことができる。
このような、平面の座標系から別の平面の座標系へ変換する2D→2Dの射影変換行列がHomography行列H(3×3の行列)となる。

OpenCVだとcv::findHomography関数を使えば2枚の画像間のHomography行列を推定することができる↓
http://qiita.com/wakaba130/items/b566f15a4f2cf1ce414f

Homography行列の算出には、対応点が最低でも6点(全て同一平面上なら4点)必要だそうです。
https://qiita.com/tomoaki_teshima/items/dc49a1431562da4da436

Fundamental Matrix:基礎行列

Fundamental Matrix(基礎行列)は同一のシーンを撮影している2つのカメラ画像の関係を表す3×3の行列。カメラ画像中の点をもう1つのカメラ画像のスクリーン座標へ変換する2D-2Dの座標変換を行うことができる。基礎行列Fと表記されたりします。Fundamental Matrix(基礎行列)は2焦点テンソル(bifocal-tensor)とも呼ばれるとか。

OpenCVならcv::FindFundamentalMat関数を使えば2枚の画像からFundamental Matrix(基礎行列)を推定することができるらしい。(8点アルゴリズム)

基礎行列の歌なんてのもあるようですよ↓


Essential Matrix:基本行列

図のように、2つのカメラO_LO_Rの3D空間上の相対的な関係は、回転行列R(3×3の行列)と並進ベクトルt(3×1の行列)で表すことができる。この回転行列Rと並進ベクトルtはカメラの3D空間での位置・姿勢を表すもので、この図ではRtで2つのカメラの相対的な位置・姿勢を表します。

Essential Matrix(基本行列)は、このRtを1つにまとめた4×4の行列[R|t]のこと。この基本行列は3D→3Dの変換を行う変換行列で、2つのカメラO_LO_R間の対応を表す基本行列を使えば、O_Lのカメラ空間(3D)で表された座標をO_Rのカメラ空間で表された座標へ変換することできる。

ここで、行列[R|t]をワールド空間の絶対座標で表せばカメラのextrinsic parameters(外部パラメータ)そのものになります。ちなみに、カメラのintrinsic parameters(内部パラメータ)となる行列はKと表記されたりもします。(何故Kなのでしょう?)
基本行列Eは基礎行列Fに内部パラメータKを与えることで導出できます。

OpenCVだと、このEssential Matrix(基本行列)cv::findEssentialMat関数を使えば算出できます。これは、いわゆる5点アルゴリズム(five-point algorithm)というやつで、計算するには対応点が5点以上必要となります。
また、cv::recoverPose関数cv::decomposeEssentialMat関数を使ってEssential Matrix(基本行列)を回転行列Rと並進ベクトルtへ分解することもできます。



スポンサーリンク

Resection/Pose Estimation:キャリブレーション/姿勢推定

Camera Resectionとは、いわゆるカメラキャリブレーションのことです。
カメラのキャリブレーション、カメラの姿勢を推定するにはワールド座標とスクリーン座標の3D-2Dの点の対応情報が必要です。推定したカメラパラメータを用いて3D→2Dの変換を行い、事前に与えたスクリーン座標との差を算出します。この差(残留誤差)が最小となるよう最適化することでカメラパラメータを求めます。

Triangulation:三角測量

CG屋は”Triangulation“と言うと三角形分割と訳してしまいそうですが、ここでは三角測量を意味します。
カメラの位置・姿勢、内部パラメータ、画像間の2D-2Dの対応の情報が既知であれば、三角測量の原理に基づいて対応点の三次元座標を推定することができます。

OpenCVには三角測量による三次元座標の計算を行うためのcv::triangulatePoints関数があります。


感想

とりあえず、今オイラが理解している情報を書いてみた。(後半ちょっと雑になりましたが)
今後も随時加筆修正していこうと思う。

こうしてまとめて見ると、OpenCVはその分野についての用語を知っていれば大体使えるようにAPIが上手く抽象化されているのが分かる。画像認識について体系的に学んだ人にとっては扱うのチョロいんだろうなぁ。
逆に、適切に抽象化されたAPIを使っているとその分野の体系が分かってくるとも言えるのかな。学ぶ上での教材としてこういうのは大事かも。これはエンジニア(プログラマ)流の学び方かもしれない。

追記:すごくいいまとめ記事↓
http://qiita.com/ykoga/items/14300e8cdf5aa7bd8d31

http://news.mynavi.jp/series/cv_future/006/
http://news.mynavi.jp/series/cv_future/008/
http://news.mynavi.jp/series/cv_future/009/
http://news.mynavi.jp/series/cv_future/010/

参考書

調べていたら、どうやらMultiple View Geometry in Computer Visionという洋書があるらしく、この書籍には2D→3D復元技術のことが体系的にまとまっているようです。

Multiple View Geometry in Computer Vision

でもお高いです。。。
追記:本書の一部はPDFで無料公開されている↓
http://www.robots.ox.ac.uk/~vgg/hzbook/

追記:最近出たこちらの書籍はそのものズバリ、3次元コンピュータービジョンを体系的に学べるようになっています。かなり教科書っぽいので、それなりに覚悟は必要です↓

3次元コンピュータビジョン計算ハンドブック

ピンホールカメラモデルとキャリブレーションについてはOpenCV 2 プログラミングブックのChapter4の2.1にもサンプルコードも合わせて解説が載っている。サンプルコードはサポートサイトから。

OpenCV 2 プログラミングブック OpenCV 2.2/2.3対応

http://qiita.com/tunepolo/items/76058121238be386bb21

2D-3D対応からのカメラ位置・姿勢の推定する、いわゆるPnP問題(Perspective-n-Pont Problem)をOpenCVで解く方法についてはOpenCV3対応のこちらが詳しい↓

OpenCV 3 プログラミングブック

同様にサンプルコードはサポートページからダウンロードできる。

追記:OpenCV3公式のカメラキャリブレーションと3次元復元の解説ドキュメントの日本語訳を掲載しているサイトを見つけた↓
http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_calib3d/py_table_of_contents_calib3d/py_table_of_contents_calib3d.html

2019年6月 追記:SSII 2019でカメラキャリブレーションのチュートリアルがあった↓


スポンサーリンク

関連記事

オープンソースの物理ベースレンダラ『Mitsuba』をMayaで使う
openMVGをWindows10 Visual Studio 2015環境でビルドする
ArUco:OpenCVベースのコンパクトなARライブラリ
Polyscope:3Dデータ操作用GUIライブラリ
組み込み向けのWindows OS 『Windows Embedded』
ディープラーニングに対応したPythonの機械学習ライブラリ『Pylearn2』
Math Inspector:科学計算向けビジュアルプログラミングツール
HD画質の無駄遣い
pythonの機械学習ライブラリ『scikit-learn』
UnityでOpenCVを使うには?
AI英語教材アプリ『abceed』
Qlone:スマホのカメラで3Dスキャンできるアプリ
TensorFlowでCGを微分できる『TensorFlow Graphics』
Verilog HDL
ManimML:機械学習の概念を視覚的に説明するためのライブラリ
YOLO (You Only Look Once):ディープラーニングによる一般物体検出手法
ポリゴン用各種イテレータと関数セット
UnityでShaderの入力パラメータとして行列を渡す
Mayaのシェーディングノードの区分
SONYの自律型エンタテインメントロボット『aibo』
Mitsuba 2:オープンソースの物理ベースレンダラ
Mask R-CNN:ディープラーニングによる一般物体検出・Instance Segmentatio...
コンピュータビジョンの技術マップ
3Dモデルを立体視で確認できるVRアプリを作っている
Amazon Web ServicesでWordPress
プログラミングスキルとは何か?
WinSCP
UnityでLight Shaftを表現する
Deep Learningとその他の機械学習手法の性能比較
OpenCV 3.1から追加されたSfMモジュール
Kinect for Windows v2の日本価格決定
OpenCV3.3.0でsfmモジュールのビルドに成功!
顔追跡による擬似3D表示『Dynamic Perspective』
OpenCVで顔のランドマークを検出する『Facemark API』
池袋パルコで3Dのバーチャルフィッティング『ウェアラブル クロージング バイ アーバンリサーチ』
ZBrushで作った3Dモデルを立体視で確認できるVRアプリを作る
機械学習で遊ぶ
CGALDotNet:計算幾何学ライブラリ CGALのC#ラッパー
Python拡張モジュールのWindows用インストーラー配布サイト
MRenderUtil::raytrace
Unity ARKitプラグインサンプルのドキュメントを読む
WordPressのサーバ引っ越し方法を考える

コメント