import mediapipe as mpimport cv2import timecap = cv2VideoCapture0mpHance = mpsolutionshands # 选择策略 -- 监测手的模型mpDraw = mpsolutionsdrawing_utilshandLmsStyle = mpDrawDrawingSpeccolor=0 0 255 thickness=5
为了实现识别石头剪刀布的功能,我们需要对手势进行分类。在本例中,我们将石头剪刀布分别对应为"0"、"1"、"2"三个数字。
具体实现思路如下:
1.在手部关键点坐标中,我们可以关注手指的位置和手指之间的角度。
2.通过计算手指的位置和角度,可以判断出手势是石头、剪刀还是布。
3.在本例中,我们可以采用简单的规则来分类手势:
- 当大拇指向上,且其他手指向前伸时,判断为“石头”手势;
- 当大拇指向下,且食指向上,判断为“剪刀”手势;
- 当大拇指向下,且其他手指向前伸时,判断为“布”手势。
4.识别出手势后,我们可以在屏幕上显示对应的文字,例如“石头”、“剪刀”、“布”等。
下面是修改后的代码:
import mediapipe as mp import cv2 import time
cap = cv2.VideoCapture(0) mpHance = 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 = mpHance.Hands(static_image_mode=False, # 影片 false 图片 True max_num_hands=2, # 最大手识别数量 model_complexity=1, # 模型的复杂度 只能是 0 1 越高越准 min_detection_confidence=0.9, # 识别的精准度 min_tracking_confidence=0.5) # 追踪的严谨度
while True: ret, img = cap.read() # 读取到的图片都是bgr的图片 ,故需要将其转换为RGB的图片
if ret:
imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
result = hands.process(imgRGB) # 侦测
# print(result.multi_hand_landmarks) 结果为 三个坐标 XYZ
imgHeight = img.shape[0] # 获取视窗的高度
imgWidth = img.shape[1] # 获取视窗的宽度
if result.multi_hand_landmarks:
for handLms in result.multi_hand_landmarks: # 画出所有点和线
mpDraw.draw_landmarks(img, handLms, mpHance.HAND_CONNECTIONS, handLmsStyle, handConStyle)
# 计算手指位置和角度
thumb = handLms.landmark[4]
index = handLms.landmark[8]
middle = handLms.landmark[12]
ring = handLms.landmark[16]
pinky = handLms.landmark[20]
# 判断手势
if thumb.y < index.y and middle.y < index.y and ring.y < index.y and pinky.y < index.y:
# 石头
cv2.putText(img, "Rock", (20, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
elif thumb.y > index.y and thumb.y > middle.y and thumb.y > ring.y and thumb.y > pinky.y and index.y < middle.y:
# 剪刀
cv2.putText(img, "Scissors", (20, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
elif thumb.y > index.y and middle.y > index.y and ring.y > index.y and pinky.y > index.y:
# 布
cv2.putText(img, "Paper", (20, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
cTime = time.time()
fps = 1 / (cTime - pTime)
pTime = cTime
cv2.putText(img, f"FPS : {int(fps)}", (20, 80), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
cv2.imshow('img', img)
if cv2.waitKey(1) == ord('q'):
break
cap.release() cv2.destroyAllWindows()
在上述代码中,我们通过计算大拇指和其他手指的位置和角度来判断手势,并在屏幕上显示对应的文字。注意,这种方法并不是非常精确,而且对手势的识别还要考虑更多因素,例如手的旋转、手的大小和手的位置等。因此,在实际应用中,我们需要根据实际情况进行调整,以达到更好的识别效果
原文地址: https://www.cveoy.top/t/topic/fKU6 著作权归作者所有。请勿转载和采集!