写一下用opencv-python识别图片中石头剪刀布手势的代码
时间: 2023-04-02 15:02:40 浏览: 306
以下是使用 OpenCV-Python 识别图片中石头剪刀布手势的代码:
```python
import cv2
import numpy as np
# 定义手势识别函数
def recognize_gesture(hand):
# 将手势图像转换为灰度图像
gray = cv2.cvtColor(hand, cv2.COLOR_BGR2GRAY)
# 对灰度图像进行高斯模糊
blur = cv2.GaussianBlur(gray, (5, 5), )
# 进行二值化处理
ret, thresh = cv2.threshold(blur, , 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# 查找轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 如果没有找到轮廓,则返回 None
if len(contours) == :
return None
# 找到最大的轮廓
max_contour = max(contours, key=cv2.contourArea)
# 计算轮廓的凸包
hull = cv2.convexHull(max_contour)
# 计算轮廓的缺陷
defects = cv2.convexityDefects(max_contour, cv2.convexHull(max_contour, returnPoints=False))
# 如果没有找到缺陷,则返回 None
if defects is None:
return None
# 计算缺陷的数量
num_defects =
for i in range(defects.shape[]):
s, e, f, d = defects[i, ]
start = tuple(max_contour[s][])
end = tuple(max_contour[e][])
far = tuple(max_contour[f][])
# 计算缺陷的角度
angle = np.degrees(np.arctan2(far[1]-start[1], far[]-start[]) - np.arctan2(end[1]-start[1], end[]-start[]))
# 如果角度小于 90 度,并且距离大于 30 像素,则认为是一个缺陷
if angle < 90 and d > 30:
num_defects += 1
# 如果缺陷的数量为 ,则认为是石头
if num_defects == :
return "rock"
# 如果缺陷的数量为 1 或 2,则认为是剪刀
elif num_defects == 1 or num_defects == 2:
return "scissors"
# 如果缺陷的数量大于 2,则认为是布
else:
return "paper"
# 加载图像
img = cv2.imread("gesture.jpg")
# 调整图像大小
img = cv2.resize(img, (640, 480))
# 获取图像的高度和宽度
height, width = img.shape[:2]
# 将图像转换为 HSV 颜色空间
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 定义 HSV 颜色范围
lower_skin = np.array([, 20, 70], dtype=np.uint8)
upper_skin = np.array([20, 255, 255], dtype=np.uint8)
# 对图像进行颜色过滤
mask = cv2.inRange(hsv, lower_skin, upper_skin)
# 对图像进行形态学操作
kernel = np.ones((5, 5), np.uint8)
mask = cv2.erode(mask, kernel, iterations=1)
mask = cv2.dilate(mask, kernel, iterations=1)
# 查找轮廓
contours, hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 如果没有找到轮廓,则返回 None
if len(contours) == :
print("No hand detected")
else:
# 找到最大的轮廓
max_contour = max(contours, key=cv2.contourArea)
# 计算轮廓的凸包
hull = cv2.convexHull(max_contour)
# 绘制凸包
cv2.drawContours(img, [hull], -1, (, 255, ), 2)
# 获取凸包的矩形
x, y, w, h = cv2.boundingRect(hull)
# 绘制矩形
cv2.rectangle(img, (x, y), (x+w, y+h), (, , 255), 2)
# 获取手势图像
hand = img[y:y+h, x:x+w]
# 如果手势图像的高度或宽度小于 50 像素,则认为手势不明确
if hand.shape[] < 50 or hand.shape[1] < 50:
print("Gesture not clear")
else:
# 调用手势识别函数
gesture = recognize_gesture(hand)
# 如果识别结果为 None,则认为手势不明确
if gesture is None:
print("Gesture not clear")
else:
# 输出识别结果
print("Gesture:", gesture)
# 显示图像
cv2.imshow("Image", img)
cv2.waitKey()
cv2.destroyAllWindows()
```
注意:以上代码仅供参考,实际应用中可能需要根据具体情况进行调整和优化。
阅读全文