OpenCV+Python3.5 简易手势识别的实现


Posted in Python onDecember 21, 2020

检测剪刀石头布三种手势,通过摄像头输入,方法如下:

  • 选用合适颜色空间及阈值提取皮肤部分
  • 使用滤波腐蚀膨胀等方法去噪
  • 边缘检测
  • 寻用合适方法分类

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()

效果如下

OpenCV+Python3.5 简易手势识别的实现

肤色识别——椭圆肤色检测模型

参考下述博文

代码如下

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

效果如下,可见与肤色相近的物体全被提取出来,包括桌子。。。
识别时需寻找一无干扰环境

OpenCV+Python3.5 简易手势识别的实现

去噪——滤波、腐蚀和膨胀

参考下述博文

采用方法:高斯滤波 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窗口为用于轮廓匹配的手势图

OpenCV+Python3.5 简易手势识别的实现

OpenCV+Python3.5 简易手势识别的实现

OpenCV+Python3.5 简易手势识别的实现

到此这篇关于OpenCV+Python3.5 简易手势识别的实现的文章就介绍到这了,更多相关OpenCV 手势识别 内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python跳出循环语句continue与break的区别
Aug 25 Python
python调用API实现智能回复机器人
Apr 10 Python
python 实现在txt指定行追加文本的方法
Apr 29 Python
解决Python requests库编码 socks5代理的问题
May 07 Python
基于python 爬虫爬到含空格的url的处理方法
May 11 Python
Python3 单行多行万能正则匹配方法
Jan 07 Python
Python3.6中Twisted模块安装的问题与解决
Apr 15 Python
Python+pyplot绘制带文本标注的柱状图方法
Jul 08 Python
django 自定义过滤器(filter)处理较为复杂的变量方法
Aug 12 Python
Matplotlib使用字符串代替变量绘制散点图的方法
Feb 17 Python
解决python 执行sql语句时所传参数含有单引号的问题
Jun 06 Python
Python作用域和名称空间的详细介绍
Apr 13 Python
如何使用python-opencv批量生成带噪点噪线的数字验证码
Dec 21 #Python
python 录制系统声音的示例
Dec 21 #Python
用python发送微信消息
Dec 21 #Python
关于多种方式完美解决Python pip命令下载第三方库的问题
Dec 21 #Python
Python爬虫模拟登陆哔哩哔哩(bilibili)并突破点选验证码功能
Dec 21 #Python
python switch 实现多分支选择功能
Dec 21 #Python
selenium自动化测试入门实战
Dec 21 #Python
You might like
搜索和替换文件或目录的一个好类--很实用
2006/10/09 PHP
PHP输出时间差函数代码
2013/01/28 PHP
php使用curl并发减少后端访问时间的方法分析
2016/05/12 PHP
在Z-Blog中运行代码[html][/html](纯JS版)
2007/03/25 Javascript
?牟┛途W扣了一??效果出?? target=
2007/05/27 Javascript
jquery下json数组的操作实现代码
2010/08/09 Javascript
JavaScript基础语法让人疑惑的地方小结
2012/05/23 Javascript
Nodejs进程管理模块forever详解
2014/06/01 NodeJs
DOM节点删除函数removeChild()用法实例
2015/01/12 Javascript
jQuery判断指定id的对象是否存在的方法
2015/05/22 Javascript
JavaScript严格模式详解
2015/11/18 Javascript
jQuery Timelinr实现垂直水平时间轴插件(附源码下载)
2016/02/16 Javascript
Bootstrap源码解读导航条(7)
2016/12/23 Javascript
详解Vue快速零配置的打包工具——parcel
2018/01/16 Javascript
Vue.js中的computed工作原理
2018/03/22 Javascript
javascript性能优化之分时函数的介绍
2018/03/28 Javascript
Javascript Promise用法详解
2018/05/10 Javascript
Vue 中对图片地址进行拼接的方法
2018/09/03 Javascript
Vue3 源码导读(推荐)
2019/10/14 Javascript
JS前后端实现身份证号验证代码解析
2020/07/23 Javascript
python读文件逐行处理的示例代码分享
2013/12/27 Python
python版opencv摄像头人脸实时检测方法
2018/08/03 Python
在pycharm上mongodb配置及可视化设置方法
2018/11/30 Python
Django组件cookie与session的具体使用
2019/06/05 Python
python爬虫中多线程的使用详解
2019/09/23 Python
Python matplotlib图例放在外侧保存时显示不完整问题解决
2020/07/28 Python
IE下实现类似CSS3 text-shadow文字阴影的几种方法
2011/05/11 HTML / CSS
CSS3实现银灰色动画效果的导航菜单代码
2015/09/01 HTML / CSS
说出你对remoting 和webservice的理解和应用
2014/06/08 面试题
实习销售业务员自我鉴定
2013/09/21 职场文书
英语专业个人求职自荐信
2013/09/21 职场文书
运动会稿件100字
2014/02/21 职场文书
班级团队活动方案
2014/08/14 职场文书
农村文化活动总结
2014/08/28 职场文书
安全教育日主题班会
2015/08/13 职场文书
JavaScript事件的委托(代理)的用法示例详解
2022/02/18 Javascript