Below is an implementation of a simple volume reconstruction module with DiffDRR.
Tip
As of v0.4.1, we can perform reconstruction with renderer="siddon". Note that for this to work, you have to use the default argument stop_gradients_through_grid_sample=True. For all prior versions of DiffDRR, you must use DRR(..., renderer="trilinear").
from diffdrr.pose import convertclass Reconstruction(torch.nn.Module):def__init__(self, subject, device):super().__init__()self.drr = DRR(subject, sdd=1020.0, height=200, delx=2.0).to(device=device)# Replace the known density with an initial estimateself.density = torch.nn.Parameter( torch.zeros(*subject.volume.spatial_shape, device=device) )def forward(self, pose, **kwargs): source, target =self.drr.detector(pose, None) img =self.drr.render(self.density, source, target)returnself.drr.reshape_transform(img, batch_size=len(pose))
3. Optimize!
Render DRRs from the given camera poses
Measure the loss between projected DRRs and the ground truth X-ray (here we use MSE)
After optimizing for 100 iterations, we get a DRR that matches the input X-ray… even after starting with a randomly initialized voxelgrid! This demonstrates that differentiable rendering for volume reconstruction works with DiffDRR. But have we actually reconstructed something useful?
Novel view synthesis
One way we can test the robustness of our reconstruction is by rendering DRRs from different poses.
First, let’s try bringing the C-arm 10 mm closer to the patient. Instantly, we can see that the intensities of the rendered images looks off…
These results should not be surprising. After all, we were trying to reconstruct a 3D volume from a single X-ray. Real reconstruction algorithms typically require >100 images to achieve good novel view synthesis. Methods that achieve reconstruction with <100 images typically have some neural shenanigans going on (which one can totally do with DiffDRR!).
So what did we reconstruct?
We visualize slices from the volume reconstructed with DiffDRR and the original CT. The results are amusing! The takeaway is that the volume we reconstructed is incredibly overfit to produce the target X-ray. Every other X-ray that one might want to render is going to suffer horrible artifacts because our reconstruction isn’t generalized at all.