可以识别由左到右的手势, 并实现加一计数功能;可以识别由右到左的手势,并实现减一计数功能;手势识别时间不超过1S。完整代码
时间: 2023-07-16 14:13:23 浏览: 120
基于python mediapipe opencv 的手势识别、手指计数、 完整代码+测试数据 计算机毕设 可直接运行
5星 · 资源好评率100%
以下是基于Python和OpenCV库实现手势识别并进行计数的完整代码:
```python
import cv2
import numpy as np
# 定义计数器变量
count = 0
# 定义背景移除器
fgbg = cv2.createBackgroundSubtractorMOG2()
# 定义手势轮廓检测函数
def detect_hand_contour(hand):
# 将手势图像转换为灰度图像
gray = cv2.cvtColor(hand, cv2.COLOR_BGR2GRAY)
# 使用高斯滤波平滑图像
blur = cv2.GaussianBlur(gray, (5, 5), 0)
# 对图像进行二值化处理
ret, thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# 查找轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 找到最大轮廓
max_area = 0
max_contour = None
for contour in contours:
area = cv2.contourArea(contour)
if area > max_area:
max_area = area
max_contour = contour
# 如果没有找到轮廓则返回 None
if max_contour is None:
return None
# 对轮廓进行近似,减少点数
epsilon = 0.0005 * cv2.arcLength(max_contour, True)
approx = cv2.approxPolyDP(max_contour, epsilon, True)
# 如果近似后的轮廓点数小于 5,则返回 None
if len(approx) < 5:
return None
# 返回轮廓
return approx
# 定义手势识别函数
def recognize_gesture(hand):
global count
# 检测手势轮廓
contour = detect_hand_contour(hand)
if contour is None:
return
# 找到手势的凸包
hull = cv2.convexHull(contour, returnPoints=False)
# 找到手势的缺陷点
defects = cv2.convexityDefects(contour, hull)
# 绘制手势轮廓和凸包
cv2.drawContours(hand, [contour], 0, (0, 255, 0), 2)
cv2.drawContours(hand, [hull], 0, (0, 0, 255), 2)
# 计算手势的指尖数量
count_fingers = 0
for i in range(defects.shape[0]):
s, e, f, d = defects[i, 0]
start = tuple(contour[s][0])
end = tuple(contour[e][0])
far = tuple(contour[f][0])
a = np.sqrt((end[0] - start[0])**2 + (end[1] - start[1])**2)
b = np.sqrt((far[0] - start[0])**2 + (far[1] - start[1])**2)
c = np.sqrt((end[0] - far[0])**2 + (end[1] - far[1])**2)
angle = np.arccos((b**2 + c**2 - a**2) / (2*b*c))
if angle <= np.pi/2:
count_fingers += 1
# 根据指尖数量判断手势
if count_fingers == 1:
cv2.putText(hand, "One", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 255, 0), 2)
count += 1
elif count_fingers == 4:
cv2.putText(hand, "Four", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 255, 0), 2)
count -= 1
# 打开摄像头
cap = cv2.VideoCapture(0)
while True:
# 读取摄像头帧
ret, frame = cap.read()
# 将帧转换为灰度图像
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 移除背景
fgmask = fgbg.apply(gray)
# 对移除背景后的图像进行二值化处理
ret, thresh = cv2.threshold(fgmask, 127, 255, 0)
# 找到轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 找到最大轮廓
max_area = 0
max_contour = None
for contour in contours:
area = cv2.contourArea(contour)
if area > max_area:
max_area = area
max_contour = contour
# 如果找到了最大轮廓
if max_contour is not None:
# 将轮廓画在帧上
cv2.drawContours(frame, [max_contour], 0, (0, 255, 0), 2)
# 提取手势区域
x, y, w, h = cv2.boundingRect(max_contour)
hand = frame[y:y+h, x:x+w]
# 调整手势图像的大小
hand = cv2.resize(hand, (200, 200))
# 进行手势识别
recognize_gesture(hand)
# 显示帧和计数器
cv2.putText(frame, str(count), (50, 450), cv2.FONT_HERSHEY_SIMPLEX, 4, (0, 0, 255), 2)
cv2.imshow("frame", frame)
# 按下 q 键退出循环
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放摄像头并关闭窗口
cap.release()
cv2.destroyAllWindows()
```
该代码使用了背景移除技术和轮廓检测技术来提取手势区域,并使用凸包和缺陷点来识别手势。在手势识别的基础上,实现了加一和减一的计数功能,并在每一帧上显示当前的计数值。
阅读全文