以下是使用Python、OpenCV和MediaPipe实现实时手势识别的完整代码。这个示例可以识别"OK"、"剪刀"、"握拳"、"一"、"二"、"三"等手势:
import cv2
import mediapipe as mp
import math
# 初始化MediaPipe
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(
static_image_mode=False,
max_num_hands=2,
min_detection_confidence=0.5,
min_tracking_confidence=0.5
)
mp_draw = mp.solutions.drawing_utils
# 打开摄像头
cap = cv2.VideoCapture(0)
def calculate_distance(p1, p2):
"""计算两点之间的距离"""
return math.sqrt((p1.x - p2.x)**2 + (p1.y - p2.y)**2)
def recognize_gesture(hand_landmarks):
"""识别手势"""
# 获取所有手指的关键点
thumb_tip = hand_landmarks.landmark[4]
index_tip = hand_landmarks.landmark[8]
middle_tip = hand_landmarks.landmark[12]
ring_tip = hand_landmarks.landmark[16]
pinky_tip = hand_landmarks.landmark[20]
# 获取手掌基准点
wrist = hand_landmarks.landmark[0]
thumb_base = hand_landmarks.landmark[2]
index_base = hand_landmarks.landmark[5]
middle_base = hand_landmarks.landmark[9]
ring_base = hand_landmarks.landmark[13]
pinky_base = hand_landmarks.landmark[17]
# 计算每个手指尖到手掌的距离
thumb_dist = calculate_distance(thumb_tip, wrist)
index_dist = calculate_distance(index_tip, wrist)
middle_dist = calculate_distance(middle_tip, wrist)
ring_dist = calculate_distance(ring_tip, wrist)
pinky_dist = calculate_distance(pinky_tip, wrist)
# 计算手指是否伸直的阈值(相对于手掌基准点的距离)
threshold = 0.1
# 检测OK手势
if calculate_distance(thumb_tip, index_tip) < threshold and middle_dist > threshold and ring_dist > threshold and pinky_dist > threshold:
return "OK"
# 检测剪刀手势
elif index_dist > threshold and middle_dist > threshold and ring_dist < threshold and pinky_dist < threshold:
return "剪刀"
# 检测握拳
elif index_dist < threshold and middle_dist < threshold and ring_dist < threshold and pinky_dist < threshold:
return "握拳"
# 检测数字1
elif index_dist > threshold and middle_dist < threshold and ring_dist < threshold and pinky_dist < threshold:
return "一"
# 检测数字2
elif index_dist > threshold and middle_dist > threshold and ring_dist < threshold and pinky_dist < threshold:
return "二"
# 检测数字3
elif index_dist > threshold and middle_dist > threshold and ring_dist > threshold and pinky_dist < threshold:
return "三"
return "未识别"
while True:
success, img = cap.read()
if not success:
break
# 转换颜色空间
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 处理图像
results = hands.process(img_rgb)
if results.multi_hand_landmarks:
for hand_landmarks in results.multi_hand_landmarks:
# 绘制手部关键点和连接线
mp_draw.draw_landmarks(img, hand_landmarks, mp_hands.HAND_CONNECTIONS)
# 识别手势
gesture = recognize_gesture(hand_landmarks)
# 在图像上显示手势名称
cv2.putText(img, f"手势: {gesture}", (10, 50),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
# 显示图像
cv2.imshow("Hand Gesture Recognition", img)
# 按'q'退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放资源
cap.release()
cv2.destroyAllWindows() 要运行这段代码,你需要先安装必要的库:
pip install opencv-python pip install mediapipe
这个程序的主要功能:
使用摄像头实时捕获视频使用MediaPipe检测手部关键点根据手指关键点的相对位置识别不同的手势在视频窗口实时显示识别结果支持的手势:
OK:大拇指和食指形成圈,其他手指伸直剪刀:食指和中指伸直,其他手指弯曲握拳:所有手指弯曲一:仅食指伸直二:食指和中指伸直三:食指、中指和无名指伸直使用方法:
运行程序后,会打开摄像头窗口将手放在摄像头前做出各种手势程序会实时显示识别结果按'q'键退出程序需要注意的是,手势识别的准确性受到多个因素影响:
光线条件手与摄像头的距离手的角度背景复杂度网友回复


