用手势操控现实:OpenCV 音量控制与 AI 换脸技术解析

基于opencv的手势控制音量和ai换脸

HandTrackingModule.py

import cv2
import mediapipe as mp
import timeclass handDetector():def __init__(self, mode = False, maxHands = 2, model_complexity = 1, detectionCon = 0.5, trackCon = 0.5):self.mode = modeself.maxHands = maxHandsself.model_complexity = model_complexityself.detectionCon = detectionConself.trackCon = trackConself.mpHands = mp.solutions.handsself.hands = self.mpHands.Hands(self.mode, self.maxHands, self.model_complexity, self.detectionCon, self.trackCon)self.mpDraw = mp.solutions.drawing_utilsdef findHands(self, img, draw = True):# Hand类的对象只能使用RGB图像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.connection_drawing_spec = self.mpDraw.DrawingSpec(color=(0, 255, 0), thickness=2)# 绘制self.mpDraw.draw_landmarks(img, handLms, self.mpHands.HAND_CONNECTIONS, connection_drawing_spec=self.connection_drawing_spec)return imgdef findPosition(self, img, handNum=0, draw=True):lmList = []# 每个点的索引和它的像素比例,若知道窗口的宽度和高度可以计算位置if self.results.multi_hand_landmarks:myHand = self.results.multi_hand_landmarks[handNum]for id, lm in enumerate(myHand.landmark):# print(id, lm)h, w, c = img.shapecx, cy = int(lm.x * w), int(lm.y * h)# print(id, cx, cy)lmList.append([id, cx, cy])if draw:cv2.circle(img, (cx, cy), 7, (255, 0, 0), cv2.FILLED)# 绘制每一只手return lmList

定义了一个名为 handDetector 的类,用于检测和跟踪手部。下面是代码的详细分析:

导入库

  • cv2: OpenCV 库,用于图像处理。
  • mediapipe as mp: 用于多媒体解决方案的库,在此用于手部检测。
  • time: 用于时间管理,但在给定的代码段中未使用。

handDetector

初始化方法 __init__

该方法用于初始化 handDetector 类的对象,并设置一些参数。

  • mode: 布尔值,控制 MediaPipe 手部解决方案的静态图像模式。默认值为 False
  • maxHands: 最大手部数量,控制同时检测的手的数量。默认值为 2
  • model_complexity: 模型复杂度,有 0、1、2 三个级别。默认值为 1
  • detectionCon: 检测置信度阈值。默认值为 0.5
  • trackCon: 跟踪置信度阈值。默认值为 0.5

此外,还创建了 MediaPipe 手部解决方案的实例,并初始化了绘图工具。

方法 findHands

该方法用于在给定图像中找到手,并根据需要绘制手部标记。

  • img: 输入图像。
  • draw: 布尔值,控制是否绘制手部标记。默认值为 True

该方法首先将图像从 BGR 转换为 RGB,然后处理图像以找到手部标记。如果找到了手部标记,并且 draw 参数为 True,则会在图像上绘制手部标记和连接线。

方法 findPosition

该方法用于在给定图像中找到手部标记的位置,并返回一个包含每个标记位置的列表。

  • img: 输入图像。
  • handNum: 手的索引,用于选择多个检测到的手中的特定一只。默认值为 0
  • draw: 布尔值,控制是否在图像上绘制每个标记的圆圈。默认值为 True

该方法遍历给定手的每个标记,并计算其在图像中的位置。如果 draw 参数为 True,则在每个标记的位置上绘制一个圆圈。

总结

handDetector 类是一个用于检测和跟踪手部的工具。它使用了 MediaPipe 的手部解决方案,并提供了在图像上绘制手部标记和连接线的功能。通过调用这些方法,你可以在视频流或静态图像中跟踪手部,甚至找到特定手部标记的位置。

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
tiga_img = cv2.imread("tiga.jpg", cv2.IMREAD_UNCHANGED)
detector = htm.handDetector(detectionCon=0.7)face_Cascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
devices = AudioUtilities.GetSpeakers()
interface = devices.Activate(IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
volume = cast(interface, POINTER(IAudioEndpointVolume))
# volume.GetMute()
# volume.GetMasterVolumeLevel()
# 音量范围
volRange = volume.GetVolumeRange()
print(volRange)
# 最小音量
minVol = volRange[0]
# 最大音量
maxVol = volRange[1]
vol = 0
volBar = 400
volPer = 0
def overlay_img(img, img_over, img_over_x, img_over_y):# 背景图像高宽img_w, img_h, img_c = img.shape# 覆盖图像高宽通道数img_over_h, img_over_w, img_over_c = img_over.shape# 转换成4通道if img_over_c == 3:img_over = cv2.cvtColor(img_over, cv2.COLOR_BGR2BGRA)# 遍历列for w in range(0, img_over_w):#遍历行for h in range(0, img_over_h):if img_over[h, w, 3] != 0:# 遍历三个通道for c in range(0, 3):x = img_over_x + wy = img_over_y + hif x >= img_w or y >= img_h:breakimg[y-40, x, c] = img_over[h, w, c]return imgwhile True:success, img = cap.read()gray_frame = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)height, width, channel = img.shapefaces = face_Cascade.detectMultiScale(gray_frame, 1.15, 5)for (x, y, w, h) in faces:gw = wgh = int(height * w / width)tiga_img = cv2.resize(tiga_img, (gw, gh+gh))print(gw, gh)if 0 <= x < img.shape[1] and 0 <= y < img.shape[0]:overlay_img(img, tiga_img, x, y)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]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)cx, cy = (x1+x2)//2, (y1+y2)//2cv2.circle(img, (cx, cy), 15, (255, 0, 255), cv2.FILLED)length = math.hypot(x2 - x1, y2 - y1)print(length)# Hand rang 130 25# Vomume Range -65 0vol = np.interp(length, [25, 175], [minVol, maxVol])volBar = np.interp(length, [25, 175], [400, 150])volPer = np.interp(length, [25, 175], [0, 100])print(int(length), vol)volume.SetMasterVolumeLevel(vol, None)if length<25: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 = cTimecv2.putText(img, f'FPS:{int(fps)}', (40, 50), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 0, 0), 3)cv2.imshow("img", img)cv2.waitKey(1)

1. 导入必要的库

  • OpenCV (cv2): 用于图像处理,例如读取图像、转换颜色空间、绘制形状等。
  • NumPy (np): 用于数值计算,特别是线性插值。
  • HandTrackingModule as htm: 导入自定义的手部检测模块。
  • math: 提供数学功能,例如计算两点间的距离。
  • ctypes, comtypes, pycaw.pycaw: 用于与操作系统的音量控制交互。

2. 初始化参数和对象

  • 摄像头大小 (wCam, hCam): 定义摄像头的宽度和高度。
  • 摄像头 (cap): 通过 OpenCV 初始化摄像头,并设置宽度和高度。
  • 时间 (pTime): 用于计算帧率。
  • 图像叠加 (tiga_img): 读取一个图像文件,稍后用于叠加。
  • 手部检测器 (detector): 使用自定义的手部检测模块创建检测器对象,设置检测置信度为 0.7。
  • 人脸检测 (face_Cascade): 加载 OpenCV 的 Haar 级联分类器来检测人脸。
  • 音量控制 (volume): 通过 pycaw 访问系统的音量控制,获取音量范围。

3. 定义图像叠加函数 overlay_img

该函数负责将一个图像叠加到另一个图像上的特定位置。它遍历覆盖图像的每个像素,并将非透明像素复制到背景图像的相应位置。

4. 主循环

在无限循环中,代码执行以下任务:

a. 人脸检测和图像叠加

  • 读取图像: 从摄像头捕获图像。
  • 灰度转换: 将图像转换为灰度,以便进行人脸检测。
  • 人脸检测: 使用级联分类器检测人脸。
  • 调整叠加图像: 根据人脸大小调整叠加图像的大小。
  • 叠加图像: 调用 overlay_img 函数将图像叠加到人脸上。

b. 手部检测和音量控制

  • 检测手部: 调用 detector.findHands 在图像上检测并绘制手部。
  • 找到位置: 调用 detector.findPosition 获取手部标记的位置。
  • 计算距离: 计算手部标记 4 和 8 之间的距离。
  • 绘制形状: 在这两个点上绘制圆圈,并在它们之间绘制线条。
  • 音量映射: 使用 NumPy 的 np.interp 函数将手的距离映射到音量范围。
  • 设置音量: 调用 volume.SetMasterVolumeLevel 设置系统音量。

c. 可视化

  • 绘制音量条: 在图像上绘制一个表示音量级别的矩形条。
  • 计算帧率: 使用当前时间和上一帧的时间计算帧率。
  • 绘制帧率: 在图像上绘制帧率文本。

d. 显示结果

  • 显示图像: 使用 OpenCV 的 imshow 方法显示处理后的图像。
  • 等待: 通过 OpenCV 的 waitKey 方法等待 1 毫秒,这样可以实时更新图像。

总结

这个代码集成了多个功能:通过摄像头捕获图像,检测人脸并在人脸上叠加图像,检测手部并通过手指之间的距离控制系统音量,然后通过 OpenCV 实时显示结果。它结合了图像处理、人脸和手部检测、系统交互和实时可视化,展示了计算机视觉和人机交互的强大功能。

效果

image-20230821012535304
(B站演示视频)[https://www.bilibili.com/video/BV1Xu41177Gz/?spm_id_from=333.999.0.0]

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

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

相关文章

如何构造不包含字母和数字的webshell

目录 利用不含字母与数字进行绕过 1.异或进行绕过 2.取反进行绕过 3.利用php语法绕过 利用不含字母与数字进行绕过 基本代码运行思路理解 <?php echo "A"^""; ?> 运行结果为! 我们可以看到&#xff0c;输出的结果是字符"!"。之所…

TM4C123库函数学习(3)---串口中断

前言 &#xff08;1&#xff09;学习本文之前&#xff0c;需要先学习前两篇文章。 &#xff08;2&#xff09;学习本文需要准备好TTL转USB模块。 函数介绍 ROM_GPIOPinConfigure&#xff08;&#xff09; 配置GPIO引脚的复用功能。因为引脚不可能只有一个输出输入作用&#xf…

Linux操作系统--linux环境搭建(1)

在上一节课中,我们对Linux有了一个初步的认识,想要进一步的学习Linux,我们需要先把Linux需要的环境搭建出来。下面我们一起来看一下如何搭建Linux环境。 1.CentOS下载 官方下载地址: The CentOS Project 下载步骤如下所示: 选择内容 选择镜像 2.Vmware下载安装 一台电脑本…

[Linux]环境变量

[Linux]环境变量 文章目录 [Linux]环境变量环境变量的概念查看环境变量环境变量的加载原理环境变量的添加刷新环境变量配置文件的路径 环境变量的概念 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数。 环境变量的本质&#xff1a;…

网络安全--wazuh环境配置及漏洞复现

目录 一、wazuh配置 二、wazuh案例复现 一、wazuh配置 1.1进入官网下载OVA启动软件 Virtual Machine (OVA) - Installation alternatives (wazuh.com) 1.2点击启动部署&#xff0c;傻瓜式操作 1.3通过账号&#xff1a;wazuh-user&#xff0c;密码&#xff1a;wazuh进入wazuh…

chatGPT界面

效果图&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html> <head><title>复选框样式示例</title> </head> <style>* {padding:0;margin: 0;}.chatpdf{display: flex;height: 100vh;flex-direction: row;}.chatpdf .pannel{widt…

实战演练 | Navicat 导出向导

数据库工具中的导出功能是指将数据从一个数据库系统导出到另一个数据库系统&#xff0c;或者将数据从一个文件格式导出到另一个文件格式。导出功能可以通过各种方式实现&#xff0c;例如使用SQL语句、数据库管理工具或第三方库和工具。在进行数据迁移时&#xff0c;通常需要先将…

5.4 webrtc的线程

那今天呢&#xff1f;我们来了解一下webrtc中的threed&#xff0c;首先我们看一下threed的类&#xff0c;它里边儿都含了哪些内容&#xff1f;由于threed的类非常大啊&#xff0c;我们将它分成两部分。 那第一部分呢&#xff0c;是我们看threed的类中都包含了哪些数据之后呢&a…

【HTML】基础语法讲解

基础语法 1. HTML 结构1.1 认识HTML标签1.2 HTML 文件基本结构1.3 标签层次结构1.4 快速生成代码框架 2. HTML 常见标签2.1 注释标签2.2 标题标签:h1-h62.3 段落标签:p2.4 <br>换行标签2.5 格式化标签2.6 图片标签&#xff1a;img2.7 超链接标签&#xff1a;a2.8 表格标签…

Vue2.0+webpack 引入字体文件(eot,ttf,woff)

webpack.base.config.js 需要配置 {test:/\/(woff2?|eot|ttf|otf)(\?.*)?$/,loader: url-loader,options: {limit: 10000,name: utils.assetsPath(fonts/[name].[hash:7].[ext])}} 如果 Vue2.0webpack3.6引入字体文件&#xff08;eot&#xff0c;ttf&#xff0c;woff&…

自己搭建Minecraft服务器并通过cpolar内网穿透实现与公网小伙伴联机我的世界

文章目录 1. Java环境搭建2.安装我的世界Minecraft服务3. 启动我的世界服务4.局域网测试连接我的世界服务器5. 安装cpolar内网穿透6. 创建隧道映射内网端口7. 测试公网远程联机8. 配置固定TCP端口地址8.1 保留一个固定tcp地址8.2 配置固定tcp地址 9. 使用固定公网地址远程联机 …

YUV图片查看器以及测试文件(YUV420)

参考文章&#xff1a;YUV格式的图片查看工具YUView 2.13 亲测可用 在windows上解压打开即可 需要输入一下宽高&#xff0c;如果格式不对&#xff0c;需要设置下格式 还可以看像素分量值&#xff0c;爽歪歪 YUV查看器和YUV测试文件 文章目录 20230816YUV图片查看器及其测试文…