Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions docs/source/api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ Medical imaging
:toctree: generated/

CT2D
MRI2D


Solvers
Expand Down
4 changes: 4 additions & 0 deletions docs/source/gpu.rst
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,10 @@ Medical:
- |:white_check_mark:|
- |:white_check_mark:|
- |:white_check_mark:|
* - :class:`pylops.medical.mri.MRI2D`
- |:white_check_mark:|
- |:red_circle:|
- |:white_check_mark:|

.. warning::

Expand Down
2 changes: 1 addition & 1 deletion examples/plot_avo.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
r"""
AVO modelling
===================
=============
This example shows how to create pre-stack angle gathers using
the :py:class:`pylops.avo.avo.AVOLinearModelling` operator.
"""
Expand Down
104 changes: 104 additions & 0 deletions examples/plot_mri.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
r"""
MRI modelling
=============
This example shows how to use the :py:class:`pylops.medical.mri.MRI2D` operator
to create K-space undersampled MRI data.
"""
import matplotlib.pyplot as plt
import numpy as np

import pylops

plt.close("all")
np.random.seed(0)

###############################################################################
# Let"s start by loading the Shepp-Logan phantom model.
x = np.load("../testdata/optimization/shepp_logan_phantom.npy")
x = x / x.max()
nx, ny = x.shape

###############################################################################
# Next, we create a mask to simulate undersampling in K-space and apply it to
# the phantom model.

# Passing mask as array
mask = np.zeros((nx, ny))
mask[:, np.random.randint(0, ny, 2 * ny // 3)] = 1
mask[:, ny // 2 - 20 : ny // 2 + 10] = 1

Mop = pylops.medical.MRI2D(dims=(nx, ny), mask=mask)

d = Mop @ x
x_adj = Mop.H @ d

fig, axs = plt.subplots(1, 3, figsize=(12, 5))
axs[0].imshow(x, cmap="gray", vmin=0, vmax=1)
axs[0].set_title("Original Image")
axs[1].imshow(np.abs(d), cmap="jet", vmin=0, vmax=1)
axs[1].set_title("K-space Data")
axs[2].imshow(x_adj.real, cmap="gray", vmin=0, vmax=1)
axs[2].set_title("Adjoint Reconstruction")
fig.tight_layout()

###############################################################################
# Alternatively, we can create the same mask by specifying a sampling pattern
# using the ``mask`` keyword argument. Here, we create a ``vertical-reg`` mask
# that samples K-space lines in the vertical direction with a regular pattern.

# Vertical uniform with center
Mop = pylops.medical.MRI2D(
dims=(nx, ny), mask="vertical-reg", nlines=ny // 2, perc_center=0.0
)

d = Mop @ x
x_adj = (Mop.H @ d).reshape(nx, ny)

fig, axs = plt.subplots(1, 3, figsize=(12, 5))
axs[0].imshow(x, cmap="gray", vmin=0, vmax=1)
axs[0].set_title("Original Image")
axs[1].imshow(np.abs(Mop.ROp.H @ d).reshape(nx, ny), cmap="jet", vmin=0, vmax=1)
axs[1].set_title("K-space Data")
axs[2].imshow(x_adj.real, cmap="gray", vmin=0, vmax=1)
axs[2].set_title("Adjoint Reconstruction")
fig.tight_layout()

###############################################################################
# Similarly, we can create a ``vertical-uni`` mask that randomly samples
# K-space lines in the vertical direction.

# Vertical uniform with center
Mop = pylops.medical.MRI2D(
dims=(nx, ny), mask="vertical-uni", nlines=40, perc_center=0.1
)

d = Mop @ x
x_adj = (Mop.H @ d).reshape(nx, ny)

fig, axs = plt.subplots(1, 3, figsize=(12, 5))
axs[0].imshow(x, cmap="gray", vmin=0, vmax=1)
axs[0].set_title("Original Image")
axs[1].imshow(np.abs(Mop.ROp.H @ d).reshape(nx, ny), cmap="jet", vmin=0, vmax=1)
axs[1].set_title("K-space Data")
axs[2].imshow(x_adj.real, cmap="gray", vmin=0, vmax=1)
axs[2].set_title("Adjoint Reconstruction")
fig.tight_layout()

###############################################################################
# Finally, we can create a sampling pattern with radial lines using the
# ``radial-uni`` (or ``radial-reg``) option.

# Radial uniform
Mop = pylops.medical.MRI2D(dims=(nx, ny), mask="radial-uni", nlines=40)

d = Mop @ x
x_adj = (Mop.H @ d).reshape(nx, ny)

fig, axs = plt.subplots(1, 3, figsize=(12, 5))
axs[0].imshow(x, cmap="gray", vmin=0, vmax=1)
axs[0].set_title("Original Image")
axs[1].imshow(np.abs(Mop.ROp.H @ d).reshape(nx, ny), cmap="jet", vmin=0, vmax=1)
axs[1].set_title("K-space Data")
axs[2].imshow(x_adj.real, cmap="gray", vmin=0, vmax=1)
axs[2].set_title("Adjoint Reconstruction")
fig.tight_layout()
7 changes: 4 additions & 3 deletions pylops/medical/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
A list of operators present in pylops.medical:
CT2D 2D Computerized Tomography.
MRI2D 2D Magnetic Resonance Imaging.
"""

from .ct import *
from .mri import *

__all__ = [
"CT2D",
]

__all__ = ["CT2D", "MRI2D"]
Loading