JerryX's picture
Publish all-view cine ONNX models and reference assets
d5d23f9 verified
Raw
History Blame Contribute Delete
9.06 kB
#!/usr/bin/env python
"""
Example usage of JDLSegmentor for myocardium and scar segmentation.
This script demonstrates how to use the ONNX-based JDL segmentor
to segment myocardium and scar tissue from cardiac MRI images.
"""
import numpy as np
import matplotlib.pyplot as plt
from pathlib import Path
import sys
# Add parent directory to path for imports
sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent))
from cardiac_toolkit.segmentation import JDLSegmentor
def example_basic_usage():
"""Example 1: Basic 2D segmentation."""
print("=" * 80)
print("Example 1: Basic 2D Segmentation")
print("=" * 80)
# Initialize segmentor
# Default model paths (update with your actual paths)
myocardium_model_path = "/gpfs/gibbs/project/kwan/jx332/code/2025-02-LGE-multiview-seg/checkpoints/jdl_myocardium.onnx"
scar_model_path = "/gpfs/gibbs/project/kwan/jx332/code/2025-02-LGE-multiview-seg/checkpoints/jdl_scar.onnx"
if not Path(myocardium_model_path).exists() or not Path(scar_model_path).exists():
print(f"\n⚠ Models not found")
print(f"Myocardium: {myocardium_model_path}")
print(f"Scar: {scar_model_path}")
print("Please update the model paths in this script.")
return None, None, None
segmentor = JDLSegmentor(
myocardium_model_path=myocardium_model_path,
scar_model_path=scar_model_path
)
# Create dummy image (replace with your own image loading)
# In practice: image = np.load('your_cardiac_mri.npy')
image = np.random.rand(256, 256).astype(np.float32) * 1000
print(f"\nInput image shape: {image.shape}")
print(f"Input image dtype: {image.dtype}")
print(f"Input image range: [{image.min():.2f}, {image.max():.2f}]")
# Perform segmentation
print("\nPerforming segmentation...")
myo_mask, scar_mask = segmentor.segment(image)
print(f"\nMyocardium mask shape: {myo_mask.shape}")
print(f"Myocardium pixels: {np.sum(myo_mask)}")
print(f"Scar mask shape: {scar_mask.shape}")
print(f"Scar pixels: {np.sum(scar_mask)}")
return image, myo_mask, scar_mask
def example_with_bbox():
"""Example 2: Segmentation with bounding box."""
print("\n" + "=" * 80)
print("Example 2: Segmentation with Bounding Box")
print("=" * 80)
# Initialize segmentor
myocardium_model_path = "/gpfs/gibbs/project/kwan/jx332/code/2025-02-LGE-multiview-seg/checkpoints/jdl_myocardium.onnx"
scar_model_path = "/gpfs/gibbs/project/kwan/jx332/code/2025-02-LGE-multiview-seg/checkpoints/jdl_scar.onnx"
if not Path(myocardium_model_path).exists() or not Path(scar_model_path).exists():
print(f"\n⚠ Models not found")
return None, None, None, None
segmentor = JDLSegmentor(
myocardium_model_path=myocardium_model_path,
scar_model_path=scar_model_path
)
# Create dummy image
image = np.random.rand(512, 512).astype(np.float32) * 1000
# Define a bounding box around the heart region
bbox = {
'x1': 150,
'y1': 150,
'x2': 350,
'y2': 350
}
print(f"\nInput image shape: {image.shape}")
print(f"Bounding box: {bbox}")
# Perform segmentation with bbox
print("\nPerforming segmentation with bounding box...")
myo_mask, scar_mask = segmentor.segment(
image,
bbox=bbox,
bbox_scale_factor=1.1 # Expand bbox by 10%
)
print(f"\nMyocardium mask shape: {myo_mask.shape}")
print(f"Myocardium pixels: {np.sum(myo_mask)}")
print(f"Scar mask shape: {scar_mask.shape}")
print(f"Scar pixels: {np.sum(scar_mask)}")
return image, myo_mask, scar_mask, bbox
def example_batch_processing():
"""Example 3: Batch processing of multiple slices."""
print("\n" + "=" * 80)
print("Example 3: Batch Processing")
print("=" * 80)
# Initialize segmentor
myocardium_model_path = "/gpfs/gibbs/project/kwan/jx332/code/2025-02-LGE-multiview-seg/checkpoints/jdl_myocardium.onnx"
scar_model_path = "/gpfs/gibbs/project/kwan/jx332/code/2025-02-LGE-multiview-seg/checkpoints/jdl_scar.onnx"
if not Path(myocardium_model_path).exists() or not Path(scar_model_path).exists():
print(f"\n⚠ Models not found")
return None, None, None
segmentor = JDLSegmentor(
myocardium_model_path=myocardium_model_path,
scar_model_path=scar_model_path
)
# Create dummy batch of images (e.g., multiple slices)
num_slices = 5
images = [np.random.rand(256, 256).astype(np.float32) * 1000 for _ in range(num_slices)]
print(f"\nNumber of slices: {num_slices}")
print(f"Each slice shape: {images[0].shape}")
# Process batch
print("\nProcessing batch...")
myo_masks, scar_masks = segmentor.segment_batch(images)
print(f"\nProcessed {len(myo_masks)} slices")
for i, (myo_mask, scar_mask) in enumerate(zip(myo_masks, scar_masks)):
print(f" Slice {i}: Myo pixels = {np.sum(myo_mask)}, Scar pixels = {np.sum(scar_mask)}")
return images, myo_masks, scar_masks
def example_3d_volume():
"""Example 4: 3D volume segmentation."""
print("\n" + "=" * 80)
print("Example 4: 3D Volume Segmentation")
print("=" * 80)
# Initialize segmentor
myocardium_model_path = "/gpfs/gibbs/project/kwan/jx332/code/2025-02-LGE-multiview-seg/checkpoints/jdl_myocardium.onnx"
scar_model_path = "/gpfs/gibbs/project/kwan/jx332/code/2025-02-LGE-multiview-seg/checkpoints/jdl_scar.onnx"
if not Path(myocardium_model_path).exists() or not Path(scar_model_path).exists():
print(f"\n⚠ Models not found")
return None, None, None
segmentor = JDLSegmentor(
myocardium_model_path=myocardium_model_path,
scar_model_path=scar_model_path
)
# Create dummy 3D volume
volume = np.random.rand(256, 256, 8).astype(np.float32) * 1000
print(f"\nInput volume shape: {volume.shape}")
# Segment 3D volume
print("\nSegmenting 3D volume...")
myo_mask_3d, scar_mask_3d = segmentor.segment_3d(
volume,
keep_largest_component='per_slice' # or 'whole_volume'
)
print(f"\nMyocardium mask shape: {myo_mask_3d.shape}")
print(f"Myocardium voxels: {np.sum(myo_mask_3d)}")
print(f"Scar mask shape: {scar_mask_3d.shape}")
print(f"Scar voxels: {np.sum(scar_mask_3d)}")
return volume, myo_mask_3d, scar_mask_3d
def example_visualization():
"""Example 5: Visualizing results."""
print("\n" + "=" * 80)
print("Example 5: Visualization")
print("=" * 80)
# Initialize segmentor
myocardium_model_path = "/gpfs/gibbs/project/kwan/jx332/code/2025-02-LGE-multiview-seg/checkpoints/jdl_myocardium.onnx"
scar_model_path = "/gpfs/gibbs/project/kwan/jx332/code/2025-02-LGE-multiview-seg/checkpoints/jdl_scar.onnx"
if not Path(myocardium_model_path).exists() or not Path(scar_model_path).exists():
print(f"\n⚠ Models not found")
return
segmentor = JDLSegmentor(
myocardium_model_path=myocardium_model_path,
scar_model_path=scar_model_path
)
# Create dummy image
image = np.random.rand(256, 256).astype(np.float32) * 1000
# Perform segmentation
print("\nPerforming segmentation...")
myo_mask, scar_mask = segmentor.segment(image)
# Create visualization
print("\nCreating visualization...")
fig, axes = plt.subplots(1, 4, figsize=(16, 4))
# Original image
axes[0].imshow(image, cmap='gray')
axes[0].set_title('Original Image')
axes[0].axis('off')
# Myocardium mask
axes[1].imshow(myo_mask, cmap='gray')
axes[1].set_title('Myocardium Mask')
axes[1].axis('off')
# Scar mask
axes[2].imshow(scar_mask, cmap='gray')
axes[2].set_title('Scar Mask')
axes[2].axis('off')
# Overlay
axes[3].imshow(image, cmap='gray')
axes[3].imshow(myo_mask, cmap='Reds', alpha=0.3)
axes[3].imshow(scar_mask, cmap='Blues', alpha=0.3)
axes[3].set_title('Overlay\n(Red=Myo, Blue=Scar)')
axes[3].axis('off')
plt.tight_layout()
# Save figure
output_path = Path(__file__).parent / 'jdl_segmentation_result.png'
plt.savefig(output_path, dpi=150, bbox_inches='tight')
print(f"\nVisualization saved to: {output_path}")
plt.close()
def main():
"""Run all examples."""
print("\n" + "*" * 80)
print("JDLSegmentor Examples")
print("*" * 80)
try:
# Example 1: Basic usage
example_basic_usage()
# Example 2: With bounding box
example_with_bbox()
# Example 3: Batch processing
example_batch_processing()
# Example 4: 3D volume
example_3d_volume()
# Example 5: Visualization
example_visualization()
print("\n" + "=" * 80)
print("All examples completed successfully!")
print("=" * 80)
print()
except Exception as e:
print(f"\n\nError running examples: {e}")
import traceback
traceback.print_exc()
if __name__ == '__main__':
main()