Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions niworkflows/utils/images.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,28 @@
import numpy as np


def rotation2canonical(img):
"""Calculate the rotation w.r.t. cardinal axes of input image."""
img = nb.as_closest_canonical(img)
newaff = np.diag(img.header.get_zooms()[:3])
r = newaff @ np.linalg.inv(img.affine[:3, :3])
if np.allclose(r, np.eye(3)):
return None
return r


def rotate_affine(img, rot=None):
"""Rewrite the affine of a spatial image."""
if rot is None:
return img

img = nb.as_closest_canonical(img)
affine = np.eye(4)
affine[:3, :3] = rot @ img.affine[:3, :3]
affine[:3, 3] = rot @ img.affine[:3, 3]
return img.__class__(img.dataobj, affine, img.header)


def unsafe_write_nifti_header_and_data(fname, header, data):
"""Write header and data without any consistency checks or data munging
Expand Down
15 changes: 13 additions & 2 deletions niworkflows/viz/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

from nipype.utils import filemanip
from .. import NIWORKFLOWS_LOG
from ..utils.images import rotation2canonical, rotate_affine


SVGNS = "http://www.w3.org/2000/svg"
Expand Down Expand Up @@ -216,19 +217,29 @@ def plot_segs(
compress="auto",
**plot_params
):
""" plot segmentation as contours over the image (e.g. anatomical).
"""
Generate a static mosaic with ROIs represented by their delimiting contour.

Plot segmentation as contours over the image (e.g. anatomical).
seg_niis should be a list of files. mask_nii helps determine the cut
coordinates. plot_params will be passed on to nilearn plot_* functions. If
seg_niis is a list of size one, it behaves as if it was plotting the mask.
"""
plot_params = {} if plot_params is None else plot_params

image_nii = _3d_in_file(image_nii)
canonical_r = rotation2canonical(image_nii)
image_nii = rotate_affine(image_nii, rot=canonical_r)
seg_niis = [rotate_affine(_3d_in_file(f), rot=canonical_r) for f in seg_niis]
data = image_nii.get_fdata()

plot_params = robust_set_limits(data, plot_params)

bbox_nii = nb.load(image_nii if bbox_nii is None else bbox_nii)
bbox_nii = (
image_nii if bbox_nii is None
else rotate_affine(_3d_in_file(bbox_nii), rot=canonical_r)
)

if masked:
bbox_nii = nlimage.threshold_img(bbox_nii, 1e-3)

Expand Down