Ljubljana dataset

PyTorch wrapper for the Ljubljana dataset with parsing of pose parameters

Ljubljana


source

LjubljanaDataset

 LjubljanaDataset (view:str,
                   filename:Union[str,pathlib.Path,NoneType]=None,
                   preprocess:bool=True)

Get X-ray projections and poses from specimens in the Ljubljana dataset.

Given a specimen ID and projection index, returns the projection and the camera matrix for DiffDRR.

Type Default Details
view str “ap” or “lat” or “ap-max” or “lat-max”
filename Union None Path to DeepFluoro h5 file
preprocess bool True Preprocess X-rays

Distribution over camera poses

We sample the three rotational and three translational parameters of \(\mathfrak{se}(3)\) from independent normal distributions defined with sufficient variance to capture wide perturbations from the isocenter.


source

get_random_offset

 get_random_offset (view, batch_size:int, device)

Fiducial markers

The LjubljanaDataset class also contains a method for evaluating the registration error for a predicted pose. Digital fiducial markers were placed along the centerlines of the vessels. Projecting them with predicted pose parameters can be used to measure their distance from the true fiducials.


source

Evaluator

 Evaluator (subject, idx)

Initialize self. See help(type(self)) for accurate signature.

Deep learning transforms

We transform X-rays and DRRs before inputting them to a deep learning model by

  • Rescaling pixels to [0, 1]
  • Resizing the images to a specified size
  • Normalizing pixels by the mean and std dev
Code
from tqdm import tqdm

mean, vars = [], []
for view in ["ap", "lat"]:
    specimen = LjubljanaDataset(view, filename="../../data/ljubljana.h5")
    for _, _, _, _, _, _, _, _, _, img, _, _ in tqdm(specimen, ncols=50):
        img = (img - img.min()) / (img.max() - img.min())
        mean.append(img.mean())
        vars.append(img.var())

print("Pixel mean :", sum(mean) / len(mean))
print("Pixel std dev :", (sum(vars) / len(vars)).sqrt())
100%|█████████████| 10/10 [00:12<00:00,  1.25s/it]
100%|█████████████| 10/10 [00:03<00:00,  2.76it/s]
Pixel mean : tensor(0.0774)
Pixel std dev : tensor(0.0569)

source

Transforms

 Transforms (height:int, width:int, eps:float=1e-06)

Transform X-rays and DRRs before inputting to CNN.

Examples

import matplotlib.pyplot as plt
from diffdrr.drr import DRR
from diffdrr.visualization import plot_drr
subject = LjubljanaDataset(view="ap", filename="../../data/ljubljana.h5")

for idx in range(len(subject)):
    (
        volume,
        spacing,
        focal_len,
        height,
        width,
        delx,
        dely,
        x0,
        y0,
        img,
        pose,
        isocenter_pose,
    ) = subject[idx]
    volume[volume < 500] = 0.0
    if idx == 5:
        volume[volume < 1000] = 0.0

    drr = DRR(
        volume,
        spacing,
        focal_len / 2,
        height // 8,
        delx * 8,
        width // 8,
        dely * 8,
        x0,
        y0,
        reverse_x_axis=True,
    ).cuda()
    transforms = Transforms(height // 8, width // 8)

    img = transforms(img).cuda()
    pred_img = drr(None, None, None, pose=pose.cuda())
    pred_img = transforms(pred_img)

    plt.figure(figsize=(12, 3))
    ax = plt.subplot(131)
    plot_drr(img, axs=ax, title="DSA")
    ax = plt.subplot(132)
    plot_drr(pred_img, axs=ax, title="DRR")
    ax = plt.subplot(133)
    plot_drr(img - pred_img, axs=ax, title="Difference", cmap="RdBu")
    plt.show()

subject = LjubljanaDataset(view="lat", filename="../../data/ljubljana.h5")

for idx in range(len(subject)):
    (
        volume,
        spacing,
        focal_len,
        height,
        width,
        delx,
        dely,
        x0,
        y0,
        img,
        pose,
        isocenter_pose,
    ) = subject[idx]
    volume[volume < 500] = 0.0
    if idx == 5:
        volume[volume < 1000] = 0.0

    drr = DRR(
        volume,
        spacing,
        focal_len / 2,
        height // 8,
        delx * 8,
        width // 8,
        dely * 8,
        x0,
        y0,
        reverse_x_axis=True,
    ).cuda()
    transforms = Transforms(height // 8, width // 8)

    img = transforms(img).cuda()
    pred_img = drr(None, None, None, pose=pose.cuda())
    pred_img = transforms(pred_img)

    plt.figure(figsize=(12, 3))
    ax = plt.subplot(131)
    plot_drr(img, axs=ax, title="DSA")
    ax = plt.subplot(132)
    plot_drr(pred_img, axs=ax, title="DRR")
    ax = plt.subplot(133)
    plot_drr(img - pred_img, axs=ax, title="Difference", cmap="RdBu")
    plt.show()