zoukankan      html  css  js  c++  java
  • 尝试实现手势控制计算机(持续跟进)

    基于语言python,主要运用的包有cv2等

    1.在python中实现摄像头的图像获取

    安装opencv:

    1. 安装依赖

    pip install --upgrade setuptools

    pip install numpy Matplotlib

    2.安装opencv python版

    pip install opencv-python

    实现摄像头图像获取代码

    
    
    #-*- coding:utf-8 -*-
    import cv2
    import time

    cap = cv2.VideoCapture(0)#调取摄像头,0表示系统默认摄像头

    while True:
    ret,photo = cap.read()#读取图像
    cv2.imshow('please take our photo!',photo)#将图像传送自窗口

    key = cv2.waitKey(2)#设置等待时间,若为0图像定格

    if key == ord(" "):#输入空格截图
    filename = time.strftime('%Y%m%d-%H%M%S')+".jpg"#文件名为当前时间
    cv2.imwrite(filename,photo)#保存位置

    if key == ord('q'):#输入q退出
    break

    3.第一次尝试

    想用去背景后获取二值图像,然后检测凸包的方式来识别手势,效果很差

    实时去掉背景代码

    #-*- coding:utf-8 -*-
    import cv2
    import time

    cap = cv2.VideoCapture(0)#调取摄像头,0表示系统默认摄像头
    #构建3*3的椭圆核
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
    #创建BackgroundSubtractorMOG2(OpenCV自带的一种背景消减方法
    fgbg = cv2.createBackgroundSubtractorMOG2(detectShadows=False)

    while True:
    ret,frame = cap.read()#读取图像
    fgmask = fgbg.apply(frame)
    fgmask = cv2.morphologyEx(fgmask,cv2.MORPH_OPEN,kernel)
    im,contours,hierarchy = cv2.findContours(fgmask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

    frame = cv2.rectangle(frame,(150,100),(300,250),(0,255,0),2)
    # for c in contours:
    # # 计算各轮廓的周长
    # perimeter = cv2.arcLength(c, True)
    # if perimeter > 188:
    # # 找到一个直矩形(不会旋转)
    # x, y, w, h = cv2.boundingRect(c)
    # # 画出这个矩形
    # cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)

    cv2.imshow('frame', frame)
    cv2.imshow('fgmask', fgmask)

    key = cv2.waitKey(30)#设置等待时间,若为0图像定格

    if key == ord(" "): # 输入空格截图
    # filename = time.strftime('%Y%m%d-%H%M%S') + ".jpg" # 文件名为当前时间
    filename = "test.jpg"
    cv2.imwrite(filename, fgmask[100:250,150:300]) # 保存位置
    elif key == 27:
    break

    cap.release()
    cv2.destroyAllWindows()#释放并销毁窗口


    比对手势形状代码(完全行不通)
    # -*- coding:utf-8 -*-

    import numpy as np
    import cv2
    from matplotlib import pyplot as plt

    im = cv2.imread('test1.jpg')#需要识别的图
    im2 = cv2.imread('ex2.jpg')#标准例图


    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))#3*3的椭圆核


    img = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)#用这个方式转换的原因是最后输出时希望能看到彩色的的轮廓图
    img2 = cv2.cvtColor(im2,cv2.COLOR_BGR2GRAY)

    ret,thresh = cv2.threshold(img,127,255,0)
    ret,thresh2 = cv2.threshold(img2,127,255,0)#将图像二值化

    dst = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel)
    dst2 = cv2.morphologyEx(thresh2,cv2.MORPH_OPEN,kernel)#将图像进行开运算

    img,contours,hierarchy = cv2.findContours(dst,1,2)
    max = 0
    maxl = -1
    for i in range(len(contours)):
    if cv2.contourArea(contours[i]) > max :
    max = cv2.contourArea(contours[i])
    maxl = i

    print(maxl)
    print(len(contours))
    cnt = contours[maxl]#找到需识别图中最大的轮廓,即手的轮廓

    img,contours,hierarchy = cv2.findContours(dst2,1,2)
    cnt2 = contours[len(contours)-1]#对照例图中手的轮廓


    cv2.drawContours(im,[cnt],0,(0,255,0),3)

    ret = cv2.matchShapes(cnt,cnt2,1,0.0)
    print(ret)#将两轮廓进行比对

    # cv2.imshow('img',img)
    # cv2.imshow('thresh',thresh)
    cv2.imshow('im',im)
    cv2.waitKey(0)

     识别凸包代码(准确度低)

      # -*- coding:utf-8 -*-

    import numpy as np
    import cv2
    from matplotlib import pyplot as plt

    im = cv2.imread('test.jpg')

    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))#3*3的椭圆核
    img = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)#用这个方式转换的原因是最后输出时希望能看到彩色的的轮廓图

    ret,thresh = cv2.threshold(img,127,255,0)

    dst = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel)

    img,contours,hierarchy = cv2.findContours(dst,1,2)
    max = 0
    maxl = -1
    for i in range(len(contours)):
    if cv2.contourArea(contours[i]) > max :
    max = cv2.contourArea(contours[i])
    maxl = i

    print(maxl)
    print(len(contours))
    cnt = contours[maxl]#找到需识别图中最大的轮廓,即手的轮廓

    #显示凸包
    hull = cv2.convexHull(cnt,returnPoints=True)
    print(hull)
    cv2.polylines(im, [hull], True, (0, 255, 0), 2)

    #凸性检测
    # hull = cv2.convexHull(cnt,returnPoints=False)
    # defect = cv2.convexityDefects(cnt,hull)
    #
    # for i in range(defect.shape[0]):
    # s,e,f,d = defect[i,0]
    # start = tuple(cnt[s][0])
    # end = tuple(cnt[e][0])
    # far = tuple(cnt[f][0])
    # # cv2.line(im,start,end,[0,255,0],2)
    # # cv2.circle(im,start,5,[0,0,255],-1)
    # # cv2.circle(im,end,5,[0,0,255],-1)
    # cv2.circle(im,far,5,[0,0,255],-1)

    M = cv2.moments(cnt)
    cx = int(M['m10']/M['m00'])
    cy = int(M['m01']/M['m00'])
    cv2.circle(im,(cx,cy),5,[0,0,255],-1)

    cv2.imshow('img',im)
    cv2.waitKey(0)

    分析原因,是因为

    1)背景杂质太多,且由于使用了笔记本自带摄像头,无法单独识别到手

    2)光线不均匀,导致背景减除时无法准确识别到整个手的完整轮廓

    综上,该方法在要求实现条件更为广泛的情况下不太行得通

     

  • 相关阅读:
    《大道至简》读后感
    PowerBuilder学习笔记之1开发环境
    PowerBuilder学习笔记之14用户自定义对象
    查询数据库大小的代码
    JAVA基础_修饰符
    SQLSERVER查询存储过程内容
    Asp.Net WebAPI中Filter过滤器的使用以及执行顺序
    运算符
    判断(if)语句
    变量的命名
  • 原文地址:https://www.cnblogs.com/zodiac7/p/9268784.html
Copyright © 2011-2022 走看看