λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
πŸ“– Theory/Computer Vision

Equirectangular Image (λ“±μž₯λ°©ν˜• 이미지) μ„€λͺ… | 이미지 μ’Œν‘œ λ³€ν™˜ | κ΅¬λ©΄μ’Œν‘œ 벑터 계산

by 뭅즀 2024. 3. 29.
λ°˜μ‘ν˜•

 

Equirectangular image (λ“±μž₯λ°©ν˜• 이미지)


Equirectangular imageλŠ” ꡬ면 μ’Œν‘œκ³„λ₯Ό 직각 μ’Œν‘œκ³„λ‘œ λ§€ν•‘ν•œ μ΄λ―Έμ§€μž…λ‘œ ꡬ면 μ’Œν‘œκ³„μ˜ 각도λ₯Ό 직각 μ’Œν‘œκ³„μ˜ ν”½μ…€λ‘œ μΌλŒ€μΌ λ§€ν•‘ν•˜μ—¬ ν‘œν˜„ν•œλ‹€.

ꡬ면 μ’Œν‘œκ³„μ—μ„œλŠ” μœ„λ„(latitude)와 경도(longitude)둜 이미지λ₯Ό ν‘œν˜„ν•˜λŠ”λ°, μœ„λ„λŠ” ꡬ의 μˆ˜ν‰ λ°©ν–₯을 λ‚˜νƒ€λ‚΄λ©°, -90μ—μ„œ 90λ„κΉŒμ§€μ˜ λ²”μœ„λ₯Ό 가지고 κ²½λ„λŠ” ꡬ의 수직 λ°©ν–₯을 λ‚˜νƒ€λ‚΄λ©°, -180μ—μ„œ 180λ„κΉŒμ§€μ˜ λ²”μœ„λ₯Ό 가진닀. Equirectangular μ΄λ―Έμ§€λŠ” μ΄λŸ¬ν•œ ꡬ면 μ’Œν‘œκ³„λ₯Ό μ‚¬μš©ν•˜μ—¬ 이미지λ₯Ό ν‘œν˜„ν•œλ‹€. μ΄λ―Έμ§€μ˜ λ„ˆλΉ„λŠ” 360λ„μ˜ 경도 λ²”μœ„μ— λ§€ν•‘λ˜κ³ , λ†’μ΄λŠ” -90μ—μ„œ 90λ„μ˜ μœ„λ„ λ²”μœ„μ— λ§€ν•‘λœλ‹€. λ”°λΌμ„œ μ΄λ―Έμ§€μ˜ ν¬κΈ°λŠ” 경도와 μœ„λ„μ˜ 해상도에 따라 κ²°μ •λœλ‹€.

μ΄λŸ¬ν•œ Equirectangular μ΄λ―Έμ§€λŠ” 주둜 360도 λ™μ˜μƒ, 가상 ν˜„μ‹€(VR) 이미지, ν–‰μ„± ν‘œλ©΄ 이미지 λ“±κ³Ό 같은 κ΅¬ν˜• 데이터λ₯Ό ν‘œν˜„ν•˜λŠ” 데 μ‚¬μš©λ˜λŠ”λ°, μ΄λŸ¬ν•œ μ΄λ―Έμ§€λŠ” ꡬ면 μ’Œν‘œκ³„μ˜ νŠΉμ„±μ„ λ³΄μ‘΄ν•˜λ©΄μ„œλ„ 직각 μ’Œν‘œκ³„μ—μ„œμ˜ 이미지 처리 및 뢄석을 κ°€λŠ₯ν•˜κ²Œ ν•œλ‹€.

 

Equirectangular Image μ˜ˆμ‹œ

 

 

κ΅¬λ©΄μ’Œν‘œκ³„ λ³€ν™˜

 

Equirectangular imageλŠ” κ°€λ‘œ(x) 360도, μ„Έλ‘œ(y) 180λ„μ˜ λ²”μœ„λ₯Ό 가지기 λ•Œλ¬Έμ— ꡬ면 μ’Œν‘œκ³„λ‘œ λ³€ν™˜ν•  수 μžˆλ‹€. 

이미지 μ’Œν‘œλ₯Ό 0~1 μ‚¬μ΄λ‘œ μ •κ·œν™”ν•˜κ³  μœ„λ„(latitude)와 경도(longtitude)λ₯Ό μœ„μ™€ 같이 κ³„μ‚°ν•˜λ©΄ λœλ‹€.

 

 

 

ꡬ면 μ’Œν‘œκΉŒμ§€μ˜ 3D 벑터

 

 

카메라 μ€‘μ‹¬μ—μ„œ ꡬ면 μ’Œν‘œ μ§€μ κΉŒμ§€μ˜ 3D 벑터λ₯Ό 계산할 수 μžˆλŠ”λ°, μœ„μ™€ 같이 μ§κ°μ’Œν‘œκ³„ μ’Œν‘œ(x, y, z)λ₯Ό κ΅¬ν•˜κ³  벑터λ₯Ό 계산할 수 μžˆλ‹€.

import numpy as np

def image_to_spherical_coordinates(x_image, y_image, image_width, image_height):
    # Normalize image coordinates to the range [0, 1]
    x_normalized = x_image / (image_width - 1)
    y_normalized = y_image / (image_height - 1)
    
    # Calculate latitude (elevation) and longitude (azimuth) from normalized image coordinates
    phi = np.pi * y_normalized
    theta = 2 * np.pi * x_normalized
    
    return phi, theta

def spherical_to_cartesian(phi, theta, r):
    x = r * np.sin(phi) * np.cos(theta)
    y = r * np.sin(phi) * np.sin(theta)
    z = r * np.cos(phi)
    return np.array([x, y, z])

def relative_vector_from_image_coordinates(x_image, y_image, image_width, image_height, camera_center, radius):
    # Convert image coordinates to spherical coordinates
    phi, theta = image_to_spherical_coordinates(x_image, y_image, image_width, image_height)
    
    # Convert spherical coordinates to Cartesian coordinates
    vector = spherical_to_cartesian(phi, theta, radius)
    
    # Calculate relative vector from camera center to the point
    relative_vector = vector - camera_center
    
    return relative_vector

# Example inputs
x_image = 100  # Example image x-coordinate
y_image = 50  # Example image y-coordinate
image_width = 800  # Example image width
image_height = 600  # Example image height
camera_center = np.array([0, 0, 0])  # Example camera center
radius = 1  # Example radius

# Calculate the relative vector
relative_vector = relative_vector_from_image_coordinates(x_image, y_image, image_width, image_height, camera_center, radius)
print("Relative vector:", relative_vector)

 

 

 

카메라 roll & pitch & yawλ₯Ό μ΄μš©ν•œ μ ˆλŒ€ μ’Œν‘œ 벑터 λ³€ν™˜

 

ν˜„μž¬κΉŒμ§€ κ³„μ‚°ν•œ λ²‘ν„°λŠ” 이미지 κΈ°μ€€μœΌλ‘œ κ³„μ‚°ν•œ μƒλŒ€ μ’Œν‘œ 벑터이닀. λ•Œλ¬Έμ— μ ˆλŒ€ μ’Œν‘œ 벑터λ₯Ό μ–»κΈ° μœ„ν•΄μ„œλŠ” 카메라 νšŒμ „ 각도인 roll, pitch, yawλ₯Ό μ΄μš©ν•˜μ—¬ ꡬ면 μ’Œν‘œμƒμ˜ 벑터λ₯Ό νšŒμ „ν•΄μ•Ό ν•œλ‹€.

import numpy as np
from scipy.spatial.transform import Rotation

def spherical_to_cartesian(phi, theta, r):
    x = r * np.sin(phi) * np.cos(theta)
    y = r * np.sin(phi) * np.sin(theta)
    z = r * np.cos(phi)
    return np.array([x, y, z])

def absolute_vector_from_spherical(phi, theta, r, camera_center, roll, pitch, yaw):
    # Convert spherical coordinates to Cartesian coordinates
    vector = spherical_to_cartesian(phi, theta, r)
    
    # Create a rotation object using Euler angles (roll, pitch, yaw)
    r = Rotation.from_euler('xyz', [roll, pitch, yaw], degrees=True)
    
    # Rotate the vector
    rotated_vector = r.apply(vector)
    
    # Translate the rotated vector to the camera center
    absolute_vector = rotated_vector + camera_center
    
    return absolute_vector

# Example inputs
phi = np.pi/4  # Example elevation
theta = np.pi/4  # Example azimuth
r = 1  # Example radius
camera_center = np.array([0, 0, 0])  # Example camera center
roll = 30  # Example roll angle in degrees
pitch = 45  # Example pitch angle in degrees
yaw = 60  # Example yaw angle in degrees

# Calculate the absolute vector
absolute_vector = absolute_vector_from_spherical(phi, theta, r, camera_center, roll, pitch, yaw)
print("Absolute vector:", absolute_vector)
λ°˜μ‘ν˜•