| |
| """ |
| 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 |
|
|
| |
| 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) |
|
|
| |
| |
| 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 |
| ) |
|
|
| |
| |
| 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}]") |
|
|
| |
| 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) |
|
|
| |
| 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 |
| ) |
|
|
| |
| image = np.random.rand(512, 512).astype(np.float32) * 1000 |
|
|
| |
| bbox = { |
| 'x1': 150, |
| 'y1': 150, |
| 'x2': 350, |
| 'y2': 350 |
| } |
|
|
| print(f"\nInput image shape: {image.shape}") |
| print(f"Bounding box: {bbox}") |
|
|
| |
| print("\nPerforming segmentation with bounding box...") |
| myo_mask, scar_mask = segmentor.segment( |
| image, |
| bbox=bbox, |
| bbox_scale_factor=1.1 |
| ) |
|
|
| 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) |
|
|
| |
| 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 |
| ) |
|
|
| |
| 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}") |
|
|
| |
| 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) |
|
|
| |
| 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 |
| ) |
|
|
| |
| volume = np.random.rand(256, 256, 8).astype(np.float32) * 1000 |
|
|
| print(f"\nInput volume shape: {volume.shape}") |
|
|
| |
| print("\nSegmenting 3D volume...") |
| myo_mask_3d, scar_mask_3d = segmentor.segment_3d( |
| volume, |
| keep_largest_component='per_slice' |
| ) |
|
|
| 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) |
|
|
| |
| 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 |
| ) |
|
|
| |
| image = np.random.rand(256, 256).astype(np.float32) * 1000 |
|
|
| |
| print("\nPerforming segmentation...") |
| myo_mask, scar_mask = segmentor.segment(image) |
|
|
| |
| print("\nCreating visualization...") |
| fig, axes = plt.subplots(1, 4, figsize=(16, 4)) |
|
|
| |
| axes[0].imshow(image, cmap='gray') |
| axes[0].set_title('Original Image') |
| axes[0].axis('off') |
|
|
| |
| axes[1].imshow(myo_mask, cmap='gray') |
| axes[1].set_title('Myocardium Mask') |
| axes[1].axis('off') |
|
|
| |
| axes[2].imshow(scar_mask, cmap='gray') |
| axes[2].set_title('Scar Mask') |
| axes[2].axis('off') |
|
|
| |
| 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() |
|
|
| |
| 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_basic_usage() |
|
|
| |
| example_with_bbox() |
|
|
| |
| example_batch_processing() |
|
|
| |
| example_3d_volume() |
|
|
| |
| 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() |
|
|