python使用opencv实现手势识别并控制ppt

news2024/9/22 19:21:36

需要使用到的包

from collections import deque

import cv2
import numpy as np
import math
import shutil

import sys
import os
import time

#这个求出现频率最高的太慢了,所以把它放弃了
from collections import Counter

准备好安装包后需要获取图片

def star():
    while camera.isOpened():
        global frame
        ret, frame = camera.read()
        frame = cv2.flip(frame, 1)
        cv2.imshow('ori', frame)
        #
        # img=frame[0:int(0.8 * frame.shape[0]),
        #       int(0.5 * frame.shape[1]):frame.shape[1]][0:int(0.8 * frame.shape[0]),
        #       int(0.5 * frame.shape[1]):frame.shape[1]]
        frame,ndefects=grdetect(frame)
        # cv2.imshow('min', img)
        k = cv2.waitKey(1)
        if k == 27:
            camera.release()
            cv2.destroyAllWindows()
            break

写进方法start中
视频也是图片构成的,只是在不同帧展示不同的图片而已。这里根据自己电脑的性能选择取图片的频率。

然后一处图片的噪点

def _remove_background(frame):
    fgbg = cv2.createBackgroundSubtractorMOG2()  # 利用BackgroundSubtractorMOG2算法消除背景
    fgmask = fgbg.apply(frame)
    kernel = np.ones((3, 3), np.uint8)
    fgmask = cv2.erode(fgmask, kernel, iterations=1)
    res = cv2.bitwise_and(frame, frame, mask=fgmask)
    # cv2.imshow('res',fgmask)
    return res

最终是给机器看的,在让他处理之前尽量降低影响条件。

再根据皮肤识别获取手的大致形状

def _bodyskin_detetc(frame):
    # 肤色检测: YCrCb之Cr分量 + OTSU二值化
    ycrcb = cv2.cvtColor(frame, cv2.COLOR_BGR2YCrCb)  # 分解为YUV图像,得到CR分量
    (_, cr, _) = cv2.split(ycrcb)
    cr1 = cv2.GaussianBlur(cr, (5, 5), 0)  # 高斯滤波
    _, skin = cv2.threshold(cr1, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)  # OTSU图像二值化
    # cv2.imshow('skin',skin)
    return skin

获取大致轮廓

def _get_contours(array):
        # 利用findContours检测图像中的轮廓, 其中返回值contours包含了图像中所有轮廓的坐标点
        contours, _ = cv2.findContours(array, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
        return contours

接下来准对这个大致图形进行处理
这里利用到了 凹凸图处理(腐蚀,另外一个名词想不起来了!)


# 根据图像中凹凸点中的 (开始点, 结束点, 远点)的坐标, 利用余弦定理计算两根手指之间的夹角, 其必为锐角, 根据锐角的个数判别手势.
def _get_defects_count(array, contour,defects, verbose = False):
    ndefects = 0
    list=[]
    for i in range(defects.shape[0]):
        s,e,f,_ = defects[i,0]
        beg     = tuple(contour[s][0])
        end     = tuple(contour[e][0])
        far     = tuple(contour[f][0])
        a = math.sqrt((beg[0] - end[0]) ** 2 + (beg[1] - end[1]) ** 2)
        b = math.sqrt((beg[0] - far[0]) ** 2 + (beg[1] - far[1]) ** 2)
        c = math.sqrt((end[0] - far[0]) ** 2 + (end[1] - far[1]) ** 2)
        angle   = math.acos((b ** 2 + c ** 2 - a ** 2) / (2 * b * c)) # * 57
        if angle <= math.pi/2 :#90:
            if far[1]>350:#有的不需要的杂点在这里给他筛出
                break
            ndefects = ndefects + 1
            if verbose:
                cv2.circle(array, far, 3, [255,0,0], -1)
        if verbose:
            cv2.line(array, beg, end, [0,255,0], 1)
            cv2.circle(array, beg, 3, [255, 255, 0], -1)
            list.append(beg)

        cv2.imshow('arry',array)
    return array,ndefects,list

根据处理咱们可以获取得到五个数据,咱们需要利用其中的三个数据 (开始点, 结束点, 远点)通过反余弦定理求出手指岔开角度,进而判断伸出手指的个数。
为了使系统稳定运行这里家里arry进行缓存50个前50帧图像处理结果然后综合判断此时此刻的识别结果。

然后就是利用手势操作ppt了


def grdetect(array):
    global num_ppt
    strDath=os.getcwd()+'/'+str(num_ppt)+'.JPG'

    print('strDath',strDath)
    #读取ppt
    ppt1 = cv2.imread(strDath)

    copy       = array.copy()
    array = _remove_background(array) # 移除背景, add by wnavy
    thresh = _bodyskin_detetc(array)
    contours= _get_contours(thresh.copy()) # 计算图像的轮廓
    largecont  = max(contours, key = lambda contour: cv2.contourArea(contour))
    hull           = cv2.convexHull(largecont, returnPoints = False) # 计算轮廓的凸点
    try:
        defects        = cv2.convexityDefects(largecont, hull) # 计算轮廓的凹点
    except:
        print('凸点有问题')
        defects=None
    if defects is not None:
        # 利用凹陷点坐标, 根据余弦定理计算图像中锐角个数
        ndefects=''
        copy,ndefects,list = _get_defects_count(copy, largecont, defects, verbose = True)
        # 根据锐角个数判断手势, 会有一定的误差

        if ndefects == 0:

            num1.append(0)

            num2.append(0)

            min_lin=10000
            min_point=(0,0)
            if (sum(num1)<50 and sum(num2)<50):
                for i in range(len(list)):
                    if min_lin>list[i][1]:
                        min_lin=list[i][1]
                        min_point=list[i]
                # print('min_point=',min_point)
                dx.append(min_point[0])
                dy.append(min_point[1])
                # print('ppt大小',ppt1.shape)
                #ppt大小 (720, 960, 3)
                cv2.rectangle(copy, (0, 0),
                              (int(0.8 * frame.shape[1]), int(0.6 * frame.shape[0])), (255, 0, 0), 2)
                # print('宽:',0.8 * frame.shape[1],'高:',0.6 * frame.shape[0])
                #宽: 512.0 高: 288.0

                cv2.circle(copy, (sum(dx)//5,sum(dy)//5), 6, [255,0 , 255], -1)
                #宽512:960
                witch = int(np.interp(sum(dx)//5, [0, 512], [0, 960]))
                #高288:720
                height = int(np.interp(sum(dy)//5, [0, 288], [0, 720]))
                cv2.circle(ppt1, (witch, height), 6, [255, 0, 255], -1)
                cv2.imshow('copy',copy)
                try:
                    cv2.imshow('ppt', ppt1)
                except:
                    print('少一个手指一')
            print(0)
        elif ndefects == 1:

            num1.append(2)
            num2.append(0)
            if (sum(num1) > 50 and sum(num2) < 50):

                min_lin = 10000
                min_point = (0, 0)
                for i in range(len(list)):
                    if min_lin > list[i][1]:
                        min_lin = list[i][1]
                        min_point = list[i]
                # print('min_point=', min_point)
                dx.append(min_point[0])
                dy.append(min_point[1])
                # 宽512:960
                witch = int(np.interp(sum(dx) // 5, [0, 512], [0, 960]))
                # 高288:720
                height = int(np.interp(sum(dy) // 5, [0, 288], [0, 720]))
                print('sum(num1)=',sum(num1))
                if sum(num1)>50 and sum(num2) <50:
                    global imgCanvas
                    global xp,yp
                    if xp==0 and yp==0:
                        xp,yp=witch,height
                    cv2.line(ppt1, (xp,yp),(witch, height),[0, 255, 0], 15)
                    cv2.line(imgCanvas, (xp, yp), (witch, height), [155,155 , 0], 15)
                    xp, yp = witch, height
                    cv2.imshow('ppt',ppt1)
                    cv2.imshow('imgCanvas',imgCanvas)
            elif 20<sum(num1)<50 or sum(num2) != 0:
                img = cv2.putText(ppt1, "pencil loading....", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 255, 0), 2)
                try:
                    cv2.imshow('ppt', img)
                except:
                    print('少一个手指二')
            print(1+1)

代码真的太长了 这里沾不下!
其中有个难点就是 手写笔迹怎么檫除,为了解决这个问题引入了蒙版概念。
效果如下:
在这里插入图片描述
在这里插入图片描述
视屏地址:https://www.bilibili.com/video/BV1sf4y1u78g/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1678577.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解决找不到msvcr100.dll,无法继续执行代码的5种方案

当你在使用电脑过程中&#xff0c;系统突然弹出一个提示框&#xff0c;显示“找不到msvcr100.dll&#xff0c;无法继续执行代码”&#xff0c;msvcr100.dll是Microsoft Visual C Redistributable Package的一部分&#xff0c;它是一个至关重要的动态链接库文件&#xff0c;许多…

从零入门激光SLAM(十六)——卡尔曼滤波基础

一、卡尔曼滤波简介KF 卡尔曼滤波器&#xff08;Kalman Filter&#xff09;是一种用于估计动态系统状态的递归算法。它通过结合系统的动态模型和噪声观测数据&#xff0c;提供对系统状态的最优估计。卡尔曼滤波器广泛应用于信号处理、控制系统、导航、计算机视觉等领域。 卡尔…

视频智能检测AI智能分析网关V4告警消息推送:公众号消息推送的配置步骤介绍

TSINGSEE青犀智能分析网关V4属于高性能、低功耗的软硬一体AI边缘计算硬件设备&#xff0c;目前拥有3种型号&#xff08;8路/16路/32路&#xff09;&#xff0c;支持Caffe/DarkNet/TensorFlow/PyTorch/MXNet/ONNX/PaddlePaddle等主流深度学习框架。硬件内部署了近40种AI算法模型…

极越07来了, 要把特斯拉ModelS 拉下马?

文 | AUTO芯球 作者 | 雷慢 喵了个咪的&#xff01;国内智能驾驶汽车圈下半年要杀出个大黑马&#xff0c; 它就是极越07&#xff01; 自北京车展亮相引起央视报道之后&#xff0c;工信部近日公式了它的产品信息&#xff0c; 这意味着&#xff0c;极越07真的要量产了&#…

国内用户如何免费抢先体验GPT-4o(国内如何免费使用各类GPT产品,包含chatgpt、claude、Gemini等)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 GPT-4o抢先体验 📒📝 方法介绍🎈 永久免费🎈 其他工具⚓️ 相关链接 ⚓️📖 介绍 📖 “OpenAI的最新突破——GPT-4o已经到来,国内用户如何免费体验这一AI革命性产品?” 随着OpenAI的GPT-4o模型的发布,全球AI领域…

搭建Prometheus+grafana监控系统

1. 项目目标 &#xff08;1&#xff09;熟练部署安装node_exporter &#xff08;2&#xff09;熟练部署安装prometheus &#xff08;3&#xff09;熟练部署安装grafana 2. 项目准备 2.1. 规划节点 主机名 主机IP 节点规划 prometheus-server 10.0.1.10 server prome…

怎么批量下载视频?DY视频爬虫在线提取采集工具

短视频批量下载工具&#xff0c;具有多种模块和功能&#xff0c;方便用户快速批量下载短视频。该软件的详细介绍&#xff1a; 功能模块介绍&#xff1a; 一. 搜索词批量搜索下载 视频关键词添加&#xff1a;支持添加多个视频关键词Q530269148进行全平台视频搜索。历史去重&a…

STM32最小系统

组件描述主控芯片STM32F103C8T6等时钟源外部晶体振荡器或者陶瓷谐振器&#xff0c;通常在4MHz到25MHz之间复位电路包括复位按钮和复位电路&#xff0c;用于将单片机置于初始状态电源电路提供稳定的电压&#xff0c;通常为3.3V或5V编程/调试接口SWD接口或JTAG接口等&#xff0c;…

继承,多态,封装以及对象的打印

前言&#xff1a; 我们都知道Java是一种面向对象的编程语言&#xff0c;面向对象语言的三大特性就是继承&#xff0c;多态&#xff0c;封装&#xff0c;而这些特性正好的Java基础的一个主体内容。在学到这之前&#xff0c;我们肯定已经学习过了类和对象&#xff0c;所以这部分…

白酒:低酒精度白酒的消费特点与市场前景

低酒精度白酒的消费特点与市场前景是酒类市场的一个重要话题。随着品质意识的提高和消费者口味的多样化&#xff0c;低酒精度白酒逐渐受到越来越多的关注。云仓酒庄豪迈白酒作为白酒的品牌之一&#xff0c;其消费特点和市场前景值得深入探讨。 首先&#xff0c;从消费特点来看…

SQLserver - 笔记

1 SQLserver - 用户管理 4、SQL SERVER数据库用户管理_哔哩哔哩_bilibili 创建用户 - user 2.选择用户&#xff0c;修改属性

MIRO时,修改页签“采购订单参考”的数量时,金额不自动计算

MIRO 发票校验时&#xff0c;进入到如下界面&#xff0c;系统参考采购订单自动带出已经收货的金额和数量。 此时如果想要修改数量时&#xff0c;有些用户账号下&#xff0c;金额不自动计算&#xff0c;但是有些用户账号下&#xff0c;数量更改时&#xff0c;系统自动计算和建议…

互联网上的IP地址定位的应用及意义

在当今高度互联的数字时代&#xff0c;IP地址定位技术发挥着重要作用&#xff0c;帮助企业、机构和个人在多种应用场景中提高效率、保障安全和优化服务。IP数据云将深入探讨IP地址定位技术的具体应用及其实际意义。 什么是IP地址定位&#xff1f; IP地址定位IP数据云 - 免费IP…

效率提升80%!苏州金龙国际贸易数字提单试点成功

日前&#xff0c;江苏苏州自贸片区基于星火链网融合型基础设施和通商互信&#xff08;TradeTrust&#xff09;标准的数字提单试点成功&#xff0c;该批数字提单业务为苏州金龙客车对菲律宾的整车出口&#xff0c;由全球最大的集装箱运输公司马士基承运。随着车辆的成功交付&…

搭建Kubernetes v1.20二进制集群——单Master和Node组件

前言 本文将介绍如何使用二进制文件手动搭建 Kubernetes v1.20 集群。通过这种方法&#xff0c;我们可以更好地理解 Kubernetes 的内部工作原理&#xff0c;并具备更大的灵活性和控制权。下面将逐步构建 Kubernetes 集群&#xff0c;并进一步了解其各个组件之间的交互和配置。…

Ardupilot Rpanion 4GLTE 网络性能测试 - 国内中转

Ardupilot Rpanion 4GLTE 网络性能测试 - 国内中转 1. 源由2. 视频效果2.1 整体刷新率不高2.2 网络延迟可接受2.3 带宽增加丢包明显2.4 实测效果流畅 3. 总结 1. 源由 上一次&#xff0c;由于ZeroTier使用了国外服务器&#xff0c;延迟~ 569 ms&#xff0c;花屏、卡顿。 本着…

如何在湖师大官网找到考研真题

今天学弟问我怎么找真题&#xff0c;我必须告诉他怎么找湖师大的真题&#xff0c;身为考研学子&#xff0c;这是必须要知道滴&#xff0c;尤其是自命题&#xff0c;是吧&#xff0c;话不多说&#xff0c;言归正传&#xff0c;我们开始吧&#xff01; 1 打开湖师大官网 什么&a…

酷开科技不断赋能电视,致力于为消费者带来更好的娱乐体验!

在这个快节奏的现代社会&#xff0c;我们总是忙忙碌碌奔波在外&#xff0c;期冀找寻一份温馨和陪伴&#xff0c;但与其在外寻寻觅觅不如把目光放回到身边来&#xff0c;或许在家里你也能收获一份安宁与陪伴呢&#xff01; 人类不断增长的信息、心理和感官需求是媒体发展进步的…

4-1 综合应用延申:RYU北向接口的应用实现案例

ryu控制器在SDN三层架构中是处于中间层&#xff0c;&#xff08;如图1&#xff09; 图1 SDN三层架构 如何实现与应用层的通信&#xff0c;如图1所示&#xff0c;实现RYU控制器与应用层&#xff08;如开发应用web界面时数据可视化平台&#xff09;数据通信就需要利用SDN的北向…

智能文档处理:解析文档场景下多模态大模型的应用与研究前沿

解析文档场景下多模态大模型的应用与研究前沿 一、TextIn 文档解析技术1. 现有大模型文档解析问题2. 文档解析技术背景3. TextIn 文档解析技术架构4. 版面分析关键技术 Layout-engine 二、TextIn 文本向量化技术三、TextIn.com Text Intelligence 一、TextIn 文档解析技术 hell…