Images with shear¶

Computerized tomography (CT or CAT) scans are often acquired with a gantry tilt, which produces oblique (rhomboidal) voxels in world space. NiiVue can render those tilted voxels in their correct world geometry, which looks physically accurate. For certain tasks like drawing, it’s useful to view the volume in image (voxel) space so the voxels align with screen pixels and the image looks rectangular on the screen. This notebook lets you interactively switch between world and image views to explore how tilt affects visualization and drawing accuracy.

This notebook emulates the shear space web page.

In [1]:
import ipywidgets as widgets
from IPython.display import display
from ipyniivue import DragMode, NiiVue

nv = NiiVue(
    drag_and_drop_enabled=True,
    back_color=(1, 1, 1, 1),
    show_3d_crosshair=True,
)

nv.set_slice_mm(True)
nv.set_radiological_convention(False)
nv.set_slice_type(nv.opts.slice_type.MULTIPLANAR)

nv.load_volumes([{"path": "../images/shear.nii.gz",}])

## Create Interactive Controls

# LR checkbox (Radiological convention)
lr_checkbox = widgets.Checkbox(
    value=False,
    description="LR",
    tooltip="Toggle between radiological and neurological convention",
)

# nose checkbox (Sagittal nose direction)
nose_checkbox = widgets.Checkbox(
    value=False, description="Nose", tooltip="Toggle sagittal nose direction"
)

# world checkbox (World space vs voxel space)
world_checkbox = widgets.Checkbox(
    value=True,
    description="World",
    tooltip="Toggle between world space (mm) and voxel space",
)

# drag mode dropdown
drag_dropdown = widgets.Dropdown(
    options=[
        ("contrast", DragMode.CONTRAST),
        ("measurement", DragMode.MEASUREMENT),
        ("pan/zoom", DragMode.PAN),
        ("none", DragMode.NONE),
    ],
    value=DragMode.CONTRAST,
    description="Drag mode:",
)

## Event Handlers

def on_lr_change(change):
    """Handle radiological convention checkbox changes."""
    nv.set_radiological_convention(change["new"])


def on_nose_change(change):
    """Handle nose direction checkbox changes."""
    nv.opts.sagittal_nose_left = change["new"]


def on_world_change(change):
    """Handle world space checkbox changes."""
    nv.set_slice_mm(change["new"])


def on_drag_mode_change(change):
    """Handle drag mode dropdown changes."""
    nv.opts.drag_mode = change["new"]


lr_checkbox.observe(on_lr_change, names="value")
nose_checkbox.observe(on_nose_change, names="value")
world_checkbox.observe(on_world_change, names="value")
drag_dropdown.observe(on_drag_mode_change, names="value")

## Display voxels and controls

controls = widgets.HBox([lr_checkbox, nose_checkbox, world_checkbox, drag_dropdown])

display(widgets.VBox([controls, nv]))
In [ ]:
 
In [ ]: