2014年6月19日木曜日

射影行列の分解

射影行列\(P\)はカメラの内部パラメータ行列\(K\)とカメラの外部パラメータ行列\(\left[R|t\right]\)を掛けあわせたもので構成されている。ここでは、射影行列から、カメラの内部パラメータ行列\(K\)とカメラの姿勢\(R\)を求める方法について紹介する。(射影行列の推定方法については、2D-3Dの対応から射影行列を求める方法(DLTアルゴリズム)を参照)

3行4列の射影行列\(P\)は左側の3×3の行列と右端の列ベクトルに分けることができ、それぞれ内部パラメータ\(K\)、カメラ姿勢\(R\)、カメラ位置\(C\)を用いて以下のように書ける。

\[P=\left[M|-MC\right]=K\left[R|-RC\right]\]

ここから、内部パラメータ\(K\)は上三角行列、カメラ姿勢を表す\(R\)は直交行列なので、行列\(M\)をQR分解により上三角行列と直交行列に分解することで\(K\)、\(R\)を算出できることがわかる。OpenCVを用いる場合、cv::RQDecomp3x3を用いてQR分解を行うことができる。

以下は、3行4列の射影行列projectionMatを分解して内部パラメータ\(K\)、カメラ姿勢\(R\)を求めるOpenCVのコードである。

//射影行列の3x3要素を抽出
cv::Mat M = projectionMat.colRange(cv::Range(0, 3));
std::cout << M << std::endl;
cv::Mat R, Q;
cv::RQDecomp3x3(M, R, Q);

std::cout << "Intrinsic Camera Parameters:\n" << R << std::endl;
std::cout << "Rotation matrix:\n" << Q << std::endl;

ただし、OpenCVには、射影行列を分解して、内部パラメータ\(K\)、カメラ姿勢\(R\)、カメラ位置\(C\)を求めるcv::decomposeProjectionMatrix関数が用意されており、上記と同様の計算を行うことができる。
cv::Mat K, R, t;
cv::decomposeProjectionMatrix(projectionMat, K, R, t);

0 件のコメント:

コメントを投稿