# optik 🔬

**The optical lens for AI model interpretability.**

[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

Analyze what object detection models (YOLO, etc.) have learned through innovative visualization and interpretability methods.

## Features

- 🔥 **DetectionFlow** - Multi-scale FPN attribution with separate class/bbox analysis
- 🎯 **CounterfactualProbe** - Find minimal changes that flip detections
- 📊 **GridCellTrace** - Visualize grid cell activations (anchor-free YOLO v8+)
- 📄 **HTML Reports** - Interactive analysis reports

## Installation

```bash
pip install optik-vision
```

### Windows Users (CPU only)
PyTorch 2.9+ has DLL issues on Windows. Install torch separately first:
```bash
pip install torch==2.8.0+cpu --index-url https://download.pytorch.org/whl/cpu
pip install optik-vision
```

## Quick Start

```python
from optik import Optik

# Load your trained YOLO model
analyzer = Optik.from_yolo("path/to/best.pt")

# Analyze an image
results = analyzer.analyze("test_image.jpg")

# Generate HTML report
analyzer.report(results, "report.html")
```

## CLI Usage

```bash
# Analyze images and generate report
optik analyze model.pt --images ./test_images --output report.html
```

## Analysis Methods

### DetectionFlow
Multi-scale attribution showing what image regions contribute to each detection.

```python
flow = analyzer.detection_flow("image.jpg", detection_idx=0)
# Returns: P3/P4/P5 attribution maps, class/bbox separate attributions
print(f"Scale contributions: {flow.scale_contributions}")
# {'p3': 0.34, 'p4': 0.57, 'p5': 0.09}
```

**What it tells you:**
- Which FPN scale (P3=small, P4=medium, P5=large objects) contributed most
- What image regions the model focused on for classification vs bbox regression

### CounterfactualProbe
Find minimal perturbations that would remove or change a detection.

```python
cf = analyzer.counterfactual("image.jpg", detection_idx=0, target="remove")
# Returns: perturbation mask, critical regions
```

**What it tells you:**
- Which pixels are critical for the detection
- How robust the detection is

### GridCellTrace
Visualize which grid cells activated across FPN scales.

```python
trace = analyzer.grid_trace("image.jpg")
# Returns: per-scale activation maps, winning cells, runner-ups
print(f"Detections per scale: {trace.detections_per_scale}")
```

**What it tells you:**
- How detections are distributed across scales
- Which cells almost made it but were suppressed by NMS

## Visualization

```python
from optik.utils import load_image, create_detection_overlay, save_image

image = load_image("test.jpg")
results = analyzer.analyze("test.jpg")

# Create heatmap overlay focused on detection bbox
for i, flow in enumerate(results["detection_flow"]):
    overlay = create_detection_overlay(
        image, 
        flow.final_attribution,
        flow.detection.bbox,
        alpha=0.5
    )
    save_image(overlay, f"detection_{i}_heatmap.jpg")
```

## Extensibility

optik is designed to support multiple model architectures. Currently supported:
- ✅ Ultralytics YOLO (v8, v10, v11)

Future support planned:
- ⏳ DETR / RT-DETR
- ⏳ EfficientDet
- ⏳ Custom PyTorch models

### Adding a new model adapter

```python
from optik.core.base import BaseModelAdapter

class MyModelAdapter(BaseModelAdapter):
    def get_fpn_layers(self):
        # Return FPN layer modules for hooking
        return {'p3': ..., 'p4': ..., 'p5': ...}
    
    def predict(self, image):
        # Run inference
        return [Detection(...), ...]
```

## Requirements

- Python 3.9+
- PyTorch 2.0-2.8 (2.9+ has Windows issues)
- ultralytics
- Pillow
- NumPy
- Jinja2

## License

MIT License - see [LICENSE](LICENSE) for details.

## Citation

If you use optik-vision in your research, please cite:

```bibtex
@software{optik_vision2025,
  title = {optik-vision: The optical lens for AI model interpretability},
  year = {2025},
  url = {https://github.com/optik-ai/optik-vision}
}
```
