IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 基于Opencv和Mediapipe实现手势控制音量 -> 正文阅读

[人工智能]基于Opencv和Mediapipe实现手势控制音量

前言

在先前的博客中已经实现过了手势追踪的基本功能,由于最近项目需要,开始学习封装操作,也为了更简洁的调用手势追踪模块,所以参照了Youtube上一位大佬的教程,把之前的追踪模块整理了一下,将代码封装到了类中,然后加了一些功能。

环境配置

开发环境:Pycharm

所需软件包:Opencv-python,Mediapipe,math,pycaw,numpy

实现原理

手势识别和追踪原理在之前的博客已经详述过了,对音量的控制是通过Mediapipe实时检测得出的拇指指尖和食指指尖的坐标,再通过坐标计算出两者距离,并将距离处理为参数调用pycaw中相关的音量控制函数实现手势对音量的实时控制,并且利用Opencv画出柱状图像以显示音量的实时大小。

源码

手势跟踪模块

import cv2
import mediapipe as mp
import time


class handDetector():
    def __init__(self,mode = False,maxHands = 2,comp = 1,detectionCon = 0.5,trackCon = 0.5):#这里由于函数库更新,所以多了一个复杂度参数,默认设为1
        self.mode = mode
        self.maxHands = maxHands
        self.comp = comp
        self.detectionCon = detectionCon
        self.trackCon = trackCon

        self.mpHands = mp.solutions.hands
        self.hands = self.mpHands.Hands(self.mode,self.maxHands,self.comp,
                                        self.detectionCon,self.trackCon)
        self.mpDraw = mp.solutions.drawing_utils

        self.handLmStyle = self.mpDraw.DrawingSpec(color=(0, 0, 255), thickness=5)  # 点的样式,前一个参数是颜色,后一个是粗细
        self.handConStyle = self.mpDraw.DrawingSpec(color=(0, 255, 0), thickness=3)  # 线的样式BGR,前一个参数是颜色,后一个是粗细
    def findHands(self,img,draw = True):
        imgRGB = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)#将图像转化为RGB图像
        self.results = self.hands.process(imgRGB)

        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)
                    self.mpDraw.draw_landmarks(img, handLms, self.mpHands.HAND_CONNECTIONS, self.handLmStyle, self.handConStyle)  # 画出点和线
        return img
    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):
                # print(id,lm)
                h, w, c = img.shape  # 得到图像的长宽以及通道数
                cx, cy = int(lm.x * w), int(lm.y * h)  # 计算出中心点位置
                #print(id, cx, cy)
                lmlist.append([id,cx,cy])
                if id == 0:
                    cv2.circle(img, (cx, cy), 15, (0, 0, 255), cv2.FILLED)
        return lmlist

def main():
    pTime = 0
    cTime = 0
    cap = cv2.VideoCapture(0)  # 捕获摄像头
    detector = handDetector()
    while True:
        success, img = cap.read()  # 读入每一帧图像
        img = detector.findHands(img)
        limist = detector.findPosition(img)
        if len(limist) != 0:
            print(limist[4])
        cTime = time.time()#用于计算FPS
        fps = 1/(cTime-pTime)
        pTime = cTime
        cv2.putText(img,f"FPS:{int(fps)}",(10,70),cv2.FONT_HERSHEY_PLAIN,3,
        (255,0,0),3)#在图像上画出实时FPS
        #print(results.multi_hand_landmarks)
        cv2.imshow("Image",img)#展示图像
        cv2.waitKey(1)#延迟1ms
if __name__ == "__main__":
    main()

音量控制代码(需要调用手势跟踪模块)

import cv2
import mediapipe as mp
import numpy as np
import time#用于得知当前时间
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
#########################
cTime = 0
pTime = 0
cap = cv2.VideoCapture(0)
cap.set(3,wCam)
cap.set(4,hCam)

detector = htm.handDetector(detectionCon=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)
    if len(lmList) != 0:
        print(lmList[4],lmList[8])
        x1,y1 = lmList[4][1],lmList[4][2]
        x2,y2 = lmList[8][1],lmList[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(length)
        #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)

    cTime = time.time()
    fps = 1/(cTime-pTime)
    pTime = cTime
    cv2.putText(img,f'{int(volPer)}%',(40,450),cv2.FONT_HERSHEY_PLAIN,
                2,(255,0,0),2)
    cv2.imshow("IMG",img)
    cv2.waitKey(1)

代码效果

音量控制及显示

扬声器音量

?

手指关节坐标显示

?

?项目不足:

1、项目所设置的音量控制手势太过简单,手势很有可能在无意状态下被识别并且改变音量,影响项目实用性,后面会设置更复杂一些的手势来改良。

2、由于代码构建时对音量控制参数的转化过于直接,在img图像显示音量为60%时,电脑实际音量只有25左右,两者并不是绝对的正比关系,需要进行参数修正。

3、由于Mediapipe所得到的坐标并不是绝对的空间坐标,会受到手势和摄像头之间远近的影响,因此对使用距离有一定的限制,这一点暂时没有想到什么好的解决方式,用深度摄像头的话实用性又不高,或许可以利用摄像头成像原理,给出手掌或者手指的大致长度,通过相似三角形大致计算出手掌和摄像头之间的距离来解决。

注意事项:

由于使用者版本可能跟作者不一样,在源码实际使用时手势跟踪模块有可能会报错,这是由于软件包版本不一致造成定义的某些函数的参数个数等不一致导致的,可以查看该软件包的官方注释来修改参数定义。当然,也可以直接将Opencv版本修改为4.5以上版本,Mediapipe修改为0.8.9.1,则不会出现上述报错。

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-02-26 11:31:25  更:2022-02-26 11:34:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 19:37:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码