개요

원근 투영(Perspective Projection)은 3D 그래픽스와 컴퓨터 비전에서 중요한 역할을 하는 변환 중 하나이다. 이 변환은 3차원 공간에 있는 점들을 2차원 평면에 투영시키는 방법으로, 카메라나 인간의 눈과 같은 관찰자 시점에서의 이미지를 생성하기 위해 사용된다. 원근 투영을 통해서, 멀리 있는 물체는 작게, 가까이 있는 물체는 크게 보이게 들어나 현실감 있는 시각 효과를 구현할 수 있다.

투영 변환 기초

원근 투영의 기본 원리는 3차원 공간에 있는 점을 관찰자의 위치에서 보이는 평면으로 변환하는 것이다. 이를 위해 다음의 요소들이 필요하다:

  1. 카메라 좌표계(Camera Coordinate System): 관찰자의 위치와 방향을 정의한다.
  2. 뷰 평면(View Plane): 투영되는 평면으로, 관찰자가 보는 2차원 이미지를 형성한다.
  3. 투영 중심(Projection Center): 보통 관찰자, 즉 카메라의 위치로 정의된다.
  4. 시야각(Field of View, FOV): 카메라가 인지할 수 있는 최대 각도.

수학적 모델링

3D 점 \mathbf{P} = (X, Y, Z)를 2D 점 \mathbf{p} = (x, y)로 투영하기 위해, 시점(Center of Projection, COP)을 \mathbf{C} = (0, 0, 0)라고 하겠다.

투영 변환

중심 투영에서 각 3D 점의 동차좌표는 다음과 같이 정의된다:

\mathbf{P}_h = \begin{bmatrix} X \\ Y \\ Z \\ 1 \end{bmatrix}

이 점을 원근 투영해 2D 평면으로 변환하는 과정은 다음의 변환 행렬 \mathbf{P}를 사용하여 표현된다:

\mathbf{P} = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & \frac{1}{d} & 0 \end{bmatrix}

여기서 d는 카메라와 뷰 평면 사이의 거리이다. 이 행렬을 3D 점 \mathbf{P}_h에 곱하면 다음과 같다:

\mathbf{P}'_h = \mathbf{P} \mathbf{P}_h
\mathbf{P}'_h = \begin{bmatrix} X \\ Y \\ Z \\ \frac{Z}{d} \end{bmatrix}

동차좌표 \mathbf{P}'_h를 2차원 평면으로 변환하기 위해서, 각 요소를 마지막 요소로 나누어 주면 다음과 같다:

\mathbf{p} = \begin{bmatrix} \frac{X}{Z/d} \\ \frac{Y}{Z/d} \end{bmatrix} = \begin{bmatrix} \frac{dX}{Z} \\ \frac{dY}{Z} \end{bmatrix}

이렇게 해서 원근 투영 변환이 완성된다. 원근 투영 변환식은 3D 점을 Z 축을 기준으로 스케일 변환을 하여 2D 평면 상의 위치를 결정하는 방식이다.


투영 변환을 통해서, 카메라의 시점에서 멀리 있는 물체는 작아지고, 가까이 있는 물체는 크게 보이는 원근감 있는 이미지를 얻을 수 있다. 이는 실제 눈으로 관찰할 때 느끼는 원근감을 그래픽상에서 재현하기 위해 매우 중요한 기법이다.

적용 사례

컴퓨터 그래픽

컴퓨터 그래픽에서 원근 투영은 매우 중요한 개념이다. 현실감 있는 3D 장면을 렌더링할 때, 원근 투영은 화면에 자연스러운 깊이 감을 부여한다. 게임, 애니메이션, 시각적 시뮬레이션에서의 카메라 시스템은 원근 투영을 사용하여 물체의 위치와 크기를 화면에 적절히 투영한다.

건축 및 디자인

건축과 디자인에서도 원근 투영은 중요한 도구이다. 설계자는 3D 모델을 2D 건축 도면으로 변환할 때 원근 투영을 사용한다. 이 과정에서 보는 시점에 따라 건물의 구조와 디자인 요소가 어떻게 보이는지 시뮬레이션할 수 있다.

한계와 확장

원근 투영은 현실감 있는 이미지를 생성하는 데 중요하지만 몇 가지 한계점이 있다:

  1. 왜곡(디스토션): 카메라의 시야각이 너무 넓거나 너무 좁을 때 원근 왜곡이 발생할 수 있다. 이는 주로 렌즈의 특성에 따른 문제이며, 이를 보정하는 다양한 기법이 존재한다.
  2. 선형 변환 아님: 원근 투영은 깊이 정보를 비선형적으로 변환하므로, 직선이 곡선으로 보일 수 있다. 이는 원근 투영의 특성상 발생하는 자연스러운 왜곡이다.

실습 예제

간단한 파이썬 코드 예제를 통해 원근 투영을 구현해보겠다. 이를 통해 원근 투영의 기본 개념을 손쉽게 이해하고, 실제로 어떻게 동작하는지 확인할 수 있다.

import numpy as np
import matplotlib.pyplot as plt

def perspective_projection(points, d):
    """
    points: 3D 점들의 배열 (N x 3)
    d: 카메라와 평면 사이의 거리
    """
    projected_points = []
    for point in points:
        x, y, z = point
        x_p = d * x / z
        y_p = d * y / z
        projected_points.append([x_p, y_p])
    return np.array(projected_points)

points_3d = np.array([
    [2, 3, 10],
    [4, 6, 15],
    [1, -2, 5],
    [-2, -4, 20]
])

d = 5

projected_points = perspective_projection(points_3d, d)

plt.scatter(projected_points[:, 0], projected_points[:, 1])
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Perspective Projection')
plt.grid(True)
plt.show()

위 코드에서는 perspective_projection 함수를 통해 3D 점들을 원근 투영해 2D 평면상의 점들로 변환하고, 이를 matplotlib를 사용해 시각화한다.


원근 투영은 현실감 있는 3D 그래픽 이미지와 시뮬레이션을 생성하는 데 필수적인 기술이다. 이 변환은 카메라나 인간의 시각 시스템을 모델링하여, 멀리 있는 물체가 작아지고 가까이 있는 물체가 크게 보이는 자연스러운 원근감을 재현한다. 보다 복잡한 응용과 더 나은 왜곡 보정을 통해 이 기법은 다양한 분야에서 계속 발전하고 있다.