# eye-cv 1.2.0 - Package Features & Capabilities

Complete guide to all functionalities available in `pip install eye-cv==1.2.0`

## Installation

```bash
# Minimal install (core features only)
pip install eye-cv==1.2.0

# Recommended: all optional features
pip install "eye-cv[all]==1.2.0"

# Or pick specific extras:
pip install "eye-cv[track]==1.2.0"    # Advanced tracking (ByteTrack/BoT-SORT)
pip install "eye-cv[smooth]==1.2.0"   # Kalman smoothing
pip install "eye-cv[web]==1.2.0"      # Flask + FastAPI helpers
```

## Core Dependencies (Always Installed)

- `opencv-python >= 4.8.0` - Computer vision operations
- `numpy >= 1.24.0` - Array operations
- `matplotlib >= 3.7.0` - Color palettes and visualization
- `tqdm >= 4.66.0` - Progress bars

## Optional Dependencies

| Extra | Package | Purpose |
|-------|---------|---------|
| `[smooth]` | `filterpy >= 1.4.5` | Kalman filter-based smoothing |
| `[track]` | `lap >= 0.4.0` | Linear assignment for ByteTrack/BoT-SORT |
| `[web]` | `flask >= 2.3.0`, `flask-cors >= 4.0.0` | Flask API helpers |
| `[web]` | `fastapi >= 0.104.0`, `uvicorn >= 0.24.0` | FastAPI server helpers |

---

## 1. Universal Model Format Conversion

**Auto-detect and convert detection results from 11+ model formats without manual box extraction.**

### Supported Formats

- ✅ YOLO (Ultralytics)
- ✅ PyTorch (torchvision, custom models)
- ✅ TensorFlow / Keras
- ✅ OpenCV DNN
- ✅ ONNX / TensorRT
- ✅ MMDetection
- ✅ Detectron2
- ✅ PaddlePaddle
- ✅ OpenVINO
- ✅ Raw NumPy arrays

### API

```python
import eye

# Automatic detection and conversion
detections = eye.auto_convert(model_output)

# Or use specific converters
detections = eye.from_yolo(results)
detections = eye.from_pytorch(outputs)
detections = eye.from_tensorflow(boxes, scores, classes)
detections = eye.from_opencv(detections)
```

---

## 2. Detections - Immutable Data Structure

**Thread-safe, immutable detection container with automatic caching.**

### Core Properties

```python
detections.xyxy           # Bounding boxes [x1, y1, x2, y2]
detections.confidence     # Detection scores
detections.class_id       # Class labels
detections.tracker_id     # Tracking IDs (after tracking)
detections.mask           # Segmentation masks (if available)
detections.data           # Custom metadata dict
```

### Cached Computed Properties

```python
detections.area           # Box areas (cached)
detections.center         # Box centers (cached)
detections.aspect_ratio   # Width/height ratios (cached)
```

### Immutable Operations

```python
# Filtering (returns new instance)
filtered = detections.filter(detections.confidence > 0.5)
filtered = detections[detections.class_id == 0]

# Updating (returns new instance)
updated = detections.with_confidence(new_scores)
updated = detections.with_tracker_id(track_ids)

# Slicing
first_10 = detections[:10]
```

---

## 3. Multi-Algorithm Object Tracking

**3 tracking algorithms bundled with smart recommendations.**

### Available Trackers

| Tracker | Speed | Accuracy | Use Case |
|---------|-------|----------|----------|
| **SORT** | ⚡⚡⚡ Fast | Good | Clear scenes, real-time |
| **ByteTrack** | ⚡⚡ Medium | Better | Crowded/occluded scenes |
| **BoT-SORT** | ⚡ Slower | Best | Maximum accuracy needed |

### Basic Usage

```python
import eye

# Create tracker with box inflation (Eye's innovation)
tracker = eye.Tracker(
    tracker_type=eye.TrackerType.BYTETRACK,
    inflation_factor=2.0,         # Inflates boxes 2x for matching
    enable_smoothing=True,        # Built-in jitter reduction (default: False)
    smoothing_alpha=0.3
)

# Track detections
detections = eye.auto_convert(model(frame))
tracked = tracker.update(detections)

# Reset between video clips
tracker.reset()

# Access tracking IDs
for box, track_id in zip(tracked.xyxy, tracked.tracker_id):
    print(f"Object {track_id}: {box}")
```

### Direct BoT-SORT Access

```python
from eye import BoTSORTTracker

# Use directly for appearance features / camera motion compensation
bot = BoTSORTTracker(max_age=30, appearance_thresh=0.25)
result = bot.update(dets_array, features=embeddings)
```

### Inflation for Tiny & Fast Objects

Box inflation expands boxes *only for tracker matching*. For tiny or fast-moving
objects (drones, birds, distant vehicles), use higher inflation (2.0–3.0x) so
frames with minimal spatial overlap still get correctly associated.

| Object type | Recommended inflation |
|---|---|
| Large & slow | 1.3–1.5x |
| Medium | 1.5–2.0x |
| Tiny & fast | 2.0–3.0x |

### Smart Recommendations

```python
# Get recommended settings for your use case
rec = eye.get_tracker_recommendation(eye.UseCase.TRAFFIC_DENSE)

tracker = eye.Tracker(
    tracker_type=rec['tracker_type'],
    inflation_factor=rec['inflation_factor'],
    **rec['config']
)
```

**Available Use Cases:**
- `TRAFFIC_CLEAR` - Highway, clear visibility
- `TRAFFIC_DENSE` - Urban traffic, frequent occlusions
- `PEDESTRIANS` - Crowded sidewalks, crosswalks
- `SPORTS` - Fast movement, camera motion
- `SURVEILLANCE` - Security cameras, slow-moving objects
- `WAREHOUSE` - Indoor logistics, predictable paths

---

## 4. Jitter Reduction & Smoothing

**Built-in smoothing to stabilize bounding boxes.**

### Exponential Smoothing (Always Available)

```python
tracker = eye.Tracker(
    enable_smoothing=True,      # Default: False
    smoothing_alpha=0.3         # 0.1 = very smooth, 0.5 = fast response
)
```

> **Note:** `filterpy` is optional. Exponential smoothing works without it;
> install `filterpy` only for Kalman smoothing.

### Kalman Filter Smoothing (Requires `[smooth]` extra)

```python
from eye import KalmanSmoothing

smoother = KalmanSmoothing(process_noise=0.05, measurement_noise=0.1)
smoothed_box = smoother.update(track_id, box)
```

### Smoothing Presets

```python
from eye import SmoothingConfig, SmoothingPreset

# Easy presets
config = SmoothingConfig.from_preset(SmoothingPreset.MEDIUM)

tracker = eye.Tracker(
    enable_smoothing=True,
    smoothing_alpha=config.alpha
)
```

**Presets:** `NONE`, `LIGHT`, `MEDIUM`, `HEAVY`, `ULTRA`

---

## 5. Professional Annotators

**Draw detection results on frames with modern styling.**

### Core Annotators (Always Available)

```python
import eye

# Bounding boxes with rounded corners
box_annotator = eye.BoxAnnotator(
    thickness=2,
    color=eye.ColorPalette.default()
)

# Labels with shadows
label_annotator = eye.LabelAnnotator(
    text_scale=0.5,
    text_thickness=1
)

# Fading motion trails
trace_annotator = eye.TraceAnnotator(
    trace_length=30,
    thickness=2
)

# Heatmaps
heatmap_annotator = eye.HeatMapAnnotator()

# Annotate frame
annotated = box_annotator.annotate(frame, detections)
annotated = label_annotator.annotate(annotated, detections, labels)
```

### Modern Annotators (v2.0 Innovations)

```python
from eye import (
    GradientBoxAnnotator,
    NeonTraceAnnotator,
    ShadowBoxAnnotator,
    FPSAnnotator,
    InfoAnnotator
)

# Gradient-filled boxes
gradient = GradientBoxAnnotator()

# Glowing neon trails
neon = NeonTraceAnnotator(glow_intensity=2.0)

# Boxes with drop shadows
shadow = ShadowBoxAnnotator(shadow_offset=5)

# FPS counter
fps = FPSAnnotator()

# Info panel overlay
info = InfoAnnotator()
```

---

## 6. Zone Management & Analytics

**Define zones and count objects crossing boundaries.**

```python
import eye
import numpy as np

# Define zone polygon
zone = eye.PolygonZone(
    polygon=np.array([[100, 300], [200, 300], [200, 400], [100, 400]]),
    triggering_anchors=[eye.Position.CENTER]
)

# Filter detections in zone
in_zone = zone.trigger(detections)

# Get counts
print(f"Current: {zone.current_count}, Total: {len(in_zone)}")

# Visualize zone
zone_annotator = eye.PolygonZoneAnnotator(
    zone=zone,
    color=eye.Color.from_hex("#FF0000"),
    thickness=2
)
annotated = zone_annotator.annotate(frame)
```

### Line Zone (Virtual Trip Wire)

```python
line_zone = eye.LineZone(
    start=eye.Point(100, 300),
    end=eye.Point(500, 300)
)

crossed = line_zone.trigger(detections)
```

---

## 7. Video Processing

**Efficient video reading/writing with progress tracking.**

```python
import eye

# Read video info
video_info = eye.VideoInfo.from_video_path("input.mp4")
print(f"FPS: {video_info.fps}, Frames: {video_info.total_frames}")

# Process video with progress bar
def process_frame(frame, frame_idx):
    # Detection
    results = model(frame)
    detections = eye.auto_convert(results)
    
    # Tracking
    detections = tracker.update(detections)
    
    # Annotation
    annotated = box_annotator.annotate(frame, detections)
    return annotated

eye.process_video(
    source_path="input.mp4",
    target_path="output.mp4",
    callback=process_frame
)

# Or use frame generator for custom processing
for frame in eye.get_video_frames_generator("input.mp4"):
    processed = process_frame(frame, 0)
```

### Video Writer

```python
writer = eye.VideoWriter(
    target_path="output.mp4",
    video_info=video_info
)

for frame in frames:
    writer.write_frame(frame)

writer.close()
```

---

## 8. Color Palettes

**Pre-defined and custom color schemes.**

```python
from eye import Color, ColorPalette

# Use built-in palette
palette = ColorPalette.default()

# Create custom palette
custom = ColorPalette([
    Color(255, 0, 0),      # Red
    Color.from_hex("#00FF00"),  # Green
    Color(0, 0, 255)       # Blue
])

# Get color by class ID
color = palette.by_idx(class_id)
```

---

## 9. Web API Support (Requires `[web]` extra)

**Flask and FastAPI helpers for REST APIs.**

### Flask (5-line setup)

```python
from ultralytics import YOLO
import eye

model = YOLO("yolo11n.pt")
app = eye.create_flask_app(model, class_names=model.names)
app.run(host='0.0.0.0', port=5000)
```

**API Endpoint:** `POST /detect` with image upload

**Response:**
```json
{
  "success": true,
  "detections": [
    {
      "bbox": [x1, y1, x2, y2],
      "confidence": 0.95,
      "class_id": 0,
      "class_name": "person"
    }
  ],
  "processing_time_ms": 15.3
}
```

### FastAPI

```python
app = eye.create_fastapi_app(model, class_names=model.names)

# Run with: uvicorn main:app --reload
```

---

## 10. Utility Functions

### Geometry Operations

```python
from eye.detection.utils import (
    box_iou_batch,           # IoU between box sets
    clip_boxes,              # Clip boxes to image bounds
    scale_boxes,             # Scale boxes by factor
    move_boxes,              # Translate boxes
    xywh_to_xyxy,           # Convert box formats
    polygon_to_mask          # Rasterize polygon
)
```

### Image Operations

```python
from eye.utils.image import (
    crop_image,              # Crop to bounding box
    resize_image,            # Resize with aspect ratio
    letterbox_image,         # Pad to square
    overlay_image            # Alpha blend images
)
```

### Non-Maximum Suppression

```python
from eye.detection.overlap_filter import (
    box_non_max_suppression,
    mask_non_max_suppression
)

# Remove overlapping detections
filtered = box_non_max_suppression(detections, iou_threshold=0.5)
```

---

## Quick Start Examples

### 1. Basic Detection + Tracking

```python
import eye
from ultralytics import YOLO
import cv2

model = YOLO("yolo11n.pt")
tracker = eye.Tracker(tracker_type=eye.TrackerType.SORT)
box_annotator = eye.BoxAnnotator()

cap = cv2.VideoCapture("video.mp4")
while True:
    ret, frame = cap.read()
    if not ret:
        break
    
    # Detect and track
    results = model(frame)[0]
    detections = eye.from_yolo(results)
    tracked = tracker.update(detections)
    
    # Annotate
    annotated = box_annotator.annotate(frame, tracked)
    cv2.imshow("Tracking", annotated)
    
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()
```

### 2. Traffic Monitoring with Zone Counting

```python
import eye
import numpy as np

# Setup
tracker = eye.Tracker(
    tracker_type=eye.TrackerType.BYTETRACK,
    inflation_factor=2.0
)

zone = eye.PolygonZone(
    polygon=np.array([[400, 300], [800, 300], [800, 500], [400, 500]])
)

# Process video
def callback(frame, idx):
    detections = eye.auto_convert(model(frame))
    tracked = tracker.update(detections)
    
    # Count in zone
    in_zone = zone.trigger(tracked)
    
    # Annotate
    annotated = box_annotator.annotate(frame, tracked)
    annotated = zone_annotator.annotate(annotated)
    
    return annotated

eye.process_video("traffic.mp4", "output.mp4", callback)
```

### 3. Multi-Class Detection with Filtering

```python
import eye

detections = eye.auto_convert(model(frame))

# Filter by confidence
high_conf = detections.filter(detections.confidence > 0.7)

# Filter by class (e.g., only people and cars)
people_cars = high_conf[
    (high_conf.class_id == 0) | (high_conf.class_id == 2)
]

# Track and annotate
tracked = tracker.update(people_cars)
annotated = box_annotator.annotate(frame, tracked)
```

---

## Performance Tips

1. **Use box inflation** (1.5-2.5x) for better tracking in crowded scenes
2. **Enable smoothing** for stable bounding boxes
3. **Batch operations** when possible (detections are vectorized)
4. **Filter early** to reduce tracking overhead
5. **Use appropriate tracker** - SORT for speed, ByteTrack for crowded scenes

---

## Type Hints & IDE Support

Eye includes full type annotations (`py.typed` marker):

```python
import eye

# All functions and classes have proper type hints
detections: eye.Detections = eye.auto_convert(results)
tracker: eye.Tracker = eye.Tracker()
```

---

## Thread Safety

- ✅ `Detections` class is fully immutable and thread-safe
- ✅ Annotators are stateless and thread-safe
- ⚠️ `Tracker` maintains state - use one per thread/video
- ⚠️ Smoothers maintain state - use one per tracked object

---

## Security Audit

✅ **Zero CVEs** (audited 2024 Q4)  
✅ **A+ Rating** - All dependencies actively maintained  
✅ **No deprecated packages**

---

## License

MIT License - Free for commercial use

---

## Support & Documentation

- 📦 PyPI: https://pypi.org/project/eye-cv/
- 🐙 GitHub: https://github.com/danssou/eye
- 📚 Examples: See `examples/` directory in repo (20+ complete examples)
- 🎯 Tracker Guide: See `TRACKER_GUIDE.md` for decision tree
- 🔧 Usage Patterns: See `USAGE.md` for common workflows

---

**Version:** 1.2.0  
**Python:** >=3.8  
**Status:** Production-Ready
