Python使用Opencv图像处理方法完成手势识别(一)


由于是使用Opencv完成手势识别,所以首先利用颜色特征是对手的颜色进行提取,获得HSV的最小值与最大值。

HSV的提取

HSV颜色空间阈值主要是靠Trackbar调节阈值和cv2.inRange来生成掩膜来提取。
这是我写的HSV阈值获取的代码:

import cv2
import numpy as np

def MouseBack(value):
    pass

cv2.namedWindow('frams')
cv2.resizeWindow('frams',[400,400])

Video=cv2.VideoCapture(0)

cv2.createTrackbar('minH','frams',0,179,MouseBack)
cv2.createTrackbar('maxH','frams',179,179,MouseBack)
cv2.createTrackbar('minS','frams',0,255,MouseBack)
cv2.createTrackbar('maxS','frams',255,255,MouseBack)
cv2.createTrackbar('minV','frams',0,255,MouseBack)
cv2.createTrackbar('maxV','frams',255,255,MouseBack)

while True:
    res,img=Video.read()
    hsvimg=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
    
    minh=cv2.getTrackbarPos('minH','frams')
    maxh=cv2.getTrackbarPos('maxH','frams')    
    mins=cv2.getTrackbarPos('minS','frams')
    maxs=cv2.getTrackbarPos('maxS','frams')
    minv=cv2.getTrackbarPos('minV','frams')
    maxv=cv2.getTrackbarPos('maxV','frams')
    
    lowHSV=np.array((minh,mins,minv),np.uint8)
    highHSV=np.array((maxh,maxs,maxv),np.uint8)
    
    newimg=cv2.inRange(hsvimg,lowHSV,highHSV)
    newimg=cv2.bitwise_and(img,img,mask=newimg)
    
    cv2.imshow('frams',newimg)
    
    if cv2.waitKey(1) == ord('q'):
        print(lowHSV)
        print(highHSV)
        break
        
Video.release()       
cv2.destroyAllWindows()

使用方法:
运行代码之后,从第一个依次调节滑块,使画面中只有手显示出来。然后按Q退出界面打印阈值。
效果如下:
在这里插入图片描述

特征提取

准备工作做完,就可以开始进行图像处理了。可以先对单张图片进行处理。

  1. 首先是进行高斯滤波去噪
  2. 然后将图像从BGR转换到HSV
  3. 使用cv2.inRange获得掩膜
  4. 进行形态学操作进一步提取特征
    代码如下:
#读取图片
img=cv2.imread(img_path)
#高斯滤波
Gaussimg=cv2.GaussianBlur(img,[5,5],0)
#HSV转换
hsvimg=cv2.cvtColor(Gaussimg,cv2.COLOR_BGR2HSV)
#获得HSV掩膜
maskimg=cv2.inRange(hsvimg,lowHSV,highHSV)
#开运算
kernel=np.ones([3,3],dtype=np.uint8)
closeimg=cv2.morphologyEx(maskimg,cv2.MORPH_CLOSE,kernel,iterations=3)
#腐蚀
kernel=np.ones([5,5],dtype=np.uint8)
dilateimg=cv2.morphologyEx(closeimg,cv2.MORPH_DILATE,kernel,iterations=3)

效果如下:
在这里插入图片描述

轮廓绘制

轮廓绘制首先需要寻找轮廓,然后对轮廓特征,比如面积周长进行进一步过滤,最后对轮廓进行逼近,对轮廓进行逼近有两种。

  1. 轮廓近似cv2.approxPolyDP
  2. 轮廓凸包cv2.convexHull
#寻找轮廓
contours,num=cv2.findContours(newimg,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
    #获得轮廓面积
    area=cv2.contourArea(contour)
    #获得轮廓周长
    lenth=cv2.arcLength(contour,True)
    #阈值判断
    if area>20000 and lenth>1000:
        epsilon = 0.02*cv2.arcLength(contour,True)
        #轮廓近似
        approx1 = cv2.approxPolyDP(contour,epsilon,True)
        #轮廓凸包
        approx2=cv2.convexHull(contour)
        approx1=approx1.reshape(len(approx1),2)
        approx2 = approx2.reshape(len(approx2), 2)
        approx1=np.array(approx1,dtype=np.int32)
        approx2 = np.array(approx2, dtype=np.int32)
        cv2.polylines(faimg, [approx1], True, [255, 125, 100], 4, 16)
        cv2.polylines(f, [approx2], True, [255, 125, 100], 4, 16)

效果如下:
在这里插入图片描述

完整代码

import cv2
import numpy as np

highHSV=np.array([ 15 ,255,255])
lowHSV=np.array([ 0 ,50 ,50])

def img_hand(img):
    # if img.shape[0]>1000 and img.shape[1]>1000:
    #     img=cv2.resize(img,None,fx=0.2,fy=0.2)
    faimg=np.copy(img)
    img=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
    cv2.GaussianBlur(img,[5,5],0)
    img=cv2.inRange(img,lowHSV,highHSV)

    kernel=np.ones([3,3],dtype=np.uint8)
    img=cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel,iterations=1)
    kernel=np.ones([5,5],dtype=np.uint8)
    newimg=cv2.morphologyEx(img,cv2.MORPH_DILATE,kernel,iterations=1)

    contours,num=cv2.findContours(newimg,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    for contour in contours:
        area=cv2.contourArea(contour)
        lenth=cv2.arcLength(contour,True)
        if area>20000 and lenth>1000:
            epsilon = 0.02*cv2.arcLength(contour,True)
            approx = cv2.approxPolyDP(contour,epsilon,True)
            approx=approx.reshape(len(approx),2)
            approx=np.array(approx,dtype=np.int32)
            cv2.polylines(faimg, [approx], True, [255, 125, 100], 4, 16)
    return faimg

video=cv2.VideoCapture(0)
while video.isOpened():
    res,img=video.read()
    if res== True:
        newimg=img_hand(img)
        cv2.imshow('frams',newimg)
    if cv2.waitKey(1)==ord('q'):
        break

cv2.destroyAllWindows()
video.release()

由于不使用机器学习方法,缺点就是使用时手往前靠一点,头往后靠一点,防止脸的肤色与手混淆,下一章讲解如何识别不同手势。
Python使用Opencv图像处理方法完成手势识别(二)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月明Mo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值