使用Mediapipe
水平镜像处理
import cvzoneimport cv2import numpy as npfrom cvzone.HandTrackingModule import HandDetector
cap = cv2.VideoCapture(0) cap.set(3, 1280) cap.set(4, 720)
detector = HandDetector(detectionCon=0.8, maxHands=2)
while True: success, img = cap.read() img = cv2.flip(img, 1) hands, img = detector.findHands(img) cv2.imshow("Image", img) cv2.waitKey(1)
修改代码
import cvzoneimport cv2
import numpy as npfrom cvzone.HandTrackingModule import HandDetector
cap = cv2.VideoCapture(0) cap.set(3, 1280) cap.set(4, 720)
detector = HandDetector(detectionCon=0.8, maxHands=1)
while True: success, img = cap.read() img = cv2.flip(img, 1) hands, img = detector.findHands(img, flipType=False) cv2.imshow("Image", img) cv2.waitKey(1)
观察手的信息
import cvzoneimport cv2import numpy as np
from cvzone.HandTrackingModule import HandDetector
cap = cv2.VideoCapture(0) cap.set(3, 1280) cap.set(4, 720)
detector = HandDetector(detectionCon=0.8, maxHands=1)
while True: success, img = cap.read() img = cv2.flip(img, 1) hands, img = detector.findHands(img, flipType=False)
print(hands)
cv2.imshow("Image", img) cv2.waitKey(1)
[{‘lmList’: [[1088, 633, 0], [1012, 655, -24], [940, 629, -32], [894, 596, -35], [875, 562, -36], [949, 504, -17], [891, 441, -16], [862, 419, -16], [838, 403, -16], [995, 480, -3], [943, 418, 8], [924, 426, 17], [920, 440, 22], [1044, 480, 8], [998, 455, 17], [987, 489, 21], [993, 513, 23], [1085, 492, 19], [1048, 477, 27], [1036, 505, 35], [1041, 528, 40]], ‘bbox’: (838, 403, 250, 252), ‘center’: (963, 529), ‘type’: ‘Left’}]import math
import cvzone
import cv2import numpy as npfrom cvzone.HandTrackingModule import HandDetector
cap = cv2.VideoCapture(0) cap.set(3, 1280) cap.set(4, 720)
detector = HandDetector(detectionCon=0.8, maxHands=1)
class SnakeGameClass: def __init__(self): self.points = [] self.lengths = [] self.currentLength = 0 self.allowedLength = 150 self.previousHead = 0, 0
def update(self, imgMain, currentHead):
px, py = self.previousHead cx, cy = currentHead
self
.points.append([cx, cy]) distance = math.hypot(cx - px, cy - py) self.lengths.append(distance) self.currentLength += distance self.previousHead = cx, cy
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(imgMain, self.points[-1], 20, (200, 0, 200), cv2.FILLED) 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.update(img, pointIndex)
cv2.imshow("Image", img) cv2.waitKey(1)
添加甜甜圈
import mathimport random
import cvzoneimport cv2import numpy as npfrom cvzone.HandTrackingModule import HandDetector
cap = cv2.VideoCapture(0) cap.set(3, 1280) cap.set(4, 720)
detector = HandDetector(detectionCon=0.8, maxHands=1)
class SnakeGameClass: def __init__(self, pathFood): self.points = []
self.lengths = [] self.currentLength = 0 self.allowedLength = 150 self.previousHead = 0, 0
self.imgFood = cv2.imread(pathFood, cv2.IMREAD_UNCHANGED) self.hFood, self.wFood, _ = self.imgFood.shape self.foodPoint = 0, 0 self.randomFoodLocation()
def randomFoodLocation(self): self.foodPoint = random.randint(100, 1000), random.randint(100, 600)
def update(self, imgMain, currentHead):
px, py = self.previousHead cx, cy = currentHead
self.points.append([cx, cy]) distance = math.hypot(cx - px, 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
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(imgMain, self.points[-1], 20, (200, 0, 200), cv2.FILLED)
rx, ry = self.foodPoint imgMain = cvzone.overlayPNG(imgMain, self.imgFood, (rx - self.wFood // 2, ry - self.hFood // 2))
return imgMain
game = SnakeGameClass("donut.png")
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.update(img, pointIndex)
cv2.imshow("Image", img) cv2.waitKey(1)
donut.png
部分代码解释说明
imgMain = cvzone.overlayPNG(imgMain, self.imgFood, (rx - self.wFood
imgMain = cvzone.overlayPNG(imgMain, self.imgFood, (rx , ry))
增加分数机制
import mathimport random
import cvzoneimport cv2import numpy as npfrom cvzone.HandTrackingModule import HandDetector
cap = cv2.VideoCapture(0) cap.set(3, 1280) cap.set(4, 720)
detector = HandDetector(detectionCon=0.8, maxHands=1)
class SnakeGameClass: def __init__(self, pathFood): self.points = [] self.lengths = [] self.currentLength = 0 self.allowedLength = 150 self.previousHead = 0, 0
self.imgFood = cv2.imread(pathFood, 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, 1000), random.randint(100, 600)
def update(self, imgMain, currentHead):
px, py = self.previousHead cx, cy = currentHead
self.points.append([cx, cy]) distance = math.hypot(cx - px, 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: self.randomFoodLocation() self.allowedLength += 50 self.score += 1 print(self.score)
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(imgMain, 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("donut.png")
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.update(img, pointIndex)
cv2.imshow("Image", img) cv2.waitKey(1)
完整代码
import mathimport random
import cvzoneimport cv2import numpy as npfrom cvzone.HandTrackingModule import HandDetector
cap = cv2.VideoCapture(0) cap.set(3, 1280) cap.set(4, 720)
detector = HandDetector(detectionCon=0.8, maxHands=1)
class SnakeGameClass: def __init__(self, pathFood): self.points = [] self.lengths = [] self.currentLength = 0 self.allowedLength = 150 self.previousHead = 0, 0
self.imgFood = cv2.imread(pathFood, cv2.IMREAD_UNCHANGED) self.hFood, self.wFood, _ = self.imgFood.shape self.foodPoint = 0, 0 self.randomFoodLocation()
self.score = 0 self.gameOver = False
def randomFoodLocation(self): self.foodPoint = random.randint(100, 1000), random.randint(100, 600)
def update(self, imgMain, currentHead):
if self.gameOver: cvzone.putTextRect(imgMain, "Game Over", [300, 400], scale=7, thickness=5, offset=20) cvzone.putTextRect(imgMain, f'Your Score:{self.score}', [300, 550], scale=7, thickness=5, offset=20) else: px, py = self.previousHead cx, cy = currentHead
self.points.append([cx, cy]) distance = math.hypot(cx - px, 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: self.randomFoodLocation() self.allowedLength += 50 self.score += 1 print(self.score)
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(imgMain, self.points[-1], 20, (200, 0, 200), cv2.FILLED)
imgMain = cvzone.overlayPNG(imgMain, self.imgFood, (rx - self.wFood // 2, ry - self.hFood // 2))
cvzone.putTextRect(imgMain, f'Your Score:{self.score}', [50, 80], scale=3, thickness=5, offset=10)
pts = np.array(self.points[:-2], np.int32) pts = pts.reshape((-1, 1, 2)) cv2.polylines(imgMain, [pts], False, (0, 200, 0), 3) minDist = cv2.pointPolygonTest(pts, (cx, cy), True)
if -1 <= minDist <= 1: print("Hit") self.gameOver = True self.points = [] self.lengths = [] self.currentLength = 0 self.allowedLength = 150 self.previousHead = 0, 0 self.randomFoodLocation()
return imgMain
game = SnakeGameClass("donut.png")
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.update(img, pointIndex)
cv2.imshow("Image", img) key = cv2.waitKey(1) if key == ord('r'): game.gameOver = False
来源:人工智能研究生