Opencv项目实战:24 手势识别的石头剪刀布

 目录

0、项目介绍

1、效果展示

2、项目搭建

3、项目代码展示与部分讲解

pyzjr库

游戏实现思路

4、项目资源

5、项目总结


0、项目介绍

简单的自娱自乐的计算机视觉互动游戏,石头剪刀布,使用random生成随机数,用于模拟AI窗口随机出拳,玩家窗口手势识别检测石头、剪刀、布三种手势,根据游戏规则,两方玩家进行比较,按下空格键即为游戏开始,玩家在游戏开始后,有三秒的时间思考出拳策略。计时器会显示在屏幕上。在时间结束后,玩家出拳并与AI进行比较,根据游戏规则判断胜负并累计分数。

1、效果展示

2、项目搭建

安装pyzjr:

pip install pyzjr==1.0.4

必须要安装大于等于1.0.4版本以上,详细可看此处。

Opencv项目实战:24 手势识别的石头剪刀布_第1张图片

这个工程只需要一个main文件就足够了。

3、项目代码展示与部分讲解

import pyzjr as pz
import cv2
from cvzone.HandTrackingModule import HandDetector
import time
import random
import cvzone

Vap=pz.VideoCap()
Vap.CapInit()
imgList,all = pz.getPhotopath(r"Resources",debug=False)
detector = HandDetector(maxHands=1,detectionCon=0.8)
timer = 0
stateResult = False
startGame = False
scores = [0, 0]  # [AI, Player]
imgAI = None
initialTime = 0
while True:
    img = Vap.read(flip=1)
    imgbackground = cv2.imread(imgList[0])

    imgScaled = cv2.resize(img, (0, 0), None, 0.875, 0.875)[:, 80:480]
    hands = detector.findHands(imgScaled,draw=False)

    if startGame:

        if stateResult is False:
            timer = time.time() - initialTime
            cv2.putText(imgbackground, str(int(timer)), (605, 435), cv2.FONT_HERSHEY_PLAIN, 6, pz.purple, 4)

            if timer > 3:
                stateResult = True
                timer = 0

                if hands:
                    playerMove = None
                    hand = hands[0]
                    fingers = detector.fingersUp(hand)
                    if fingers == [0, 0, 0, 0, 0]:
                        playerMove = 1
                    if fingers == [1, 1, 1, 1, 1]:
                        playerMove = 2
                    if fingers == [0, 1, 1, 0, 0]:
                        playerMove = 3

                    randomNumber = random.randint(1, 3)
                    imgAI = cv2.imread(imgList[randomNumber], cv2.IMREAD_UNCHANGED)
                    imgbackground = cvzone.overlayPNG(imgbackground, imgAI, (149, 310))

                    winning_rules = {
                        # 1-石头,2-布,3-剪刀
                        (1, 3): "player",  # 石头 vs 剪刀
                        (2, 1): "player",  # 布 vs 石头
                        (3, 2): "player",  # 剪刀 vs 布
                        (3, 1): "AI",      # 剪刀 vs 石头
                        (1, 2): "AI",      # 石头 vs 布
                        (2, 3): "AI",      # 布 vs 剪刀
                    }
                    result = winning_rules.get((playerMove, randomNumber))
                    if result == "player":
                        scores[1] += 1
                    elif result == "AI":
                        scores[0] += 1

    imgbackground[234:654, 795:1195] = imgScaled

    if stateResult:
        imgbackground = cvzone.overlayPNG(imgbackground, imgAI, (149, 310))

    cv2.putText(imgbackground, str(scores[0]), (410, 215), cv2.FONT_HERSHEY_PLAIN, 4, pz.white, 6)
    cv2.putText(imgbackground, str(scores[1]), (1112, 215), cv2.FONT_HERSHEY_PLAIN, 4, pz.white, 6)

    cv2.imshow("background", imgbackground)

    k = cv2.waitKey(1)
    if k == 32:
        startGame = True
        initialTime = time.time()
        stateResult = False
    elif k == 27:
        break

pyzjr库

只要环境没有任何问题,这个代码是可以直接运行的,我先来讲解一下pyzjr的一些函数。

VideoCap:opencv视频捕捉类的再封装,CapInit为VideoCap的镜头初始化函数,默认的参数为调取本地摄像头、宽度、高度、亮度,未给参数,使用默认值即可。read函数只返回img,不返回标志位,flip参数可选,对镜头进行翻转,1表示进行了水平翻转。

getPhotopath:获取目标文件夹下的路径,解决了转义字符的问题。debug默认为True,会返回路径有问题的信息,可以设置为False。

white,purple:常量,默认的BGR格式。

游戏实现思路

游戏开始后,使用计时器来限制玩家思考时间。在倒计时结束后,玩家会做出出拳动作。利用条件判断来比较玩家和AI的出拳,根据游戏规则判断胜负并计算分数。

检测玩家的手势的方式是使用的mediapipe的方法,这在cvzone中已被集成。通过打印fingers的值,确定剪刀、石头、布三种手势的手指上下的情况。overlayPNG函数将AI的出拳图像也加入到了背景图像中,让玩家能够清楚地看到双方的出拳。

游戏规则的方式由字典的方式进行判断,scores=[AI,player]进行累计积分,并打印在背景图片当中。通过按下空格键来触发游戏的重新开始。玩家有三秒的时间来思考出拳策略,倒计时会显示在屏幕上,让玩家清楚地知道还剩多少时间。

请注意手势识别错误或相同手势均不计分。

4、项目资源

Opencv项目实战:24 石头剪刀布

5、项目总结

通过手势识别检测石头、剪刀、布完成了这个视觉小游戏,比起网上现在的形态学方法和搭建模型要简单许多。个人也可以体验一下视觉游戏的乐趣,检测手势的画面被我关了,你可以通过将findHands的参数draw设置为True即可。

你可能感兴趣的:(人工智能,计算机视觉)