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

Opencv完成手势识别

  • HSV的提取
  • 特征提取
  • 轮廓绘制
  • 完整代码

由于是使用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退出界面打印阈值。
效果如下:
Python使用Opencv图像处理方法完成手势识别(一)_第1张图片

特征提取

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

  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)

效果如下:
Python使用Opencv图像处理方法完成手势识别(一)_第2张图片

轮廓绘制

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

  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)

效果如下:
Python使用Opencv图像处理方法完成手势识别(一)_第3张图片

完整代码

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图像处理方法完成手势识别(二)

你可能感兴趣的:(opencv,python,计算机视觉)