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.

Open In Colab   View on GitHub   Hugging Face model

‼️ 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()
Carotid Example Output