Skip to content

Commit 59c9d2d

Browse files
authored
Fix Ljubljana preprocessing (#19)
* Fix Ljubljana preprocessing * Remove unused inputs * Update README * Switch DeepFluoro orientation to PA * Rotate pose * Rerun notebooks * Move dim flip
1 parent 0a4ea2f commit 59c9d2d

9 files changed

Lines changed: 147 additions & 144 deletions

File tree

README.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# DiffDRR Datasets
2-
1+
DiffDRR Datasets
2+
================
33

44
<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->
55

@@ -90,15 +90,14 @@ drr = DRR(
9090
deepfluoro.delx * subsample,
9191
x0=deepfluoro.x0,
9292
y0=deepfluoro.y0,
93-
reverse_x_axis=False,
9493
)
9594
transform = Transforms(deepfluoro.height // subsample)
9695

9796
# Render a DRR from the ground truth camera pose
9897
gt, pose = deepfluoro[0]
9998
img = drr(pose)
10099
gt, img = transform(gt), transform(img)
101-
plot_drr(torch.concat([gt, img]), title=["Downsampled X-ray", "DRR"])
100+
plot_drr(torch.concat([gt, img, gt - img]), title=["Downsampled X-ray", "DRR", "Difference"])
102101
plt.show()
103102
```
104103

@@ -141,7 +140,7 @@ drr = DRR(
141140
delx * subsample,
142141
width // subsample,
143142
dely * subsample,
144-
x0=-x0,
143+
x0=x0,
145144
y0=y0,
146145
reverse_x_axis=False,
147146
)
@@ -150,7 +149,7 @@ transform = Transforms(height // subsample, width // subsample)
150149
# Render a DRR from the ground truth camera pose
151150
img = drr(pose)
152151
gt, img = transform(gt), transform(img)
153-
plot_drr(torch.concat([gt, img]), title=["Downsampled X-ray", "DRR"])
152+
plot_drr(torch.concat([gt, img, gt - img]), title=["Downsampled X-ray", "DRR", "Difference"])
154153
plt.show()
155154
```
156155

diffdrrdata/deepfluoro.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@
99
import h5py
1010
import numpy as np
1111
import torch
12-
from diffdrr.data import read
13-
from diffdrr.pose import RigidTransform
14-
from diffdrr.utils import parse_intrinsic_matrix
1512
from torchio import LabelMap, ScalarImage, Subject
1613
from torchio.transforms.preprocessing import ToCanonical
1714
from torchvision.transforms.functional import center_crop, gaussian_blur
1815

16+
from diffdrr.data import read
17+
from diffdrr.pose import RigidTransform
18+
from diffdrr.utils import parse_intrinsic_matrix
19+
1920
from .utils import load_file
2021

2122
# %% ../notebooks/00_deepfluoro.ipynb 6
@@ -64,7 +65,7 @@ def __init__(
6465
torch.tensor(
6566
[
6667
[0, 1, 0, 0],
67-
[1, 0, 0, 0],
68+
[-1, 0, 0, 0],
6869
[0, 0, -1, 0],
6970
[0, 0, 0, 1],
7071
]
@@ -93,10 +94,12 @@ def __getitem__(self, idx):
9394
pose = self.projections[f"{idx:03d}/gt-poses/cam-to-pelvis-vol"][:]
9495
pose = RigidTransform(torch.from_numpy(pose))
9596
pose = (
96-
self.flip_z
97+
self.rot_180
98+
.compose(self.flip_z)
9799
.compose(self.world2camera.inverse())
98100
.compose(pose)
99101
.compose(self.anatomical2world)
102+
.compose(self.rot_180)
100103
)
101104
if self.rot_180_for_up(idx):
102105
img = torch.rot90(img, k=2)
@@ -118,11 +121,11 @@ def parse_volume(subject, bone_attenuation_multiplier, labels):
118121
# Get all parts of the volume
119122
volume = subject["vol/pixels"][:]
120123
volume = np.swapaxes(volume, 0, 2).copy()
121-
volume = torch.from_numpy(volume).unsqueeze(0)
124+
volume = torch.from_numpy(volume).unsqueeze(0).flip(1).flip(2)
122125

123126
mask = subject["vol-seg/image/pixels"][:]
124127
mask = np.swapaxes(mask, 0, 2).copy()
125-
mask = torch.from_numpy(mask).unsqueeze(0)
128+
mask = torch.from_numpy(mask).unsqueeze(0).flip(1).flip(2)
126129

127130
affine = np.eye(4)
128131
affine[:3, :3] = subject["vol/dir-mat"][:]
@@ -161,10 +164,13 @@ def parse_volume(subject, bone_attenuation_multiplier, labels):
161164
volume=volume,
162165
labelmap=labelmap,
163166
labels=labels,
167+
orientation="PA",
164168
bone_attenuation_multiplier=bone_attenuation_multiplier,
165169
label_def=defns,
166170
fiducials=fiducials,
167171
)
172+
reorient = RigidTransform(torch.diag(torch.tensor([-1.0, -1.0, 1.0, 1.0])))
173+
subject.fiducials = reorient(subject.fiducials)
168174

169175
return subject, anatomical2world
170176

diffdrrdata/ljubljana.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ def __getitem__(self, idx):
5757
)
5858

5959
if self.preprocess:
60-
img += 1
60+
img = img - img.mode().values.mode().values.item() # Subtract background color
61+
img = torch.clamp(img, -1, 0) + 1 # Restrict to [0, 1]
62+
img += 1 # Convert to log-scale
6163
img = img.max().log() - img.log()
6264

6365
pose = (
@@ -75,9 +77,9 @@ def parse_volume(f, subject_id):
7577

7678
# Get the volume
7779
volume = subject["volume/pixels"][:]
78-
volume = volume[::-1].copy()
79-
volume = torch.from_numpy(volume).unsqueeze(0)
80-
volume[volume < 250] = -1000.0
80+
volume = volume.copy()
81+
volume = torch.from_numpy(volume).unsqueeze(0).flip(1)
82+
volume[volume < 1000] = 0.0 # Discard a lot of the background from the 3D DSA
8183

8284
affine = np.eye((4))
8385
spacing = subject["volume/spacing"][:]
@@ -162,7 +164,7 @@ def __init__(self, height: int, width: int, eps: float = 1e-6):
162164
[
163165
Lambda(lambda x: (x - x.min()) / (x.max() - x.min() + eps)),
164166
Resize((height, width), antialias=True),
165-
Normalize(mean=0.0774, std=0.0569),
167+
Normalize(mean=0.0306, std=0.0564),
166168
]
167169
)
168170

-28.3 KB
Loading
-32.5 KB
Loading

notebooks/00_deepfluoro.ipynb

Lines changed: 82 additions & 87 deletions
Large diffs are not rendered by default.

notebooks/01_ljubljana.ipynb

Lines changed: 31 additions & 29 deletions
Large diffs are not rendered by default.

notebooks/deepfluoro_camera_poses.html

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

notebooks/index.ipynb

Lines changed: 7 additions & 8 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)