14 KiB
О проекте
Проект позволяет управлять роботом (в симуляторе) с помощью жестов рук, распознаваемых через камеру. Используется 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- список классов детектируемых жестов, + noneROBOT_MODE- simulator (мини игра проехать роботом мимо препятствий) или dummy (простой модуль, пишуший отправленную команду, для первичной отладки)ROBOT_IMAGE_PATH- путь до картинки робота, который будет ездить в симуляции (если не указать будет треугольник просто)- параметры для симулятора карты:
MAP_WIDTH- ширина картыMAP_HEIGHT- высота картыMAP_OBSTACLES- лист препятствий в формате (x, y, width, height)START_POS- стартовая позиция роботаFINISH_POS- позиция финишаROBOT_RADIUS- радиус робота
Примеры запуска
Запуск с геометрическим распознаванием
- Настройте
config.py:MIRROR_CAMERA = True– для фронтальной камеры.SPECIAL_GESTURE_MODE = 'geometric'.
- Запустите основной скрипт:
python3 main.py
- Запустится симулятор и изображение с камеры
Запуск с ML-распознаванием статических жестов
- Соберите датасет с нужными изображениями фото. Можете заснять собственные через
utils/capture_photo.py:
python3 -m utils/capture_photo.py --dir data/raw
Нажмите s, подождите 3 секунды, фото сохранится в папку data/raw. Нажмите q чтобы закончить.
- Разметьте фото с помощью аннотатора:
python3 -m utils/annotate.py --folder data/raw --classes dome,cross,none --output data.csv
Для каждого фото нажмите цифру, соответствующую жесту (1–dome, 2–cross, 3–none), или n для пропуска. При выходе данные сохранятся в data.csv.
- Обучите модель
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 остаётся неизменным.
- Оценка модели
После обучения модель сохраняется, и создаётся отчёт
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
- Подключите модель в
config.py
SPECIAL_GESTURE_MODE = 'ml'
ML_GESTURE_MODEL = 'ml_gestures/models/special_model.pkl'
ML_GESTURE_CLASSES = ['dome', 'cross', 'none']
- Запустите основной скрипт:
python3 main.py
- Запустится симулятор и изображение с камеры
Запуск с ML-распознаванием динамических жестов
- Соберите датасетс нужными последовательностями жестов.
python -m utils.record_dynamic --label wave_right --output dynamic_data.csv --duration 2.0
Нажмите space, подождите 3 секунды, последовательность точек с меткой сохранится в файл dynamic_data.csv. Нажмите q чтобы закончить.
2. Обучите модель
python -m ml_gestures_dynamic.train --data dynamic_data.csv --model dynamic_model.h5 --max_len 14 --epochs 50 --test_size 0.2
Укажите путь до вашего файла, укажите путь, куда сохранить модель, а также укажите длину последовательности кадров (зависит от вашей камеры и железа, будет выводится при сборе данных)
3. Оценка модели
После обучения модель сохраняется, и создаётся отчёт dynamic_model_report.json с метриками (accuracy, precision, recall, f1, confusion matrix). Для повторной оценки используйте:
python -m ml_gestures_dynamic.evaluate --data dynamic_data.csv --model dynamic_model.h5 --max_len 14 --test_size 0.2
- Подключить модель в
config.py
DYNAMIC_GESTURE = {
'enabled': True, # включить/выключить
'model_path': 'ml_gestures/models/dynamic_model.h5',
'classes_path': 'ml_gestures//odels/dynamic_model_classes.pkl',
'window_size': 14, # длина буфера
'threshold': 0.7, # порог уверенности
'actions': {
'wave_left': 'reset', # при жесте wave_left – перезапуск симулятора
'wave_right': 'restart', # при wave_right – рестарт
}
Управление в симуляторе
Симулятор – поле с препятствиями, стартом и финишем. Робот движется согласно командам. При столкновении – игра заканчивается (перезапуск по r). Закрытие окна игры или нажатие q в окне камеры – выход.
- Управление скоростями
- Линейная скорость (вперёд) – горизонтальное положение правой руки (рука вдоль тела – 0, вытянута в сторону – максимум).
- Угловая скорость – вертикальное положение левой руки (рука на уровне плеча – 0, вверх – поворот вправо, вниз – поворот влево).
- Специальные жесты. Режим распознавания может быть геометрическим (по правилам) или обучаемым (ML-модель).
- Домик – обе руки над головой (включает управление).
- Крест – предплечья скрещены на груди (выключает управление).
Возможные проблемы
- Камера не работает - проверьте
CAMERA_IDвconfig.py(обычно 0 или 1). - Скелет не определяется – убедитесь, что человек стоит на расстоянии 1–2 метра, плечи в кадре. Можете также повысить сложность модели определения скелета (
skeleton/mediapipe_detector.py), но скажется на производительности. - Ложные срабатывания жестов – в геометрическом режиме увеличьте
min_confвspecial_gestures.pyили переключитесь на ML-режим с большим количеством примеров - Робот не движется – проверьте, включено ли управление (жест "домик") и видимость рук.
Датасеты
| Название | Описание | Ссылка | Количество примеров | Классы |
|---|---|---|---|---|
| special_gestures_v1 | Набор фотографий для распознавания специальных жестов (домик, крест, none). Собран с помощью capture_photo.py и стоковых изображений, размечен через annotate.py. |
Скачать | 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 |
Скачать | 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 |
Скачать | 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 |
Скачать | dome (руки над головой домиком)cross (предплечья скрещены на груди)none (остальные) |

