from inspect import getfile
from pathlib import Path
import deepdrr
import matplotlib.pyplot as plt
import numpy as np
import torch
from deepdrr import MobileCArm, Projector, Volume, geo
from deepdrr.load_dicom import load_dicom
from diffdrr.detector import diffdrr_to_deepdrr
from diffdrr.drr import DRR
from diffdrr.metrics import NormalizedCrossCorrelation2d
Converting to DeepDRR
It just involves changing the order of Euler angles
= 400
SDR = 4.0 P
# Load a DICOM and extract voxel information
= str(Path(getfile(DRR)).parent / "data/cxr") + "/"
example_ct_path = load_dicom(example_ct_path)
volume, materials, spacing
# Make volume conventions same as DiffDR
= lambda x: np.rot90(x, -1)[:, ::-1]
preprocess = preprocess(volume)
volume for key, value in materials.items():
= preprocess(value)
materials[key]
# Use the center of the volume as the "world" coordinates. The origin is the (0, 0, 0) index of the volume in the world frame.
= (np.array(volume.shape) - 1) / 2 * spacing
vol_center = geo.point(-vol_center[0], -vol_center[1], -vol_center[2])
origin
# Create the volume object with segmentation
= Volume.from_parameters(
patient =volume,
data=materials,
materials=origin,
origin=spacing,
spacing="LPS",
anatomical_coordinate_system
)=True, supine=True) patient.orient_patient(head_first
Using downloaded and verified file: /home/vivekg/datasets/DeepDRR_DATA/model_segmentation.pth.tar
# defines the C-Arm device, which is a convenience class for positioning the Camera.
# isocenter=volume.center_in_world
= MobileCArm(
carm =patient.center_in_world,
isocenter=False,
rotate_camera_left=SDR * 2,
source_to_detector_distance=SDR,
source_to_isocenter_vertical_distance=P,
pixel_size=256,
sensor_height=256,
sensor_width=-720,
min_alpha=720,
max_alpha=-720,
min_beta=720,
max_beta
)
def test_phantom_deepdrr(alpha, beta, gamma):
with Projector(
=patient,
volume=carm,
carmas projector:
)
carm.move_to(=np.rad2deg(alpha),
alpha=np.rad2deg(np.pi / 2 - beta),
beta=np.rad2deg(-gamma),
gamma=True,
degrees
)= (
img
projector()# The first run doesn't use updated parameters, for some reason?
) = projector()[:, ::-1].copy()
img return img
def test_phantom_diffdrr(alpha, beta, gamma, sdr=SDR, p=P):
= (torch.tensor(volume.shape) - 1) * torch.tensor(spacing) / 2
bx, by, bz = DRR(volume, spacing, sdr=SDR, height=256, delx=P, convention="deepdrr")
drr = drr(
img
diffdrr_to_deepdrr(torch.tensor([[alpha, beta, gamma]])),
torch.tensor([[bx, by, bz]]),="euler_angles",
parameterization="YZX",
convention
)= img / img.max()
img return img
for idx in range(5):
= np.random.uniform(-torch.pi, torch.pi)
alpha = np.random.uniform(-torch.pi, torch.pi)
beta = np.random.uniform(-torch.pi, torch.pi)
gamma = test_phantom_diffdrr(alpha, beta, gamma).squeeze().numpy()
diff = test_phantom_deepdrr(alpha, beta, gamma)
deep = NormalizedCrossCorrelation2d()(
metric
torch.tensor(diff[np.newaxis, np.newaxis, ...]),
torch.tensor(deep[np.newaxis, np.newaxis, ...]),
).item()
=(12, 3))
plt.figure(figsize131)
plt.subplot("DiffDRR")
plt.title(="gray")
plt.imshow(diff, cmap
plt.colorbar()132)
plt.subplot("DeepDRR")
plt.title(="gray")
plt.imshow(deep, cmap
plt.colorbar()133)
plt.subplot(f"NCC = {metric:.5g}")
plt.title(- diff, cmap="gray")
plt.imshow(deep
plt.colorbar()
plt.tight_layout() plt.show()