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算法之栈(stack)的实现
Aug 18 Python
python学习之第三方包安装方法(两种方法)
Jul 30 Python
python中Matplotlib实现绘制3D图的示例代码
Sep 04 Python
python安装模块如何通过setup.py安装(超简单)
May 05 Python
Python使用OpenCV进行标定
May 08 Python
Python3基于sax解析xml操作示例
May 22 Python
Apache,wsgi,django 程序部署配置方法详解
Jul 01 Python
Python 运行.py文件和交互式运行代码的区别详解
Jul 02 Python
python实现控制电脑鼠标和键盘,登录QQ的方法示例
Jul 06 Python
Python dict和defaultdict使用实例解析
Mar 12 Python
python上传时包含boundary时的解决方法
Apr 08 Python
Python 随机生成测试数据的模块:faker基本使用方法详解
Apr 09 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
php二维数组排序详解
2013/11/06 PHP
PHP编写daemon process详解及实例代码
2016/09/30 PHP
关于ThinkPhp 框架表单验证及ajax验证问题
2017/07/19 PHP
visual studio code 调试php方法(图文详解)
2017/09/15 PHP
laravel5.1框架基础之Blade模板继承简单使用方法分析
2019/09/05 PHP
jQuery 使用手册(六)
2009/09/23 Javascript
jQuery 获取URL的GET参数值的小例子
2013/04/18 Javascript
struts2+jquery组合验证注册用户是否存在
2014/04/30 Javascript
js鼠标悬浮出现遮罩层的方法
2015/01/28 Javascript
Bootstrap每天必学之面板
2015/11/30 Javascript
理解nodejs的stream和pipe机制的原理和实现
2017/08/12 NodeJs
JavaScript中防止微信浏览器被整体拖动的方法
2017/08/25 Javascript
D3.js实现拓扑图的示例代码
2018/06/30 Javascript
详解Vue 匿名、具名和作用域插槽的使用方法
2019/04/22 Javascript
Vue3.0的优化总结
2020/10/16 Javascript
Javascript生成器(Generator)的介绍与使用
2021/01/31 Javascript
[45:52]2018DOTA2亚洲邀请赛 4.1小组赛 A组加赛 LGD vs Liquid
2018/04/02 DOTA
Python中__init__和__new__的区别详解
2014/07/09 Python
python uuid模块使用实例
2015/04/08 Python
python实现类的静态变量用法实例
2015/05/08 Python
Python中字典的setdefault()方法教程
2017/02/07 Python
python正则表达式去除两个特殊字符间的内容方法
2018/12/24 Python
详解python中init方法和随机数方法
2019/03/13 Python
对python 调用类属性的方法详解
2019/07/02 Python
Python解析json时提示“string indices must be integers”问题解决方法
2019/07/31 Python
浅析python 通⽤爬⾍和聚焦爬⾍
2020/09/28 Python
python 递归相关知识总结
2021/03/03 Python
TripAdvisor德国:全球领先的旅游网站
2017/12/07 全球购物
美国值得信赖的婚恋交友网站:eHarmony
2018/10/04 全球购物
KENZO官网:高田贤三在法国创立的品牌
2019/05/16 全球购物
大唐面试试题(CPU,UNIX等等)
2012/01/11 面试题
2014社区三八妇女节活动总结
2014/03/01 职场文书
孝敬父母的活动方案
2014/08/28 职场文书
推广普通话共筑中国梦演讲稿
2014/09/21 职场文书
2015年幼儿园大班工作总结
2015/04/25 职场文书
实施意见格式范本
2015/06/05 职场文书