当前位置: 首页 > news >正文

用手势操控现实: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]

相关文章:

用手势操控现实: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 max…...

【leetcode 力扣刷题】移除链表元素 多种解法

移除链表元素的多种解法 203. 移除链表元素解法①&#xff1a;头节点单独判断解法②&#xff1a;虚拟头节点解法③&#xff1a;递归 203. 移除链表元素 题目链接&#xff1a;203.移除链表元素 题目内容&#xff1a; 理解题意&#xff1a;就是单纯的删除链表中所有值等于给定的…...

leetcode503. 下一个更大元素 II 单调栈

思路&#xff1a; 与之前 739、1475 单调栈的问题如出一辙&#xff0c;唯一不同的地方就是对于遍历完之后。栈中元素的处理&#xff0c;之前的栈中元素因无法找到符合条件的值&#xff0c;直接加入vector中。而这里需要再重头遍历一下数组&#xff0c;找是否有符合条件的&…...

Oracle中列的维护

由于商业环境中&#xff0c;数据是不断变化的&#xff0c;客户的需求也是不断变化的&#xff0c;所以当一个表用了一段时间后&#xff0c;其结构就有可能需要变化。 而在Oracle中&#xff0c;提供了alter table这种方式来改变列。 从Oracle9.2版本之后&#xff1a; 如果需要变…...

后端项目开发:分页功能的实现(Mybatis+pagehelper)

分页查询是项目中的常用功能&#xff0c;此处我们基于Mybatis对分页查询进行处理。 引入分页依赖 <!-- pagehelper --> <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId>…...

SpringBoot集成Drools

一:简介 规则引擎全称为业务规则管理系统(Business Rule Management System)简称BRMS,主要思想是将应用程序中的业务决策部分分离开来,并使用预定义的语义模块编写业务决策(业务规则),由用户或开发者在需要时进行配置、管理。 其实就是将计算逻辑写在脚本中,通过Jav…...

React创建组件的三种方式及其区别是什么?

在React中&#xff0c;创建组件的三种主要方式是函数式组件、类组件和使用React Hooks的函数式组件。以下是对每种方式的详细解释以及它们之间的区别&#xff1a; 1、函数式组件&#xff1a; 函数式组件是使用纯粹的JavaScript函数来定义的。它接收一个props对象作为参数&…...

W6100-EVB-PICO进行UDP组播数据回环测试(九)

前言 上一章我们用我们的开发板作为UDP客户端连接服务器进行数据回环测试&#xff0c;那么本章我们进行UDP组播数据回环测试。 什么是UDP组播&#xff1f; 组播是主机间一对多的通讯模式&#xff0c; 组播是一种允许一个或多个组播源发送同一报文到多个接收者的技术。组播源将…...

Qt 阴影边框

阴影边框很常见&#xff0c;诸如360以及其他很多软件都有类似效果&#xff0c;了解CSS3的同学们应该都知道box-shadow&#xff0c;它就是来设定阴影效果的&#xff0c;那么Qt呢&#xff1f;看过一些资料&#xff0c;说是QSS是基于CSS2的&#xff0c;既然如此&#xff0c;box-sh…...

前端面试:【性能优化】页面加载性能、渲染性能、资源优化

嗨&#xff0c;亲爱的前端开发者&#xff01;在今天的Web世界中&#xff0c;用户期望页面加载速度快、交互流畅。因此&#xff0c;前端性能优化成为了至关重要的任务。本文将探讨三个关键方面的性能优化&#xff1a;页面加载性能、渲染性能以及资源优化&#xff0c;以帮助你构建…...

从按下电源键到进入系统,CPU在干什么?

本专栏更新速度较慢&#xff0c;简单讲讲计算机的那些事&#xff0c;简单讲讲那些特别散乱杂的知识&#xff0c;欢迎各位朋友订阅专栏啊 感谢一路相伴的朋友们 浅淡操作系统系列第2篇 目录 通电 保护模式和实模式 内存管理单元MMU 逻辑地址&#xff1f;物理地址&#xff1…...

TypeScript初体验

1.安装编译TS工具包 npm i -g typescript 2. 查看版本号 tsc -v 3.创建ts文件 说明&#xff1a;创建一个index.ts文件 4.TS编译为JS tsc index.ts 5.执行JS代码 node index.js 6.简化TS的步骤 6.1安装 npm i -g ts-node 6.2执行 ts-node index.ts...

基于 Alpine 环境源码构建 alibaba-tengine(阿里巴巴)的 Docker 镜像

About Alpine&#xff08;简介&#xff09; Alpine Linux 是一款极其轻量级的 Linux 发行版&#xff0c;基于 busybox&#xff0c;多被当做 Docker 镜像的底包&#xff08;基础镜像&#xff09;&#xff0c;在使用容器时或多或少都会接触到此系统&#xff0c;本篇文章我们以该镜…...

政府网站定期巡检:构建高效、安全与透明的数字政务

在数字时代&#xff0c;政府网站已不仅仅是一个信息发布窗口&#xff0c;更是政府与公众互动的桥梁、政务服务的主要渠道以及数字化治理的重要平台。因此&#xff0c;确保政府网站的高效运行、信息安全与透明公开就显得尤为重要。在此背景下&#xff0c;定期的网站巡检与巡查成…...

C++信息学奥赛1138:将字符串中的小写字母转换成大写字母

#include<bits/stdc.h> using namespace std; int main() {string arr;// 输入一行字符串getline(cin, arr);for(int i0;i<arr.length();i){if(arr[i]>97 and arr[i]<122){char aarr[i]-32; // 将小写字母转换为大写字母cout<<a; // 输出转换后的字符}els…...

leetcode1475. 商品折扣后的最终价格 【单调栈】

简单题 第一次错误做法 class Solution { public:vector<int> finalPrices(vector<int>& prices) {int n prices.size();stack<int> st;unordered_map<int, int> mp;int i 0;while(i ! prices.size()) {int t prices[i];if (st.empty() || t …...

macOS M1使用TensorFlow GPU加速

本人是在pycharm运行代码&#xff0c;安装了tensorflow版本2.13.0 先运行代码查看有没有使用GPU加速&#xff1a; import tensorflow as tf# Press the green button in the gutter to run the script. if __name__ __main__:physical_devices tf.config.list_physical_dev…...

GNU-gcc编译选项-1

include目录 -I &#xff0c;比如: -I. -I ./Platform/include -I ./Platform/include/prototypes -I ./tpm/include -I ./tpm/include/prototypes -I ./Simulator/include -I ./Simulator/include/prototypes 编译选项 在GCC编译器中&#xff0c;-D是一个编译选项&…...

【DEVOPS】Jenkins使用问题 - 控制台输出乱码

0. 目录 1. 问题描述2. 解决方案3. 最终效果4. 总结 1. 问题描述 部门内部对于Jenkins的使用采取的是Master Slave Work Node的方式&#xff0c;即作为Master节点的Jenkins只负责任务调度&#xff0c;具体的操作由对应的Slave Work Node去执行。 最近团队成员反馈一个问题&a…...

logback-spring.xml

<?xml version"1.0" encoding"UTF-8"?> <configuration> <appender name"stdout" class"ch.qos.logback.core.ConsoleAppender"> <encoder> <springProfile name"dev"> <pattern>%d{…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving

地址&#xff1a;LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂&#xff0c;正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...

嵌入式学习之系统编程(九)OSI模型、TCP/IP模型、UDP协议网络相关编程(6.3)

目录 一、网络编程--OSI模型 二、网络编程--TCP/IP模型 三、网络接口 四、UDP网络相关编程及主要函数 ​编辑​编辑 UDP的特征 socke函数 bind函数 recvfrom函数&#xff08;接收函数&#xff09; sendto函数&#xff08;发送函数&#xff09; 五、网络编程之 UDP 用…...

五子棋测试用例

一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏&#xff0c;有着深厚的文化底蕴。通过将五子棋制作成网页游戏&#xff0c;可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家&#xff0c;都可以通过网页五子棋感受到东方棋类…...

spring Security对RBAC及其ABAC的支持使用

RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型&#xff0c;它将权限分配给角色&#xff0c;再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...