1

After reading this post, I could make the rotated image on x,y,z axis using following code:

import numpy as np
import cv2


def get_3d_rotation_matrix(width, height, theta, phi, gamma, dx, dy, dz):
    w, h = width, height
    d = np.sqrt(w ** 2 + h ** 2)
    focal = f = d / (2 * np.sin(gamma) if np.sin(gamma) != 0 else 1)
    dz = focal

    # Projection 2D -> 3D matrix
    A1 = np.array([[1, 0, -w / 2],
                   [0, 1, -h / 2],
                   [0, 0, 1],
                   [0, 0, 1]])

    # Rotation matrices around the X, Y, and Z axis
    RX = np.array([[1, 0, 0, 0],
                   [0, np.cos(theta), -np.sin(theta), 0],
                   [0, np.sin(theta), np.cos(theta), 0],
                   [0, 0, 0, 1]])

    RY = np.array([[np.cos(phi), 0, -np.sin(phi), 0],
                   [0, 1, 0, 0],
                   [np.sin(phi), 0, np.cos(phi), 0],
                   [0, 0, 0, 1]])

    RZ = np.array([[np.cos(gamma), -np.sin(gamma), 0, 0],
                   [np.sin(gamma), np.cos(gamma), 0, 0],
                   [0, 0, 1, 0],
                   [0, 0, 0, 1]])

    # Composed rotation matrix with (RX, RY, RZ)
    R = np.dot(np.dot(RX, RY), RZ)

    # Translation matrix
    T = np.array([[1, 0, 0, dx],
                  [0, 1, 0, dy],
                  [0, 0, 1, dz],
                  [0, 0, 0, 1]])

    # Projection 3D -> 2D matrix
    A2 = np.array([[f, 0, w / 2, 0],
                   [0, f, h / 2, 0],
                   [0, 0, 1, 0]])

    # Final transformation matrix
    return np.dot(A2, np.dot(T, np.dot(R, A1)))


def get_image_3d_rotated(image, theta, phi, gamma, dx, dy, dz):
    height, width, _ = image.shape
    rtheta, rphi, rgamma = np.deg2rad(theta), np.deg2rad(phi), np.deg2rad(gamma)
    mat = get_3d_rotation_matrix(width, height, rtheta, rphi, rgamma, dx, dy, dz)

    return cv2.warpPerspective(image.copy(), mat, (width, height))


if __name__ == '__main__':
    image = cv2.imread('1.jpg')
    rotated_img = get_image_3d_rotated(image, 15, 16, 17, 0, 0, 0)

My question is, where I know 3d rotation angle of the image, is there way to get rectified image like original? I tried to re-rotated the warped image with negative degrees on each x,y,z axis, but I couldn't get satisfied result.

  1. Original image:
    enter image description here

  2. Warped image rotated 15 degree on x-axis, 16 degree y-axis, 17 degree z-axis: enter image description here

  3. Re-rotated image 2 with -15 degree on x-axis, -16 degree y-axis, -17 degree z-axis: enter image description here

But the third image still looks tilted towards the y-axis.

YeongHwa Jin
  • 435
  • 5
  • 15
  • 2
    I haven't digged deeply into it, but the issue might be linked to the fact that the rotations are not commutative. So if you do `res=A(B(C(img)))` do `Ainv(Binv(Cinv(res)))` – user_na May 10 '21 at 15:48
  • @user_na your advice make sense, but projection matrix A1, A2 in code are 4x3, 3x4 matrix, so doesn't have inverse matrix. How can solve it? – YeongHwa Jin May 11 '21 at 08:07
  • work with 3x3 homographies for plane-to-plane mapping (which can model any 3D transformation between (projected) planes), or stick with 4x4 matrices for more general 3d transformations. – Christoph Rackwitz Nov 01 '21 at 18:09

0 Answers0