import mediapipe as mp import cv2 import timecap = cv2VideoCapture0 mpHance = mpsolutionshands # 选择策略 -- 监测手的模型 mpDraw = mpsolutionsdrawingutils handLmsStyle = mpDrawDrawingSpeccolor=0 0 255 thickness
识别出石头剪刀布的手势。
以下是修改后的代码:
import mediapipe as mp import cv2 import time import random
cap = cv2.VideoCapture(0)
mpHands = mp.solutions.hands # 选择策略 -- 监测手的模型 mpDraw = mp.solutions.drawing_utils
handLmsStyle = mpDraw.DrawingSpec(color=(0, 0, 255), thickness=5) # 设定点的样式 颜色 粗细,半径 handConStyle = mpDraw.DrawingSpec(color=(0, 255, 2), thickness=10) # 设定线的样式 颜色 粗细,半径
pTime = 0 cTime = 0
hands = mpHands.Hands(static_image_mode=False, # 影片 false 图片 True max_num_hands=2, # 最大手识别数量 min_detection_confidence=0.9, # 识别的精准度 min_tracking_confidence=0.5) # 追踪的严谨度
石头剪刀布
gestures = {'rock': 0, 'paper': 1, 'scissors': 2} gestures_text = ['Rock', 'Paper', 'Scissors'] user_gesture = None computer_gesture = None
while True: ret, img = cap.read()
if ret:
imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
result = hands.process(imgRGB) # 侦测
img_height, img_width, _ = img.shape
if result.multi_hand_landmarks:
for hand_landmarks in result.multi_hand_landmarks:
mpDraw.draw_landmarks(img, hand_landmarks, mpHands.HAND_CONNECTIONS, handLmsStyle, handConStyle)
# 计算手的中心点
x_center = int(hand_landmarks.landmark[mpHands.HandLandmark.WRIST].x * img_width)
y_center = int(hand_landmarks.landmark[mpHands.HandLandmark.WRIST].y * img_height)
# 计算手的大小
x_min, y_min, x_max, y_max = float('inf'), float('inf'), float('-inf'), float('-inf')
for lm in hand_landmarks.landmark:
x, y = int(lm.x * img_width), int(lm.y * img_height)
x_min, y_min = min(x_min, x), min(y_min, y)
x_max, y_max = max(x_max, x), max(y_max, y)
hand_size = (x_max - x_min) * (y_max - y_min)
# 计算手的旋转角度
angle = 0
if hand_landmarks.landmark[mpHands.HandLandmark.INDEX_FINGER_TIP].visibility > 0.5 and hand_landmarks.landmark[mpHands.HandLandmark.THUMB_TIP].visibility > 0.5:
x1, y1 = hand_landmarks.landmark[mpHands.HandLandmark.INDEX_FINGER_TIP].x * img_width, hand_landmarks.landmark[mpHands.HandLandmark.INDEX_FINGER_TIP].y * img_height
x2, y2 = hand_landmarks.landmark[mpHands.HandLandmark.THUMB_TIP].x * img_width, hand_landmarks.landmark[mpHands.HandLandmark.THUMB_TIP].y * img_height
angle = (180 / 3.1415) * math.atan2(y2 - y1, x2 - x1)
# 识别石头剪刀布
if hand_size > 10000:
if angle > -30 and angle < 30:
user_gesture = 'scissors'
elif angle > 60 and angle < 120:
user_gesture = 'rock'
elif angle > -120 and angle < -60:
user_gesture = 'paper'
else:
user_gesture = None
# 显示手的中心点和大小
cv2.circle(img, (x_center, y_center), 5, (255, 0, 0), -1)
cv2.putText(img, f"Size : {hand_size}", (x_center + 10, y_center + 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1)
# 显示手的旋转角度
cv2.putText(img, f"Angle : {int(angle)}", (x_center + 10, y_center + 30), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1)
# 计算fps并显示
cTime = time.time()
fps = 1 / (cTime - pTime)
pTime = cTime
cv2.putText(img, f"FPS : {int(fps)}", (20, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
# 如果用户已经选择手势,则计算电脑的手势
if user_gesture is not None:
computer_gesture = random.choice(list(gestures.keys()))
# 显示用户和电脑的手势
cv2.putText(img, f"You : {gestures_text[gestures[user_gesture]] if user_gesture is not None else ''}", (20, img_height - 60), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
cv2.putText(img, f"Computer : {gestures_text[gestures[computer_gesture]] if computer_gesture is not None else ''}", (20, img_height - 20), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
cv2.imshow('img', img)
if cv2.waitKey(1) == ord('q'):
break
cap.release() cv2.destroyAllWindows(
原文地址: http://www.cveoy.top/t/topic/fKVy 著作权归作者所有。请勿转载和采集!