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

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



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

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


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


スポンサーリンク

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

Pinhole Camera Model

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

Homography:ホモグラフィ

Homography

画像認識におけるHomographyとは、2D空間同士の射影変換のこと。(一般的には射影変換全般を指す)
図で赤く示されているような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点)必要だそうです。

Fundamental Matrix:基礎行列

Fundamental matrix

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

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

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

【動画】 “The Fundamental Matrix Song” を翻訳してみた
基礎行列の歌 (The Fundamental Matrix Song)

Essential Matrix:基本行列

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:キャリブレーション/姿勢推定

Resection/Pose estimation matrix

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

Triangulation:三角測量

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でカメラキャリブレーションのチュートリアルがあった↓


スポンサーリンク

関連記事

Iterator
WordPress on Google App Engineを1週間運用してみて
WordPressプラグインの作り方
Raspberry Pi 2のGPIOピン配置
ニューラルネットワークで画像分類
株式会社ヘキサドライブの研究室ページ
クリエイターのための機械学習ツール『Runway ML』
UnityからROSを利用できる『ROS#』
.NETで使えるTensorFlowライクなニューラルネットワークライブラリ『NeuralNetwo...
Twitter APIのPythonラッパー『python-twitter』
UnityユーザーがUnreal Engineの使い方を学ぶには?
Webスクレイピングの勉強会に行ってきた
UnityでOpenCVを使うには?
オープンソースのSLAMライブラリ『Cartographer』
PSPNet (Pyramid Scene Parsing Network):ディープラーニングによ...
ディープラーニング
WinSCP
写真に3Dオブジェクトを違和感無く合成する『3DPhotoMagic』
Deep Neural Networkによる顔の個人識別フレームワーク『OpenFace』
自前のShaderがおかしい件
OpenCV 3.1のsfmモジュールを試す
OpenCVでPhotoshopのプラグイン開発
機械学習に役立つPythonライブラリ一覧
画像からカメラの3次元位置・姿勢を推定するライブラリ『OpenGV』
Unity MonoBehaviourクラスのオーバーライド関数が呼び出される順番
オープンソースの顔の動作解析ツールキット『OpenFace』
JavaScriptとかWebGLとかCanvasとか
PCA (主成分分析)
iOSデバイスと接続して連携するガジェットの開発方法
OpenCV 3.1とopencv_contribモジュールをVisual Studio 2015で...
takminさんが機械学習・画像認識の便利ツールを公開しています
続・ディープラーニングの資料
Google App Engineのデプロイ失敗
機械学習について理解するための可視化ツール『MLDemos』
オープンソースの3Dメッシュデータライブラリ『OpenMesh』
なんかすごいサイト
MeshroomでPhotogrammetry
UnityでPoint Cloudを表示する方法
Point Cloud Consortiumのセミナー「3D点群の未来」に行ってきたよ
オープンソースのロボットアプリケーションフレームワーク『ROS (Robot Operating S...
FacebookがDeep learningツールの一部をオープンソース化
ブログが1日ダウンしてました

コメント