mediapipe 手势节点识别自动控制音量

news2025/1/15 22:57:51

参考:https://www.computervision.zone/topic/volumehandcontrol-py/
在这里插入图片描述

主函数:
VolumeHandControl.py

import cv2
import time
import numpy as np
import HandTrackingModule as htm
import math
from ctypes import cast, POINTER
from comtypes import CLSCTX_ALL
from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume
################################
wCam, hCam = 640, 480
################################
cap = cv2.VideoCapture(0)
cap.set(3, wCam)
cap.set(4, hCam)
pTime = 0
detector = htm.handDetector(min_detection_confidence=0.7)
devices = AudioUtilities.GetSpeakers()
interface = devices.Activate(
    IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
volume = cast(interface, POINTER(IAudioEndpointVolume))
# volume.GetMute()
# volume.GetMasterVolumeLevel()
volRange = volume.GetVolumeRange()
minVol = volRange[0]
maxVol = volRange[1]
vol = 0
volBar = 400
volPer = 0
while True:
    success, img = cap.read()
    img = detector.findHands(img)
    lmList = detector.findPosition(img, draw=False)
    # print(lmList)
    if len(lmList[0]) != 0:
        # print(lmList[4], lmList[8])
        x1, y1 = lmList[0][4][1], lmList[0][4][2]
        x2, y2 = lmList[0][8][1], lmList[0][8][2]
        cx, cy = (x1 + x2) // 2, (y1 + y2) // 2
        cv2.circle(img, (x1, y1), 15, (255, 0, 255), cv2.FILLED)
        cv2.circle(img, (x2, y2), 15, (255, 0, 255), cv2.FILLED)
        cv2.line(img, (x1, y1), (x2, y2), (255, 0, 255), 3)
        cv2.circle(img, (cx, cy), 15, (255, 0, 255), cv2.FILLED)
        length = math.hypot(x2 - x1, y2 - y1)
        print(x2 - x1, y2 - y1)
        # Hand range 50 - 300
        # Volume Range -65 - 0
        vol = np.interp(length, [50, 300], [minVol, maxVol])
        volBar = np.interp(length, [50, 300], [400, 150])
        volPer = np.interp(length, [50, 300], [0, 100])
        # print(int(length), vol)
        volume.SetMasterVolumeLevel(vol, None)
        if length < 50:
            cv2.circle(img, (cx, cy), 15, (0, 255, 0), cv2.FILLED)
        cv2.rectangle(img, (50, 150), (85, 400), (255, 0, 0), 3)
        cv2.rectangle(img, (50, int(volBar)), (85, 400), (255, 0, 0), cv2.FILLED)
        cv2.putText(img, f'{int(volPer)} %', (40, 450), cv2.FONT_HERSHEY_COMPLEX,
            1, (255, 0, 0), 3)
    cTime = time.time()
    fps = 1 / (cTime - pTime)
    pTime = cTime
    cv2.putText(img, f'FPS: {int(fps)}', (40, 50), cv2.FONT_HERSHEY_COMPLEX,
                1, (255, 0, 0), 3)
    cv2.imshow("Img", img)
    cv2.waitKey(1)

  
    if cv2.waitKey(20) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

HandTrackingModule.py

import cv2
import mediapipe as mp
import time
import math

class handDetector():
    def __init__(self, mode=False, max_num_hands=2, min_detection_confidence=0.5, min_tracking_confidence=0.5):
        self.mode = mode
        self.max_num_hands = max_num_hands
        self.min_detection_confidence = min_detection_confidence
        self.min_tracking_confidence = min_tracking_confidence

        self.mpHands = mp.solutions.hands
        self.hands = self.mpHands.Hands(static_image_mode=self.mode, 
                                        max_num_hands=self.max_num_hands,
                                        min_detection_confidence=self.min_detection_confidence, 
                                        min_tracking_confidence=self.min_tracking_confidence)
        self.mpDraw = mp.solutions.drawing_utils
        self.tipIds = [4, 8, 12, 16, 20]

    def findHands(self, img, draw=True):
        imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        self.results = self.hands.process(imgRGB)
        # print(results.multi_hand_landmarks)

        if self.results.multi_hand_landmarks:
            for handLms in self.results.multi_hand_landmarks:
                if draw:
                    self.mpDraw.draw_landmarks(img, handLms,self.mpHands.HAND_CONNECTIONS)
        return img

    def findPosition(self, img, handNo=0, draw=True):
        xList = []
        yList = []
        bbox = []
        self.lmList = []
        if self.results.multi_hand_landmarks:
            myHand = self.results.multi_hand_landmarks[handNo]
            for id, lm in enumerate(myHand.landmark):
            # print(id, lm)
                h, w, c = img.shape
                cx, cy = int(lm.x * w), int(lm.y * h)
                xList.append(cx)
                yList.append(cy)
                # print(id, cx, cy)
                self.lmList.append([id, cx, cy])
            if draw:
                cv2.circle(img, (cx, cy), 5, (255, 0, 255), cv2.FILLED)
            xmin, xmax = min(xList), max(xList)
            ymin, ymax = min(yList), max(yList)
            bbox = xmin, ymin, xmax, ymax

            if draw:
                cv2.rectangle(img, (bbox[0] - 20, bbox[1] - 20),(bbox[2] + 20, bbox[3] + 20), (0, 255, 0), 2)

        return self.lmList, bbox

    def fingersUp(self):
        fingers = []
        # Thumb
        if self.lmList[self.tipIds[0]][1] > self.lmList[self.tipIds[0] - 1][1]:
            fingers.append(1)
        else:
            fingers.append(0)
        # 4 Fingers
        for id in range(1, 5):
            if self.lmList[self.tipIds[id]][2] < self.lmList[self.tipIds[id] - 2][2]:
                fingers.append(1)
            else:
                fingers.append(0)
        return fingers

    def findDistance(self, p1, p2, img, draw=True):

        x1, y1 = self.lmList[p1][1], self.lmList[p1][2]
        x2, y2 = self.lmList[p2][1], self.lmList[p2][2]
        cx, cy = (x1 + x2) // 2, (y1 + y2) // 2

        if draw:
            cv2.circle(img, (x1, y1), 15, (255, 0, 255), cv2.FILLED)
            cv2.circle(img, (x2, y2), 15, (255, 0, 255), cv2.FILLED)
            cv2.line(img, (x1, y1), (x2, y2), (255, 0, 255), 3)
            cv2.circle(img, (cx, cy), 15, (255, 0, 255), cv2.FILLED)

        length = math.hypot(x2 - x1, y2 - y1)
        return length, img, [x1, y1, x2, y2, cx, cy]

def main():
    pTime = 0
    cap = cv2.VideoCapture(0)
    detector = handDetector()
    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 = cTime

        cv2.putText(img, str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3,
        (255, 0, 255), 3)

        cv2.imshow("Image", img)
        cv2.waitKey(1)

if __name__ == "__main__":
    main()

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

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

相关文章

[问题解决] ubuntu 18.04 GPU驱动安装

删除当前显卡驱动[参考] sudo apt-get purge nvidia* 查看推荐驱动 sudo ubuntu-drivers devices 安装对应驱动 sudo apt install nvidia-driver-530 验证安装是否成功&#xff1a;nvidia-smi

「一本通 3.2 例 3」架设电话线

题目大意 在加权无向图上求出一条从 号结点到 号结点的路径&#xff0c;使路径上第 大的边权尽量小。 思路 由于是一次性的&#xff0c;且这题数据极小&#xff0c;考虑 正常情况下是来更新数组的&#xff0c;不过这次是更新 表示第个节点&#xff0c;&#xff08;可以…

springboot引入外部sdk,以及在maven中配置,以及连同sdk打包

目录 1 安置sdk 2 配置maven配置文件 3 刷新maven即可 4 打包配置 1 安置sdk 将外部的sdk放在项目的指定目录下&#xff0c;我选择放在resource/sdk的目录下 示例&#xff1a; 2 配置maven配置文件 打开pom.xml&#xff0c;新增以下的依赖配置 具体如下所示&#xff1a; …

C# OpenCvSharp 透视变换(图像摆正)Demo

效果 Demo下载 代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; using OpenCvSharp; using OpenCvSha…

王爽《汇编语言》期末考试题库(附答案)

单选题 第一章 PC机的最小信息单位是&#xff08; &#xff09;。 A. bit B. 字节 C. 字长 D. 字 A PC机的最小信息单位是比特(bit)&#xff0c;常用来表示一位二进制数字&#xff08;0或1&#xff09;。字节(byte)是计算机中常用的数据单位&#xff0c;一个字…

vscode中ModuleNotFoundError: No module named ‘torch‘解决方法

文章目录 遇到的问题解决方法参考 遇到的问题 使用vscode训练模型&#xff0c;没有使用远程服务器&#xff0c;使用本地运行代码&#xff0c;显示“ModuleNotFoundError: No module named ‘torch’” 解决方法 这是因为没有选择合适的python解释器。如何选择正确的解释器呢&…

【HDFS实战】HDFS上的数据均衡

HDFS上的数据均衡简介 文章目录 HDFS上的数据均衡简介重新平衡数据节点之间的数据块相关命令 重新平衡DN内磁盘间的数据相关命令PlanExecuteQueryCancelReport 相关配置调试 HDFS上的balance目前有两类&#xff1a; Balancer&#xff1a;节点之间的balanceDisk Balancer&#x…

C# WinForm 学习记录

1.为项目添加dll引用 在“解决方案资源管理器”面板中选择项目&#xff0c;单机鼠标右键&#xff0c;弹出菜单中选择“添加”->“引用”打开引用管理器&#xff0c;选择浏览添加自己需要的dll文件即可 2.位移运算符使用技巧 在进行位移运算时&#xff0c;当数值的二进制数…

设计模式学习笔记——你真的学透单例模式了吗

你真的学透单例模式了吗 一、概述 单例模式&#xff08;Singleton Pattern&#xff09;指确保一个类在任何情况下都绝对只有一个实例&#xff0c;并提供一个全局访问点&#xff0c;属于创建型设计模式 二、类图 三、通用写法 public class SingletonTest {public static vo…

使用docker安装redis,修改密码

1、搜索镜像 docker search redis 2、拉取镜像 docker pull redis 3.创建容器 前边是宿主机端口 后面是docker使用的端口 docker run --name redis -p 6379:6379 redis-test --requirepass 123456 这里密码设置为123456 4、如何修改密码 现有的redis创建密码或修改密码…

Python学习——字符串

一、字符串 字符串也是基本数据类型&#xff0c;是一个不可变的字符序列&#xff0c;字符串可以用单引号&#xff0c;双引号&#xff0c;三引号进行定义。 字符串的驻留机制&#xff0c;简而言之&#xff0c;就是相同的字符串只保留一个&#xff0c;后续创建相同字符串的时候&a…

【漏洞案例】云上攻防-记一次打穿云上内网的攻防实战

0x01 外网打点&#xff0c;但在云上 目标单位就给出了一个子域名和一个IP&#xff0c;访问给出的子域名就一个登录框&#xff0c;测试了下忘记密码处有用户名枚举&#xff0c;但登录功能做了登录失败处理&#xff0c;知道用户名也无法进行爆破。 登录时会调用api.target.com域…

CICflowmeter安装使用

项目地址&#xff1a;https://github.com/ahlashkari/CICFlowMeter前置条件&#xff1a;maven&#xff0c;winpcap或其他抓包工具&#xff0c;ideal或 Eclipse 用 ideal 打开项目&#xff0c;发现还需要 jnetpcap 包&#xff0c;但是 maven 仓库好像没有&#xff0c;自己编译 …

思科(Cisco)日志分析工具

作为网络安全管理员&#xff0c;实时监控和分析思科防火墙日志至关重要。对于安全网络&#xff0c;管理员需要&#xff1a; 检测各种网络攻击&#xff0c;并查明攻击的来源和类型&#xff08;思科实时日志查看器&#xff09;。跟踪思科防火墙上未经授权的登录尝试。获取有关活…

PHP OA协同办公管理系统mysql数据库web结构apache计算机软件工程网页wamp

一、源码特点 PHP OA协同办公管理系统 是一套完善的web设计系统&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 代码下载 https://download.csdn.net/download/qq_41221322/87959360https://do…

wireshark抓包工具常用功能

wireshark工具面板如下图所示&#xff1a; 本文记录我比较常用的功能。如果有大佬还用过其他功能麻烦指点一二。 抓包、查找、过滤、数据分析。 菜单工具栏&#xff1a; 设置时间戳格式&#xff1a; 为了方便自己查看&#xff0c;把时间戳格式设置为自己认为比较好看的格式…

ThinkPHP6 请求

ThinkPHP6 请求 前言一、 获取请求二、request其他方法三, 请求信息总结 前言 什么是请求&#xff0c;就是 G E T 和 _GET和 G​ET和_POST类似的东西 一、 获取请求 获取请求可以使用$_GET、$_POST、$_REQUEST、$_SERVER、$_SESSION、$_COOKIE、$_ENV等系统变量&#xff0c;也可…

Android——快速设置Quick Settings Tile(创建自定义快速设置磁贴)

Android——快速设置Quick Settings Tile&#xff08;创建自定义快速设置磁贴&#xff09; 简介快速设置磁贴的使用场景创建磁贴创建自定义图标创建并声明你的tile服务 管理你的tile服务TileService生命周期选择监听模式Active mode (推荐)Non-active mode Tile状态更新Tile处理…

字节跳动云原生大数据平台运维管理实践

云原生大数据是大数据平台新一代架构和运行形态。随着字节跳动内部业务的快速增长&#xff0c;传统大数据运维平台的劣势开始逐渐暴露&#xff0c;如组件繁多&#xff0c;安装运维复杂&#xff0c;与底层环境过度耦合&#xff1b;对业务方来说缺少开箱即用的日志、监控、告警功…

第7讲:使用ajax技术实现弹出商品详情提示功能(xml数据)

使用ajax技术使用ajax技术实现弹出商品详情提示功能&#xff0c;本案例使用原生态xmlhttprequest对象&#xff0c;GET方法异步通讯&#xff0c;后台使用map保存搜索数据&#xff0c;查询到对应数据后&#xff0c;返回xml格式数据&#xff0c;前端使用responseXML属性返回xml格式…