title: 3D image rotation in python
body: <p>I have the following image I1. I did not capture it. I downloaded it from Google</p>
  
  <p><a href="https://i.stack.imgur.com/SBLIu.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/SBLIu.jpg" alt="enter image description here"></a></p>
  
  <p>I apply a known homography h to I1 to obtain the following image I2.</p>
  
  <p><a href="https://i.stack.imgur.com/157TY.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/157TY.jpg" alt="enter image description here"></a></p>
  
  <p>I want to assume that a camera has taken this above shot of I2. I have found the camera matrix of this "camera". Let this camera matrix be <code>k</code>. Now, I want to rotate this image I2 about the camera axis. According to the explanation in the accepted answer in <a href="https://stackoverflow.com/questions/47990350/python-rotate-image-about-camera-axis">this question</a>, I need to set the rotation matrix R and then perform <code>k*R*inv(k)*h</code> on image I1 to get the required rotated image I3. </p>
  
  <p>I have been facing problems when I try to set this rotation matrix R. I have used <a href="https://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle" rel="noreferrer">this method</a> to set the matrix R. </p>
  
  <p>To test my code, I initially tried to rotate the image around the z-axis by 10 degrees but I wasn't getting the correct output.</p>
  
  <p>My partial Python code: </p>
  
  <pre><code>theta_in_degrees = 10
  theta_in_radians = theta_in_degrees*math.pi/180
  ux=0.0 
  uy=0.0 
  uz=1.0 
  vector_normalize_factor = math.sqrt(ux*ux+uy*uy+uz*uz)
  ux=ux/vector_normalize_factor
  uy=uy/vector_normalize_factor
  uz=uz/vector_normalize_factor
  print "ux*ux+uy*uy+uz*uz = ", ux*ux+uy*uy+uz*uz 
  rotation_matrix = np.zeros([3,3])
  c1 = math.cos(theta_in_radians)
  c2 = 1-c1
  s1 = math.sin(theta_in_radians)
  rotation_matrix[0][0] = c1+ux*ux*c2
  rotation_matrix[0][1] = ux*uy*c2-uz*s1
  rotation_matrix[0][2] = ux*uz*c2+uy*s1
  rotation_matrix[1][0] = uy*ux*c2+uz*s1
  rotation_matrix[1][1] = c1+uy*uy*c2
  rotation_matrix[1][2] = uy*uz*c2-ux*s1
  rotation_matrix[2][0] = uz*ux*c2-uy*s1
  rotation_matrix[2][1] = uz*uy*c2+ux*s1
  rotation_matrix[2][2] = c1+uz*uz*c2
  print "rotation_matrix = ", rotation_matrix
  R = rotation_matrix
  #Calculate homography H1 between reference top view and rotated frame
  k_inv = np.linalg.inv(k)
  Hi = k.dot(R)
  Hii = k_inv.dot(h)
  H1 = Hi.dot(Hii)
  print "H1 = ", H1
  im_out = cv2.warpPerspective(im_src, H1, (im_dst.shape[1],im_dst.shape[0]))
  </code></pre>
  
  <p>Here, <code>img_src</code> is the source of I1.</p>
  
  <p>The result I got when I tried the above code is a black image with no part of the image visible. However, when I changed the value of <code>theta_in_degrees</code> to the following values, these were my outputs:</p>
  
  <p>0.00003</p>
  
  <p><a href="https://i.stack.imgur.com/tz1Rp.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/tz1Rp.jpg" alt="enter image description here"></a></p>
  
  <p>0.00006</p>
  
  <p><a href="https://i.stack.imgur.com/MiWIC.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/MiWIC.jpg" alt="enter image description here"></a></p>
  
  <p>0.00009</p>
  
  <p><a href="https://i.stack.imgur.com/3bT8k.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/3bT8k.jpg" alt="enter image description here"></a></p>
  
  <p>Why is the rotation working only for such small values of <code>theta_in_degrees</code>? Also, the rotation visible in the images is not actually happening around the z-axis. Why isn't the image rotating about the z-axis? Where am I going wrong and how can I fix these issues?</p>
  
  <p>h matrix:</p>
  
  <pre><code>[[  1.71025842e+00  -7.51761942e-01   1.02803446e+02]
   [ -2.98552735e-16   1.39232576e-01   1.62792482e+02]
   [ -1.13518150e-18  -2.27094753e-03   1.00000000e+00]]
  </code></pre>
  
  <p>k matrix:</p>
  
  <pre><code>[[  1.41009391e+09   0.00000000e+00   5.14000000e+02]
   [  0.00000000e+00   1.78412347e+02   1.17000000e+02]
   [  0.00000000e+00   0.00000000e+00   1.00000000e+00]]
  </code></pre>
  
  <p><strong>Edit:</strong></p>
  
  <p>After incorporating the suggestion by Toby Collins, I set the top left value of <code>k</code> to be the same as <code>k[1][1]</code>. When I now perform rotation about the z-axis, I get the correct rotated images for all values of <code>theta_in_degrees</code> from 0 to 360. However, when I try to rotate the image about the y-axis by changing the ux, uy and uz in the above code to the following, I get absurd rotation results:</p>
  
  <pre><code>ux=0.0 
  uy=1.0 
  uz=0.0 
  </code></pre>
  
  <p>Some samples for different values of <code>theta_in_degrees</code> and the corresponding results for rotation about the y-axis are shown below:</p>
  
  <p>-10</p>
  
  <p><a href="https://i.stack.imgur.com/5kJ41.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/5kJ41.jpg" alt="enter image description here"></a></p>
  
  <p>-40</p>
  
  <p><a href="https://i.stack.imgur.com/KGAC8.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/KGAC8.jpg" alt="enter image description here"></a></p>
  
  <p>-90</p>
  
  <p><a href="https://i.stack.imgur.com/LVJIw.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/LVJIw.jpg" alt="enter image description here"></a></p>
  
  <p>-110</p>
  
  <p><a href="https://i.stack.imgur.com/EIHIo.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/EIHIo.jpg" alt="enter image description here"></a></p>
  
  <p>Where am I still going wrong? Also, why is there such a huge drop in the length and width of successive yellow stripes in a rotated image? And why does a part of the image wrap around (for example, the results of rotation by -90 and -110 degrees)?</p>
  
  <p>The second part of my question is this: The vector equation of my axis of rotation is <code>(320, 0, -10)+t(0, 1, 0)</code>. In order to use <a href="https://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle" rel="noreferrer">this method</a>, to calculate the rotation matrix, I need to define the <code>ux</code>, <code>uy</code> and <code>uz</code> of the axis of rotation such that <code>ux^2+uy^2+uz^2=1</code>. This would be straightforward if the rotation needs to be done around one of the coordinate axes (as I am currently doing for testing purposes). But how do I get these values of <code>ux</code>, <code>uy</code> and <code>uz</code> if the <code>t</code> in the vector equation of my rotation axis is variable? I am also open to suggestions regarding any other approaches to finding a suitable rotation matrix R such that the rotation happens around the axis I have mentioned (say, by x degrees).</p>