|
| 1 | +#!/usr/bin/env python3 |
1 | 2 | """ |
2 | | -CurveAlign API Usage Examples |
3 | | -Demonstrates basic and advanced usage of the modern CurveAlign Python API. |
4 | | -""" |
| 3 | +Simple usage examples for pycurvelets (manually converted API from MATLAB CurveAlign). |
5 | 4 |
|
| 5 | +Requires: curvelops (for curvelet transform), pycurvelets (this package). |
| 6 | +Run from repo root: python simple_usage.py |
| 7 | +""" |
6 | 8 | import numpy as np |
7 | | -import curvealign_py as curvealign |
8 | | -import ctfire_py as ctfire |
9 | 9 |
|
10 | | -def basic_analysis_example(): |
11 | | - """Basic fiber analysis with CurveAlign API.""" |
12 | | - print("=== Basic CurveAlign Analysis ===") |
13 | | - |
14 | | - # Create test image (replace with: io.imread('your_image.tif')) |
15 | | - image = np.random.rand(256, 256) |
16 | | - print(f"Image shape: {image.shape}") |
17 | | - |
18 | | - # Run core analysis |
19 | | - print("Running curvelet-based analysis...") |
20 | | - result = curvealign.analyze_image(image) |
21 | | - |
22 | | - # Display results |
23 | | - print(f"\nResults:") |
24 | | - print(f" Fiber segments detected: {len(result.curvelets)}") |
25 | | - print(f" Mean angle: {result.stats['mean_angle']:.1f}°") |
26 | | - print(f" Alignment score: {result.stats['alignment']:.3f}") |
27 | | - print(f" Fiber density: {result.stats['density']:.6f}") |
28 | | - |
29 | | - return result |
| 10 | +try: |
| 11 | + from pycurvelets.models import ( |
| 12 | + CurveletControlParameters, |
| 13 | + FeatureControlParameters, |
| 14 | + ImageInputParameters, |
| 15 | + BoundaryParameters, |
| 16 | + FiberAnalysisParameters, |
| 17 | + OutputControlParameters, |
| 18 | + AdvancedAnalysisOptions, |
| 19 | + ) |
| 20 | + from pycurvelets.get_ct import get_ct |
| 21 | + from pycurvelets.new_curv import new_curv |
| 22 | + from pycurvelets.process_image import process_image |
| 23 | + HAS_PYCURVELETS = True |
| 24 | +except ImportError as e: |
| 25 | + HAS_PYCURVELETS = False |
| 26 | + print(f"pycurvelets not available: {e}") |
| 27 | + |
30 | 28 |
|
31 | | -def ctfire_analysis_example(): |
32 | | - """Individual fiber extraction with CT-FIRE integration.""" |
33 | | - print("\n=== CT-FIRE Analysis ===") |
34 | | - |
35 | | - image = np.random.rand(256, 256) |
36 | | - |
37 | | - # Option 1: Use unified CurveAlign interface |
38 | | - print("Using unified interface (CT-FIRE mode)...") |
39 | | - result_unified = curvealign.analyze_image(image, mode="ctfire") |
40 | | - print(f" Unified interface: {len(result_unified.curvelets)} features") |
41 | | - |
42 | | - # Option 2: Use CT-FIRE directly |
43 | | - print("Using CT-FIRE API directly...") |
44 | | - result_ctfire = ctfire.analyze_image(image) |
45 | | - print(f" Direct CT-FIRE: {len(result_ctfire.fibers)} fibers") |
46 | | - print(f" Network analysis: {len(result_ctfire.network.intersections)} intersections") |
47 | | - |
48 | | - return result_unified, result_ctfire |
| 29 | +def example_get_ct(): |
| 30 | + """Extract curvelets from an image using get_ct.""" |
| 31 | + if not HAS_PYCURVELETS: |
| 32 | + return |
| 33 | + # Create a simple test image (e.g. 128x128) |
| 34 | + img = np.random.rand(128, 128).astype(np.float64) * 255 |
| 35 | + curve_cp = CurveletControlParameters(keep=0.05, scale=1.0, radius=10.0) |
| 36 | + feature_cp = FeatureControlParameters( |
| 37 | + minimum_nearest_fibers=2, |
| 38 | + minimum_box_size=32, |
| 39 | + fiber_midpoint_estimate=1, |
| 40 | + ) |
| 41 | + fiber_structure, density_df, alignment_df, _ = get_ct(img, curve_cp, feature_cp) |
| 42 | + print(f"get_ct: {len(fiber_structure)} curvelets extracted") |
| 43 | + if len(fiber_structure) > 0: |
| 44 | + print(f" angles: min={fiber_structure['angle'].min():.1f}, max={fiber_structure['angle'].max():.1f}") |
49 | 45 |
|
50 | | -def visualization_example(): |
51 | | - """Create visualizations with different backends.""" |
52 | | - print("\n=== Visualization Examples ===") |
53 | | - |
54 | | - image = np.random.rand(128, 128) |
55 | | - result = curvealign.analyze_image(image) |
56 | | - |
57 | | - # Create overlay visualization |
58 | | - try: |
59 | | - overlay = curvealign.overlay(image, result.curvelets) |
60 | | - print(f"Overlay created: {overlay.shape}") |
61 | | - |
62 | | - # Create angle map |
63 | | - angle_map_raw, angle_map_processed = curvealign.angle_map(image, result.curvelets) |
64 | | - print(f"Angle maps created: {angle_map_processed.shape}") |
65 | | - |
66 | | - except ImportError as e: |
67 | | - print(f"Visualization backend not available: {e}") |
68 | 46 |
|
69 | | -def batch_processing_example(): |
70 | | - """Process multiple images efficiently.""" |
71 | | - print("\n=== Batch Processing ===") |
72 | | - |
73 | | - # Create sample images |
74 | | - images = [np.random.rand(128, 128) for _ in range(3)] |
75 | | - print(f"Processing {len(images)} images...") |
76 | | - |
77 | | - # Batch analysis with curvelet method |
78 | | - results_curvelets = curvealign.batch_analyze(images, mode="curvelets") |
79 | | - print(f"Curvelet analysis: {len(results_curvelets)} results") |
80 | | - |
81 | | - # Batch analysis with CT-FIRE method |
82 | | - results_ctfire = curvealign.batch_analyze(images, mode="ctfire") |
83 | | - print(f"CT-FIRE analysis: {len(results_ctfire)} results") |
84 | | - |
85 | | - # Summary statistics |
86 | | - total_features = sum(len(r.curvelets) for r in results_curvelets) |
87 | | - print(f"Total features detected: {total_features}") |
| 47 | +def example_new_curv(): |
| 48 | + """Extract curvelets using new_curv (lower-level).""" |
| 49 | + if not HAS_PYCURVELETS: |
| 50 | + return |
| 51 | + img = np.random.rand(64, 64).astype(np.float64) * 255 |
| 52 | + curve_cp = CurveletControlParameters(keep=0.1, scale=1.0, radius=5.0) |
| 53 | + in_curves, coeffs, inc = new_curv(img, curve_cp) |
| 54 | + print(f"new_curv: {len(in_curves)} curvelets, inc={inc:.4f}") |
88 | 55 |
|
89 | | -def advanced_options_example(): |
90 | | - """Demonstrate custom analysis parameters.""" |
91 | | - print("\n=== Advanced Configuration ===") |
92 | | - |
93 | | - image = np.random.rand(256, 256) |
94 | | - |
95 | | - # Configure custom analysis options |
96 | | - options = curvealign.CurveAlignOptions( |
97 | | - keep=0.002, # Stricter coefficient threshold |
98 | | - dist_thresh=150.0, # Boundary analysis distance |
99 | | - minimum_nearest_fibers=6, # Feature computation requirements |
100 | | - minimum_box_size=24 # Local analysis window size |
101 | | - ) |
102 | | - |
103 | | - result = curvealign.analyze_image(image, options=options) |
104 | | - print(f"Custom analysis: {len(result.curvelets)} features with strict parameters") |
105 | | - |
106 | | - # CT-FIRE with custom options |
107 | | - ctfire_options = ctfire.CTFireOptions( |
108 | | - run_mode="ctfire", |
109 | | - thresh_flen=20.0, # Minimum fiber length |
110 | | - sigma_im=1.5 # Image smoothing |
111 | | - ) |
112 | | - |
113 | | - ctfire_result = ctfire.analyze_image(image, ctfire_options) |
114 | | - print(f"Custom CT-FIRE: {len(ctfire_result.fibers)} fibers") |
115 | 56 |
|
116 | | -def main(): |
117 | | - """Run all examples to demonstrate API capabilities.""" |
118 | | - print("CurveAlign Python API - Usage Examples") |
119 | | - print("=" * 50) |
120 | | - |
121 | | - # Run examples |
122 | | - basic_result = basic_analysis_example() |
123 | | - ctfire_results = ctfire_analysis_example() |
124 | | - visualization_example() |
125 | | - batch_processing_example() |
126 | | - advanced_options_example() |
127 | | - |
128 | | - print("\n" + "=" * 50) |
129 | | - print("All examples completed successfully!") |
130 | | - print("\nNext steps:") |
131 | | - print("1. Load your own images with: from skimage import io; image = io.imread('path.tif')") |
132 | | - print("2. Use visualization: matplotlib (default) or optional backends (napari, imagej)") |
133 | | - print("3. Customize analysis with CurveAlignOptions and CTFireOptions") |
134 | | - print("4. Process datasets with batch_analyze() for efficiency") |
| 57 | +def example_process_image(): |
| 58 | + """Run full process_image pipeline (requires curvelops).""" |
| 59 | + if not HAS_PYCURVELETS: |
| 60 | + return |
| 61 | + import tempfile |
| 62 | + import os |
| 63 | + img = np.random.rand(128, 128).astype(np.float64) * 255 |
| 64 | + with tempfile.TemporaryDirectory() as tmp: |
| 65 | + image_params = ImageInputParameters(img=img, img_name="test") |
| 66 | + fiber_params = FiberAnalysisParameters(fiber_mode=0, keep=0.05) |
| 67 | + output_params = OutputControlParameters( |
| 68 | + output_directory=tmp, |
| 69 | + make_associations=False, |
| 70 | + make_map=False, |
| 71 | + make_overlay=False, |
| 72 | + make_feature_file=True, |
| 73 | + ) |
| 74 | + result = process_image(image_params, fiber_params, output_params) |
| 75 | + if result and "fib_feat_df" in result: |
| 76 | + print(f"process_image: wrote features, {len(result['fib_feat_df'])} rows") |
| 77 | + else: |
| 78 | + print("process_image: no result (curvelops may be required)") |
| 79 | + |
135 | 80 |
|
136 | 81 | if __name__ == "__main__": |
137 | | - main() |
| 82 | + print("pycurvelets simple usage examples\n" + "=" * 40) |
| 83 | + example_get_ct() |
| 84 | + example_new_curv() |
| 85 | + example_process_image() |
| 86 | + print("\nDone.") |
0 commit comments