手势 识别

news/2024/12/4 4:32:32/

小组做的一个基于mediapipe的手势识别

文章目录

  • 前言
  • 一、mediapipe是什么?
  • 二、使用步骤
    • 1.引入库
    • 2.定义手势内容
    • 3.手势识别

前言

在基于mediapipe的基础上实现对手势的识别

一、mediapipe是什么?

MediaPipe是一个主要用于构建音频、视频或任何时间序列数据的框架。在 MediaPipe 框架的帮助下,我们可以为不同的媒体处理功能构建管道。可以看看这篇文章

二、使用步骤

1.引入库

import cv2 as cv
import numpy as np
import mediapipe as mp
from numpy import linalg

2.定义手势函数

# 手指检测def finger_stretch_detect(point1, point2, point3):result = 0# 计算向量的L2范数dist1 = np.linalg.norm((point2 - point1), ord=2)dist2 = np.linalg.norm((point3 - point1), ord=2)if dist2 > dist1:result = 1return result# 检测手势
def detect_hands_gesture(result):if (result[0] == 1) and (result[1] == 0) and (result[2] == 0) and (result[3] == 0) and (result[4] == 0):gesture = "good"elif (result[0] == 0) and (result[1] == 1) and (result[2] == 0) and (result[3] == 0) and (result[4] == 0):gesture = "one"elif (result[0] == 0) and (result[1] == 0) and (result[2] == 1) and (result[3] == 0) and (result[4] == 0):gesture = "what?"elif (result[0] == 0) and (result[1] == 1) and (result[2] == 1) and (result[3] == 0) and (result[4] == 0):gesture = "two"elif (result[0] == 0) and (result[1] == 1) and (result[2] == 1) and (result[3] == 1) and (result[4] == 0):gesture = "three"elif (result[0] == 0) and (result[1] == 1) and (result[2] == 1) and (result[3] == 1) and (result[4] == 1):gesture = "four"elif (result[0] == 1) and (result[1] == 1) and (result[2] == 1) and (result[3] == 1) and (result[4] == 1):gesture = "five"elif (result[0] == 1) and (result[1] == 0) and (result[2] == 0) and (result[3] == 0) and (result[4] == 1):gesture = "six"elif (result[0] == 0) and (result[1] == 0) and (result[2] == 1) and (result[3] == 1) and (result[4] == 1):gesture = "OK"elif (result[0] == 0) and (result[1] == 0) and (result[2] == 0) and (result[3] == 0) and (result[4] == 0):gesture = "stone"else:gesture = "not in detect range..."return gesture

三.函数调用与机器视觉判断

def detect():cap = cv.VideoCapture(0)# 加载手部检测函数mpHands = mp.solutions.handshands = mpHands.Hands()# 加载绘制函数,并设置手部关键点和连接线的形状、颜色mpDraw = mp.solutions.drawing_utilshandLmsStyle = mpDraw.DrawingSpec(color=(0, 0, 255), thickness=int(5))handConStyle = mpDraw.DrawingSpec(color=(0, 255, 0), thickness=int(10))figure = np.zeros(5)landmark = np.empty((21, 2))if not cap.isOpened():print("Can not open camera.")exit()while True:ret, frame = cap.read()if not ret:print("Can not receive frame. Exiting...")breakframe_RGB = cv.cvtColor(frame, cv.COLOR_BGR2RGB)result = hands.process(frame_RGB)# 读取视频图像的高和宽frame_height = frame.shape[0]frame_width = frame.shape[1]# print(result.multi_hand_landmarks)# 如果检测到手if result.multi_hand_landmarks:# 为每个手绘制关键点和连接线for i, handLms in enumerate(result.multi_hand_landmarks):mpDraw.draw_landmarks(frame,handLms,mpHands.HAND_CONNECTIONS,landmark_drawing_spec=handLmsStyle,connection_drawing_spec=handConStyle)for j, lm in enumerate(handLms.landmark):xPos = int(lm.x * frame_width)yPos = int(lm.y * frame_height)landmark_ = [xPos, yPos]landmark[j, :] = landmark_# 通过判断手指尖与手指根部到0位置点的距离判断手指是否伸开(拇指检测到17点的距离)for k in range(5):if k == 0:figure_ = finger_stretch_detect(landmark[17], landmark[4 * k + 2], landmark[4 * k + 4])else:figure_ = finger_stretch_detect(landmark[0], landmark[4 * k + 2], landmark[4 * k + 4])figure[k] = figure_print(figure, '\n')gesture_result = detect_hands_gesture(figure)cv.putText(frame, f"{gesture_result}", (30, 60 * (i + 1)), cv.FONT_HERSHEY_COMPLEX, 2, (255, 255, 0), 5)cv.imshow('frame', frame)if cv.waitKey(1) == ord('q'):breakcap.release()cv.destroyAllWindows()if __name__ == '__main__':detect()

结果展示:

定义了one-six数字,以及石头,未定义

(根据你手指弯曲状态判定为0或1,再判定手势代表的意义)

 

 

总结

全部代码都放在这了,有需要的小伙伴直接复制就可以了


http://www.ppmy.cn/news/662295.html

相关文章

12 | 领域建模:如何用事件风暴构建领域模型?

还记得微服务设计为什么要选择 DDD 吗? 其中有一个非常重要的原因,就是采用 DDD 方法建立的领域模型,可以清晰地划分微服务的逻辑边界和物理边界。可以说,在 DDD 的实践中,好的领域模型直接关乎微服务的设计水平。因此…

vector 的基本用法

vector \text{vector} vector 的基本用法 头文件 : #include <vector>定义&#xff1a; vector<type> name; //type表示数据类型&#xff0c;name为名字在下面的例子中&#xff0c;有如下定义&#xff1a; vector<int> v; 在尾部插入元素 name.push_bac…

Web前端开发 -- HTML基础(2)

接 HTML基础&#xff08;1&#xff09; 目录 六、javascipt 脚本语言 1 定义文档内嵌脚本 2 载入外部脚本库 3 延迟执行脚本 4 defer延迟执行脚本 5 异步执行脚本async 6 不支持JavaScript的浏览器——noscript 七 、块级元素和行内元素 1 含义 2 块级元素和行内元素…

Java基础 常见数据结构与算法 项目总结

Java基础 1 Java基础必知必会 1.1 Java语言有哪些特点&#xff1f; 面向对象&#xff08;封装&#xff0c;继承&#xff0c;多态&#xff09;&#xff1b;平台无关性&#xff0c;平台无关性的具体表现在于&#xff0c;Java 是“一次编写&#xff0c;到处运行&#xff08;Wri…

Redis学习笔记2

个人博客 欢迎访问个人博客: https://www.crystalblog.xyz/ 备用地址: https://wang-qz.gitee.io/crystal-blog/ 1. Redis入门 1.1 Redis简介 B站视频: Redis入门到精通&#xff0c;深入剖析Redis缓存技术&#xff0c;Java企业级解决方案必看的redis教程 Redis官网 Redi…

通俗易懂了解50个IT专业术语

假设你是个妹子&#xff0c;你有一位男朋友&#xff0c;于此同时你和另外一位男生暧昧不清&#xff0c;比朋友好&#xff0c;又不是恋人。你随时可以甩了现任男友&#xff0c;另外一位马上就能补上。这是冷备份。 假设你是个妹子&#xff0c;同时和两位男性在交往&#xff0c;…

史上最污技术解读,60 个 IT 术语我竟然秒懂了......

假设你是个妹子...... 文末留言送书5本 关注公众号回复&#xff1a;抽奖 参与 假设你是个妹子&#xff0c;你有一位男朋友&#xff0c;于此同时你和另外一位男生暧昧不清&#xff0c;比朋友好&#xff0c;又不是恋人。你随时可以甩了现任男友&#xff0c;另外一位马上就能补上。…

React笔记 Taro笔记

React基础 1 组件通讯 1.1 props 子组件 import React from "react"; import PropTypes from "prop-types"; import { Button } from "antd";export default class EightteenChildOne extends React.Component {static propTypes { //propTypes…