Skip to content

Registration

nanodrr.registration

Registration

Registration(
    subject: Subject,
    rt_inv: Float[Tensor, "B 4 4"],
    k_inv: Float[Tensor, "B 3 3"],
    sdd: Float[Tensor, B],
    height: int,
    width: int,
    eps: float = 1e-08,
)

Differentiable 2D/3D registration module.

Optimize poses in SE(3) by aligning rendered X-rays with real target X-ray images. Initial intrinsic and extrinsic matrices are fixed at construction. Optimizable parameters are parameterized as perturbations.

PARAMETER DESCRIPTION
subject

The volume to render DRRs from during optimization.

TYPE: Subject

rt_inv

Initial inverse extrinsic (camera-to-world) matrix.

TYPE: Float[Tensor, 'B 4 4']

k_inv

Inverse intrinsic camera matrix.

TYPE: Float[Tensor, 'B 3 3']

sdd

Source-to-detector distance.

TYPE: Float[Tensor, B]

height

Output image height in pixels.

TYPE: int

width

Output image width in pixels.

TYPE: int

eps

Small constant for numerical stability.

TYPE: float DEFAULT: 1e-08

Source code in src/nanodrr/registration/registration.py
def __init__(
    self,
    subject: Subject,
    rt_inv: Float[torch.Tensor, "B 4 4"],
    k_inv: Float[torch.Tensor, "B 3 3"],
    sdd: Float[torch.Tensor, "B"],
    height: int,
    width: int,
    eps: float = 1e-8,
) -> None:
    super().__init__()
    self.subject = subject
    self.register_buffer("rt_inv", rt_inv)
    self.register_buffer("k_inv", k_inv)
    self.register_buffer("sdd", sdd)
    self.height = height
    self.width = width

    # Parameterize the perturbation about the isocenter rather than the world origin
    c = transform_point(rt_inv.inverse(), subject.isocenter[None])
    self.register_buffer("pivot", self._make_translation(c))
    self.register_buffer("pivot_inv", self._make_translation(-c))

    # Parameterization of the perturbation
    self._rot = torch.nn.Parameter(eps * torch.randn(1, 3, device=c.device))
    self._xyz = torch.nn.Parameter(eps * torch.randn(1, 3, device=c.device))

pose property

pose: Float[Tensor, 'B 4 4']

Change of basis about the volume's isocenter.

rescale_

rescale_(scale: float) -> None

Change the rendering resolution by rescaling the camera's intrinsics.

Source code in src/nanodrr/registration/registration.py
@torch.no_grad()
def rescale_(self, scale: float) -> None:
    """Change the rendering resolution by rescaling the camera's intrinsics."""
    self.k_inv[..., 0, 0] /= scale
    self.k_inv[..., 1, 1] /= scale
    self.height = int(round(self.height * scale))
    self.width = int(round(self.width * scale))