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 获取et和excel的版本号
Apr 09 Python
numpy中实现二维数组按照某列、某行排序的方法
Apr 04 Python
浅述python2与python3的简单区别
Sep 19 Python
python实现年会抽奖程序
Jan 22 Python
Python实现的IP端口扫描工具类示例
Feb 15 Python
Python3简单实现串口通信的方法
Jun 12 Python
Numpy 中的矩阵求逆实例
Aug 26 Python
浅谈keras中自定义二分类任务评价指标metrics的方法以及代码
Jun 11 Python
Pytorch框架实现mnist手写库识别(与tensorflow对比)
Jul 20 Python
记一次django内存异常排查及解决方法
Aug 07 Python
Python常用base64 md5 aes des crc32加密解密方法汇总
Nov 06 Python
Python+Appium自动化测试的实战
Jun 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
实现树状结构的两种方法
2006/10/09 PHP
php读取数据库信息的几种方法
2008/05/24 PHP
PHP+jQuery 注册模块的改进(一):验证码存入SESSION
2014/10/14 PHP
php+mysql数据库实现无限分类的方法
2014/12/12 PHP
PHP多线程编程之管道通信实例分析
2015/03/07 PHP
PHP实现将textarea的值根据回车换行拆分至数组
2015/06/10 PHP
PHP面试常用算法(推荐)
2016/07/22 PHP
PHP多进程之pcntl_fork的实例详解
2017/10/15 PHP
php 命名空间(namespace)原理与用法实例小结
2019/11/13 PHP
Javascript连接Access数据库完整实例
2015/08/03 Javascript
如何检测JavaScript的各种类型
2016/07/30 Javascript
JavaScript中的子窗口与父窗口的互相调用问题
2017/02/08 Javascript
微信小程序的部署方法步骤
2018/09/04 Javascript
关于Vue项目跨平台运行问题的解决方法
2018/09/18 Javascript
axios异步提交表单数据的几种方法
2019/08/11 Javascript
Vue实现多标签选择器
2019/11/28 Javascript
Vue页面刷新记住页面状态的实现
2019/12/27 Javascript
JS实现旋转木马轮播图
2020/01/01 Javascript
vue中利用iscroll.js解决pc端滚动问题
2020/02/15 Javascript
[53:03]Optic vs TNC 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
python读取word文档,插入mysql数据库的示例代码
2018/11/07 Python
python+opencv实现霍夫变换检测直线
2020/10/23 Python
Python 实现王者荣耀中的敏感词过滤示例
2019/01/21 Python
python内存监控工具memory_profiler和guppy的用法详解
2019/07/29 Python
关于sys.stdout和print的区别详解
2019/12/05 Python
2020版Python学习路线图(附学习资料)
2020/09/15 Python
css3.0 图形构成实例练习二
2013/03/19 HTML / CSS
HTML5 Canvas基本线条绘制的实例教程
2016/03/17 HTML / CSS
诗普兰迪官方网站:Splendid
2018/09/18 全球购物
怎么样写好简历中的自我评价
2013/10/25 职场文书
片区教研活动总结
2014/07/02 职场文书
个人典型事迹材料
2014/12/30 职场文书
环境卫生整治简报
2015/07/20 职场文书
postgresql使用filter进行多维度聚合的解决方法
2021/07/16 PostgreSQL
python 中的jieba分词库
2021/11/23 Python
Python内置包对JSON文件数据进行编码和解码
2022/04/12 Python