OpenCV图像处理实现手势识别贪吃蛇(含完整代码)

OpenCV图像处理实现手势识别贪吃蛇(含完整代码)

版本

pyrhon 3.8
opencv-python 4.9.0.80
numpy 1.21.5

简介

MediaPipe Hands 是一种高保真手和手指跟踪解决方案。它采用机器学习 (ML) 从单个帧中推断出手的 21 个 3D 地标。当前最先进的方法主要依赖于强大的桌面环境进行推理,而我们的方法在手机上实现了实时性能,甚至可以扩展到多只手。我们希望向更广泛的研究和开发社区提供这种手部感知功能,以将导致创造性用例的出现,刺激新的应用程序和新的研究途径。
hands

代码

import cvzone
import cv2
import numpy as np
from cvzone.HandTrackingModule import HandDetector
import math
import random

cap = cv2.VideoCapture(0)
cap.set(3,720)
cap.set(4,640)

detector = HandDetector(detectionCon = 0.8,maxHands=1)

class SnakeGameClass:
    def __init__(self):
        self.points = [] # 蛇所有的点
        self.lengths = [] # 每一个点之间的距离
        self.currentLength = 0 # 蛇的总长度
        self.allowedLength = 400 # 蛇被允许的总长度
        self.previousHead = 0,0 # 蛇头值钱点的位置


        self.imgFood = cv2.imread('Donut.png',cv2.IMREAD_UNCHANGED)
        self.hFood,self.wFood,_ = self.imgFood.shape
        self.foodPoint = 0,0
        self.randomFoodLocation()
        self.score = 0


    def randomFoodLocation(self):
        self.foodPoint = random.randint(100,600),random.randint(100,500)



    def updata(self,imgMain,currentHead):

        px,py = self.previousHead
        cx,cy = currentHead

        self.points.append([cx,cy])
        distance = math.hypot(cx -py,cy - py)
        self.lengths.append(distance)
        self.currentLength += distance
        self.previousHead = cx,cy


        # 减少长度
        if self.currentLength > self.allowedLength:
            for i,length in enumerate(self.lengths):
                self.currentLength -= length
                self.lengths.pop(i)
                self.points.pop(i)
                if self.currentLength < self.allowedLength:
                    break

        # 检查设是否吃了食物
        rx, ry = self.foodPoint
        if rx - self.wFood//2 < cx < rx +self.wFood // 2 and 
                ry - self.hFood // 2 < cy < ry + self.hFood // 2:
            # print('eat')
            self.randomFoodLocation()
            self.allowedLength += 50
            self.score +=1
            print(self.score)
        cv2.putText(img, "Count score:" + str(self.score), (150, 60), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
        # 检查碰撞


        # 画蛇
        if self.points:
            for i,point in enumerate(self.points):
                if i != 0:
                    cv2.line(imgMain,self.points[i-1],self.points[i],(0,0,255),20)
            cv2.circle(img,self.points[-1],20,(200,0,200),cv2.FILLED)
        # 落下食物

        imgMain = cvzone.overlayPNG(imgMain,self.imgFood,(rx-self.wFood // 2,ry - self.hFood // 2))

        return imgMain

game = SnakeGameClass()

while True:
    success,img = cap.read()
    img = cv2.flip(img,1)
    hands,img = detector.findHands(img,flipType=False)

    if hands:
        lmList = hands[0]['lmList']
        pointIndex = lmList[8][0:2]
        img = game.updata(img,pointIndex)
    cv2.imshow("Image",img)

    key = cv2.waitKey(1)
    if (key == 27):
        break

代码还可以进一步完善,之后我也会不断更新,点赞,评论,加关注,谢谢大家。