射影行列の分解
射影行列\(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のコードである。
ただし、OpenCVには、射影行列を分解して、内部パラメータ\(K\)、カメラ姿勢\(R\)、カメラ位置\(C\)を求めるcv::decomposeProjectionMatrix関数が用意されており、上記と同様の計算を行うことができる。
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);
コメント
コメントを投稿