同次座標と変換行列

Homogeneous Coordinates and Transformation Matrices

同次座標とは

同次座標(Homogeneous Coordinates)は、射影幾何学で使われる座標系で、通常の座標に1次元を追加したものである。厳密には $(kx, ky, kw) \sim (x, y, w)$($k \neq 0$)のように比例関係にある座標を同じ点とみなす同値類であり、これにより平行移動を含むすべての変換を行列の積で表現できる。

2D点 (x, y) 通常座標 同次座標 (x, y, 1) 3要素ベクトル 3D: (X, Y, Z) → 同次: (X, Y, Z, 1) スケール不変: (kx, ky, k) ∼ (x, y, 1)
図1. 通常座標と同次座標の対応

同次座標の定義

  • 2D点 $(x, y)$ の同次座標: $(x, y, 1)$ または一般に $(kx, ky, k)$ for $k \neq 0$
  • 3D点 $(X, Y, Z)$ の同次座標: $(X, Y, Z, 1)$ または $(kX, kY, kZ, k)$
  • 通常座標への変換: $(x, y, w) \to (x/w, y/w)$

なぜ同次座標を使うのか?

  • 平行移動を行列の積で表現できる
  • 複数の変換を1つの行列に合成できる
  • 射影変換(透視投影)を線形に扱える
  • 無限遠点を有限の座標で表現できる($w = 0$)

平行移動はなぜ特別か

通常座標では平行移動は加算 $(x', y') = (x, y) + (t_x, t_y)$ であり、原点を固定する線形変換(1つの行列の積)では書けない。同次座標で次元を1つ増やすと、平行移動も $(x', y', 1) = T\,(x, y, 1)$ という単一の行列積で表せる。これにより回転・スケール・平行移動を同じ枠組みで合成できるのが最大の利点である。

2D変換行列

ベクトルの向き: 本記事ではベクトルを列ベクトルとして扱い、$p' = T\,p$ と行列を左から掛ける。$(x, y, 1)$ とカンマ区切りで横書きするのは、列ベクトル $(x, y, 1)^\top$ を縦に積む代わりに省スペースで書いた省略表記である。

平行移動(Translation)

元の位置 移動後 (tx, ty) 平行移動行列: T = 10tx 01ty 001 p′ = T p (x′, y′, 1) = (x+tx, y+ty, 1)
図2. 平行移動の変換行列

回転(Rotation)

θ 原点中心で回転 回転行列: R = cos θ−sin θ0 sin θcos θ0 001 反時計回りを正とする
図3. 原点中心の回転変換

スケーリング(Scaling)

sx = 2, sy = 3 スケール行列: S = sx00 0sy0 001 sx ≠ sy: 異方スケール
図4. スケーリング変換の効果

変換の合成

複数の変換は行列の積で合成できる。右から順に適用される点に注意。

変換の合成

スケール → 回転 → 平行移動 の順に適用する場合:

$$M = T \cdot R \cdot S$$ $$\mathbf{p}' = M \mathbf{p} = T(R(S \mathbf{p}))$$
S 拡大 R 回転 T 移動
図5. 幾何変換の合成(スケール→回転→平行移動)

重要: 行列の積は非可換($AB \neq BA$)。変換の順序が異なると結果も異なる。

3D変換行列

3D空間での変換は $4 \times 4$ 行列で表現される。

3D平行移動

$$T = \begin{pmatrix} 1 & 0 & 0 & t_x \\ 0 & 1 & 0 & t_y \\ 0 & 0 & 1 & t_z \\ 0 & 0 & 0 & 1 \end{pmatrix}$$

3D回転行列

X軸周り(ロール):

$$R_x(\theta) = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & \cos\theta & -\sin\theta & 0 \\ 0 & \sin\theta & \cos\theta & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}$$

Y軸周り(ピッチ):

$$R_y(\theta) = \begin{pmatrix} \cos\theta & 0 & \sin\theta & 0 \\ 0 & 1 & 0 & 0 \\ -\sin\theta & 0 & \cos\theta & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}$$

Z軸周り(ヨー):

$$R_z(\theta) = \begin{pmatrix} \cos\theta & -\sin\theta & 0 & 0 \\ \sin\theta & \cos\theta & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}$$
X・Y・Z 各軸まわりの回転を1枚にまとめた3D図。各軸の周りに右ねじ方向の回転矢印を描く Pitch(Y軸) Roll(X軸) Yaw(Z軸)
図6. 3軸回転(Roll・Pitch・Yaw)— 各オレンジ矢印は右ねじ(反時計回り)方向

注意(オイラー角の限界): Roll・Pitch・Yaw は航空宇宙分野由来の呼び方で、CV/CG では単に X 軸・Y 軸・Z 軸回りの回転と呼ぶことも多い。3つの回転を合成する順序(例: $R = R_z(\text{yaw})\,R_y(\text{pitch})\,R_x(\text{roll})$)は慣例により異なる。またオイラー角による表現にはジンバルロック(特定の姿勢で回転の自由度が1つ失われる現象)があり、滑らかな補間や特異点回避が必要な場面ではクォータニオンや回転行列を直接扱うことが多い。

剛体変換と相似変換

剛体変換(Rigid Transformation / Euclidean)

回転+平行移動。形状と大きさを保存(6自由度: 3回転 + 3並進)

$$\begin{pmatrix} \mathbf{R} & \mathbf{t} \\ \mathbf{0}^T & 1 \end{pmatrix}, \quad \mathbf{R} \in SO(3), \quad \mathbf{t} \in \mathbb{R}^3$$

相似変換(Similarity Transformation)

剛体変換+等方スケール。角度を保存(3Dで7自由度: 剛体6 + 等方スケール1)

$$\begin{pmatrix} s\mathbf{R} & \mathbf{t} \\ \mathbf{0}^T & 1 \end{pmatrix}, \quad s > 0$$

アフィン変換(Affine Transformation)

平行性を保存(3Dで12自由度: 線形部 $\mathbf{A}$ の9 + 並進 $\mathbf{t}$ の3)

$$\begin{pmatrix} \mathbf{A} & \mathbf{t} \\ \mathbf{0}^T & 1 \end{pmatrix}, \quad \mathbf{A} \in \mathbb{R}^{3 \times 3}$$

コード例(Python)

import numpy as np

def translation_matrix_2d(tx, ty):
    """2D平行移動行列"""
    return np.array([
        [1, 0, tx],
        [0, 1, ty],
        [0, 0, 1]
    ])

def rotation_matrix_2d(theta):
    """2D回転行列(ラジアン)"""
    c, s = np.cos(theta), np.sin(theta)
    return np.array([
        [c, -s, 0],
        [s,  c, 0],
        [0,  0, 1]
    ])

def scale_matrix_2d(sx, sy):
    """2Dスケール行列"""
    return np.array([
        [sx, 0, 0],
        [0, sy, 0],
        [0,  0, 1]
    ])

# 変換の合成: スケール → 回転 → 平行移動
S = scale_matrix_2d(2, 2)
R = rotation_matrix_2d(np.radians(45))
T = translation_matrix_2d(100, 50)
M = T @ R @ S  # 右から順に適用

# 点の変換
p = np.array([10, 20, 1])  # 同次座標
p_transformed = M @ p
print(f"変換後: ({p_transformed[0]:.1f}, {p_transformed[1]:.1f})")

# OpenCVでの使用
import cv2
# img: 入力画像(cv2.imread で読み込む)
height, width = img.shape[:2]
# 2x3のアフィン行列に変換
M_cv = M[:2, :]
img_transformed = cv2.warpAffine(img, M_cv, (width, height))

まとめ

  • 同次座標により、平行移動を含む変換を行列の積で表現
  • 2D変換は $3 \times 3$ 行列、3D変換は $4 \times 4$ 行列
  • 変換の合成は行列の積(右から順に適用)
  • 剛体変換は回転+平行移動(形状保存)
  • カメラの外部パラメータは剛体変換で表される