2015年7月14日火曜日

画角と解像度から内部パラメータ行列を作る

ピンホールカメラモデルのモデルパラメータである内部パラメータは、様々な形式で記述されるが 画角と解像度だけが分かっている場合に、どのようにOpenCVなどで用いられる内部パラメータ行列(camera matrix)を構成すればよいか解説する。

画角はカメラが映す範囲を直接角度として測ることができるので 画角だけがおおよそ分かっておりスペック等から解像度だけが 知り得る内部パラメータに関係する情報である場合が時々ある。 主点は画像のど真ん中、アスペクト比は1:1だとして、 このような場合、内部パラメータ行列はどのように設定すれば良いのか?

  • $X$, $Y$, $Z$: シーン点のカメラ座標
  • $f$: 焦点距離
  • $U$, $V$: シーン点の画像上の座標 [mm]
  • $u$, $v$: シーン点の画像上の座標 [pixel]
  • $w$, $h$: 撮像素子の画素数
  • $W$, $H$: 撮像素子のサイズ

ピンホールカメラにおける透視投影変換といえば 教科書などでは大抵次のような式が登場する。 \[ U=f\frac{X}{Z} \] ただし、大抵単位の変換が無視されていて三次元座標$X,Z$も焦点距離$f$も、 画像上の座標$U$もmm単位が前提で、単位は省略して書かれることが多い。 ここでは画素単位の画像上の座標$u$もちゃんと考慮する。

mm単位での撮像素子のサイズ$W$と撮像素子の画素数$w$の比から 画素単位の画像上の座標$u$次の様に書ける。 \[ u = \frac{w}{W}U=w\frac{f}{W}\frac{X}{Z} \]

ここで画角$\theta$がわかっていれば$\tan\theta=\frac{W/2}{f}$と書けるので、 次式のように書け、この$\tan\theta$こそがOpenCVなどの内部パラメータ行列の要素として登場する$f_x$に相当することが分かる。 \[ u = \frac{w}{2\tan\theta}\frac{X}{Z}=f_x\frac{X}{Z} \] 画角が本質的なパラメータなので実際の焦点距離$f$も撮像素子のサイズ$W$も必要ないことがここから分かる。

上の図は画像の水平方向のみのものだけど,もう一方も同様になる.

\[ v=\frac{h}{H}V=h\frac{f}{H}\frac{Y}{Z} \]

ここで$w:h=W:H$なので$\frac{h}{H}=\frac{w}{W}$であり

\[ v=\frac{w}{W}f\frac{Y}{Z}=\frac{w}{2\tan\theta}\frac{Y}{Z} \]

と,水平方向と同じになる.画像の左上が原点だとすると結局内部パラメータ行列$K$は次のようになる。

\[ K=\left[ \begin{array}{ccc} \frac{w}{2\tan\theta} & 0 & w/2 \\ 0 & \frac{w}{2\tan\theta} & h/2 \\ 0 & 0& 1 \end{array} \right] \]