基于MediaPipeUnityPlugin的三维手势追踪

MediaPipe-UnityPlugin的基本使用 一个帮我们把MediaPipe移植到Unity的插件 阅读详情

VID_20230421_005228

简述

目前比较好用的几种手势追踪,很多都是基于AR,需要硬件支持

而Google的MediaPipe则门槛比较低,用电脑摄像头也能跑
同时,又有MediaPipeUnityPlugin已经帮我们移植进了Unity

但 MediaPipe 是基于图像识别的,因此我手的往前往后,近大远小 在它看来只是在放大缩小,得到的数据都只发生在一个平面上,缺少硬件的支持所以没有深度信息。
幸运的是,即使只是一个平面,强大的Google至少帮我们做到了骨骼的相对深度
请添加图片描述

于是,本文要做的是,如最上面视频所示,模拟出手的深度,让我们的手真正在一个三维空间里面活动

如果你尚不了解 MediaPipeUnityPlugin,先看看我上一篇 MediaPipe-UnityPlugin的基本使用
如果你已经认识 MediaPipeUnityPlugin 的 HandTracking,可以直接跳到 [5.获取坐标] 环节


参考案例

Assets\MediaPipeUnity\Samples\Scenes\Hand Tracking\Hand Tracking.unity
在这里插入图片描述

虽说插件已经提供了完整的案例,但因为我们要在这基础上加入额外的功能,所以还是模仿着搭一个自己的Graph和Solution,同时去掉一些用不到的内容,以简化代码

1. 声明一个 MyGraph

public class MyHandTrackingGraph : GraphRunner
{
   
   
	public override void StartRun(ImageSource imageSource)
    {
   
   
    	// 此处进行输出流的启动 和 CalculatorGraph的StartRun
    }
    protected override IList<WaitForResult> RequestDependentAssets()
    {
   
   
    	// 此处加载用到的数据文件
    }
}
  • 首先声明我们的输出流 和 输出流的名称

输出流我们使用插件提供的 OutputStream<TPacket, TValue>
手部追踪的输出流有6种:
手掌检测、基于手掌检测的矩形区、手节点的坐标、手节点的世界坐标、基于坐标的矩形区、左右手检测

分别如下:

// 手掌检测
OutputStream<DetectionVectorPacket, List<Detection>> _palmDetectionsStream;
const string _PalmDetectionsStreamName = "palm_detections";
// 基于手掌检测的矩形区
OutputStream<NormalizedRectVectorPacket, List<NormalizedRect>> _handRectsFromPalmDetectionsStream;
const string _HandRectsFromPalmDetectionsStreamName = "hand_rects_from_palm_detections";
// 手节点的坐标
OutputStream<NormalizedLandmarkListVectorPacket, List<NormalizedLandmarkList>> _handLandmarksStream;
const string _HandLandmarksStreamName = "hand_landmarks";
// 手节点的世界坐标
OutputStream<LandmarkListVectorPacket, List<LandmarkList>> _handWorldLandmarksStream;
const string _HandWorldLandmarksStreamName = "hand_world_landmarks";
// 基于坐标的矩形区
OutputStream<NormalizedRectVectorPacket, List<NormalizedRect>> _handRectsFromLandmarksStream;
const string _HandRectsFromLandmarksStreamName = "hand_rects_from_landmarks";
// 左右手检测
OutputStream<ClassificationListVectorPacket, List<ClassificationList>> _handednessStream;
const string _HandednessStreamName = "handedness";

还有我们输入流的名称

const string _InputStreamName = "input_video";

我们此次用到的只有手节点的坐标,所以只需要

const string _InputStreamName = "input_video";

OutputStream<NormalizedLandmarkListVectorPacket, List<NormalizedLandmarkList>> _handLandmarksStream;
const string _HandLandmarksStreamName = "hand_landmarks";
  • 随后在 ConfigureCalculatorGraph() 对它进行一下初始化和配置
protected override Status ConfigureCalculatorGraph(CalculatorGraphConfig config)
{
   
   
    _handLandmarksStream = new OutputStream<NormalizedLandmarkListVectorPacket, List<NormalizedLandmarkList>>(
        calculatorGraph, _HandLandmarksStreamName, config.AddPacketPresenceCalculator(_HandLandmarksStreamName), timeoutMicrosec);
        
    return base.ConfigureCalculatorGraph(config);
}

OutputStream的构造函数如下

/// <summary>
///   实例化一个 OutputStream class
///   图形必须具有 PacketPresenceCalculator 节点,用于计算流是否有输出
/// </summary>
/// <remarks>
///   当您希望同步获取输出,但不希望在等待输出时阻塞线程时,这很有用
/// </remarks>
/// <param name="calculatorGraph"> 流的所有者 </param>
/// <param name="streamName"> 输出流的名称 </param>
/// <param name="presenceStreamName"> 当输出存在时,输出true的流的名称 </param>
/// <param name="timeoutMicrosec"> 如果输出数据包为空,则 OutputStream 实例会丢弃数据包,直到此处指定的时间结束 </param>
public OutputStream(CalculatorGraph calculatorGraph, string streamName, string presenceStreamName, long timeoutMicrosec = 0) : this(calculatorGraph, streamName, false, timeoutMicrosec)
{
   
   
    this.presenceStreamName = presenceStreamName;
}
  • 然后定义一个异步输出监听的接口 和 一个获取同步输出的接口
public event EventHandler<OutputEventArgs<List<NormalizedLandmarkList>>> OnHandLandmarksOutput
{
   
   
    add => _handLandmarksStream.AddListener(value);
    remove => _handLandmarksStream.RemoveListener(value);
}

public bool TryGetNext(out List<NormalizedLandmarkList> handLandmarks, bool allowBlock = true)
{
   
   
    var currentTimestampMicrosec = GetCurrentTimestampMicrosec();
    return TryGetNext(_handLandmarksStream, out handLandmarks, allowBlock, currentTimestampMicrosec);
}
  • 在 StartRun() 和 Stop() 中进行启动和释放
public override void StartRun(ImageSource imageSource)
{
   
   
    _handLandmarksStream.StartPolling().AssertOk();
    calculatorGraph.StartRun().AssertOk();
}

public override void Stop()
{
   
   
    _handLandmarksStream?.Close();
    _handLandmarksStream = null;
    base.Stop();
}
  • 然后定义一个输入接口,用于将输入源传给输入流
public void AddTextureFrameToInputStream(TextureFrame textureFrame)
{
   
   
    AddTextureFrameToInputStream(_InputStreamName, textureFrame);
}
  • 至此,输入输出已经写好,我们的Graph目前应该是像这样
public class MyHandTrackingGraph : GraphRunner
{
   
   
    const string _InputStreamName = 
MediaPipeUnityPlugin(最新版)摇摆拳人脸识别 阅读详情

相关推荐

MediaPipe-UnityPlugin实战:从零搭建三维手势追踪系统

本文详细介绍了如何利用MediaPipe-UnityPlugin从零搭建三维手势追踪系统。通过环境配置、官方示例解析、核心架构剖析及自定义Graph与Solution开发,手把手指导开发者在Unity中集成AI视觉能力,实现低门槛的手部关键点检测与3D模型驱动,为AR/VR和游戏开发提供强大的自然交互解决方案。

weixin_29008805的博客 143

Unity三维手势交互实战:基于MediaPipe-UnityPlugin从配置到算法实现

计算机视觉中的手势识别技术,通过深度学习模型实时检测并定位手部关键点,是实现自然人机交互的核心原理。其技术价值在于将复杂的图像理解转化为结构化的坐标数据,为虚拟操控提供了高精度、低延迟的输入基础。在增强现实、体感游戏、虚拟培训等应用场景中,手势交互能极大提升沉浸感和操作直觉。本文聚焦于MediaPipe-UniityPlugin这一高效工具,它作为MediaPipe框架在Unity引擎中的桥梁,封装了完整的手部关键点检测管道,显著降低了在游戏和AR/VR项目中集成先进视觉功能的门槛。通过解析其本地化高性能的

weixin_34252686的博客 399

MediaPipe手势追踪避坑指南:从骨骼坐标提取到3D可视化(Unity2022实测)

本文详细解析了MediaPipe手势追踪在Unity2022中的实践应用,涵盖从骨骼坐标提取到3D可视化的全流程。通过MediaPipeUnityPlugin实现高精度21点手势识别,解决坐标系镜像、Z轴抖动等常见问题,并提供多手追踪优化方案。文章还分享了3D可视化进阶技巧和实战问题解决方案,帮助开发者提升虚拟交互体验。

weixin_42521856的博客 256

Unity集成Mediapipe手部追踪:从原理到AR试戴实战

计算机视觉中的手部姿态估计是理解人体动作交互的核心技术,它通过检测和定位手部关键点来解析手势意图。其原理通常基于深度学习模型,如卷积神经网络,对输入图像进行特征提取与关键点回归。这项技术的价值在于为自然用户界面提供了高精度的输入方式,极大增强了人机交互的沉浸感与直观性。在应用场景上,它广泛服务于虚拟现实操控、增强现实试戴、手势控制游戏以及无障碍手语识别等领域。本文聚焦于利用Google开源的Mediapipe这一轻量级机器学习方案,结合Unity引擎,实现跨平台的实时21点手部追踪。内容涵盖从环境搭建、插件

weixin_34198762的博客 313

Unity集成MediaPipe实战:跨平台视觉AI开发与性能优化指南

计算机视觉作为人工智能的核心分支,旨在使机器能够“看懂”和理解图像与视频内容。其基本原理是通过算法模型对像素数据进行分析,提取特征并识别模式。这项技术的核心价值在于将物理世界的视觉信息转化为计算机可处理的数据,从而在数字世界中创造智能交互。在工程实践中,开发者常面临模型集成复杂、跨平台部署困难以及实时性能优化等挑战。MediaPipe作为Google推出的开源跨平台框架,提供了一系列经过优化的预训练模型,能够高效处理人脸、手势、姿态等通用视觉任务,显著降低了开发门槛。通过MediaPipeUnityPlug

weixin_30516429的博客 289

MediaPipeUnityPlugin:运行MediaPipe图形的Unity插件

MediaPipe Unity插件 这是一个使用MediaPipe的Unity(2019.4.18f1)插件。 平台类 Linux桌面(在ArchLinux上测试) 安卓 的iOS macOS(仅CPU) Windows 10(仅限CPU,实验性) 先决条件 MediaPipe 请确保安装必需的软件包,并检查是否可以在计算机上运行官方演示。 OpenCV 默认情况下,假定OpenCV 3安装在/usr (例如/usr/lib/libopencv_core.so )。 如果您的版本或路径不同,请编辑和 。 .NET核心 该项目使用协议缓冲区与MediaPipe进行通信,并且必须安装.

MediaPipeUnity插件

MediaPipeUnity插件,包含人脸识别,骨骼识别,手势识别等,例程可测试通过

MediaPipeUnityPlugin

Unity摄像头识别插件,包括人脸识别、面部识别、手势识别、绿幕抠图等

ubuntu22.04降级安装CUDA11.3

ubuntu22.04原CUDA12.1降级安装11.3

gls_nuaa的博客 1774

硬件电路(22)-TTL和232切换电路

工作中会遇到TTL和232电平的通信的状态,为了实现一种便捷的切换方式,参考了一些文章,提供一种电路方便大家使用。

剑藏锋的博客 1843

邮件伪造和SPF

之前看了下邮件伪造觉得挺有意思的,所以看了下邮件伪造的东西,下面简单的总结了一下,如果有不妥的地方还望大佬们提出来。 1. 什么是SPF SPF是 Sender Policy Framework 的缩写,一种以IP地址认证电子邮件发件人身份的技术,是为了防范垃圾邮件而提出来的一种DNS记录类型,它是一种TXT类型的记录。 接收邮件方会首先检查域名的SPF记录,来确定发件人的IP地址是否被包含在SP...

SunJ3t的菠萝屋 2441

FunASR语音识别服务在Win11上的Docker部署避坑指南:模型配置与热词优化

本文详细介绍了在Windows 11系统上通过Docker部署FunASR语音识别服务的完整流程,包括环境准备、模型配置、热词优化及常见问题解决方案。特别针对Win11环境下的特殊配置和性能调优提供了实用指南,帮助开发者高效搭建高性能语音识别服务。

e3f4g5的博客 220

具身机器人内部PCB板分类与系统架构详解

本文系统梳理了机器人内部PCB板的功能架构,将其划分为5大模块:1)核心主板(含主控计算机板、实时控制板等);2)感知类PCB(视觉、听觉、触觉等);3)运动控制类PCB(伺服驱动、编码器等);4)电源与安全类PCB(电源管理、BMS等);5)通信类PCB(EtherCAT背板等)。通过人体器官类比(如大脑对应主控板、小脑对应实时控制板),详解了各模块的芯片选型、位置分布及协同关系,并给出信号/能量/指令的三流闭环示意图和典型系统参数(48V供电、1ms通信周期)。整体呈现了机器人"神经系统&qu

几十年资深高级架构师,技术专家的技术笔记。专注C、Java、Python、微服务、云原生、AI工程化及高并发系统分布式架构实战,分享源码剖析、性能调优与架构治理经验。 299

程序员必备75道逻辑思维题(附答案)之二

逻辑训练 身为一个大数据工程师,平时的算法训练还是不能少的,今天给大家看几道我曾经看到的逻辑思维题觉得很好,想分享一下。 【6】一个球、一把长度大约是球的直径2/3长度的直尺.你怎样测出球的半径?方法很多,看看谁的比较巧妙 【7】五个大小相同的一元人民币硬币。要求两两相接触,应该怎么摆? 【8】猜牌问题 S先生、P先生、Q先生他们知道桌子的抽屉里有16张扑克牌:红桃A、Q、4 黑桃J、8、4、2、...

蛋蛋淡淡定的庄园 3543

在Simulink中实现一个基于SiC MOSFET的高效率电机驱动系统

本文介绍了在Simulink中构建基于SiC MOSFET的高效率电机驱动系统的详细流程。系统由直流电源模块、SiC MOSFET逆变器模块、PMSM电机模型、控制策略模块(包括矢量控制和PWM生成)以及反馈测量模块组成。文章逐步指导了从模型创建到参数设置的完整过程,包括各模块的具体实现方法。通过仿真可以评估系统在不同负载条件下的响应速度、效率、功率密度等性能指标。该建模方法为电机驱动系统的设计和优化提供了有效工具,同时建议根据实际硬件规格和工程需求进行参数调整和定制化开发。

xiaoheshang_123的博客 241

出现 has been blocked by CORS policy: No ‘Access-Control-Allow-Origin‘ header is present on the 解决方法

Access to XMLHttpRequest at 'http://127.0.0.1:5000/api/data' from origin 'http://10.197.0.79:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

码农研究僧的博客 1万+

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

上一篇: MediaPipe-UnityPlugin的基本使用
下一篇: UnityEditor 判断材质上的贴图是否为Missing
EdmundRF
博客等级 码龄8年 31粉丝 10原创
评论 46
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值