基于OpenCV和MediaPipe的石头剪刀布手势识别系统
基于OpenCV和MediaPipe的石头剪刀布手势识别系统
本项目使用OpenCV和MediaPipe实现石头剪刀布手势识别。项目分为数据采集、模型训练和实时识别三个部分。
数据采集
- 打开摄像头并设置分辨率。
- 读取摄像头的每一帧图像。
- 检测手的关键点。
- 根据手的关键点,判断手势类型(石头、剪刀或布)。
- 将手势类型和对应的图像保存到本地。
代码示例:
import cv2
import os
# 打开摄像头
cap = cv2.VideoCapture(0)
# 设置分辨率
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
# 创建目录
data_dir = './data'
if not os.path.exists(data_dir):
os.makedirs(data_dir)
# 采集数据
gesture_names = ['rock', 'paper', 'scissors']
for gesture_name in gesture_names:
gesture_dir = os.path.join(data_dir, gesture_name)
if not os.path.exists(gesture_dir):
os.makedirs(gesture_dir)
print(f'Collecting data for {gesture_name} gesture...')
for i in range(200):
ret, frame = cap.read()
if not ret:
print('Failed to read frame from camera!')
break
img_path = os.path.join(gesture_dir, f'{gesture_name}_{i}.jpg')
cv2.imwrite(img_path, frame)
cv2.imshow('Collecting Data', frame)
if cv2.waitKey(10) == ord('q'):
break
print(f'Data collection for {gesture_name} gesture finished!')
cap.release()
cv2.destroyAllWindows()
模型训练
- 加载数据集。
- 构建模型。
- 训练模型。
- 评估模型性能。
代码示例:
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# 加载数据集
train_dir = './data'
train_datagen = ImageDataGenerator(
rescale=1./255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
validation_split=0.2
)
train_generator = train_datagen.flow_from_directory(
train_dir,
target_size=(224, 224),
batch_size=32,
class_mode='categorical',
subset='training'
)
validation_generator = train_datagen.flow_from_directory(
train_dir,
target_size=(224, 224),
batch_size=32,
class_mode='categorical',
subset='validation'
)
# 构建模型
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(224, 224, 3)),
tf.keras.layers.MaxPooling2D((2, 2)),
tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D((2, 2)),
tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D((2, 2)),
tf.keras.layers.Conv2D(256, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D((2, 2)),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(3, activation='softmax')
])
# 编译模型
model.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
# 训练模型
history = model.fit(
train_generator,
epochs=10,
validation_data=validation_generator
)
# 评估模型性能
test_generator = train_datagen.flow_from_directory(
train_dir,
target_size=(224, 224),
batch_size=32,
class_mode='categorical',
shuffle=False
)
test_loss, test_acc = model.evaluate(test_generator)
print(f'Test loss: {test_loss}, Test accuracy: {test_acc}')
实时识别
- 打开摄像头并设置分辨率。
- 读取摄像头的每一帧图像。
- 检测手的关键点。
- 根据手的关键点,判断手势类型(石头、剪刀或布)。
- 显示识别结果。
代码示例:
import cv2
import mediapipe as mp
import tensorflow as tf
# 打开摄像头
cap = cv2.VideoCapture(0)
# 设置分辨率
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
# 加载模型
model = tf.keras.models.load_model('./model.h5')
# 初始化关键点检测器
mp_hands = mp.solutions.hands.Hands(
static_image_mode=False,
max_num_hands=1,
min_detection_confidence=0.5,
min_tracking_confidence=0.5
)
# 定义手势类别
gesture_names = ['rock', 'paper', 'scissors']
while True:
ret, frame = cap.read()
if not ret:
print('Failed to read frame from camera!')
break
# 检测手的关键点
rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = mp_hands.process(rgb)
if results.multi_hand_landmarks:
hand_landmarks = results.multi_hand_landmarks[0]
hand_points = []
for point in hand_landmarks.landmark:
hand_points.append((point.x, point.y))
hand_points = tf.expand_dims(hand_points, axis=0)
# 预测手势类别
prediction = model.predict(hand_points)
gesture_idx = tf.argmax(prediction, axis=1).numpy()[0]
gesture_name = gesture_names[gesture_idx]
# 在图像上显示识别结果
font = cv2.FONT_HERSHEY_SIMPLEX
font_scale = 1
color = (0, 255, 0)
thickness = 2
cv2.putText(frame, gesture_name, (50, 50), font, font_scale, color, thickness)
cv2.imshow('Real-time Gesture Recognition', frame)
if cv2.waitKey(10) == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
结论
基于OpenCV和MediaPipe实现石头剪刀布的识别,可以通过收集数据、训练模型和实时识别实现。这个项目可以用来展示计算机视觉和机器学习的应用,也可以作为一个有趣的玩具项目。
原文地址: https://www.cveoy.top/t/topic/oDx4 著作权归作者所有。请勿转载和采集!