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 第一步 hello world
Sep 25 Python
在Python中使用zlib模块进行数据压缩的教程
Jun 26 Python
实例讲解Python中global语句下全局变量的值的修改
Jun 16 Python
python 反向输出字符串的方法
Jul 16 Python
python TF-IDF算法实现文本关键词提取
May 29 Python
Falsk 与 Django 过滤器的使用与区别详解
Jun 04 Python
使用python写一个自动浏览文章的脚本实例
Dec 05 Python
Python如何使用正则表达式爬取京东商品信息
Jun 01 Python
快速了解Python开发环境Spyder
Jun 29 Python
python利用线程实现多任务
Sep 18 Python
Python timeit模块原理及使用方法
Oct 10 Python
Pandas加速代码之避免使用for循环
May 30 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程序员的技术成长规划
2016/03/25 PHP
php实现微信企业付款到个人零钱功能
2018/10/09 PHP
Thinkphp框架使用list_to_tree 实现无限级分类列出所有节点示例
2020/04/04 PHP
Javascript 写的简单进度条控件
2008/01/22 Javascript
Prototype中dom对象方法汇总
2008/09/17 Javascript
JavaScript高级程序设计(第3版)学习笔记9 js函数(下)
2012/10/11 Javascript
javascript:void(0)是什么意思示例介绍
2013/11/17 Javascript
JavaScript Array对象详解
2016/03/01 Javascript
深入学习AngularJS中数据的双向绑定机制
2016/03/04 Javascript
JS实现仿百度文库评分功能
2017/01/12 Javascript
ES6新特性一: let和const命令详解
2017/04/20 Javascript
用javascript获取任意颜色的更亮或更暗颜色值示例代码
2017/07/21 Javascript
用 Vue.js 递归组件实现可折叠的树形菜单(demo)
2017/12/25 Javascript
基于$.ajax()方法从服务器获取json数据的几种方式总结
2018/01/31 Javascript
vue-cli 3.0 版本与3.0以下版本在搭建项目时的区别详解
2018/12/11 Javascript
ES2020系列之空值合并运算符 '??'
2020/07/22 Javascript
python模拟登录并且保持cookie的方法详解
2017/04/04 Python
使用Python3制作TCP端口扫描器
2017/04/17 Python
python求解数组中两个字符串的最小距离
2018/09/27 Python
详解Python3序列赋值、序列解包
2019/05/14 Python
django中ImageField的使用详解
2020/12/21 Python
CSS3 实现雷达扫描图的示例代码
2020/09/21 HTML / CSS
基于HTML5 Canvas:字符串,路径,背景,图片的详解
2013/05/09 HTML / CSS
HTML5操作WebSQL数据库的实例代码
2017/08/26 HTML / CSS
英国领先的在线旅游和休闲零售商:lastminute.com
2019/01/23 全球购物
您在慕尼黑的跑步商店:Lauf-bar
2019/10/11 全球购物
荷兰睡眠专家:Beter Bed
2020/11/23 全球购物
阿迪达斯越南官网:adidas越南
2020/07/19 全球购物
酒店led欢迎词
2014/01/09 职场文书
求职意向书范文
2014/04/01 职场文书
企业新年寄语
2014/04/04 职场文书
科长竞争上岗演讲稿
2014/05/12 职场文书
教师节大会主持词
2015/07/06 职场文书
开业典礼致辞
2015/07/29 职场文书
PyMongo 查询数据的实现
2021/06/28 Python
Pytest中skip和skipif的具体使用方法
2021/06/30 Python