Plane Wave Compounding#

This example demonstrates plane wave compounding of data from the PICMUS challenge (Plane-wave Imaging Challenge in Medical Ultrasound). PICMUS provides standardized datasets for evaluating plane wave imaging algorithms.

Example overview:

  • Load ultrasound data from UFF format files

  • Beamform data from multiple plane-wave transmits

  • Coherently compound the results

  • Visualize the results

Attribution:

Note

To run this example, we recommend installing mach with all optional dependencies:

pip install mach-beamform[all]

This ensures all dependencies for the examples are available.

Import Required Libraries#

Let’s start by importing the necessary libraries.

import hashlib

import matplotlib.pyplot as plt
import numpy as np

# Import mach modules
from mach import experimental
from mach._vis import db_zero
from mach.io.uff import create_beamforming_setup
from mach.io.utils import cached_download

try:
    from pyuff_ustb import Uff
except ImportError as err:
    raise ImportError("⚠️  pyuff_ustb is required for UFF data loading. Install with: pip install pyuff-ustb") from err

# Convenience constants
MM_PER_METER = 1000

Download PICMUS Challenge Dataset#

The PICMUS challenge contains multiple datasets with multi-angle plane-wave transmits. This example uses the resolution dataset, which features:

  • 128-element linear array at 5.2 MHz center frequency

  • 75 plane wave transmits at angles from -16° to +16°

  • Point targets and cysts for resolution and contrast assessment

print("📂 Downloading PICMUS challenge dataset...")

# Download the UFF data file (cached locally after first download)
# Source: https://unioslo.github.io/USTB/datasets.html
url = "https://zenodo.org/records/20261898/files/PICMUS_experiment_resolution_distortion.uff"
uff_path = cached_download(
    url,
    expected_size=145_518_524,
    expected_hash="c93af0781daeebf771e53a42a629d4f311407410166ef2f1d227e9d2a1b8c641",
    digest=hashlib.sha256,
    filename="PICMUS_experiment_resolution_distortion.uff",
)

print(f"✓ Dataset downloaded to: {uff_path}")
print(f"  File size: {uff_path.stat().st_size / 1e6:.1f} MB")
📂 Downloading PICMUS challenge dataset...

Downloading PICMUS_experiment_resolution_distortion.uff:   0%|          | 0.00/146M [00:00<?, ?B/s]
Downloading PICMUS_experiment_resolution_distortion.uff:   1%|          | 1.05M/146M [00:01<03:44, 644kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:   1%|▏         | 2.10M/146M [00:02<03:20, 714kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:   2%|▏         | 3.15M/146M [00:04<03:05, 765kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:   3%|▎         | 4.19M/146M [00:05<02:50, 827kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:   4%|▎         | 5.24M/146M [00:06<02:41, 866kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:   4%|▍         | 6.29M/146M [00:07<02:25, 960kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:   5%|▌         | 7.34M/146M [00:08<02:24, 954kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:   6%|▌         | 8.39M/146M [00:09<02:13, 1.02MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:   6%|▋         | 9.44M/146M [00:10<02:16, 997kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:   7%|▋         | 10.5M/146M [00:11<02:22, 946kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:   8%|▊         | 11.5M/146M [00:12<02:21, 946kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:   9%|▊         | 12.6M/146M [00:13<02:15, 978kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:   9%|▉         | 13.6M/146M [00:14<02:16, 967kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  10%|█         | 14.7M/146M [00:16<02:20, 929kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  11%|█         | 15.7M/146M [00:16<02:09, 1.00MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  12%|█▏        | 16.8M/146M [00:17<02:06, 1.02MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  12%|█▏        | 17.8M/146M [00:18<02:04, 1.03MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  13%|█▎        | 18.9M/146M [00:20<02:10, 967kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  14%|█▎        | 19.9M/146M [00:21<02:06, 990kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  14%|█▍        | 21.0M/146M [00:22<01:58, 1.05MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  15%|█▌        | 22.0M/146M [00:22<01:53, 1.09MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  16%|█▌        | 23.1M/146M [00:24<01:57, 1.04MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  17%|█▋        | 24.1M/146M [00:25<01:56, 1.05MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  17%|█▋        | 25.2M/146M [00:26<02:03, 977kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  18%|█▊        | 26.2M/146M [00:27<02:03, 967kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  19%|█▊        | 27.3M/146M [00:28<01:58, 994kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  19%|█▉        | 28.3M/146M [00:29<01:47, 1.09MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  20%|██        | 29.4M/146M [00:29<01:39, 1.17MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  21%|██        | 30.4M/146M [00:30<01:41, 1.14MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  22%|██▏       | 31.5M/146M [00:31<01:34, 1.21MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  22%|██▏       | 32.5M/146M [00:32<01:37, 1.15MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  23%|██▎       | 33.6M/146M [00:33<01:43, 1.08MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  24%|██▍       | 34.6M/146M [00:34<01:43, 1.07MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  24%|██▍       | 35.7M/146M [00:35<01:38, 1.11MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  25%|██▌       | 36.7M/146M [00:36<01:43, 1.06MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  26%|██▌       | 37.7M/146M [00:37<01:41, 1.06MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  27%|██▋       | 38.8M/146M [00:38<01:36, 1.10MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  27%|██▋       | 39.8M/146M [00:39<01:48, 977kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  28%|██▊       | 40.9M/146M [00:40<01:44, 1.00MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  29%|██▉       | 41.9M/146M [00:41<01:41, 1.02MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  30%|██▉       | 43.0M/146M [00:42<01:39, 1.03MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  30%|███       | 44.0M/146M [00:43<01:30, 1.12MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  31%|███       | 45.1M/146M [00:44<01:34, 1.06MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  32%|███▏      | 46.1M/146M [00:45<01:37, 1.02MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  32%|███▏      | 47.2M/146M [00:46<01:31, 1.07MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  33%|███▎      | 48.2M/146M [00:47<01:34, 1.03MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  34%|███▍      | 49.3M/146M [00:48<01:32, 1.04MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  35%|███▍      | 50.3M/146M [00:49<01:31, 1.04MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  35%|███▌      | 51.4M/146M [00:50<01:29, 1.05MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  36%|███▌      | 52.4M/146M [00:51<01:28, 1.05MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  37%|███▋      | 53.5M/146M [00:52<01:23, 1.10MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  37%|███▋      | 54.5M/146M [00:53<01:17, 1.18MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  38%|███▊      | 55.6M/146M [00:54<01:18, 1.14MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  39%|███▉      | 56.6M/146M [00:55<01:16, 1.16MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  40%|███▉      | 57.7M/146M [00:56<01:21, 1.08MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  40%|████      | 58.7M/146M [00:57<01:21, 1.07MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  41%|████      | 59.8M/146M [00:58<01:26, 987kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  42%|████▏     | 60.8M/146M [00:59<01:26, 975kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  43%|████▎     | 61.9M/146M [01:00<01:23, 1.00MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  43%|████▎     | 62.9M/146M [01:01<01:21, 1.02MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  44%|████▍     | 64.0M/146M [01:02<01:24, 960kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  45%|████▍     | 65.0M/146M [01:03<01:21, 989kB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  45%|████▌     | 66.1M/146M [01:04<01:13, 1.09MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  46%|████▌     | 67.1M/146M [01:05<01:12, 1.08MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  47%|████▋     | 68.2M/146M [01:06<01:11, 1.08MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  48%|████▊     | 69.2M/146M [01:07<01:13, 1.03MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  48%|████▊     | 70.3M/146M [01:08<01:14, 1.00MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  49%|████▉     | 71.3M/146M [01:09<01:10, 1.06MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  50%|████▉     | 72.4M/146M [01:10<01:11, 1.02MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  50%|█████     | 73.4M/146M [01:11<01:02, 1.16MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  51%|█████     | 74.4M/146M [01:11<00:45, 1.57MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  52%|█████▏    | 75.5M/146M [01:11<00:33, 2.07MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  53%|█████▎    | 76.5M/146M [01:11<00:25, 2.69MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  54%|█████▍    | 78.6M/146M [01:11<00:15, 4.39MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  56%|█████▌    | 81.8M/146M [01:11<00:08, 7.47MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  59%|█████▉    | 86.0M/146M [01:12<00:04, 12.0MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  62%|██████▏   | 90.2M/146M [01:12<00:03, 16.1MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  64%|██████▍   | 93.3M/146M [01:12<00:02, 18.1MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  67%|██████▋   | 97.5M/146M [01:12<00:02, 21.5MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  69%|██████▉   | 101M/146M [01:13<00:03, 11.3MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  71%|███████   | 103M/146M [01:13<00:05, 8.39MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  72%|███████▏  | 105M/146M [01:13<00:05, 7.42MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  73%|███████▎  | 107M/146M [01:14<00:04, 8.51MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  76%|███████▌  | 110M/146M [01:14<00:03, 11.1MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  78%|███████▊  | 113M/146M [01:14<00:02, 13.6MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  81%|████████  | 117M/146M [01:14<00:01, 17.2MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  84%|████████▎ | 122M/146M [01:14<00:01, 20.6MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  86%|████████▋ | 126M/146M [01:14<00:01, 18.8MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  89%|████████▊ | 129M/146M [01:15<00:01, 11.0MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  90%|█████████ | 131M/146M [01:16<00:01, 7.58MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  92%|█████████▏| 133M/146M [01:16<00:01, 7.02MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  93%|█████████▎| 135M/146M [01:16<00:01, 6.63MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  94%|█████████▎| 136M/146M [01:17<00:01, 6.13MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  94%|█████████▍| 137M/146M [01:17<00:01, 5.69MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  95%|█████████▌| 138M/146M [01:17<00:01, 5.33MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  96%|█████████▌| 139M/146M [01:17<00:01, 5.80MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  97%|█████████▋| 141M/146M [01:17<00:00, 5.33MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  97%|█████████▋| 142M/146M [01:18<00:00, 5.00MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  98%|█████████▊| 143M/146M [01:18<00:00, 4.74MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  99%|█████████▊| 144M/146M [01:18<00:00, 4.63MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff:  99%|█████████▉| 145M/146M [01:18<00:00, 5.25MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff: 100%|██████████| 146M/146M [01:19<00:00, 4.65MB/s]
Downloading PICMUS_experiment_resolution_distortion.uff: 100%|██████████| 146M/146M [01:19<00:00, 1.84MB/s]
✓ Dataset downloaded to: /home/runner/.cache/mach/PICMUS_experiment_resolution_distortion.uff
  File size: 145.5 MB

Load and Inspect PICMUS Data#

UFF files contain structured ultrasound data including channel data (RF signals), probe geometry, and scan parameters. Let’s examine the PICMUS dataset structure.

print("\n📋 Loading PICMUS data structure...")

# Open UFF file and extract components
uff_file = Uff(str(uff_path))
channel_data = uff_file.read("/channel_data")
scan = uff_file.read("/scan")

# Display challenge dataset information
print("\n📊 PICMUS Challenge Dataset:")
print(f"   Plane wave transmits: {len(channel_data.sequence)}")
print(f"   Array elements: {channel_data.probe.N}")
print(f"   Samples per acquisition: {channel_data.data.shape[0]}")
print(f"   Frames: {channel_data.data.shape[-1] if channel_data.data.ndim > 3 else 1}")
print(f"   Sampling frequency: {channel_data.sampling_frequency / 1e6:.1f} MHz")
print(f"   Center frequency: {channel_data.modulation_frequency / 1e6:.1f} MHz")
print(f"   Speed of sound: {channel_data.sound_speed} m/s")

# Display plane wave transmit angles
angles_deg = [np.rad2deg(wave.source.azimuth) for wave in channel_data.sequence]
print(f"   Plane wave angles: {min(angles_deg):.1f}° to {max(angles_deg):.1f}°")
print(f"   Angular step: {np.diff(angles_deg)[0]:.1f}°")

# Display imaging region
print("\n🎯 Imaging Region:")
print(f"   Lateral samples: {scan.x_axis.size}")
print(f"   Depth samples: {scan.z_axis.size}")
print(f"   Lateral extent: {scan.x_axis.min() * MM_PER_METER:.1f} to {scan.x_axis.max() * MM_PER_METER:.1f} mm")
print(f"   Depth extent: {scan.z_axis.min() * MM_PER_METER:.1f} to {scan.z_axis.max() * MM_PER_METER:.1f} mm")
📋 Loading PICMUS data structure...

📊 PICMUS Challenge Dataset:
   Plane wave transmits: 75
   Array elements: 128
   Samples per acquisition: 3328
   Frames: 1
   Sampling frequency: 20.8 MHz
   Center frequency: 0.0 MHz
   Speed of sound: 1540.0 m/s
   Plane wave angles: -16.0° to 16.0°
   Angular step: 0.4°

🎯 Imaging Region:
   Lateral samples: 387
   Depth samples: 609
   Lateral extent: -19.1 to 19.0 mm
   Depth extent: 5.0 to 49.9 mm

Extract metadata for mach#

print("\n🔄 Preparing data for beamforming...")

# Create beamforming setup for all plane wave angles
beamform_kwargs = create_beamforming_setup(
    channel_data=channel_data,
    scan=scan,
    f_number=1.7,
)

print("📊 Beamforming setup:")
print(f"   Sensor data shape: {beamform_kwargs['channel_data'].shape}")
print("   (transmits, elements, samples, frames)")
print(f"   Output points: {beamform_kwargs['scan_coords_m'].shape[0]:,}")
print(f"   Transmit arrivals shape: {beamform_kwargs['tx_wave_arrivals_s'].shape}")
print(f"   F-number: {beamform_kwargs['f_number']}")

# Extract number of plane-wave transmits
n_transmits = beamform_kwargs["channel_data"].shape[0]
print(f"   Beamforming {n_transmits} plane-wave transmits")
🔄 Preparing data for beamforming...
📊 Beamforming setup:
   Sensor data shape: (75, 128, 3328, 1)
   (transmits, elements, samples, frames)
   Output points: 235,683
   Transmit arrivals shape: (75, 235683)
   F-number: 1.7
   Beamforming 75 plane-wave transmits

Beamform and compound#

Now we beamform and compound the data:

  1. Individual beamforming: Apply delay-and-sum beamforming to each plane-wave transmit

  2. Coherent compounding: Sum the results to form the final image

Note: The mach.experimental API is subject to change.

print("\n🚀 Beamforming and compounding...")

result = experimental.beamform(**beamform_kwargs)

print("✓ Beamforming and compounding completed!")
print(f"  Output shape: {result.shape} (points, frames)")
print(f"  Data type: {result.dtype}")
print(f"  Coherently compounded {n_transmits} plane-wave transmits")
🚀 Beamforming and compounding...
/home/runner/work/mach/mach/src/mach/kernel.py:251: UserWarning: array is not contiguous, rearranging will add latency
  channel_data = try_contiguous(channel_data)
/home/runner/work/mach/mach/src/mach/kernel.py:274: UserWarning: Found 4 input array(s) on CPU. This will add latency due to CPU<->GPU memory transfers. For optimal performance with CUDA beamforming, move arrays to GPU using cupy, jax, or similar.
  nb_beamform(  # ty: ignore[no-matching-overload]
✓ Beamforming and compounding completed!
  Output shape: (235683, 1) (points, frames)
  Data type: complex64
  Coherently compounded 75 plane-wave transmits

Reshape results#

The beamformed data needs to be reshaped to the 2D imaging grid.

print("\n📊 Processing compounded results...")

# Reshape from flattened points back to 2D imaging grid
grid_shape = (scan.x_axis.size, scan.z_axis.size)
beamformed_image = result.reshape(grid_shape)

# Extract magnitude for B-mode display (envelope detection)
bmode_image = np.abs(beamformed_image)

print("✓ Image processing complete")
print(f"  Image shape: {bmode_image.shape} (lateral, depth)")
print(f"  Dynamic range: {bmode_image.min():.2e} to {bmode_image.max():.2e}")
📊 Processing compounded results...
✓ Image processing complete
  Image shape: (387, 609) (lateral, depth)
  Dynamic range: 2.82e-03 to 8.00e+01

Visualize B-Mode#

print("\n📊 Visualizing B-mode...")

# Convert to logarithmic (dB) scale for display
bmode_db = db_zero(beamformed_image)

# Create high-quality visualization
fig, ax = plt.subplots(figsize=(8, 8), dpi=300)

# Set up coordinate system for proper display
extent = [
    scan.x_axis.min() * MM_PER_METER,
    scan.x_axis.max() * MM_PER_METER,
    scan.z_axis.max() * MM_PER_METER,
    scan.z_axis.min() * MM_PER_METER,
]

# Display the compounded image
im = ax.imshow(
    bmode_db.T,
    cmap="gray",  # Clinical grayscale colormap
    vmin=-40,  # 40 dB dynamic range
    vmax=0,  # Normalized to maximum
    extent=extent,  # Physical coordinates in mm
    aspect="equal",  # Preserve spatial relationships
    origin="upper",  # Depth increases downward (standard)
    interpolation="nearest",  # Preserve sharp phantom features
)

# Add comprehensive labeling
ax.set_title(
    f"PICMUS Challenge: Plane Wave Compounding\n"
    f"Coherent Compounding of {n_transmits} Plane Wave Angles "
    f"({min(angles_deg):.0f}° to {max(angles_deg):.0f}°)",
    fontsize=14,
)
ax.set_xlabel("Lateral Distance [mm]", fontsize=12)
ax.set_ylabel("Depth [mm]", fontsize=12)

# Add colorbar with proper formatting
cbar = plt.colorbar(im, ax=ax, shrink=0.8)
cbar.set_label("Magnitude [dB]", fontsize=12)
cbar.ax.tick_params(labelsize=10)

# Add subtle grid for better readability
ax.grid(True, alpha=0.3, linestyle="--", linewidth=0.5)
PICMUS Challenge: Plane Wave Compounding Coherent Compounding of 75 Plane Wave Angles (-16° to 16°)
📊 Visualizing B-mode...

Expected results#

The plane wave compounded image should clearly resolve:

  • Point targets: Sharp, well-defined spots for lateral/axial resolution measurement

  • Hyperechoic lesion: Bright circle to test for geometric distortion

  • Uniform speckle: Consistent background texture in tissue-mimicking regions

Total running time of the script: (1 minutes 22.063 seconds)

Gallery generated by Sphinx-Gallery