[18]:
import numpy as np
import matplotlib.pyplot as plt
import torch
from torchvision.transforms.functional import rotate
from pytomography.utils import rotate_detector_z
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
Last Time#
We implemented \(g=Hf\) on an object \(f\) and for the case of a system matrix \(H\) that doesn’t model any phenomena
[3]:
x = torch.linspace(-1,1,128)
xv, yv, zv = torch.meshgrid(x,x,x, indexing='ij')
obj = (xv**2 + 0.9*zv**2 < 0.5) * (torch.abs(yv)<0.8)
obj = obj.to(torch.float).unsqueeze(dim=0)
angles = np.arange(0,360.,3)
image = torch.zeros((1,len(angles),128,128))
for i,angle in enumerate(angles):
object_i = rotate_detector_z(obj,angle)
image[:,i] = object_i.sum(axis=1)
[4]:
plt.pcolormesh(image[0,:,:,64].T)
plt.xlabel('Angle')
plt.ylabel('r')
[4]:
Text(0, 0.5, 'r')

This Time#
We’ll talk about how to model \(\hat{f} = H^T g\) for the same operator \(H\). This time, we’ll start by creating an empty object. I claim that the following implements back projection from a single angle:
[22]:
image[:,0].unsqueeze(dim=1).shape
[22]:
torch.Size([1, 1, 128, 128])
[23]:
bp_single_angle = torch.ones([1, 128, 128, 128]) * image[:,0].unsqueeze(dim=1)
Example: If forward projection is
then back projection is
So there is an element of duplication going on.
Nopw I need to back project for each angle, and rotate the coordinate system back to the original object coordinate axes, and add everything together
[24]:
obj_bp = torch.zeros([1, 128, 128, 128])
for i,angle in enumerate(angles):
bp_single_angle = torch.ones([1, 128, 128, 128]) * image[:,i].unsqueeze(dim=1)
bp_single_angle = rotate_detector_z(bp_single_angle, angle, negative=True)
obj_bp += bp_single_angle
Just like we did for obj
in tutorial 1, we’ll look at different projections for obj_bp
[25]:
fig, _ = plt.subplots(1,3,figsize=(10,3))
plt.subplot(131)
plt.pcolormesh(x,x,obj_bp[0].sum(axis=0).T, cmap='Greys_r')
plt.xlabel('y')
plt.ylabel('z')
plt.title('Coronal')
plt.subplot(132)
plt.pcolormesh(x,x,obj_bp[0].sum(axis=1).T, cmap='Greys_r')
plt.xlabel('x')
plt.ylabel('z')
plt.title('Sagittal')
plt.subplot(133)
plt.pcolormesh(obj_bp[0].sum(axis=2).T, cmap='Greys_r')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Axial')
fig.tight_layout()

Clearly theres some blurring going on: \(H^T g\) does not give the original object \(f\) (if it did, then our job would be easy, and there’d be no need for reconstruction algorithms).