ピンホールカメラモデル
Pinhole Camera Model
ピンホールカメラとは
ピンホールカメラは、小さな穴(ピンホール)を通して光が入り、反対側のスクリーンに像を結ぶ最もシンプルなカメラモデルである。レンズを使わないため、理想的な幾何学的モデルとして広く使われる。
透視投影の数学
3D点 $P = (X, Y, Z)$ から像平面上の点 $p = (x, y)$ への透視投影は、相似三角形の関係から導かれる:
記法の注意: 図1 では物理的なピンホール幾何 (像平面が camera 後方、$-Z$ 側) を示したが、以下の数式導出では計算の見通しを良くするため、像平面を camera 前方 ($+Z$ 側、$Z = f$ の位置) に置く仮想像平面モデルを採用する (図2)。両者は像が上下/左右反転するかの違いだけで、相似比の計算は同じ。CV/CG 分野の教科書でもこの仮想像平面表示が標準。
透視投影の基本式
3D点 $(X, Y, Z)$ から像平面上の点 $(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$。半角 $\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, y)$ からピクセル座標 $(u, v)$ への変換:
$$u = f_x \cdot x + c_x, \quad v = f_y \cdot y + c_y$$- $f_x, f_y$: ピクセル単位の焦点距離($f_x = f / p_x$、$p_x$はピクセルサイズ)
- $(c_x, c_y)$: 主点のピクセル座標
カメラモデルの統合
透視投影とピクセル座標変換を統合すると:
$$\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 (フルサイズセンサー)
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_homogeneous = np.array([P[0], P[1], P[2]])
p_homogeneous = K @ P_homogeneous
p = p_homogeneous[:2] / p_homogeneous[2]
print(f"Pixel (matrix): ({p[0]:.1f}, {p[1]:.1f})")
まとめ
- ピンホールカメラは透視投影の理想モデル
- 透視投影: $x = fX/Z$, $y = fY/Z$(非線形変換)
- 焦点距離が小さいほど画角が広い
- 主点は光軸と像平面の交点(画像中心からずれることがある)
- 内部パラメータ行列 $K$ で投影を表現できる