Carotid artery segmentation¶
This section demonstrates how to use the CarotidSegmenter model from the zea library to segment the carotid artery in ultrasound images. The model predicts a mask highlighting the carotid region for a given input image.
For more details, see the original paper:
Luuk van Knippenberg, “Unsupervised domain adaptation method for segmenting cross-sectional CCA images”, Computers in Biology and Medicine, 2022.
‼️ Important: This notebook is optimized for GPU/TPU. Code execution on a CPU may be very slow.
If you are running in Colab, please enable a hardware accelerator via:
Runtime → Change runtime type → Hardware accelerator → GPU/TPU 🚀.
[1]:
%%capture
%pip install zea
[2]:
import os
# NOTE: should be `tensorflow` or `jax` for EchoNetDynamic
os.environ["KERAS_BACKEND"] = "tensorflow"
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
import matplotlib.pyplot as plt
from keras import ops
from PIL import Image
import numpy as np
import requests
from io import BytesIO
from zea import init_device, log
from zea.visualize import plot_shape_from_mask
from zea.visualize import set_mpl_style
init_device(verbose=False)
set_mpl_style()
zea: Using backend 'tensorflow'
[3]:
from zea.models.carotid_segmenter import CarotidSegmenter
presets = list(CarotidSegmenter.presets.keys())
log.info(f"Available built-in zea presets for CarotidSegmenter: {presets}")
model = CarotidSegmenter.from_preset("carotid-segmenter")
zea: Available built-in zea presets for CarotidSegmenter: ['carotid-segmenter']
[4]:
n_imgs = 1
url = "https://raw.githubusercontent.com/tue-bmd/zea/main/docs/source/notebooks/assets/carotid.png"
response = requests.get(url)
img = Image.open(BytesIO(response.content)).convert("L")
img_np = np.asarray(img).astype(np.float32) / 255.0
img_np = img_np[None, ..., None] # add batch and channel dimensions
batch = ops.convert_to_tensor(img_np)
masks = model(batch)
masks = ops.squeeze(masks, axis=-1)
masks_clipped = ops.where(masks > 0.5, 1, 0)
masks_clipped = ops.convert_to_numpy(masks_clipped)
# stack batch twice to get 2 rows
batch_stacked = ops.concatenate([batch, batch])
# Plot the original image and its mask side by side, with each row as an example
fig, axes = plt.subplots(n_imgs, 2, figsize=(6, 3 * n_imgs))
axes = np.atleast_2d(axes)
for ax_img, ax_mask, img_arr, mask_arr in zip(axes[:, 0], axes[:, 1], batch[..., 0], masks_clipped):
ax_img.imshow(img_arr, cmap="gray", vmin=0, vmax=1)
ax_img.set_title("Input Image")
ax_img.axis("off")
ax_mask.imshow(img_arr, cmap="gray", vmin=0, vmax=1)
plot_shape_from_mask(ax_mask, mask_arr, color="red", alpha=0.5)
ax_mask.set_title("Predicted Mask")
ax_mask.axis("off")
plt.tight_layout()
plt.savefig("carotid_output.png")
plt.close()