基于opencv的手势识别

这篇具有很好参考价值的文章主要介绍了基于opencv的手势识别。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

大家好,我是一名本科生,我的主要学习方向是计算机视觉以及人工智能。按照目前的学习进度来说,我就是一小白,在这里写下自己编写的程序,与大家分享,记录一下自己的成长。
基于opencv的手势识别

今天与大家分享的是基于OpenCv的手势识别。

思路分析

获取图片,在图片中找到手,然后进行一系列的闭运算,降噪平滑处理,轮廓查找,凸缺陷检测。(如果你不太理解这些操作,别着急在下面的源码中我会尝试着解释)
然后根据凸包缺陷的个数来判断手指的个数。

遇到的困难

在上述的过程借助opencv库很容易就可以实现,但实现的过程中令人头疼的地方。

在图像中找出手部是很麻烦的,一开始按照书上的方法是将读入的图片由BGR转换为HSV模式,由HSV来确定手的肤色范围,将手从图像中分离出来,代码如下:

//设置肤色范围,该范围的数值是百度出来的人体肤色范围
lower_skin = np.array([0,28,70],dtype = np.uint8)
upper_skin = np.array([20,255,255],dtype = np.uint8)
//根据肤色范围进行手的查找,
//cv2.inRange函数会将图像内不在该范围区域设置为黑色
mask = cv2.inRange(img_hsv,lower_skin,upper_skin)
//但是该方法的效果不理想,找出的手部不准确

我又在网上查找一番,找到了比HSV好的方法:椭圆肤色检测

//这里我写成了一个类
class check_skin():
    def __init__(self):
        // 创建椭圆模型
        self.ellipse_mode = np.zeros((256, 256), dtype=np.uint8)
        /// 在图像上绘制白色椭圆
        cv2.ellipse(self.ellipse_mode, (113, 155), (23, 15), 43, 0, 360, (255, 255, 255), -1)
    def check_finger(self,path):
        img = cv2.imread(path, cv2.IMREAD_COLOR)
        // 图像皮肤掩膜创建
        skin_mask = np.zeros(img.shape[:2], dtype=np.uint8)
        // 将图像转换为YCBCR
        img_ycrcb = cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB)
        for i in range(img.shape[0]):
            for j in range(img.shape[1]):
                cr = img_ycrcb[i, j][1]
                cb = img_ycrcb[i, j][2]
                if self.ellipse_mode[cr, cb] > 0:
                    skin_mask[i, j] = 255
        img = cv2.bitwise_and(img,img,mask = skin_mask)
        return img

这个方法要比HSV检测出来的手部效果好的多,效果图就不展示了,有兴趣的可以自己实验一下。
更多的肤色检测方法:请点击这里

手部识别的问题解决后,我来讲一下手势识别的过程
首先,了解一下凸包与凸缺陷

红色为凸包,蓝色点为凸缺陷的最深点(即边缘点到凸包距离最大点),绿色是轮廓。红色与绿色之间的区域即为凸缺陷。基于opencv的手势识别
接着我们使用函数:cv2.convexityDefects,convexityDefects:输出参数,检测到的最终结果,返回一个数组,其中每一行包含的值是[起点,终点,最远的点,到最远点的近似距离]。前三个点都是轮廓索引。前三个值得含义分别为:凸缺陷的起始点,凸缺陷的终点,凸缺陷的最深点(即边缘点到凸包距离最大点)
就是上图的蓝色小点,然后根据convexityDefects返回数组的每一行的前三个值,构成的三角形由于人手指伸开的时候所构成的三角形角度总是小于90度,来去除不属于手指的凸缺陷,然后统计小于90度的凸缺陷个数再加1就是手指的个数。
在伸出的手指的个数为一和零的时候统计凸缺陷是不可行的,如图:
基于opencv的手势识别
基于opencv的手势识别
这时候应该统计轮廓以及凸包的面积,设置比例关系来判断手指为1和0的情况。

代码

import numpy as np
import cv2
import time
import math
#将肤色检测的椭圆模型设计为类
class check_skin():
    def __init__(self):
        # 创建椭圆模型
        self.ellipse_mode = np.zeros((256, 256), dtype=np.uint8)
        # 在图像上绘制白色椭圆
        cv2.ellipse(self.ellipse_mode, (113, 155), (23, 15), 43, 0, 360, (255, 255, 255), -1)
    def check_finger(self,path):
        img = cv2.imread(path, cv2.IMREAD_COLOR)
        # 图像皮肤掩膜创建
        skin_mask = np.zeros(img.shape[:2], dtype=np.uint8)
        # 将图像转换为YCBCR
        img_ycrcb = cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB)
        for i in range(img.shape[0]):
            for j in range(img.shape[1]):
                cr = img_ycrcb[i, j][1]
                cb = img_ycrcb[i, j][2]
                if self.ellipse_mode[cr, cb] > 0:
                    skin_mask[i, j] = 255
        img = cv2.bitwise_and(img,img,mask = skin_mask)
        return img
 #将类初始化为对象
check_finger = check_skin()
#这个列表储存图片名称
img_path = ['zero','one','two','three','four','five']

for path in img_path:
	#图片地址合成以及椭圆模型检测
    finger_img = check_finger.check_finger(path+'.JPG')

    #转换为灰度图像
    finger_img_gray = cv2.cvtColor(finger_img,cv2.COLOR_BGR2GRAY)
    #阈值函数转化为二值图像
    _,finger_img_binary = cv2.threshold(finger_img_gray,50,255,cv2.THRESH_BINARY)
    #进行闭运算
    kernel = np.ones((4,4),dtype = np.uint8)
    finger_img_binary = cv2.morphologyEx(finger_img_binary,cv2.MORPH_CLOSE,kernel,iterations = 2)
    #高斯滤波进行去噪平滑
    finger_img_binary = cv2.GaussianBlur(finger_img_binary,(3,3),50)
    #轮廓查找
    contours, hierarchy = cv2.findContours(finger_img_binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    area_cont = cv2.contourArea(contours[0])
    #凸缺陷检测
    hull1 = cv2.convexHull(contours[0])
    area_hull = cv2.contourArea(hull1)
    #根据轮廓面积和轮廓凸包面积的比例来确定zero和one
    percentage = (area_hull-area_cont)/area_cont
    print(percentage)
    hull = cv2.convexHull(contours[0], returnPoints=False)
    convex = cv2.convexityDefects(contours[0],hull)
    #用来统计小于90的角的个数
    count = 0
    for i in range(convex.shape[0]):
        s,e,f,d = convex[i][0]
        start = contours[0][s][0]
        end = contours[0][e][0]
        far = contours[0][f][0]
        #计算三角形的三边的长度
        a = math.sqrt((start[0]-far[0])**2+(start[1]-far[1])**2)
        b = math.sqrt((end[0]-far[0])**2+(end[1]-far[1])**2)
        c = math.sqrt((start[0]-end[0])**2+(start[1]-end[1])**2)
        #计算角度
        angle = math.acos((a**2+b**2-c**2)/(2*a*b))*57
        #画出角度
        cv2.line(finger_img,start,far,(0,255,0),2)
        cv2.line(finger_img,end,far,(0,255,0),2)
        # #在角上放上角的度数
        # cv2.putText(finger_img,str(angle),far,cv2.FONT_HERSHEY_COMPLEX,1,(0,255,0),1)
        #判断角度小于九十度的角的个数
        if angle<90:
            count += 1
    if count == 0 :
        if percentage < 0.2 :
            cv2.putText(finger_img,str(count),(50,20),cv2.FONT_HERSHEY_COMPLEX,1,(0,255,0),1)
        else:
            cv2.putText(finger_img, str(count+1), (50,20), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 255, 0), 1)
    else:
        cv2.putText(finger_img, str(count+1), (50,20), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 255, 0), 1)

    cv2.imshow(path,finger_img)
    cv2.waitKey(0)

cv2.destroyAllWindows()

结尾

后来在网上无意间发现了mediapipe这个手势检测库,然后我使用这个库重新又写了一个手势识别的程序,如果大家想要了解,请看我的下一个文章。

最后,创作不易,请各位支持一下。我也是小白一名,欢迎大家的指导,交流。
基于opencv的手势识别文章来源地址https://www.toymoban.com/news/detail-438703.html

到了这里,关于基于opencv的手势识别的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于OpenCV的简易实时手势识别(含代码)

    这是我大一寒假时写着玩的,非常简陋。基于凸包检测,所以实际上是计算指尖数量判断1~5的手势。又为1 ~3手势赋了控制鼠标操作的功能(但不能移动鼠标,而且因为手势识别不太准确所以这个功能实现得很废/doge)。(才疏学浅,希望有生之年能写个更好的 版本信息:Vi

    2024年02月03日
    浏览(52)
  • 基于OpenCV的手势识别系统设计与开发

    随着计算机技术与信息处理技术迅速发展,智能化电子设备逐渐进入到日常的生产和生活中,与此同时,人们对电子设备操作过程的便捷化也提出了新的要求,这也促使计算机进行图像处理的技术也得到了发展。近些年兴起的模式识别技术为操作便捷化提供了新的研究方向和

    2024年02月03日
    浏览(47)
  • 课程设计——基于opencv的手势识别【真】完整项目

    一个简单的手势识别,过程很简单,主要用到了 opencv 和 sklearn 和 tkinter 三个库,下面我将会展示整个项目的代码和简要说明,并且 下面将会是完整的已经全部集成在三个 .py 文件的代码,你只需要将三个文件分别执行就可以训练出自己的手势识别模型 项目思想: 通过颜色寻

    2024年02月04日
    浏览(39)
  • 基于opencv + cnn + PIL的手势识别系统

    涉及技术栈:opencv + cnn + PIL 网络训练算法流程( train ing .py) 图像读取及预处理 本实验采用PLL库里的open函数完成图片的读取工作,用resize函数将图像的尺寸变为统一值。为减少卷积操作的计算量,将图像做归一化处理,将图像的像素值变为[0,1]之间。 2,编码标签 将训练集和测

    2024年02月04日
    浏览(54)
  • 设计一个学生类和它的一个子类——本科生类

    设计一个学生类( Student )和它的一个子类——本科生类( Undergraduate )。要求如下: (1)Student类有姓名( name )和年龄( age )属性,两者的访问权限为 protected ;一个包含两个参数的构造方法,用于给姓名和年龄属性赋值;一个 show( ) 方法用于输出Student的属性信息,输

    2023年04月09日
    浏览(48)
  • 基于python+opencv+mediapipe实现手势识别详细讲解

    目录 运行环境: 一、opencv 二、meidapipe配置 三、实现手部的识别并标注 1、参数分析 1.multi_hand_landmarks  2.multi_hand_world_landmarks 3.multi_handedness 2.绘制信息点和连线 python3.9.7  opencv-python4.6.0.66  mediapipe0.8.11 运行之前先要安装opencv-python、opencv-contrib-python、mediapipe 项目可能对版本的

    2024年01月25日
    浏览(50)
  • 基于OpenCV的手势1~5识别系统(源码&环境部署)

    项目参考AAAI Association for the Advancement of Artificial Intelligence 研究背景与意义: 随着计算机视觉技术的快速发展,手势识别系统在人机交互、虚拟现实、智能监控等领域得到了广泛应用。手势识别系统可以通过分析人体的手势动作,实现与计算机的自然交互,提高用户体验和操

    2024年02月04日
    浏览(48)
  • 毕业设计-基于机器视觉的手势识别系统-OPENCV

    目录 前言 课题背景和意义 实现技术思路 一、系统总体设计 二、手势区域特征提取 三、系统设计与实现 四、总结 实现效果图样例 最后     📅大四是整个大学期间最忙碌的时光,一边要忙着备考或实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年

    2024年02月08日
    浏览(68)
  • 本科生高薪专业top10,全被计算机承包了

    在每年被唱衰的行业里,即使如高薪神话的IT行业,也难逃此“劫”—— IT不行了!疲软了!现在再入行IT和计算机就是坑! 然而事实上,根据最新数据报告显示,2022届本科毕业生毕业半年后月收入排前10位的,全是与IT相关的计算机与电子信息类专业。 真正应了那句话:看

    2024年02月05日
    浏览(41)
  • 毕设项目分享 基于机器视觉opencv的手势检测 手势识别 算法 - 深度学习 卷积神经网络 opencv python

    今天学长向大家介绍一个机器视觉项目 基于机器视觉opencv的手势检测 手势识别 算法 普通机器视觉手势检测的基本流程如下: 其中轮廓的提取,多边形拟合曲线的求法,凸包集和凹陷集的求法都是采用opencv中自带的函数。手势数字的识别是利用凸包点以及凹陷点和手部中心

    2024年02月03日
    浏览(81)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包