Metadata-Version: 2.4
Name: vascx_simplify
Version: 0.1.6
Summary: A PyTorch library for vessel and fundus image analysis (simplified rewrite)
Author-email: Phongphan Phienphanich <garpong@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/kapong/vascx_simplify
Project-URL: Repository, https://github.com/kapong/vascx_simplify.git
Project-URL: Documentation, https://github.com/kapong/vascx_simplify#readme
Project-URL: Bug Tracker, https://github.com/kapong/vascx_simplify/issues
Project-URL: Original Work, https://github.com/Eyened/rtnls_vascx_models
Keywords: pytorch,medical-imaging,fundus,vessel-analysis,computer-vision
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Scientific/Engineering :: Image Processing
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: huggingface-hub>=0.10.0
Requires-Dist: kornia>=0.6.0
Requires-Dist: numpy>=1.21.0
Requires-Dist: scikit-learn>=1.0.0
Requires-Dist: scipy>=1.7.0
Requires-Dist: torch>=1.10.0
Provides-Extra: dev
Requires-Dist: black>=22.0.0; extra == "dev"
Requires-Dist: flake8>=5.0.0; extra == "dev"
Requires-Dist: isort>=5.10.0; extra == "dev"
Requires-Dist: mypy>=0.990; extra == "dev"
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Provides-Extra: test
Requires-Dist: pillow>=9.0.0; extra == "test"
Requires-Dist: pytest>=7.0.0; extra == "test"
Requires-Dist: pytest-cov>=4.0.0; extra == "test"
Dynamic: license-file

# vascx_simplify

A PyTorch library for vessel and fundus image analysis, providing GPU-accelerated preprocessing and inference utilities for medical imaging tasks.

**Note:** This is a simplified rewrite of [rtnls_vascx_models](https://github.com/Eyened/rtnls_vascx_models) by Eyened.

## AI Usage Disclaimer

This project was developed with significant assistance from AI tools (GitHub Copilot, ChatGPT, Claude) for code organization, refactoring, documentation, and packaging.

## Features

- **GPU-Accelerated Preprocessing**: Fast fundus image contrast enhancement with mixed precision support
- **Sliding Window Inference**: Efficient inference for large images
- **Ensemble Models**: Segmentation, classification, regression, and heatmap-based models
- **HuggingFace Integration**: Easy model loading from HuggingFace Hub
- **Minimal Dependencies**: Uses fewer dependency libraries for easier installation and maintenance

## Installation

```bash
pip install vascx_simplify
```

From source:
```bash
git clone https://github.com/kapong/vascx_simplify.git
cd vascx_simplify
pip install -e .
```

## Requirements

- Python >= 3.12
- PyTorch >= 1.10.0
- kornia >= 0.6.0
- scikit-learn >= 1.0.0
- scipy >= 1.7.0
- numpy >= 1.21.0
- huggingface-hub >= 0.10.0

## Usage Examples

### Artery/Vein Segmentation

Segment arteries (red), veins (blue), and crossings (green) from fundus images:

```python
from vascx_simplify import EnsembleSegmentation, VASCXTransform, from_huggingface
from PIL import Image
import torch

# Load model
model_path = from_huggingface('Eyened/vascx:artery_vein/av_july24.pt')
model = EnsembleSegmentation(model_path, VASCXTransform())

# Predict
rgb_image = Image.open('fundus.jpg')
prediction = model.predict(rgb_image)  # Returns [B, H, W] with class values
```

![Artery/Vein Segmentation Result](https://github.com/kapong/vascx_simplify/raw/main/examples/artery_vein_segmentation_result.png)

### Optic Disc Segmentation

Detect and segment the optic disc:

```python
from vascx_simplify import EnsembleSegmentation, VASCXTransform, from_huggingface
from PIL import Image

model_path = from_huggingface('Eyened/vascx:disc/disc_july24.pt')
model = EnsembleSegmentation(model_path, VASCXTransform(512))

rgb_image = Image.open('fundus.jpg')
prediction = model.predict(rgb_image)  # Returns [B, H, W] with class values
```

![Optic Disc Segmentation Result](https://github.com/kapong/vascx_simplify/raw/main/examples/disc_segmentation_result.png)

### Fovea Detection

Locate the fovea center using heatmap regression:

```python
from vascx_simplify import HeatmapRegressionEnsemble, VASCXTransform, from_huggingface
from PIL import Image

model_path = from_huggingface('Eyened/vascx:fovea/fovea_july24.pt')
model = HeatmapRegressionEnsemble(model_path, VASCXTransform())

rgb_image = Image.open('fundus.jpg')
prediction = model.predict(rgb_image)  # Returns [B, M, 2] with (x, y) coordinates

fovea_x = prediction[0, 0, 0].item()
fovea_y = prediction[0, 0, 1].item()
```

![Fovea Detection Result](https://github.com/kapong/vascx_simplify/raw/main/examples/fovea_detection_result.png)

### Image Quality Assessment

Classify fundus image quality (Reject/Usable/Good):

```python
from vascx_simplify import ClassificationEnsemble, VASCXTransform, from_huggingface
from PIL import Image

model_path = from_huggingface('Eyened/vascx:quality/quality.pt')
model = ClassificationEnsemble(model_path, VASCXTransform(have_ce=False))

rgb_image = Image.open('fundus.jpg')
prediction = model.predict(rgb_image)  # Returns [B, 3] with quality scores (already softmaxed)

# Get probabilities (already normalized)
q1_reject, q2_usable, q3_good = prediction[0].tolist()
```

![Image Quality Classification Result](https://github.com/kapong/vascx_simplify/raw/main/examples/quality_classification_result.png)

### Batch Processing

Process multiple images efficiently with automatic batch splitting to prevent out-of-memory errors:

```python
from vascx_simplify import EnsembleSegmentation, VASCXTransform, from_huggingface
from PIL import Image

# Load model once
model_path = from_huggingface('Eyened/vascx:artery_vein/av_july24.pt')
model = EnsembleSegmentation(model_path, VASCXTransform())

# Load multiple images
images = [Image.open(f'fundus_{i}.jpg') for i in range(10)]

# Batch prediction (much faster than sequential processing)
predictions = model.predict(images)  # Returns [10, H, W]
# Automatically splits into chunks of 4 (default for segmentation)

# Process each result
for i, pred in enumerate(predictions):
    # pred is [H, W] - no need for [0] indexing
    save_prediction(pred, f'result_{i}.png')

# For large datasets, automatic splitting prevents OOM
large_images = [Image.open(f'img_{i}.jpg') for i in range(100)]
predictions = model.predict(large_images)  # Auto-splits into chunks
# Returns [100, H, W] - seamlessly handles large batches

# Override batch size for your GPU memory
predictions = model.predict(images, batch_size=8)  # Process 8 at once
```

**Key Features**:
- 🚀 **2-3x faster** than processing images sequentially
- 🛡️ **Automatic OOM prevention** - large batches split automatically
- 🔄 **100% backward compatible** - existing single-image code works unchanged
- ⚙️ **Configurable** - override batch size per call or use smart defaults
- 📊 **Flexible inputs** - accepts PIL.Image, torch.Tensor, or lists of either

**Memory Management**: Each model type has sensible default batch sizes:
- **Segmentation**: 4 images (sliding window is memory-intensive)
- **Classification**: 16 images (lightweight forward pass)
- **Regression**: 16 images
- **Heatmap**: 2 images (heatmaps are very memory-intensive)

**Usage Patterns**:

```python
# Pattern 1: Batch processing a directory
import glob
from pathlib import Path

image_paths = glob.glob('fundus_images/*.jpg')
images = [Image.open(p) for p in image_paths]
predictions = model.predict(images)  # Efficient batch processing

# Pattern 2: Process with torch tensors
tensors = [torch.randn(3, 512, 512) for _ in range(20)]
predictions = model.predict(tensors)  # Works with tensors too

# Pattern 3: Memory-constrained environment
predictions = model.predict(images, batch_size=2)  # Smaller batches

# Pattern 4: High-memory GPU
predictions = model.predict(images, batch_size=16)  # Larger batches
```

**Backward Compatibility**: All existing single-image code works without modification:
```python
# This still works exactly as before
image = Image.open('fundus.jpg')
pred = model.predict(image)  # Returns [1, H, W]
result = pred[0]  # Access with [0] as before
```

**Performance Tips**:
- Use batch processing for 3+ images to see significant speedup
- Default batch sizes are optimized for most GPUs (8-16GB VRAM)
- Increase batch_size for high-memory GPUs (24GB+)
- Decrease batch_size if you encounter OOM errors
- List of tensors is slightly faster than list of PIL.Images

See `examples/05_batch_processing.py` for a complete performance demonstration.

## License

MIT License - see LICENSE file for details.

## Author

Phongphan Phienphanich <garpong@gmail.com>

## Acknowledgments

This is a simplified rewrite of [rtnls_vascx_models](https://github.com/Eyened/rtnls_vascx_models) by Eyened.
