152 lines
4.8 KiB
Markdown
152 lines
4.8 KiB
Markdown
# 🎾 Pickle - Pickleball Ball Tracking
|
||
|
||
Система трекинга пикабольного мяча с автоматической детекцией корта и преобразованием координат в метры.
|
||
|
||
## Что делает
|
||
|
||
1. **Детекция корта** - автоматический поиск 4 углов корта (Roboflow модель)
|
||
2. **Детекция мяча** - поиск мяча на каждом кадре (YOLO v8)
|
||
3. **Трансформация координат** - преобразование пикселей в метры (homography)
|
||
4. **Визуализация** - видео с траекторией, графики, тепловая карта
|
||
|
||
## Быстрый старт
|
||
|
||
```bash
|
||
# Запуск
|
||
docker-compose up -d
|
||
|
||
# Открыть Dagster UI
|
||
open http://localhost:3000
|
||
|
||
# Запустить пайплайн
|
||
docker exec pickle-dagster dagster asset materialize --select '*' -m dagster_project
|
||
```
|
||
|
||
## Структура пайплайна
|
||
|
||
```
|
||
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 команды
|
||
|
||
```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
|
||
```
|
||
|
||
## Dagster UI
|
||
|
||
http://localhost:3000
|
||
|
||
Показывает:
|
||
- Граф зависимостей между assets
|
||
- Логи выполнения
|
||
- История запусков
|
||
- Метаданные результатов
|
||
|
||
## Формат данных
|
||
|
||
**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 сек
|
||
- Детекция корта: ~1 сек
|
||
- Детекция мяча: ~6 сек (100 кадров, ~15 FPS)
|
||
- Трансформация координат: <1 сек
|
||
- Визуализация: ~1 сек
|
||
|
||
**Итого**: ~10 секунд на 100 кадров видео
|
||
|
||
## Стоимость
|
||
|
||
**$0** - всё работает локально в Docker, без облачных API
|
||
|
||
## License
|
||
|
||
MIT
|