618 文字
3 分
【OpenCV】decomposeProjectionMatrixを使った外部パラメータの導出
透視投影変換行列を内部パラメータと外部パラメータに分解するため、OpenCVのdecomposeProjectionMatrixを使用したのですが、ちょっと使い方にはまったので使い方メモです。
公式ドキュメントを見てみる
decomposeProjectionMatrixの使い方はここに書いてます。
この関数の引数や返り値は以下の通りです。
void decomposeProjectionMatrix(InputArray projMatrix, OutputArray cameraMatrix, OutputArray rotMatrix, OutputArray transVect, OutputArray rotMatrixX=noArray(), OutputArray rotMatrixY=noArray(), OutputArray rotMatrixZ=noArray(), OutputArray eulerAngles=noArray() )各パラメータの役割はこんな感じです。(rotMatrixXとかは今回触れないので省略してます。)
| 引数 | 役割 | |
|---|---|---|
| 入力 | projMatrix | 透視投影変換行列 |
| 出力 | cameraMatrix | 内部パラメータ |
| rotMatrix | 外部パラメータの回転行列 | |
| transVect | カメラ位置の示したベクトル |
はまったところ
この関数の出力であるtransVect、すなわちカメラ位置を示したベクトルがどの座標系で表現されているのかを確認せずに使ったので、見事にバグを生み出してしまいました。
カメラ位置は世界座標系で求まる
はい、結論から言うと、transVectは世界座標系でのカメラ位置です。なので、外部パラメータで使用するような並進ベクトルを求めるにはtransVectから導出してやる必要があります。
なお、この変換には外部パラメータへの理解が必要となりますので、わからない人はこの記事をご覧ください。
カメラ外部パラメータとは
変換するにはまず、transVectは4次元ベクトルとして返ってきて扱いづらいため、3次元ベクトルにしてやります。これは、1~3番目の要素を4番目の要素で割ればいいです。
この3次元ベクトルをと置きます。
ついでに求まった回転行列rotMatrixをと置いておきます。
さらに、この世界座標系で表現されたカメラ位置は外部パラメータによって変換されるとカメラ座標系の原点の座標になるはずです。
すなわちこうなります。

つまり、並進ベクトルはこのように求めることができます。

なお、decomposeProjectionMatrixには他にもハマりどころが何箇所かあるので、それはこちらにまとめています。
【OpenCV】decomposeProjectionMatrixを使って透視投影変換行列を分解する~完全版~