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处理RSS、ATOM模块FEEDPARSER介绍
Feb 18 Python
Python语言实现机器学习的K-近邻算法
Jun 11 Python
Python 爬虫图片简单实现
Jun 01 Python
深入理解python中sort()与sorted()的区别
Aug 29 Python
python ChainMap 合并字典的实现步骤
Jun 11 Python
讲解Python3中NumPy数组寻找特定元素下标的两种方法
Aug 04 Python
Python 70行代码实现简单算式计算器解析
Aug 30 Python
python实现大量图片重命名
Mar 23 Python
python通过文本在一个图中画多条线的实例
Feb 21 Python
python 子类调用父类的构造函数实例
Mar 12 Python
python中_del_还原数据的方法
Dec 09 Python
Python常用配置文件ini、json、yaml读写总结
Jul 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
利用递归把多维数组转为一维数组的函数
2006/10/09 PHP
PHP实现MVC开发得最简单的方法――模型
2007/04/10 PHP
PHP脚本中include文件出错解决方法
2008/11/20 PHP
通过JavaScript或PHP检测Android设备的代码
2011/03/09 PHP
探讨:使用XMLSerialize 序列化与反序列化
2013/06/08 PHP
PHP设计模式之装饰器模式实例详解
2018/02/07 PHP
jQuery下扩展插件和拓展函数的写法(匿名函数使用的典型例子)
2010/10/20 Javascript
javascript 兼容所有浏览器的DOM扩展功能
2012/08/01 Javascript
jQuery常用操作方法及常用函数总结
2014/06/19 Javascript
学习使用bootstrap3栅格系统
2016/04/12 Javascript
Vue-Router实现组件间跳转的三种方法
2017/11/07 Javascript
实例分析JS与Node.js中的事件循环
2017/12/12 Javascript
Vue 项目中遇到的跨域问题及解决方法(后台php)
2018/03/28 Javascript
微信小程序日历效果
2018/12/29 Javascript
过滤器vue.filters的使用方法实现
2019/09/18 Javascript
node.js实现简单的压缩/解压缩功能示例
2019/11/05 Javascript
js判断浏览器的环境(pc端,移动端,还是微信浏览器)
2020/12/24 Javascript
如何在Node和浏览器控制台中打印彩色文字
2020/01/09 Javascript
python获取当前计算机cpu数量的方法
2015/04/18 Python
Python中常见的数据类型小结
2015/08/29 Python
Python之Scrapy爬虫框架安装及简单使用详解
2017/12/22 Python
python-opencv 将连续图片写成视频格式的方法
2019/01/08 Python
python爬取酷狗音乐排行榜
2019/02/20 Python
python爬虫爬取微博评论案例详解
2019/03/27 Python
将pymysql获取到的数据类型是tuple转化为pandas方式
2020/05/15 Python
Python flask路由间传递变量实例详解
2020/06/03 Python
Python多线程threading创建及使用方法解析
2020/06/17 Python
在python中对于bool布尔值的取反操作
2020/12/11 Python
css 元素选择器的简单实例
2016/05/23 HTML / CSS
css3新单位vw、vh的使用教程
2018/03/23 HTML / CSS
社区工作者思想汇报
2014/01/13 职场文书
农村结婚典礼司仪主持词
2014/03/14 职场文书
入党思想汇报怎么写
2014/04/03 职场文书
简单租房协议书
2014/04/09 职场文书
2014年保育员工作总结
2014/12/02 职场文书
学校党支部公开承诺书
2015/04/30 职场文书