Ruslan Bakiev f14249dec9 Rewrite calibration: intersection matching + dual mapping strategy
The core calibration was broken because the green quad corners didn't
correspond to the correct court corners (giving Z=15m camera positions).

New approach:
1. Detect white line segments on green court surface
2. Merge into distinct lines, find intersections
3. Match intersections to known court template using initial
   homography from green quad (tries both left-right mirror mappings)
4. solvePnP with matched 2D-3D correspondences
5. Sanity check: camera Z must be 0-5m, prefers ~1m height
6. Fallback to quad-only calibration with both mappings if
   not enough intersections detected

Also: CameraCalibrator now uses findHomography for N>4 points,
and get_half_court_intersections() provides the 6 template keypoints.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 15:09:57 +07:00
2026-03-06 09:43:52 +07:00
2026-03-06 09:43:52 +07:00
2026-03-06 09:43:52 +07:00
2026-03-06 09:43:52 +07:00
2026-03-06 09:43:52 +07:00
2026-03-06 09:43:52 +07:00
2026-03-06 09:43:52 +07:00
2026-03-06 09:43:52 +07:00
2026-03-06 09:43:52 +07:00
2026-03-06 09:43:52 +07:00
2026-03-06 09:43:52 +07:00

🎾 Pickle - Pickleball Ball Tracking

Система трекинга пикабольного мяча с автоматической детекцией корта и преобразованием координат в метры.

Что делает

  1. Детекция корта - автоматический поиск 4 углов корта (Roboflow модель)
  2. Детекция мяча - поиск мяча на каждом кадре (YOLO v8)
  3. Трансформация координат - преобразование пикселей в метры (homography)
  4. Визуализация - видео с траекторией, графики, тепловая карта

Быстрый старт

# Запуск
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 команды

# Билд и запуск
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:

[
  {
    "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

Description
No description provided
Readme 65 MiB
Languages
Python 62.5%
HTML 37%
Dockerfile 0.3%
Shell 0.2%