Введение в распознавание жестов рук

Распознавание жестов рук — это увлекательная область взаимодействия человека и компьютера (HCI), которая имеет множество приложений: от управления виртуальной средой и перевода языка жестов до управления роботами и создания музыки. В этой статье мы углубимся в процесс создания системы распознавания жестов рук в режиме реального времени с использованием TensorFlow, OpenCV и фреймворка MediaPipe.

Почему распознавание жестов рук?

Представьте себе мир, где вы можете управлять своим компьютером или роботом простым взмахом руки. Это звучит как что-то из научно-фантастического фильма, но это становится всё более возможным благодаря достижениям в области компьютерного зрения и машинного обучения. Распознавание жестов рук может улучшить взаимодействие с пользователем, предоставить новые способы взаимодействия и даже помочь людям с ограниченными возможностями.

Инструменты и фреймворки

Для создания нашей системы распознавания жестов рук мы будем использовать следующие инструменты и фреймворки:

  • TensorFlow: открытая библиотека машинного обучения, разработанная Google. Она будет использоваться для создания и развёртывания нашей модели распознавания жестов.
  • OpenCV: библиотека компьютерного зрения в реальном времени, которая будет обрабатывать обработку изображений и взаимодействие с веб-камерой.
  • MediaPipe: ещё один фреймворк, разработанный Google, который поможет нам с обнаружением рук и оценкой ключевых точек.

Предварительные требования

Прежде чем мы перейдём к реализации, убедитесь, что у вас установлены следующие компоненты:

  • Python 3.x;
  • OpenCV 4.5;
  • MediaPipe 0.8.11;
  • TensorFlow 2.5.0;
  • NumPy 1.19.3.

Вы можете установить эти пакеты с помощью pip:

pip install -r requirements.txt

Пошаговая реализация

Шаг 1: импорт необходимых пакетов

Для начала вам необходимо импортировать необходимые пакеты. Вот как вы можете это сделать:

import cv2
import numpy as np
import mediapipe as mp
import tensorflow as tf
from tensorflow.keras.models import load_model

Шаг 2: инициализация моделей

Затем инициализируйте модель MediaPipe hands и загрузите предварительно обученную модель распознавания жестов.

mp_hands = mp.solutions.hands
hands = mp_hands.Hands(min_detection_confidence=0.5, min_tracking_confidence=0.5)

# Загрузка предварительно обученной модели распознавания жестов
gesture_model = load_model('gesture_recognition_model.h5')

Шаг 3: чтение кадров с веб-камеры

Используйте OpenCV для захвата видеокадров с вашей веб-камеры.

cap = cv2.VideoCapture(0)
while cap.isOpened():
    success, image = cap.read()
    if not success:
        break

    # Преобразование изображения BGR в RGB.
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    # Чтобы повысить производительность, помечаем изображение как недоступное для записи для передачи по ссылке.
    image.flags.writeable = False
    results = hands.process(image)

    # Рисование аннотаций рук на изображении.
    image.flags.writeable = True
    image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
    if results.multi_hand_landmarks:
        for hand_landmarks in results.multi_hand_landmarks:
            mp_drawing = mp.solutions.drawing_utils
            mp_drawing.draw_landmarks(
                image,
                hand_landmarks,
                mp_hands.HAND_CONNECTIONS,
                mp_drawing.DrawingSpec(color=(121, 22, 76), thickness=2, circle_radius=4),
                mp_drawing.DrawingSpec(color=(250, 44, 250), thickness=2, circle_radius=2),
            )

            # Извлечение ключевых точек руки
            keypoints = []
            for landmark in hand_landmarks.landmark:
                keypoints.append([landmark.x, landmark.y, landmark.z])
            keypoints = np.array(keypoints)

            # Распознавание жестов руки
            prediction = gesture_model.predict(np.array([keypoints]))
            gesture = np.argmax(prediction[0])

            # Отображение распознанного жеста
            cv2.putText(image, f"Жест: {жест}", (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)

    cv2.imshow('Распознавание Жестов Рук', image)
    if cv2.waitKey(5) & 0xFF == 27:
        break
cap.release()
cv2.destroyAllWindows()

Шаг 4: запуск приложения

Чтобы запустить приложение, просто выполните скрипт Python:

python hand_gesture_detection.py

Убедитесь, что ваша веб-камера подключена и работает. Выполняйте жесты руками перед веб-камерой, чтобы наблюдать за распознаванием в режиме реального времени.

Интеграция веб-приложения

Если вы хотите интегрировать это в веб-приложение с использованием Flask, вот как вы можете это сделать:

Шаг 1: настройка Flask

Сначала убедитесь, что у вас установлен Flask:

pip install flask

Шаг 2: создание приложения Flask

Создайте файл с именем app.py и добавьте следующий код:

from flask import Flask, render_template, Response
import cv2
import mediapipe as mp
import numpy as np
import tensorflow as tf
from tensorflow.keras.models import load_model

app = Flask(__name__)

mp_hands = mp.solutions.hands
hands = mp_hands.Hands(min_detection_confidence=0.5, min_tracking_confidence=0.5)
gesture_model = load_model('gesture_recognition_model.h5')

cap = cv2.VideoCapture(0)

def gen_frames():
    while True:
        success, image = cap.read()
        if not success:
            break

        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        image.flags.writeable = False
        results = hands.process(image)

        image.flags.writeable = True
        image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
        if results.multi_hand_landmarks:
            for hand_landmarks in results.multi_hand_landmarks:
                mp_drawing = mp.solutions.drawing_utils
                mp_drawing.draw_landmarks(
                    image,
                    hand_landmarks,
                    mp_hands.HAND_CONNECTIONS,
                    mp_drawing.DrawingSpec(color=(121, 22, 76), thickness=2, circle_radius=4),
                    mp_drawing.DrawingSpec(color=(250, 44, 250), thickness=2, circle_radius=2),
                )

                keypoints = []
                for landmark in hand_landmarks.landmark:
                    keypoints.append([landmark.x, landmark.y, landmark.z])
                keypoints = np.array(keypoints)

                prediction = gesture_model.predict(np.array([keypoints]))
                gesture = np.argmax(prediction[0])

                cv2.putText(image, f"Gesture: {gesture}", (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)

        ret, buffer = cv2.imencode('.jpg', image)
        frame = buffer.tobytes()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

@app.route('/video_feed')
def video_feed():
    return Response(gen_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')

@app.route('/')
def index():
    return render_template('index.html')

if __name__ == "__main__":
    app.run(debug=True)

Шаг 3: запустите приложение Flask

Запустите веб-приложение Flask с помощью:

python app.py

Откройте веб-браузер и перейдите на http://127.0.0.1:5000, чтобы увидеть систему обнаружения жестов рук в действии.

Блок-схема процесса

Вот блок-схема,