Search code examples
pythongraphics3dcomputer-vision

How to calculate 2d X-ray image projection given camera orientation (theta, phi, distance) and 3d object coordinates


I'm trying to recreate an X-ray projection

I have 3D coordinates of an object of shape (100,3), spherical coordinates of the camera (theta, phi, distance), distance from camera to image, and size of image (512x512)

There are plenty of tutorials out there but I am struggling to get plausible results

Here is what I have done so far

  1. Convert spherical to cartesian
def spherical_2_cartesian (phi, theta, p):

    x = p * np.sin(phi) * np.cos(theta)
    y = p * np.sin(phi) * np.sin(theta)
    z = p * np.cos(phi)
    
    return x,y,z

xa,ya,za = spherical_2_cartesian (23.1, 32.6, 730.0779523)
  1. Calculate extrinsic matrix via the 'look at' method
L = [xa,ya,za]
L = L / np.linalg.norm(L)
s = np.cross(L, [0,1,0])
s = s / np.linalg.norm(s)
u_prime = s * L
R = np.array([s, u_prime, -L])
t = np.dot(-R,[xa,ya,za])
extrinsic = np.column_stack((R, t))
  1. Define intrinsic matrix
f = 1066 ## distance from source to image plane
cx, cy = 512.0/2, 512.0/2 ## image size / 2
intrisic = np.array([[f, 0, cx], [0, f, cy], [0, 0, 1]])
  1. Convert 3d shape coords to homogenous, so shape is (100, 4)
mesh_homo = np.concatenate((mesh_coords,np.ones((len(mesh_coords),1))), axis=1)
  1. Calculate 3d shape coords in camera coordinate system.
mesh_in_camera_coords = np.dot(extrinsic,np.swapaxes(mesh_homo, 0, 1))
  1. Finally calculate projection and convert to x,y image coords
homogenous = np.dot(intrisic, mesh_in_camera_coords)
x = homogenous[0] / homogenous[2]
y = homogenous[1] / homogenous[2]

Can anyone see where I'm going wrong?


Solution

  • SOLVED: For those interested, the correct way to build an extrinsic matrix for angiographic x-ray is described in this paper:

    https://ieeexplore.ieee.org/document/6820797