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 相关文章推荐
Google开源的Python格式化工具YAPF的安装和使用教程
May 31 Python
python3使用scrapy生成csv文件代码示例
Dec 28 Python
Python multiprocess pool模块报错pickling error问题解决方法分析
Mar 20 Python
Python Numpy计算各类距离的方法
Jul 05 Python
python障碍式期权定价公式
Jul 19 Python
使用PyTorch将文件夹下的图片分为训练集和验证集实例
Jan 08 Python
Python3 利用face_recognition实现人脸识别的方法
Mar 13 Python
keras 获取某层的输入/输出 tensor 尺寸操作
Jun 10 Python
python转化excel数字日期为标准日期操作
Jul 14 Python
python中加背景音乐如何操作
Jul 19 Python
python 对xml解析的示例
Feb 27 Python
python re模块和正则表达式
Mar 24 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
PHPLog php 程序调试追踪工具
2009/09/09 PHP
处理php自动反斜杠的函数代码
2010/01/05 PHP
无JS,完全php面向过程数据分页实现代码
2012/08/27 PHP
Zend Framework入门教程之Zend_Config组件用法详解
2016/12/09 PHP
PHP数组去重的更快实现方式分析
2018/05/09 PHP
Web版彷 Visual Studio 2003 颜色选择器
2007/01/09 Javascript
JS中==与===操作符的比较
2009/03/21 Javascript
JS获取页面窗口大小的代码解读
2011/12/01 Javascript
javascript表单验证和Window详解
2014/12/11 Javascript
纯JavaScript实现的兼容各浏览器的添加和移除事件封装
2015/03/28 Javascript
js表单验证实例讲解
2016/03/31 Javascript
Ajax 加载数据 练习代码
2017/01/05 Javascript
vue组件表单数据回显验证及提交的实例代码
2018/08/30 Javascript
在小程序/mpvue中使用flyio发起网络请求的方法
2018/09/13 Javascript
vue中各种通信传值方式总结
2019/02/14 Javascript
小程序实现搜索界面 小程序实现推荐搜索列表效果
2019/05/18 Javascript
Vue使用vue-recoure + http-proxy-middleware + vuex配合promise实现基本的跨域请求封装
2019/10/21 Javascript
Python collections模块实例讲解
2014/04/07 Python
python opencv 图像尺寸变换方法
2018/04/02 Python
python3 中的字符串(单引号、双引号、三引号)以及字符串与数字的运算
2019/07/18 Python
解决pytorch 保存模型遇到的问题
2021/03/03 Python
HTML5微信播放全屏问题的解决方法
2017/03/09 HTML / CSS
canvas实现手机的手势解锁的步骤详细
2020/03/16 HTML / CSS
"火柴棍式"程序员面试题
2014/03/16 面试题
中科创达面试题
2016/12/28 面试题
高中自我鉴定范文
2013/11/03 职场文书
就业自荐书
2013/12/05 职场文书
甜品店的创业计划书范文
2014/01/02 职场文书
写自荐信三大法宝
2014/01/24 职场文书
小学国庆节活动方案
2014/02/11 职场文书
建筑设计专业求职自我评价
2014/03/02 职场文书
幼儿园亲子活动总结
2014/04/26 职场文书
全国劳模先进事迹材料(2016精选版)
2016/02/25 职场文书
vue点击弹窗自动触发点击事件的解决办法(模拟场景)
2021/05/25 Vue.js
go goroutine 怎样进行错误处理
2021/07/16 Golang
Python+Tkinter制作专属图形化界面
2022/04/01 Python