Skip to content

Instantly share code, notes, and snippets.

@ThomasParistech
Last active August 22, 2025 15:49
Show Gist options
  • Save ThomasParistech/8dc6de09701955ca1a46bd5c65182089 to your computer and use it in GitHub Desktop.
Save ThomasParistech/8dc6de09701955ca1a46bd5c65182089 to your computer and use it in GitHub Desktop.
Tilt/Pan a 360 image
import cv2
import numpy as np
# Load input 360 image
img = cv2.imread("my_360_image.png")
h, w = img.shape[:2]
# Select arbitrary rotation angles
d_theta = 0.2 * np.pi
d_phi = 0.1 * np.pi
# Compute the transformation maps
x_grid, y_grid = np.meshgrid(0.5+np.arange(w),
0.5+np.arange(h),
indexing="xy")
theta_1 = (x_grid / w - 0.5) * 2*np.pi
phi_1 = (y_grid / h - 0.5) * np.pi
px = np.cos(phi_1)*np.sin(theta_1 - d_theta)
py = np.cos(d_phi)*np.sin(phi_1) - np.sin(d_phi)*np.cos(phi_1)*np.cos(theta_1-d_theta)
pz = np.sin(d_phi)*np.sin(phi_1) + np.cos(d_phi)*np.cos(phi_1)*np.cos(theta_1-d_theta)
phi_0 = np.arcsin(py)
theta_0 = np.arctan2(px, pz)
map_x = w * (0.5 + theta_0 / (2*np.pi))
map_y = h * (0.5 + phi_0 / np.pi)
# Generate the transformed image using cv2.remap
map_x -= 0.5 # Opencv shift
map_y -= 0.5
transformed_img = cv2.remap(img,
map_x.astype(np.float32),
map_y.astype(np.float32),
cv2.INTER_CUBIC,
borderMode=cv2.BORDER_WRAP)
# Display the results
cv2.imshow("Input image", img)
cv2.imshow("Transformed Image", transformed_img)
cv2.waitKey(0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment