ワールド座標系とカメラ座標系

著者 石田 岳志 サイバーエージェント AI Lab

みなさんはスマートフォンで風景やお菓子の写真を撮るとき、写りがよくなるように撮影位置を変えたり、設定をいじったりしますよね。このとき、みなさんはカメラの世界で物事を考えています。「横から撮ったほうがケーキがおいしそうに見えるかも」「もうすこし明るく撮れば紅葉がもっときれいに写るかも」。こんなふうに考えながら写真を撮っているときは、誰もが画面に写る景色に夢中になっているでしょう。では、カメラを使っていないときはどうでしょうか。赤く染まる紅葉が湖面に反射するのを眺めているとき、ケーキを口に運んで甘さにうっとりしているとき、みなさんは現実世界のことに夢中です。

カメラは現実世界を写す道具です。湖の向こうから流れてくる空気の冷たさや、ケーキのスポンジのやわらかさこそ伝えられないものの、現実世界の光を画像というかたちで記録することができます。今回の内容は、現実世界とカメラの関係を、数式で明らかにしてみようというお話です。

カメラの世界と現実の世界

ピンホールカメラモデル のページではピンホールカメラモデルについて解説し、3次元空間の物体とその像の関係を記述する数式を紹介しました。

_images/2d_3d_relationship_pinhole_camera.png

図 22 ピンホールカメラモデル

ピンホールカメラモデルは、「カメラから見て \((X, Y, Z)\) の位置にある物体を写すと写真の \((u, v)\) の位置に写るよ」というふうに3次元空間上の物体の座標とその像の位置の関係を説明するものでした。これで3次元空間の物体とその像の関係を簡潔に記述できるようになり、とても便利になったのですが、現実世界の問題を扱うためにはもう少しやらなければならないことがあります。それが本稿で解説する、ワールド座標系での物体位置の表現とカメラ座標系への変換方法です。この変換をマスターすると、たとえば自動運転において道路周辺の物体を高速に認識できるようになるなど、さまざまな製品の品質向上に役立てることができます。

自動運転の車によってスーパーに行きたいとします。スーパーに行くには、地図上のスーパーの位置と、地図上での自分の位置がわかっていなければなりません。スーパーの位置はあらかじめ地図に記録されていますが、自動車のように常に位置が変化する物体を地図に埋め込むことはできないので、自動車の位置は常に推定し続ける必要があります。自動車の位置を推定する方法にはGPSを使う方法やLiDARと呼ばれるセンサを使う方法などさまざまなものがありますが、今回はカメラの話なので車載カメラで位置推定することを考えます。自動車のフロントガラスにカメラを埋め込んで、周囲の状況を把握して車の位置を推定するとしましょう。このとき必要になるのがワールド座標系とカメラ座標系という概念です。

一般的に、地図は適当な場所を原点として、北や東など方角にあった向きに描かれます。一方で、ピンホールカメラモデルによって像の位置を計算するときは、周囲の物体はカメラの位置や向きを基準として表現されます( 図 22 )。位置推定や3次元復元の問題において、地図の座標系は一般的に地図座標系や ワールド座標系 と呼ばれ、カメラの座標系は カメラ座標系 と呼ばれます。横断歩道や標識などの物体の位置を表現するには、地図の原点を基準にしたワールド座標系と、カメラを基準にしたカメラ座標系という2つの方法があるというわけです。

_images/vehicle_location_on_road.png

図 23 ワールド座標系とカメラ座標系それぞれによる停止線の位置の表現。停止線の位置を星で表現し、その値をカメラ座標系とワールド座標系でそれぞれ表現している。

_images/vehicle_side_view.png

図 24 図 23 を横から見たもの。カメラの高さは地面から1メートルとする。

具体例を見てみましょう。 図 23図 24 を見てください。ワールド座標系とカメラ座標系を区別しやすいように、ワールド座標系の軸には右肩に \(w\) を、カメラ座標系の軸には右肩に \(c\) をつけています。ワールド座標系の位置や向きは基本的に地図の作成者が好きなように決めることができます。図中では停止線の位置を星マークで表現したので、これをワールド座標系とカメラ座標系でそれぞれ表現してみましょう。

図 23 において、停止線の位置をワールド座標系で表現すると、 \(X^{w}\) 方向に6メートル、\(Y^{w}\) 方向に12メートルです。また、 図 24 より、停止線の位置は \(Z^{w}\) 方向に0メートルです。すべて列挙すると、 \(X^{w} = 6,\;Y^{w} = 12,\; Z^{w} = 0\) というふうになるでしょう。同様に、 カメラ座標系で停止線の位置を表現すると、 図 23 より \(X^{c}\) 方向に0メートル、 図 24 より \(Y^{c}\) 方向に1メートル、 \(Z^{c}\) 方向に10メートルなので、 \(X^{c} = 0,\; Y^{c} = 1,\; Z^{c} = 10\) となります。停止線という同じ物体を見ていても、基準となる座標系が変わることで全く別の値になることがわかっていただけたでしょうか。見やすいよう、これらを 表 1 にまとめました。

表 1 各座標系からの停止線の位置

座標系

停止線の位置

ワールド座標系

(6, 12, 0)

カメラ座標系

(0, 1, 10)

座標変換

ピンホールカメラモデル のページで解説したように、ピンホールカメラモデルは、カメラ座標系を基準として物体を見たときに、それが画像上のどの位置に映るのかを表すモデルです。したがって、ピンホールカメラモデルにはカメラ座標系で表現される物体の場所、すなわち \((X^{c}, Y^{c}, Z^{c})\) を入力する必要があります。一方で、地図上の物体の位置はワールド座標系の値 \((X^{w}, Y^{w}, Z^{w})\) で表現されています。先ほど示した自動車の位置推定などの問題では、「ワールド座標系で表現されている物体の座標をカメラに投影すると、画像中のどこに写るのか」という計算を非常に頻繁に行うのですが、ワールド座標系で表現されている座標をピンホールカメラモデルにそのまま入力することはできません。ここで必要になるのがワールド座標系からカメラ座標系への座標変換です。ワールド座標系上の座標の値は「地図の世界の言葉」で書かれている一方で、カメラ座標系上の座標の値は「カメラの世界の言葉」で書かれています。ピンホールカメラモデルは地図の世界の言葉を理解できないので、これをカメラの世界の言葉に翻訳する必要があるのです。

座標変換を使うと、実世界のさまざまな課題を解決することができます。たとえば、自動運転車には周囲の標識や信号機を認識するための高性能なカメラが搭載されています。これらのカメラは非常に高画質なので、画像のサイズも大きくなります。自動運転によって安全な走行を実現するためには、車両のはるか遠くにある標識や信号機も早い段階で見つける必要があります。しかし、高性能カメラが撮影した大きな画像の中から、車両のはるか遠くの小さな物体を見つけるのは簡単ではありません。もし「画像のこのあたりに標識が写っているはずだ」という見当をつけられれば、標識や信号機の認識処理を効率化できますよね。これから説明する座標変換を使うと、標識や信号機が画像のどこに写るのかを正確に計算できるので、物体認識の処理を効率化できます。このように、座標変換をマスターすると、自動運転車をはじめとして世の中の多くの製品やサービスの品質向上に貢献できます。

一般に、3次元空間上である物体の座標を2つの異なる座標系で表現できているとき、この間の変換は回転行列と並進ベクトルで記述できることが知られています。

\(R^{cw}\) を3次元の回転行列、 \(\mathbf{t}^{cw}\) を3次元の並進ベクトルとすると、ワールド座標系上の座標 \(\mathbf{p}^{w} = \left[X^{w} \quad Y^{w} \quad Z^{w}\right]^{\top}\) からカメラ座標系上の座標 \(\mathbf{p}^{c} = \left[X^{c} \quad Y^{c} \quad Z^{c}\right]^{\top}\) までの変換は次のようになります。

(11)\[\mathbf{p}^{c} = R^{cw}\mathbf{p}^{w} + \mathbf{t}^{cw}\]

この式による \(\mathbf{p}^{w}\) から \(\mathbf{p}^{c}\) への変換が「翻訳」に相当します。

すこし分かりづらいと思うので、具体例を見てみましょう。

図 24 および 図 23 の例では、ワールド座標系から見た停止線の位置は

\[\begin{split}\mathbf{p}^{w} = \begin{bmatrix} X^{w} \\ Y^{w} \\ Z^{w} \end{bmatrix} = \begin{bmatrix} 6 \\ 12 \\ 0 \end{bmatrix}\end{split}\]

カメラ座標系から見た停止線の位置は

\[\begin{split}\mathbf{p}^{c} = \begin{bmatrix} X^{c} \\ Y^{c} \\ Z^{c} \end{bmatrix} = \begin{bmatrix} 0 \\ 1 \\ 10 \end{bmatrix}\end{split}\]

でした。

実際に 式 (11) によってワールド座標系の停止線の位置 \(\mathbf{p}^{w}\) をカメラ座標系から見た値 \(\mathbf{p}^{c}\) に変換してみましょう。

\(R^{cw}\)\(\mathbf{t}^{cw}\) を次のように設定すると、ワールド座標系からカメラ座標系への変換を行うことができます。なぜこのような値になるのかはあとで説明するので、まずは変換を実際にやってみましょう。

\[\begin{split}R^{cw} &= \begin{bmatrix} 0 & -1 & 0 \\ 0 & 0 & -1 \\ 1 & 0 & 0 \\ \end{bmatrix} \\ \mathbf{t}^{cw} &= \begin{bmatrix} 12 \\ 1 \\ 4 \\ \end{bmatrix}\end{split}\]

式 (11) に当てはめてみます。

(12)\[\begin{split}R^{cw}\mathbf{p}^{w} + \mathbf{t}^{cw} &= \begin{bmatrix} 0 & -1 & 0 \\ 0 & 0 & -1 \\ 1 & 0 & 0 \\ \end{bmatrix} \begin{bmatrix} 6 \\ 12 \\ 0 \end{bmatrix} + \begin{bmatrix} 12 \\ 1 \\ 4 \\ \end{bmatrix} \\ &= \begin{bmatrix} 0 \\ 1 \\ 10 \\ \end{bmatrix} \\ &= \mathbf{p}^{c}\end{split}\]

となり、実際に変換を行うことができました。

回転行列であることの確認

ところで \(R^{cw}\) は回転行列でなければならないので、回転行列の定義である \({R^{cw}}^{\top} = {R^{cw}}^{-1}\) および \(\det{R^{cw}} = 1\) を満たさなければなりません。

\({R^{cw}}^{\top} = {R^{cw}}^{-1}\) であることを確かめるには \({R^{cw}}^{\top}R^{cw}\) が単位行列であることを示せればよいので、実際に計算してみましょう。

\[\begin{split}{R^{cw}}^{\top}R^{cw} &= \begin{bmatrix} 0 & 0 & 1 \\ -1 & 0 & 0 \\ 0 & -1 & 0 \\ \end{bmatrix} \begin{bmatrix} 0 & -1 & 0 \\ 0 & 0 & -1 \\ 1 & 0 & 0 \\ \end{bmatrix} \\ &= \begin{bmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \\ \end{bmatrix} \\\end{split}\]

また、 \(\det{R^{cw}} = 1\) についてもサラスの公式により容易に確かめられます。

導出方法

さて、回転行列と並進ベクトルによってワールド座標系からカメラ座標系への変換を記述できることを確認できたので、ここからは回転行列と並進ベクトルの導出手順を見ていきます。とはいってもたいしたことはせず、それぞれの座標系の中心から停止線までの位置関係を比較していくだけなので、それほど難しくありません。

図 23 を見てください。 カメラ座標系の \(Z^{c}\) 軸とワールド座標系の \(X^{w}\) 軸は同じ向きを向いていますね。また、カメラ座標系の原点から見ると、ワールド座標系の原点の位置は \(Z^{c}\) 軸方向に4メートル進んだ場所にあることがわかります。

したがって、

(13)\[Z^{c} = X^{w} + 4\]

が成り立ちます。

他の2つの軸についても見ていきましょう。

\(X^{c}\) 軸はどうでしょう。\(X^{c}\) 軸に対して \(Y^{w}\) 軸は逆を向いています。また、カメラ座標系の原点から見てワールド座標系の原点の位置は \(X^{c}\) 軸方向に12メートル進んだ場所にあります。したがって、両者の関係は

\[X^{c} = -Y^{w} + 12\]

となります。

最後に \(Y^{c}\) 軸も見てみましょう。 図 24 において、\(Y^{c}\) 軸に対して \(Z^{w}\) 軸は逆を向いています。また、カメラ座標系の原点から見てワールド座標系の原点の位置は \(Y^{c}\) 軸方向に1メートル進んだ場所にあります。したがって、両者の関係は

\[Y^{c} = -Z^{w} + 1\]

と記述できます。

3つの式を並べると次のようになります。

\[\begin{split}X^{c} &= -Y^{w} + 12 \\ Y^{c} &= -Z^{w} + 1 \\ Z^{c} &= X^{w} + 4 \\\end{split}\]

これこそがカメラ座標系とワールド座標系の関係です。これを行列で表現すれば、 式 (12) の回転行列や並進ベクトルが得られます。

(14)\[\begin{split}\begin{bmatrix} X^{c} \\ Y^{c} \\ Z^{c} \end{bmatrix} &= \begin{bmatrix} 0 & -1 & 0 \\ 0 & 0 & -1 \\ 1 & 0 & 0 \\ \end{bmatrix} \begin{bmatrix} X^{w} \\ Y^{w} \\ Z^{w} \end{bmatrix} + \begin{bmatrix} 12 \\ 1 \\ 4 \\ \end{bmatrix} \\\end{split}\]

たしかに、 式 (12) で用いた回転行列と並進ベクトルと同じ値が出てきました。

ワールド座標系とカメラ座標系という異なる2つの座標系を回転行列と並進ベクトルが関連付けているということがおわかりいただけたでしょうか?

同次座標による表現

同次座標表現という表現方法を用いると 式 (11) をより簡潔に書くことができるのでここで紹介しておきます。といっても、ベクトルの末尾に1をくっつけると計算が簡潔になるというだけの話なのでとてもかんたんです。

例としてベクトル \(\mathbf{p}^{w} = \begin{bmatrix} X^{w} & Y^{w} & Z^{w} \end{bmatrix}^{\top}\) の同次座標表現を示します。 \(\mathbf{p}^{w}\) の同次座標表現を \(\dot{\mathbf{p}^{w}}\) とすると、これは次のようになっています。

\[\begin{split}\dot{\mathbf{p}^{w}} = \begin{bmatrix} \mathbf{p}^{w} \\ 1 \end{bmatrix} = \begin{bmatrix} X^{w} \\ Y^{w} \\ Z^{w} \\ 1 \end{bmatrix}\end{split}\]

単純に末尾に1がついただけですね。

同次座標表現を使うと 式 (11) をより単純な1本の式で表現できます。

\[\begin{split}\mathbf{p}^{c} &= R^{cw}\mathbf{p}^{w} + \mathbf{t}^{cw} \\ &= \begin{bmatrix} \begin{array}{ccc|c} & & & \\ & R^{cw} & & \mathbf{t}^{cw} \\ & & & \\ \end{array} \end{bmatrix} \begin{bmatrix} \mathbf{p}^{w} \\ \\ 1 \end{bmatrix}\end{split}\]

具体例として 式 (14) を同次座標表現すると次のようになります。

(15)\[\begin{split}\begin{bmatrix} X^{c} \\ Y^{c} \\ Z^{c} \\ \end{bmatrix} &= \begin{bmatrix} 0 & -1 & 0 & 12 \\ 0 & 0 & -1 & 1 \\ 1 & 0 & 0 & 4 \\ \end{bmatrix} \begin{bmatrix} X^{w} \\ Y^{w} \\ Z^{w} \\ 1 \\ \end{bmatrix}\end{split}\]

たしかに、 式 (15)\(X^{w},\;Y^{w},\;Z^{w}\) にワールド座標系の座標値を入力すれば、たった1回の行列演算でカメラ座標系の値に変換できて便利ですね。

\[\begin{split}\begin{bmatrix} X^{c} \\ Y^{c} \\ Z^{c} \\ \end{bmatrix} &= \begin{bmatrix} 0 & -1 & 0 & 12 \\ 0 & 0 & -1 & 1 \\ 1 & 0 & 0 & 4 \\ \end{bmatrix} \begin{bmatrix} 6 \\ 12 \\ 0 \\ 1 \\ \end{bmatrix} \\ &= \begin{bmatrix} 0 \\ 1 \\ 10 \end{bmatrix}\end{split}\]

なお、入力側(ワールド座標系側)だけでなく、出力側(カメラ座標側)も同次座標表現することが可能です。この場合、変換行列のサイズが \(4 \times 4\) になります。

\[\begin{split}\begin{bmatrix} X^{c} \\ Y^{c} \\ Z^{c} \\ 1 \end{bmatrix} &= \begin{bmatrix} 0 & -1 & 0 & 12 \\ 0 & 0 & -1 & 1 \\ 1 & 0 & 0 & 4 \\ 0 & 0 & 0 & 1 \\ \end{bmatrix} \begin{bmatrix} X^{w} \\ Y^{w} \\ Z^{w} \\ 1 \end{bmatrix}\end{split}\]

ピンホールカメラモデルとの組み合わせ

ここまで、ワールド座標系で表現された物体の座標をカメラ座標系での値に変換する方法を見てきました。物体の位置がワールド座標系で表現されていたとしても、上記の方法でカメラ座標系の値に変換すれば、ピンホールカメラモデルに入力することができます。ワールド座標系からカメラ座標系への変換パラメータ(回転行列と並進ベクトル)と、カメラの内部パラメータさえわかっていれば、ワールド座標系上の物体をカメラで撮影したときの像の位置を得ることができます。すなわち、「地図上で○○の場所にある物体を××の場所にあるカメラで撮影すると画像上の△△のところに写るよ」ということを計算で示せるわけです。図 23図 24 を例として実際にやってみましょう。ただしカメラパラメータは 表 2 の値を用いることとします。

表 2 計算に用いるカメラパラメータ

パラメータ

数値

X方向焦点距離

500ピクセル

Y方向焦点距離

500ピクセル

X方向オフセット

180ピクセル

Y方向オフセット

120ピクセル

図 23図 24 において、ワールド座標系における停止線の位置は

\[\begin{split}\mathbf{p}^{w} = \begin{bmatrix} X^{w} \\ Y^{w} \\ Z^{w} \end{bmatrix} = \begin{bmatrix} 6 \\ 12 \\ 0 \end{bmatrix}\end{split}\]

でした。これをカメラ座標系から見た値に変換すると、

(16)\[\begin{split}\mathbf{p}^{c} &= \begin{bmatrix} X^{c} \\ Y^{c} \\ Z^{c} \\ \end{bmatrix} \\ &= \begin{bmatrix} 0 & -1 & 0 & 12 \\ 0 & 0 & -1 & 1 \\ 1 & 0 & 0 & 4 \\ \end{bmatrix} \begin{bmatrix} X^{w} \\ Y^{w} \\ Z^{w} \\ 1 \\ \end{bmatrix} \\ &= \begin{bmatrix} 0 & -1 & 0 & 12 \\ 0 & 0 & -1 & 1 \\ 1 & 0 & 0 & 4 \\ \end{bmatrix} \begin{bmatrix} 6 \\ 12 \\ 0 \\ 1 \\ \end{bmatrix} \\ &= \begin{bmatrix} 0 \\ 1 \\ 10 \end{bmatrix}\end{split}\]

となるのでした。

ピンホールカメラモデルを使って停止線をカメラに投影してみます。 表 2 より、カメラの内部行列 \(K\) は次のようになります。

\[\begin{split}K = \begin{bmatrix} 500 & 0 & 180 \\ 0 & 500 & 120 \\ 0 & 0 & 1 \\ \end{bmatrix}\end{split}\]
\[\begin{split}Z \begin{bmatrix} u \\ v \\ 1 \end{bmatrix} &= K\mathbf{p}^{c} \\ &= \begin{bmatrix} 500 & 0 & 180 \\ 0 & 500 & 120 \\ 0 & 0 & 1 \\ \end{bmatrix} \begin{bmatrix} 0 \\ 1 \\ 10 \end{bmatrix}\end{split}\]

一番下の行を計算すると、 \(Z = 10\) であることがわかります。これを代入して計算を進めていきます。

(17)\[\begin{split}\begin{bmatrix} u \\ v \\ 1 \end{bmatrix} &= \frac{1}{Z} \begin{bmatrix} 500 & 0 & 180 \\ 0 & 500 & 120 \\ 0 & 0 & 1 \\ \end{bmatrix} \begin{bmatrix} 0 \\ 1 \\ 10 \end{bmatrix} \\ &= \frac{1}{10} \begin{bmatrix} 500 & 0 & 180 \\ 0 & 500 & 120 \\ 0 & 0 & 1 \\ \end{bmatrix} \begin{bmatrix} 0 \\ 1 \\ 10 \end{bmatrix} \\ &= \begin{bmatrix} 180 \\ 170 \\ 1 \end{bmatrix}\end{split}\]

計算の結果、 \((u,\; v) = (180,\; 170)\) が得られました。

ワールド座標系で \((X^{w},\;Y^{w},\;Z^{w}) = (6,\;12,\;0)\) にある停止線は、画像の左上を基準として右に180ピクセル、下に170ピクセル数えたところに写ることがわかりました。

これらの計算はひとつにまとめることができます。式 (16) によるワールド座標系からカメラ座標系への変換と、 式 (17) によるカメラ座標系上の座標からカメラへの投影を組み合わせると次のようになります。

\[\begin{split}\begin{bmatrix} u \\ v \\ 1 \end{bmatrix} &= \frac{1}{Z} \; K \begin{bmatrix} \begin{array}{ccc|c} & & & \\ & R^{cw} & & \mathbf{t}^{cw} \\ & & & \\ \end{array} \end{bmatrix} \begin{bmatrix} \mathbf{p}^{w} \\ \\ 1 \end{bmatrix} \\ &= \frac{1}{10} \begin{bmatrix} 500 & 0 & 180 \\ 0 & 500 & 120 \\ 0 & 0 & 1 \\ \end{bmatrix} \begin{bmatrix} 0 & -1 & 0 & 12 \\ 0 & 0 & -1 & 1 \\ 1 & 0 & 0 & 4 \\ \end{bmatrix} \begin{bmatrix} 6 \\ 12 \\ 0 \\ 1 \\ \end{bmatrix} \\ &= \begin{bmatrix} 180 \\ 170 \\ 1 \end{bmatrix}\end{split}\]

まとめ

ピンホールカメラモデルでは「カメラを基準とした世界」しか扱えませんでしたが、ワールド座標系を導入することで「地図を基準とした世界」も扱えるようになりました。また、ワールド座標系からカメラ座標系への変換方法を知ることにより、地図上の物体をカメラで扱うことができるようになりました。身の回りには掃除ロボットや配膳ロボットをはじめとして、地図とカメラをセットで扱う製品がすでに普及してきています。こういった製品は小型で、安く、長時間動作することが求められるので、その中で行っている物体認識や位置推定などのさまざまな計算を効率化する必要があります。同次座標のような効率のよい表現方法を知っておくと、こういった計算を少しだけ速くしたり、コードをシンプルに書いたりすることができ、より高品質な製品を生み出す助けとなります。位置推定や3次元復元の分野ではここで紹介した座標変換を非常に頻繁に用いるので、みなさんもぜひたくさん計算して、マスターしてみてください。