fixed some errors, dynamic fine
This commit is contained in:
@@ -163,6 +163,7 @@ DYNAMIC_GESTURE = {
|
|||||||
| Название | Описание | Ссылка | Количество примеров | Классы |
|
| Название | Описание | Ссылка | Количество примеров | Классы |
|
||||||
|----------|----------|--------|---------------------|--------|
|
|----------|----------|--------|---------------------|--------|
|
||||||
| **special_gestures_v1** | Набор фотографий для распознавания специальных жестов (домик, крест, none). Собран с помощью `capture_photo.py` и стоковых изображений, размечен через `annotate.py`. | [Скачать](https://disk.yandex.ru/d/F25kMjrmZ8xwRA) | 77 (после балансировки, 13 на класс dome/cross, 51 none) | `dome`, `cross`, `none` |
|
| **special_gestures_v1** | Набор фотографий для распознавания специальных жестов (домик, крест, none). Собран с помощью `capture_photo.py` и стоковых изображений, размечен через `annotate.py`. | [Скачать](https://disk.yandex.ru/d/F25kMjrmZ8xwRA) | 77 (после балансировки, 13 на класс dome/cross, 51 none) | `dome`, `cross`, `none` |
|
||||||
|
| **dynamic_data_v1** | csv файл с последовательностью точек скелета для 14 кадров | [Скачать](https://disk.yandex.ru/d/hnm6apfuxJsEyw) | 81 (по 20 на махи правой и левой рукой, 61 на none) | `none`, `wave_left`, `wave_right` |
|
||||||
|
|
||||||
## Модели
|
## Модели
|
||||||
| Название | Тип | Архитектура / параметры | Вход | Выход | Точность (test) | Precision / Recall (по классам) | Ссылка | Распознаваемые жесты |
|
| Название | Тип | Архитектура / параметры | Вход | Выход | Точность (test) | Precision / Recall (по классам) | Ссылка | Распознаваемые жесты |
|
||||||
@@ -170,3 +171,4 @@ DYNAMIC_GESTURE = {
|
|||||||
| **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<br>**cross**: P=0.00, R=0.00<br>**none**: P=0.60, R=0.90 | [Скачать](https://disk.yandex.ru/d/I1WyAfN3PJM9fw) | `dome` (руки над головой домиком)<br>`cross` (предплечья скрещены на груди)<br>`none` (остальные) |
|
| **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<br>**cross**: P=0.00, R=0.00<br>**none**: P=0.60, R=0.90 | [Скачать](https://disk.yandex.ru/d/I1WyAfN3PJM9fw) | `dome` (руки над головой домиком)<br>`cross` (предплечья скрещены на груди)<br>`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<br>**cross**: P=0.750, R=1.00<br>**none**: P=0.90, R=0.90 | [Скачать](https://disk.yandex.ru/d/fcXxQh4LGjqA1g) |`dome` (руки над головой домиком)<br>`cross` (предплечья скрещены на груди)<br>`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<br>**cross**: P=0.750, R=1.00<br>**none**: P=0.90, R=0.90 | [Скачать](https://disk.yandex.ru/d/fcXxQh4LGjqA1g) |`dome` (руки над головой домиком)<br>`cross` (предплечья скрещены на груди)<br>`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<br>**cross**: P=0.750, R=1.00<br>**none**: P=1.00, R=0.90 | [Скачать](https://disk.yandex.ru/d/4_XCPEeOGvNX6g) |`dome` (руки над головой домиком)<br>`cross` (предплечья скрещены на груди)<br>`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<br>**cross**: P=0.750, R=1.00<br>**none**: P=1.00, R=0.90 | [Скачать](https://disk.yandex.ru/d/4_XCPEeOGvNX6g) |`dome` (руки над головой домиком)<br>`cross` (предплечья скрещены на груди)<br>`none` (остальные) |
|
||||||
|
| **dynamic_model** | LSTM | 2 слоя LSTM по 64 нейрона, Dropout(0.3), Dense(3, softmax), optimizer=Adam, loss=sparse_categorical_crossentropy, epochs=50, batch_size=16 | Последовательность из 14 кадров, каждый кадр – 99 признаков (нормализованные координаты скелета) | 3 класса (none, wave_left, wave_right) | 0.8235 | Precision / Recall (по классам) | [Скачать](https://disk.yandex.ru/d/yDol79iB2ZlS6Q) | `wave_left` (махание левой рукой) `wave_right` (махание правой рукой) `none` (отсутствие жеста) |
|
||||||
|
|||||||
@@ -16,18 +16,19 @@ class Config:
|
|||||||
|
|
||||||
# ===== Специальные жесты =====
|
# ===== Специальные жесты =====
|
||||||
SPECIAL_GESTURE_MODE = 'ml' #ml #geometric
|
SPECIAL_GESTURE_MODE = 'ml' #ml #geometric
|
||||||
ML_GESTURE_MODEL = '/home/ubuntu/sirius/models/rf/special_model.pkl'
|
ML_GESTURE_MODEL = '/home/ubuntu/sirius/models/rf/special_gestures_rf.pkl'
|
||||||
ML_GESTURE_CLASSES = ['dome', 'cross', 'none']
|
ML_GESTURE_CLASSES = ['dome', 'cross', 'none']
|
||||||
|
|
||||||
DYNAMIC_GESTURE = {
|
DYNAMIC_GESTURE = {
|
||||||
'enabled': True, # включить/выключить
|
'enabled': True, # включить/выключить
|
||||||
'model_path': 'dynamic_model.h5',
|
'model_path': '/home/ubuntu/sirius/models/lstm/dynamic_model.h5',
|
||||||
'classes_path': 'dynamic_model_classes.pkl',
|
'classes_path': '/home/ubuntu/sirius/models/lstm/dynamic_model_classes.pkl',
|
||||||
'window_size': 14, # длина буфера
|
'window_size': 14, # длина буфера
|
||||||
'threshold': 0.7, # порог уверенности
|
'threshold': 0.8, # порог уверенности
|
||||||
'actions': {
|
'actions': {
|
||||||
'wave_left': 'reset', # при жесте wave_left – перезапуск симулятора
|
'wave_left': 'reset', # при жесте wave_left – перезапуск симулятора
|
||||||
'wave_right': 'restart', # при wave_right – рестарт
|
'wave_right': 'restart' # при wave_right – рестарт
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# ===== Робот =====
|
# ===== Робот =====
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ def main():
|
|||||||
print("В симуляторе: R – перезапуск после Game Over/победы")
|
print("В симуляторе: R – перезапуск после Game Over/победы")
|
||||||
print("q – выход")
|
print("q – выход")
|
||||||
|
|
||||||
|
last_dynamic_gesture = None
|
||||||
|
dynamic_gesture_counter = 0
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
ret, frame = cap.read()
|
ret, frame = cap.read()
|
||||||
if not ret:
|
if not ret:
|
||||||
@@ -67,7 +70,6 @@ def main():
|
|||||||
if result['success']:
|
if result['success']:
|
||||||
landmarks = result['landmarks']
|
landmarks = result['landmarks']
|
||||||
|
|
||||||
if result['success']:
|
|
||||||
if cfg.DYNAMIC_GESTURE['enabled']:
|
if cfg.DYNAMIC_GESTURE['enabled']:
|
||||||
dynamic_predictor.add_frame(landmarks)
|
dynamic_predictor.add_frame(landmarks)
|
||||||
gesture = dynamic_predictor.predict()
|
gesture = dynamic_predictor.predict()
|
||||||
@@ -77,6 +79,8 @@ def main():
|
|||||||
robot.reset()
|
robot.reset()
|
||||||
elif action == 'restart':
|
elif action == 'restart':
|
||||||
robot.reset()
|
robot.reset()
|
||||||
|
last_dynamic_gesture = gesture
|
||||||
|
dynamic_gesture_counter = 30
|
||||||
|
|
||||||
vis_frame = detector.draw_landmarks(frame, result['pose_landmarks'])
|
vis_frame = detector.draw_landmarks(frame, result['pose_landmarks'])
|
||||||
|
|
||||||
@@ -99,6 +103,12 @@ def main():
|
|||||||
if special != 'none':
|
if special != 'none':
|
||||||
cv2.putText(vis_frame, f"Special: {special}", (10, 90),
|
cv2.putText(vis_frame, f"Special: {special}", (10, 90),
|
||||||
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255,255,0), 2)
|
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255,255,0), 2)
|
||||||
|
|
||||||
|
if dynamic_gesture_counter > 0 and last_dynamic_gesture:
|
||||||
|
cv2.putText(vis_frame, f"Dynamic: {last_dynamic_gesture}", (10, 120),
|
||||||
|
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 255), 2)
|
||||||
|
dynamic_gesture_counter -= 1
|
||||||
|
|
||||||
else:
|
else:
|
||||||
vis_frame = frame
|
vis_frame = frame
|
||||||
cv2.putText(vis_frame, "No pose detected", (10, 30),
|
cv2.putText(vis_frame, "No pose detected", (10, 30),
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ class DynamicGesturePredictor:
|
|||||||
self.threshold = threshold
|
self.threshold = threshold
|
||||||
|
|
||||||
def add_frame(self, landmarks):
|
def add_frame(self, landmarks):
|
||||||
|
if landmarks is None or np.isnan(landmarks).any():
|
||||||
|
landmarks = np.zeros(99)
|
||||||
self.buffer.append(landmarks)
|
self.buffer.append(landmarks)
|
||||||
|
|
||||||
def predict(self):
|
def predict(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user