opencv实战项目 实现手势跟踪并返回位置信息(封装调用)

 OpenCV 是一个基于 Apache2.0 许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。

需要提前准备opencv 和 mediapipe库

在这里插入图片描述

 

pip --default-timeout=5000 install -i https://pypi.tuna.tsinghua.edu.cn/simple mediapipe

接着上一章的内容,这一次我们加入了fps显示和模块封装,以便我们接下来的学习。

import cv2
import numpy as np
import mediapipe as mp
import time

这部分是导入所需的Python库。cv2 是OpenCV库,用于图像处理和计算机视觉任务。numpy 用于数值计算。mediapipe 是一个Google开发的库,用于处理计算机视觉任务,例如姿势检测、手势识别等。time 是Python标准库,用于处理时间相关的操作。

class handDetector():def __init__(self, mode=False, maxHands=2, detectionCon=0.5, trackCon=0.5):self.mode = modeself.maxHands = maxHandsself.detectionCon = detectionConself.trackCon = trackConself.mpHands = mp.solutions.handsself.hands = self.mpHands.Hands(self.mode, self.maxHands, self.detectionCon, self.trackCon)self.mpDraw = mp.solutions.drawing_utils

这部分定义了一个名为 handDetector 的类。它有一个构造函数 __init__,用于初始化手部检测器对象。传递给构造函数的参数包括:

  • mode: 用于设置手部检测的模式,默认为 False
  • maxHands: 最大检测手的数量,默认为 2。
  • detectionCon: 检测的置信度阈值,默认为 0.5。
  • trackCon: 跟踪的置信度阈值,默认为 0.5。

在构造函数中,还初始化了 mpHandshandsmpDraw 对象。mpHandsmediapipe 库中的手部检测模块,hands 是用于手部检测的实际处理器,mpDraw 是用于在图像上绘制标记的实用工具。

    def findHands(self, img, draw=True):imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)results = self.hands.process(imgRGB)if results.multi_hand_landmarks:for handLms in results.multi_hand_landmarks:if draw:self.mpDraw.draw_landmarks(img, handLms, self.mpHands.HAND_CONNECTIONS)return img

这部分定义了一个名为 findHands 的方法,用于在给定图像上进行手部检测。它接受一个图像(img)和一个布尔值参数 draw,用于指定是否绘制检测结果。

在方法中,首先将图像转换为RGB格式,然后使用手部检测器 hands 处理图像,返回结果。如果检测到了手部,就遍历每个检测到的手部标记点,然后在图像上绘制出手部标记和连接线。最后,返回绘制了标记的图像。

    def findPosition(self,img,handNO=0,draw = True):lmList = []if self.results.multi_hand_landmarks:myHand = self.results.multi_hand_landmarks[handNO]for id, lm in enumerate(myHand.landmark):h, w, c = img.shapecx, cy = int(lm.x * w), int(lm.y * h)lmList.append([id,cx,cy])if draw:cv2.circle(img, (cx, cy), 10, (255, 255, 0), cv2.FILLED)return lmList

这部分定义了 findPosition 方法,用于获取手部标记点的坐标。方法接收一个图像(img)、一个可选的 handNO 参数(表示检测到的手部编号,默认为0)和一个布尔值参数 draw。方法首先检查是否有检测到的手部,如果有,就获取指定编号的手部标记点信息。然后,遍历手部标记点,计算并保存标记点的坐标,并在图像上绘制圆圈。最后,返回标记点坐标的列表。 

def main():pTime = 0cTime = 0cap = cv2.VideoCapture(0)detector = handDetector(maxHands=1)while True:success, img = cap.read()img = detector.findHands(img)lmList = detector.findPosition(img)if len(lmList)!= 0 :print(lmList[4])cTime = time.time()fps = 1 / (cTime - pTime)pTime = cTimecv2.putText(img, str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3,(255, 0, 155), 3)cv2.imshow("Image", img)cv2.waitKey(1)if __name__ == '__main__':main()

这部分定义了一个名为 main 的函数,用于主要的程序逻辑。在其中,首先初始化了摄像头捕获对象 cap,然后创建了一个 handDetector 的实例,即手部检测器。

进入主循环,不断从摄像头捕获图像,然后调用 detector.findHands(img) 进行手部检测和绘制,将结果显示在窗口中。还计算并绘制了帧率信息。

最后,使用 cv2.waitKey(1) 来处理键盘输入,允许用户退出程序。

总体来说,这段代码实现了从摄像头捕获图像,并使用 mediapipe 进行手部检测和标记绘制,同时还显示了帧率信息。这可以用于实时手势识别和交互应用。

 帧率在三十左右

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

怎么系统的学习机器学习、深度学习?当然是看书了

目录 前言 内容简介 学完本书,你将能够 作者简介 本书目录 京东自购链接 前言 近年来,机器学习方法凭借其理解海量数据和自主决策的能力,已在医疗保健、 机器人、生物学、物理学、大众消费和互联网服务等行业得到了广泛的应用。自从Ale…

论文阅读:《Waymo Public Road Safety Performance Data》

文章目录 1 背景2 方法2.1 数据来源2.2 碰撞数据 3 碰撞事件分析4 讨论 1 背景 这篇文章是讲waymo道路安全性能数据分析的,主要想表达的是waymo自动驾驶系统在安全上面的出色表现,以向政府、大众提高自己产品的公信力。 这篇文章分析的数据是自从2019年到…

《人月神话》:我所遇见的“焦油坑”

最近在读《人月神话》这本书。 发现大部分task延期和研发关系不是很大,技术为业务服务,但是偿还不了业务债。 焦油坑的概念源自于挖掘坑井时的一种不幸状况。当挖掘坑井时,首先会进入表土层,进展颇快。但接下来遇到了沥青或泥浆…

C++ 学习系列3 -- 函数压栈与出栈

在C中,函数压栈(函数调用)和出栈(函数返回)是函数调用过程中的两个关键步骤。下面将逐步解释这两个过程: 一 函数压栈与出栈过程简介 函数压栈(函数调用)的过程如下: …

【Bert101】变压器模型背后的复杂数学【01/4】

一、说明 众所周知,变压器架构是自然语言处理(NLP)领域的突破。它克服了 seq-to-seq 模型(如 RNN 等)无法捕获文本中的长期依赖性的局限性。变压器架构被证明是革命性架构(如 BERT、GPT 和 T5 及其变体&…

RocketMQ 延迟消息

RocketMQ 延迟消息 RocketMQ 消费者启动流程 什么是延迟消息 RocketMQ 延迟消息是指,生产者发送消息给消费者消息,消费者需要等待一段时间后才能消费到。 使用场景 用户下单之后,15分钟未支付,对支付账单进行提醒或者关单处理…

走进知识图谱(二)【世界知识图谱篇】知识表示的经典模型与平移模型及基于复杂关系建模的知识表示学习

上篇文章提到,该系列文章将主要围绕世界知识图谱和语言知识图谱这两大类知识图谱进行展开,并且提到知识图谱的主要研究包括了知识表示学习、知识自动获取和知识的推理与应用三大部分。今天主要介绍世界知识图谱的知识表示学习,其中包括经典的…

使用C语言实现UDP消息接收

目录 简介:步骤:步骤 1: 创建套接字步骤 2: 接收消息步骤 3: 完成 函数及变量解释总结: 简介: 在网络通信中,UDP(User Datagram Protocol)是一种无连接协议,它提供了一种快速、高效的数据传输方法。本文将向您展示如何使用C语言编…

Spring Bean 生命周期的执行流程

问题描述 Spring 生命周期全过程大致分为五个阶段: 1、创建前准备阶段 2、创建实例阶段 3、依赖注入阶段 4、 容器缓存阶段 5、销毁实例阶段 下图是 Spring Bean 生命周期完整流程图,其中对每个阶段的具体操作做了详细介绍: 一、创建前准备阶…

栈和队列详解

目录 栈 栈的概念及结构: 栈的实现: 代码实现: Stack.h stack.c 队列: 概念及结构: 队列的实现: 代码实现: Queue.h Queue.c 拓展: 循环队列(LeetCode题目链接&#xff0…

每天一道leetcode:516. 最长回文子序列(动态规划中等)

今日份题目: 给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。 子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。 示例1 输入:s "bbb…

【高频面试题】JVM篇

文章目录 一、JVM组成1.什么是程序计数器2.什么是Java堆?3.能不能介绍一下方法区(元空间)4.你听过直接内存吗5.什么是虚拟机栈6.垃圾回收是否涉及栈内存?7.栈内存分配越大越好吗?8.方法内的局部变量是否线程安全?9.什么…