## О проекте Проект позволяет управлять роботом (в симуляторе) с помощью жестов рук, распознаваемых через камеру. Используется MediaPipe для детекции скелета. ## Структура проекта ``` gesture_robot/ ├── main.py # Основной цикл ├── config.py # Конфигурация ├── skeleton/ # Детекция скелета (MediaPipe) │ └── mediapipe_detector.py ├── gesture_control/ # Управление жестами │ ├── arm_control.py # Скорости по рукам │ ├── special_gestures.py # Специальные жесты по геометрии │ └── state.py # Вкл/выкл режима (определение какой жест какую команду триггерит) ├── ml_gestures/ # ML для специальных жестов │ ├── feature_extractor.py │ ├── predict.py │ └── train.py ├── ml_gestures_dynamic/ # ML для динамических жестов │ ├── feature_extractor.py │ ├── sequence_utils.py │ ├── predict.py │ ├── evaluate.py │ └── train.py ├── robot/ # Робот (симулятор или заглушка) │ ├── map_simulator.py │ └── dummy.py ├── utils/ # Вспомогательные скрипты │ ├── annotate.py # Разметка изображений │ ├── capture_photo.py # Съёмка фото с камеры │ └── record_dynamic.py # Разметка видеопоследовательности └── requirements.txt ``` ## Подготовка и запуск ### Установка зависимостей pip install -r requirements.txt ### Настройка параметров Все основные параметры вынесены в `config.py`. Основные: - `CAMERA_ID` - индекс камеры (по умолчанию 0) - `MIRROR_CAMERA` - зеркальное отображение (True для фронтальной камеры). - `ARM_CONTROL` - настройки управления жестами (геометрией) управления - `linear_arm` - рука, отвечающая за изменение линейной скорости - `angular_arm` - рука, отвечающая за изменение угловой скорости - `max_speed_linear` - максимальная линейная скорость (по умолчанию 1) - `max_speed_angular` - максимальная угловая скорость (по умолчанию 1) - `dead_zone` - мёртвая зона - доля от ширины плеч/высоты торса (по умолчанию 0.2) для предотвращения ложных срабатываний - `debug` - Режим отладки, вкл/выкл логи (по умолчанию False) - `SPECIAL_GESTURE_MODE` - способ детекции специальных статических жестов (ml или geometric) - `ML_GESTURE_MODEL` - путь до весов ml модели статических жестов - `ML_GESTURE_CLASSES` - список классов детектируемых жестов, + none - `ROBOT_MODE` - simulator (мини игра проехать роботом мимо препятствий) или dummy (простой модуль, пишуший отправленную команду, для первичной отладки) - `ROBOT_IMAGE_PATH` - путь до картинки робота, который будет ездить в симуляции (если не указать будет треугольник просто) - параметры для симулятора карты: - `MAP_WIDTH` - ширина карты - `MAP_HEIGHT` - высота карты - `MAP_OBSTACLES` - лист препятствий в формате (x, y, width, height) - `START_POS` - стартовая позиция робота - `FINISH_POS` - позиция финиша - `ROBOT_RADIUS` - радиус робота ### Примеры запуска #### Запуск с геометрическим распознаванием 1. Настройте `config.py`: - `MIRROR_CAMERA = True` – для фронтальной камеры. - `SPECIAL_GESTURE_MODE = 'geometric'`. 2. Запустите основной скрипт: ``` python3 main.py ``` 3. Запустится симулятор и изображение с камеры #### Запуск с ML-распознаванием специальных жестов 1. Соберите датасет с нужными изображениями фото. Можете заснять собственные через `utils/capture_photo.py`: ``` python3 -m utils/capture_photo.py --dir data/raw ``` Нажмите `s`, подождите 3 секунды, фото сохранится в папку `data/raw`. Нажмите `q` чтобы закончить. 2. Разметьте фото с помощью аннотатора: ``` python3 -m utils/annotate.py --folder data/raw --classes dome,cross,none --output data.csv ``` Для каждого фото нажмите цифру, соответствующую жесту (1–dome, 2–cross, 3–none), или n для пропуска. При выходе данные сохранятся в `data.csv`. 3. Обучите модель ``` python3 -m ml_gestures/train.py --csv data.csv --model ml_gestures/models/special_model.pkl --type mlp --balance --target_classes dome,cross ``` Параметр `balance` уменьшит целевые классы (в параметре `target_classes`) до размера наименьшего из них, чтобы избежать перекоса. Класс none остаётся неизменным. 4. Оценка модели После обучения модель сохраняется, и создаётся отчёт `special_model_report.json` с метриками (`accuracy`, `precision`, `recall`, `f1`, `confusion matrix`). Для повторной оценки используйте: ``` python3 -m ml_gestures/evaluate.py --csv data.csv --model ml_gestures/models/special_model.pkl --test_size 0.2 ``` 5. Подключите модель в `config.py` ``` SPECIAL_GESTURE_MODE = 'ml' ML_GESTURE_MODEL = 'ml_gestures/models/special_model.pkl' ML_GESTURE_CLASSES = ['dome', 'cross', 'none'] ``` 6. Запустите основной скрипт: ``` python3 main.py ``` 7. Запустится симулятор и изображение с камеры ### Управление в симуляторе Симулятор – поле с препятствиями, стартом и финишем. Робот движется согласно командам. При столкновении – игра заканчивается (перезапуск по `r`). Закрытие окна игры или нажатие `q` в окне камеры – выход. 1. Управление скоростями - Линейная скорость (вперёд) – горизонтальное положение правой руки (рука вдоль тела – 0, вытянута в сторону – максимум). - Угловая скорость – вертикальное положение левой руки (рука на уровне плеча – 0, вверх – поворот вправо, вниз – поворот влево). ![Схема управления скоростями](images/arm_control.png) 2. Специальные жесты. Режим распознавания может быть геометрическим (по правилам) или обучаемым (ML-модель). - Домик – обе руки над головой (включает управление). - Крест – предплечья скрещены на груди (выключает управление). ![Схема управления жестами](images/gesture_control.png) ## Возможные проблемы 1. Камера не работает - проверьте `CAMERA_ID` в `config.py` (обычно 0 или 1). 2. Скелет не определяется – убедитесь, что человек стоит на расстоянии 1–2 метра, плечи в кадре. Можете также повысить сложность модели определения скелета (`skeleton/mediapipe_detector.py`), но скажется на производительности. 3. Ложные срабатывания жестов – в геометрическом режиме увеличьте `min_conf` в `special_gestures.py` или переключитесь на ML-режим с большим количеством примеров 4. Робот не движется – проверьте, включено ли управление (жест "домик") и видимость рук. ## Датасеты | Название | Описание | Ссылка | Количество примеров | Классы | |----------|----------|--------|---------------------|--------| | **special_gestures_v1** | Набор фотографий для распознавания специальных жестов (домик, крест, none). Собран с помощью `capture_photo.py` и стоковых изображений, размечен через `annotate.py`. | [Скачать](https://disk.yandex.ru/d/F25kMjrmZ8xwRA) | 77 (после балансировки, 13 на класс dome/cross, 51 none) | `dome`, `cross`, `none` | ## Модели | Название | Тип | Архитектура / параметры | Вход | Выход | Точность (test) | Precision / Recall (по классам) | Ссылка | Распознаваемые жесты | |----------|-----|-------------------------|------|-------|-----------------|--------------------------------|--------|----------------------| | **special_gestures_mlp** | MLP (scikit-learn) | Скрытые слои: (64, 32), активация ReLU, Adam, early stopping, 500 эпох | 99 нормализованных координат скелета (33 точки × 3) | 3 класса (dome, cross, none) | **0.56** | **dome**: P=0.00, R=0.00
**cross**: P=0.00, R=0.00
**none**: P=0.60, R=0.90 | [Скачать](https://disk.yandex.ru/d/I1WyAfN3PJM9fw) | `dome` (руки над головой домиком)
`cross` (предплечья скрещены на груди)
`none` (остальные) | | **special_gestures_rf** | Random Forest | 50 деревьев, max_depth=10, random_state=42 | 99 нормализованных координат скелета (33 точки × 3) | 3 класса (dome, cross, none) | **0.87** | **dome**: P=0.67, R=1.00
**cross**: P=0.750, R=1.00
**none**: P=0.90, R=0.90 | [Скачать](https://disk.yandex.ru/d/fcXxQh4LGjqA1g) |`dome` (руки над головой домиком)
`cross` (предплечья скрещены на груди)
`none` (остальные) | | **special_gestures_lin** | Logistic Regression | max_iter=1000, random_state=42 | 99 нормализованных координат скелета (33 точки × 3) | 3 класса (dome, cross, none) | **0.94** | **dome**: P=1.00, R=1.00
**cross**: P=0.750, R=1.00
**none**: P=1.00, R=0.90 | [Скачать](https://disk.yandex.ru/d/4_XCPEeOGvNX6g) |`dome` (руки над головой домиком)
`cross` (предплечья скрещены на груди)
`none` (остальные) |