I am trying to rotate 3d point cloud data to theta degree using rotation matrix. The shape of point cloud data that is indicated as 'xyz' in code is (64,2048,3), so there are 131,072 points including x,y,z. I have tried with 2d rotation matrix (since I want to rotate in bird's eye view).
The 2d rotation matrix that I used is:
And this is my code for the rotation:
def rotation (xyz):
original_x = []
original_y = []
for i in range(64):
for j in range(2048):
original_x.append(xyz[i][j][0])
original_y.append(xyz[i][j][1])
original = np.matrix.transpose(np.array([original_x,original_y]))
rotation_2d = [[np.cos(theta), -np.sin(theta)],[np.sin(theta),np.cos(theta)]]
rotated_points = np.matmul(original,rotation_2d)
return rotated_points
The result looks successful from bird's eye view, but not successful from the front view, as it is very messy so it is not possible to understand the data.
I have also tried with 3d rotation matrix with [x,y,z] that is :
However, the result was exactly the same when 2d rotation matrix was used.
What could be the possible reason? Is there any mistake in the rotation method?
Here's a function that applies the rotation you're after and a demonstration of this code.
Note that the rotation is applied clockwise. For a counterclockwise rotation, use the transpose of the rotation matrix.
import numpy as np
import matplotlib.pyplot as plt
from scipy.linalg import block_diag
def rotation(xyz):
before = xyz.reshape((-1,3))
rot_3d = block_diag([[np.cos(theta), -np.sin(theta)],[np.sin(theta),np.cos(theta)]],1)
after = before @ rot_3d
return after
theta = 3*np.pi/2
xyz_test = np.random.rand(8,16)
xyz_test = np.stack([xyz_test]*3,axis = -1)
xyz_test += np.random.randn(8,16,3)*.1
original = xyz_test.reshape([8*16,3])
rotated = rotation(xyz_test)
# plt.plot(1,2,3,projection = '3d')
fig,ax = plt.subplots(figsize = (10,10), subplot_kw = {"projection":"3d"})
ax.plot3D(*original.T, 'x', ms = 20)
ax.plot3D(*rotated.T, 'x', ms = 20)
Sample resulting plot (of cloud and rotated cloud):