ピンホールカメラモデル
Pinhole Camera Model
ピンホールカメラとは
ピンホールカメラは、小さな穴(ピンホール)を通して光が入り、反対側のスクリーンに像を結ぶ最もシンプルなカメラモデルである。レンズを使わないため、理想的な幾何学的モデルとして広く使われる(本記事では穴を 1 点とみなし、穴の大きさによるぼけや回折は扱わない)。
透視投影の数学
3D点 $P = (X, Y, Z)$ から像平面上の点 $p = (x, y)$ への透視投影は、相似三角形の関係から導かれる:
記法の注意: 図1 では物理的なピンホール幾何 (像平面が camera 後方、$-Z$ 側) を示したが、以下の数式導出では計算の見通しを良くするため、像平面を camera 前方 ($+Z$ 側、$Z = f$ の位置) に置く仮想像平面モデルを採用する (図2)。両者は像が上下/左右反転するかの違いだけで、相似比の計算は同じ(ただし符号まで含めると、物理的な像平面では $x = -fX/Z,\ y = -fY/Z$ になる)。CV/CG 分野の教科書でもこの仮想像平面表示が標準。
透視投影の基本式
カメラ座標(原点=ピンホール、光軸の前方を $+Z$)で表した 3D 点 $(X, Y, Z)$($Z > 0$)から像平面上の点 $(x, y)$ への投影:
$$x = f \dfrac{X}{Z}, \quad y = f \dfrac{Y}{Z}$$ここで $f$ はピンホールから像平面までの距離(慣例で焦点距離と呼ぶ。ピンホールに光を集める焦点があるわけではない)、$Z$ は奥行き(深度)
重要: $Z$ で割る操作のため、透視投影は通常の (行列との積で表せる) 意味では線形変換ではない。 しかし次章で扱う同次座標 ($(X, Y, Z) \to (X, Y, Z, 1)$ への拡張) を使えば、変換を (1) 行列積で表せる部分と(2) 最後の $Z$ 除算 (同次座標の正規化) の 2 段階に分離できる。 非線形性は (2) の正規化に閉じ込められ、(1) の行列部分は回転・平行移動・投影などを統一的に扱える。
画角(Field of View)
画角はカメラが撮影できる範囲の角度で、焦点距離とセンサーサイズから決まる。
画角 (Field of View, FOV) の定義
カメラが捉えられる視野の最大角度。光軸を中心として、ピンホール $O$ から像平面 (センサー) の両端を結ぶ 2 本の光線がなす角を $\theta$ とする。
センサーの幅 $w$ / 高さ $h$ / 対角線長 $d$ のどれを基準にするかで、それぞれ 水平画角・垂直画角・対角画角が定義される (規格や用途で使い分けられる)。
図3 は焦点距離 $f$ を変えたときの画角の変化を直感的に示している。
FOV 計算式の導出
画角は単純な直角三角形の関係から導ける。光軸とセンサーは直交するので、ピンホール $O$・センサー中心・センサー上端を結ぶと直角三角形になる。
図4 のように、直角三角形の隣辺は焦点距離 $f$、対辺はセンサーの半幅 $w/2$(図は縦方向に描いたが、幅でも高さでも同じ式になる。縦方向なら $w$ を高さ $h$ と読み替える)。半角 $\theta/2$ について
$$\tan\!\left(\dfrac{\theta}{2}\right) = \dfrac{w/2}{f} = \dfrac{w}{2f}$$
両辺 $\arctan$ を取って 2 倍すると全画角 $\theta$ が得られる。
画角 (FOV) の計算式
$$\boxed{\;\theta = 2\,\arctan\!\left(\dfrac{w}{2f}\right)\;}$$$w$ にセンサーの幅を入れれば水平画角、高さを入れれば垂直画角、対角線長 $d$ を入れれば対角画角。
$f$ が大きいほど $\theta$ は小さく (望遠)、$f$ が小さいほど $\theta$ は大きく (広角) なる。
この式は主点がセンサーの中央にある場合。主点がずれるときは、左右(上下)それぞれの角を別々に求めて足す。
主点とスキュー
実際のカメラでは、光軸が画像中心を通らない場合がある。
ピクセル座標への変換
正規化画像座標 $(x_n, y_n) = (X/Z,\ Y/Z)$(像平面上の点 $(x, y)$ を焦点距離 $f$ で割ったもの)からピクセル座標 $(u, v)$ への変換:
$$u = f_x\, x_n + c_x, \quad v = f_y\, y_n + c_y$$- $f_x, f_y$: ピクセル単位の焦点距離($f_x = f / p_x$、$f_y = f / p_y$。$p_x, p_y$ は横・縦のピクセルサイズ)
- $(c_x, c_y)$: 主点のピクセル座標
ここでは画素の軸が直交するとしてスキュー($K$ の (1,2) 成分 $s$)を 0 とした。$s \neq 0$ なら $u = f_x\, x_n + s\, y_n + c_x$ になる。現代のカメラではほぼ 0 とみなせる。
カメラモデルの統合
透視投影とピクセル座標変換を統合すると:
$$\begin{pmatrix} u \\ v \\ 1 \end{pmatrix} = \dfrac{1}{Z} \begin{pmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} X \\ Y \\ Z \end{pmatrix}$$右辺の行列積を計算すると $(f_x X + c_x Z,\; f_y Y + c_y Z,\; Z)^\top$ になり、$1/Z$ 倍 (= 同次座標の正規化) で第 3 成分が 1 になる。これを行ごとに展開すると次のスカラー式が得られる:
$$u = f_x \dfrac{X}{Z} + c_x, \quad v = f_y \dfrac{Y}{Z} + c_y$$この行列はカメラの内部パラメータ行列 $K$(intrinsic matrix)と呼ばれ、次章で詳しく扱う。
コード例(Python)
import numpy as np
# カメラパラメータ
fx, fy = 800, 800 # 焦点距離(ピクセル単位)
cx, cy = 320, 240 # 主点
f = 50 # 焦点距離(mm)
# 3D点(カメラ座標系)
P = np.array([1.0, 0.5, 5.0]) # (X, Y, Z) in meters
# 透視投影
x = P[0] / P[2] # X/Z
y = P[1] / P[2] # Y/Z
# ピクセル座標への変換
u = fx * x + cx
v = fy * y + cy
print(f"Pixel coordinates: ({u:.1f}, {v:.1f})")
# 画角の計算
sensor_width = 36 # mm(フルサイズ。上の fx・f とは独立に置いた例の値)
fov = 2 * np.arctan(sensor_width / (2 * f))
print(f"Field of View: {np.degrees(fov):.1f}°")
# 行列形式での投影
K = np.array([
[fx, 0, cx],
[0, fy, cy],
[0, 0, 1]
])
P_camera = P # カメラ座標の 3D 点(同次座標なのは、次の行で得る 2D 像点のほう)
p_homogeneous = K @ P_camera
p = p_homogeneous[:2] / p_homogeneous[2]
print(f"Pixel (matrix): ({p[0]:.1f}, {p[1]:.1f})")
まとめ
- ピンホールカメラは透視投影の理想モデル
- 透視投影: $x = fX/Z$, $y = fY/Z$(非線形変換)
- 焦点距離が小さいほど画角が広い
- 主点は光軸と像平面の交点(画像中心からずれることがある)
- 内部パラメータ行列 $K$ で投影を表現できる
よくある質問
ピンホールカメラモデルとは何ですか?
ピンホールカメラは、小さな穴 (ピンホール) を通って光が入り、反対側のスクリーンに像を結ぶ最もシンプルなカメラモデルです。穴を 1 点とみなした理想的な幾何モデルとして、コンピュータビジョン・コンピュータグラフィックスで標準的に使われます。カメラ座標の 3D 点 $P(X, Y, Z)$($Z > 0$)は、像平面上の点 $p(x, y)$ に $x = fX/Z,\ y = fY/Z$ で写されます($f$ はピンホールから像平面までの距離=焦点距離)。
仮想像平面モデルと物理的なピンホール幾何の違いは?
物理的なピンホール幾何では像平面がカメラ後方 ($-Z$ 側) にあり、像が上下/左右反転します。一方、仮想像平面モデルでは像平面をカメラ前方 ($+Z$ 側、$Z = f$ の位置) に置き、反転を解消します。相似比の計算は同じですが、符号まで含めると物理的な像平面では $x = -fX/Z$ になります。仮想像平面のほうが符号反転がなく扱いやすいため、CV/CG の数式導出では標準的に用いられます。
透視投影の式 x = fX/Z はどう導かれますか?
カメラ中心 $O$ から 3D 点 $P(X, Y, Z)$ への光線が像平面 ($Z = f$ の位置) と交わる点を $p(x, y)$ とすると、$O$・像点・3D 点で形成される 2 つの相似三角形から $x : f = X : Z$ および $y : f = Y : Z$ が成り立ちます。これを整理して $x = fX/Z,\ y = fY/Z$ を得ます。
なぜ透視投影では深度情報が失われるのですか?
透視投影では $x = fX/Z,\ y = fY/Z$ と $Z$ で割るため、3D 点 $(X, Y, Z)$ と $(kX, kY, kZ)$(任意の $k > 0$)が同じ 2D 点に写されます。つまり光線上のすべての点が 1 つの像点に集約されるため、1 枚の像の点だけから元の $Z$ (深度) を一意に復元することはできません。復元には、別の視点からの画像(ステレオ・SfM など)、大きさが既知の物体、深度センサなどの追加の情報が要ります。