Remove Dagster pipeline and redesign calibration flow UI

This commit is contained in:
Ruslan Bakiev
2026-03-26 09:28:49 +07:00
parent f14249dec9
commit a3b57c5742
21 changed files with 455 additions and 2215 deletions

183
README.md
View File

@@ -1,151 +1,72 @@
# 🎾 Pickle - Pickleball Ball Tracking
# Pickle Vision
Система трекинга пикабольного мяча с автоматической детекцией корта и преобразованием координат в метры.
Real-time referee system for pickleball with 2 CSI cameras on Jetson.
## Что делает
## Current Product Scope
1. **Детекция корта** - автоматический поиск 4 углов корта (Roboflow модель)
2. **Детекция мяча** - поиск мяча на каждом кадре (YOLO v8)
3. **Трансформация координат** - преобразование пикселей в метры (homography)
4. **Визуализация** - видео с траекторией, графики, тепловая карта
Three tabs in the web UI:
## Быстрый старт
1. `Camera` - live feeds from both cameras.
2. `Calibration` - step-by-step court calibration flow (ROI -> lines -> intersections -> template match -> camera pose).
3. `Trajectory` - 3D court + ball trajectory + VAR overlay.
Dagster pipeline has been removed from active project runtime.
## Run
### Local (Jetson)
```bash
# Запуск
docker-compose up -d
# Открыть Dagster UI
open http://localhost:3000
# Запустить пайплайн
docker exec pickle-dagster dagster asset materialize --select '*' -m dagster_project
python3 jetson/main.py --port 8080
```
## Структура пайплайна
Open: `http://<jetson-ip>:8080`
```
1. extract_video_frames → Извлекает 100 кадров (с 10-й секунды)
2. detect_court_keypoints → Находит 4 угла корта
↓ ↓
3. detect_ball_positions ←┘ Детектит мяч на всех кадрах
4. compute_2d_coordinates → Преобразует пиксели в метры
5. visualize_trajectory → Создает визуализации
```
## Результаты
После выполнения пайплайна в `data/`:
- **extract_video_frames.json** - метаданные видео
- **detect_court_keypoints.json** - координаты углов корта
- **detect_ball_positions.json** - позиции мяча в пикселях
- **compute_2d_coordinates.json** - позиции мяча в метрах
- **visualization.mp4** - видео с траекторией, кортом и координатами
- **frames/** - извлеченные кадры
- **ball_detections/** - кадры с найденным мячом
- **court_detection_preview.jpg** - превью с найденными углами корта
## Структура проекта
```
pickle/
├── dagster_project/ # Dagster пайплайн
│ ├── assets/ # 5 asset'ов пайплайна
│ └── io_managers/ # JSON IO manager
├── src/ # Основной код
│ ├── ball_detector.py # YOLO детекция
│ ├── court_calibrator.py # Калибровка корта
│ ├── ball_tracker.py # Трекинг
│ └── video_processor.py # Обработка видео
├── data/ # Результаты выполнения
├── DJI_0017.MP4 # Видео для обработки
├── docker-compose.yml
└── Dockerfile
```
## Конфигурация
Параметры в `dagster_project/assets/`:
- **video_extraction.py** - `start_sec=10`, `num_frames=100`
- **ball_detection.py** - `confidence_threshold=0.3`, slicing 320x320
- **coordinate_transform.py** - корт 13.4м × 6.1м
## Модели
- **Корт**: `ping-pong-paddle-ai-with-images/pickleball-court-p3chl-7tufp` (Roboflow)
- **Мяч**: `pickleball-detection-1oqlw/1` (Roboflow) → fallback на YOLOv8n
## Требования
- Docker & Docker Compose
- 4GB+ RAM
- Видео файл `DJI_0017.MP4` в корне проекта
## Docker команды
### Docker
```bash
# Билд и запуск
docker-compose up --build -d
# Логи
docker-compose logs -f
# Остановка
docker-compose down
# Выполнить пайплайн
docker exec pickle-dagster dagster asset materialize --select '*' -m dagster_project
# Выполнить один asset
docker exec pickle-dagster dagster asset materialize --select 'detect_ball_positions' -m dagster_project
docker-compose up --build
```
## Dagster UI
Open: `http://localhost:8080`
http://localhost:3000
## Calibration Flow
Показывает:
- Граф зависимостей между assets
- Логи выполнения
- История запусков
- Метаданные результатов
Calibration is launched from the `Calibration` tab with `Run Calibration Flow`.
## Формат данных
Per camera, UI shows each step status:
**compute_2d_coordinates.json**:
```json
[
{
"frame": 6,
"timestamp": 0.2,
"pixel_x": 1234.5,
"pixel_y": 678.9,
"x_m": 5.67,
"y_m": 2.34,
"confidence": 0.85
}
]
1. Court ROI (green mask)
2. White line segments detection
3. Segment merge into court lines
4. Line intersections
5. Template point match
6. Camera pose solve (PnP)
7. Geometry overlay
Output is stored in:
- `jetson/config/cam0_calibration.json`
- `jetson/config/cam1_calibration.json`
## Main Runtime Files
- `jetson/main.py` - dual-camera loop, calibration, detection, VAR events
- `src/web/app.py` - Flask API + tab endpoints
- `src/web/templates/index.html` - 3-tab UI
- `src/calibration/camera_calibrator.py` - camera geometry / projection
- `src/physics/trajectory.py` - trajectory model
- `src/physics/event_detector.py` - close-call logic
## Dependencies
Install from `requirements.txt`.
```bash
pip install -r requirements.txt
```
## Производительность
## Notes
- Извлечение кадров: ~1 сек
- Детекция корта: ~1 сек
- Детекция мяча: ~6 сек (100 кадров, ~15 FPS)
- Трансформация координат: <1 сек
- Визуализация: ~1 сек
**Итого**: ~10 секунд на 100 кадров видео
## Стоимость
**$0** - всё работает локально в Docker, без облачных API
## License
MIT
- Calibration is required before trajectory/VAR logic becomes fully useful.
- Each camera is calibrated independently against known half-court geometry.