OpenCV图像处理实现手势识别贪吃蛇(含完整代码)
版本
pyrhon 3.8
opencv-python 4.9.0.80
numpy 1.21.5
简介
MediaPipe Hands 是一种高保真手和手指跟踪解决方案。它采用机器学习 (ML) 从单个帧中推断出手的 21 个 3D 地标。当前最先进的方法主要依赖于强大的桌面环境进行推理,而我们的方法在手机上实现了实时性能,甚至可以扩展到多只手。我们希望向更广泛的研究和开发社区提供这种手部感知功能,以将导致创造性用例的出现,刺激新的应用程序和新的研究途径。
代码
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
代码还可以进一步完善,之后我也会不断更新,点赞,评论,加关注,谢谢大家。