OpenCV+Python3.5 简易手势识别的实现
作者:*_Sasuke? 发布时间:2022-06-02 18:38:26
检测剪刀石头布三种手势,通过摄像头输入,方法如下:
选用合适颜色空间及阈值提取皮肤部分
使用滤波腐蚀膨胀等方法去噪
边缘检测
寻用合适方法分类
OpenCV用摄像头捕获视频
采用方法:调用OpenCV——cv2.VideoCapture()
def video_capture():
cap = cv2.VideoCapture(0)
while True:
# capture frame-by-frame
ret, frame = cap.read()
# our operation on the frame come here
# gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) 可选择灰度化
# display the resulting frame
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'): # 按q键退出
break
# when everything done , release the capture
cap.release()
cv2.destroyAllWindows()
效果如下
肤色识别——椭圆肤色检测模型
参考下述博文
https://www.jb51.net/article/202594.htm
代码如下
def ellipse_detect(img):
# 椭圆肤色检测模型
skinCrCbHist = np.zeros((256, 256), dtype=np.uint8)
cv2.ellipse(skinCrCbHist, (113, 155), (23, 15), 43, 0, 360, (255, 255, 255), -1)
YCRCB = cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB)
(y, cr, cb) = cv2.split(YCRCB)
skin = np.zeros(cr.shape, dtype=np.uint8)
(x, y) = cr.shape
for i in range(0, x):
for j in range(0, y):
CR = YCRCB[i, j, 1]
CB = YCRCB[i, j, 2]
if skinCrCbHist[CR, CB] > 0:
skin[i, j] = 255
dst = cv2.bitwise_and(img, img, mask=skin)
return dst
效果如下,可见与肤色相近的物体全被提取出来,包括桌子。。。
识别时需寻找一无干扰环境
去噪——滤波、腐蚀和膨胀
参考下述博文
https://www.jb51.net/article/202599.htm
采用方法:高斯滤波 cv2.GaussianBlur() + 膨胀 cv2.dilate(),代码如下
# 膨胀
def dilate_demo(image):
# 灰度化
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 二值化
ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
# 定义结构元素的形状和大小
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
# 膨胀操作
dst = cv2.dilate(binary, kernel)
return dst
# 腐蚀
def erode_demo(image):
# 灰度化
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 二值化
ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
# 定义结构元素的形状和大小
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (15, 15))
# 腐蚀操作
dst = cv2.erode(binary, kernel)
return dst
# 滤波
def img_blur(image):
# 腐蚀操作
# img_erode = erode_demo(image)
# 膨胀操作
img_dilate = dilate_demo(image)
# 均值滤波
# blur = cv2.blur(image, (5, 5))
# 高斯滤波
blur = cv2.GaussianBlur(img_dilate, (3, 3), 0)
return blur
Canny边缘检测
参考OpenCV中文教程
https://www.kancloud.cn/aollo/aolloopencv/271603
代码如下
# Canny边缘检测v
def canny_detect(image):
edges = cv2.Canny(image, 50, 200)
return edges
识别——轮廓匹配
Tensorflow框架实在太难搭,搭了半天没搭出来,还一堆错误。。。所以采用轮廓匹配 cv2.matchShapes() ,方案如下:
划分出了一个手势识别区域,可避免周围环境的干扰,也可简化图像处理过程
寻找轮廓时采用寻找矩形框架 cv2.boundingRect()的方法找到最大轮廓,即手势的轮廓
将找到的轮廓直接与标准图片进行匹配,简化识别过程
但在匹配时发现“剪刀”的手势常与“石头”、“布”的手势匹配到一起。。。所以另辟蹊径,在匹配时加上了对于矩形框架面积的判断,一般来说有如下规律,石头<剪刀<布,代码如下
# 轮廓匹配
value = [0, 0, 0]
value[0] = cv2.matchShapes(img_contour, img1, 1, 0.0)
value[1] = cv2.matchShapes(img_contour, img2, 1, 0.0)
value[2] = cv2.matchShapes(img_contour, img3, 1, 0.0)
min_index = np.argmin(value)
if min_index == 0: # 剪刀
print(text[int(min_index)], value)
elif min_index == 1 and w*h < 25000: # 石头
print(text[int(min_index)], value)
elif min_index == 1 and w*h >= 25000: # 剪刀
print(text[0], value)
elif min_index == 2 and w * h > 30000: # 布
print(text[int(min_index)], value)
elif min_index == 2 and w * h <= 30000: # 剪刀
print(text[0], value)
程序会根据匹配值和面积大小来决定识别结果,例如,下述结果,1.179515828609219, 0.9604643714904955, 0.9896353720020925分别对应剪刀、石头、布的匹配值,越小说明越吻合;结合最终识别情况来看,在三种手势中,石头的识别成功率最高,约98%;布其次,约88%;剪刀最低,约80%,而且结果易受环境亮度影响,环境过暗或过亮,有时候手势轮廓都出不来。。。看来仍有待改进,还是得用机器学习的方法
石头 [1.179515828609219, 0.9604643714904955, 0.9896353720020925]
程序效果如下,黄色矩形框为识别区域,gesture窗口为用于轮廓匹配的手势图
来源:https://blog.csdn.net/lzhlegen/article/details/111403242


猜你喜欢
- sql server 2008 r2 express是什么版本express是精简版的意思 r2是2008的第2版本,推荐使用。SQL Se
- 说实话,第一次写这么长的Python代码,期间遇到了很多问题,但是,最终还是完成了,花了我一天半的时间。该程序实现了用户的增,删,改,查,主
- 随着3G的普及,越来越多的人使用手机上网。移动设备正超过桌面设备,成为访问互联网的最常见终端。于是,网页设计师不得不面对一个难题:如何才能在
- break 语句Python break语句,就像在C语言中,打破了最小封闭for或while循环。break语句用来终止循环语句,即循环条
- 当一个应用的数据量大的时候,我们用单表和单库来存储会严重影响操作速度,如mysql的myisam存储,我们经过测试,200w以下的时候,my
- 将时间信息“2018-02-04 18:23:35“ 解析成字典形式的结果如:{‘year':2018,‘month
- 本文使用c语言来对sql server数据库进行操作,实现通过程序来对数据库进行增删改查操作。操作系统:windows 10
- 1.首先要绘制一个简单的条形图import numpy as npimport matplotlib.pyplot as pltfrom m
- 在Pycharm里设置断点如下:这样启动debug模式后(Shift+F9),程序就会暂停在断点处。如上面所示,暂停在第15行处,可以看到程
- 前言Always On 可用性组活动辅助功能包括支持在辅助副本上执行备份操作。 备份操作可能会给 I/O 和 CPU 带来很大的压力(使用备
- isset和is_null啥区别,看手册上讲的话, isset和is_null的功能几乎完全”相反的一样”..是不是isset就是一个is_
- 超级鹰平台验证码的破解可以有以下方式:简单的数字字母组合可以使用图像识别(python 现成模块),成功率不高使用第三方打码平台(破解验证码
- python中ord函数Python ord()函数 (Python ord() function)ord() function is a
- 前言在上一节我们通过使用NumPy的数组分割成功的在我们的图像上画了一个绿色的方块,但是如果我们想画一个单一的线条或者圆圈该怎么办呢?Num
- re.search():匹配整个字符串,并返回第一个成功的匹配。如果匹配失败,则返回None pattern: 匹配的规则,str
- 本文实例讲述了Python可变和不可变、类的私有属性。分享给大家供大家参考,具体如下:可变和不可变items = []print(id(li
- 1.计算长度value = "wangdianchao"# 计算字符个数(长度)number = len(value)p
- 首先得有一个Scrapy项目,我在Desktop上新建一个Scrapy的项目叫test,在Desktop目录打开命令行,键入命令:scrap
- 命令模式(Command Pattern)是什么命令模式是一种行为型模式,它将请求封装成一个对象,从而允许您将不同的请求排队或记录请求日志、
- Gtid + Mha +Binlog server配置:1:测试环境OS:CentOS 6.5Mysql:5.6.28Mha:0.56192