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

基于Mediapipe_Unity_Plugin实现手势识别

 GitHub - homuler/MediaPipeUnityPlugin: Unity plugin to run MediaPipehttps://github.com/homuler/MediaPipeUnityPlugin

实现了以下:

public enum HandGesture
{
    None,
    Stop,
    ThumbsUp,
    Victory,
    OK,
    OpenHand
}

核心脚本:

// Copyright (c) 2023 homuler
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.using System.Collections;
using Mediapipe.Tasks.Vision.HandLandmarker;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;namespace Mediapipe.Unity.Sample.HandLandmarkDetection
{public class HandLandmarkerRunner : VisionTaskApiRunner<HandLandmarker>{[SerializeField] private HandLandmarkerResultAnnotationController _handLandmarkerResultAnnotationController;private Experimental.TextureFramePool _textureFramePool;public readonly HandLandmarkDetectionConfig config = new HandLandmarkDetectionConfig();public UnityAction<HandLandmarkerResult> ProcessHandLandmark;public override void Stop(){base.Stop();_textureFramePool?.Dispose();_textureFramePool = null;}protected override IEnumerator Run(){Debug.Log($"Delegate = {config.Delegate}");Debug.Log($"Image Read Mode = {config.ImageReadMode}");Debug.Log($"Running Mode = {config.RunningMode}");Debug.Log($"NumHands = {config.NumHands}");Debug.Log($"MinHandDetectionConfidence = {config.MinHandDetectionConfidence}");Debug.Log($"MinHandPresenceConfidence = {config.MinHandPresenceConfidence}");Debug.Log($"MinTrackingConfidence = {config.MinTrackingConfidence}");yield return AssetLoader.PrepareAssetAsync(config.ModelPath);var options = config.GetHandLandmarkerOptions(config.RunningMode == Tasks.Vision.Core.RunningMode.LIVE_STREAM ? OnHandLandmarkDetectionOutput : null);taskApi = HandLandmarker.CreateFromOptions(options, GpuManager.GpuResources);var imageSource = ImageSourceProvider.ImageSource;yield return imageSource.Play();if (!imageSource.isPrepared){Debug.LogError("Failed to start ImageSource, exiting...");yield break;}// Use RGBA32 as the input format.// TODO: When using GpuBuffer, MediaPipe assumes that the input format is BGRA, so maybe the following code needs to be fixed._textureFramePool = new Experimental.TextureFramePool(imageSource.textureWidth, imageSource.textureHeight, TextureFormat.RGBA32, 10);// NOTE: The screen will be resized later, keeping the aspect ratio.screen.Initialize(imageSource);SetupAnnotationController(_handLandmarkerResultAnnotationController, imageSource);var transformationOptions = imageSource.GetTransformationOptions();var flipHorizontally = transformationOptions.flipHorizontally;var flipVertically = transformationOptions.flipVertically;var imageProcessingOptions = new Tasks.Vision.Core.ImageProcessingOptions(rotationDegrees: (int)transformationOptions.rotationAngle);AsyncGPUReadbackRequest req = default;var waitUntilReqDone = new WaitUntil(() => req.done);var waitForEndOfFrame = new WaitForEndOfFrame();var result = HandLandmarkerResult.Alloc(options.numHands);// NOTE: we can share the GL context of the render thread with MediaPipe (for now, only on Android)var canUseGpuImage = SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLES3 && GpuManager.GpuResources != null;using var glContext = canUseGpuImage ? GpuManager.GetGlContext() : null;while (true){if (isPaused){yield return new WaitWhile(() => isPaused);}if (!_textureFramePool.TryGetTextureFrame(out var textureFrame)){yield return new WaitForEndOfFrame();continue;}// Build the input ImageImage image;switch (config.ImageReadMode){case ImageReadMode.GPU:if (!canUseGpuImage){throw new System.Exception("ImageReadMode.GPU is not supported");}textureFrame.ReadTextureOnGPU(imageSource.GetCurrentTexture(), flipHorizontally, flipVertically);image = textureFrame.BuildGPUImage(glContext);// TODO: Currently we wait here for one frame to make sure the texture is fully copied to the TextureFrame before sending it to MediaPipe.// This usually works but is not guaranteed. Find a proper way to do this. See: https://github.com/homuler/MediaPipeUnityPlugin/pull/1311yield return waitForEndOfFrame;break;case ImageReadMode.CPU:yield return waitForEndOfFrame;textureFrame.ReadTextureOnCPU(imageSource.GetCurrentTexture(), flipHorizontally, flipVertically);image = textureFrame.BuildCPUImage();textureFrame.Release();break;case ImageReadMode.CPUAsync:default:req = textureFrame.ReadTextureAsync(imageSource.GetCurrentTexture(), flipHorizontally, flipVertically);yield return waitUntilReqDone;if (req.hasError){Debug.LogWarning($"Failed to read texture from the image source");continue;}image = textureFrame.BuildCPUImage();textureFrame.Release();break;}switch (taskApi.runningMode){case Tasks.Vision.Core.RunningMode.IMAGE:if (taskApi.TryDetect(image, imageProcessingOptions, ref result)){_handLandmarkerResultAnnotationController.DrawNow(result);}else{_handLandmarkerResultAnnotationController.DrawNow(default);}break;case Tasks.Vision.Core.RunningMode.VIDEO:if (taskApi.TryDetectForVideo(image, GetCurrentTimestampMillisec(), imageProcessingOptions, ref result)){_handLandmarkerResultAnnotationController.DrawNow(result);}else{_handLandmarkerResultAnnotationController.DrawNow(default);}break;case Tasks.Vision.Core.RunningMode.LIVE_STREAM:taskApi.DetectAsync(image, GetCurrentTimestampMillisec(), imageProcessingOptions);break;}}}private void OnHandLandmarkDetectionOutput(HandLandmarkerResult result, Image image, long timestamp){_handLandmarkerResultAnnotationController.DrawLater(result);ProcessHandLandmark?.Invoke(result);}}
}

对于ProcessHandLandmark?.Invoke(result);进行处理手部21个关键点的三维坐标信息。

http://www.dtcms.com/a/313950.html

相关文章:

  • 笔记:webpack项目优化图片体积大小时 遇到 图片无法正常显示
  • 可信数据库大会现场,TDengine 时序数据库展示核电场景下的高性能与 AI 创新
  • 小程序七牛云文件上传封装js
  • 入门MicroPython+ESP32:PC远程控制ESP32 LED灯
  • 百度翻译详解:包括PaddleNLP、百度AI开放平台、接口逆向(包括完整代码)
  • 四、Linux 的实用操作
  • 基于开源AI智能名片链动2+1模式与S2B2C商城小程序的客户关系深化研究
  • 【高等数学】第八章 向量代数与空间解析几何——第一节 向量及其线性运算
  • 菜鸟集团招Java研发啦
  • Kubernetes RBAC 鉴权:构建安全的集群访问控制体系
  • k8s常见问题
  • 力扣热题100——数组
  • 关于Npm和Nvm的用法
  • 华为云产品图解
  • falsk windows 服务器部署-解决服务器外无法访问
  • 零售行业线上线下融合趋势,华为云智能零售解决方案,在门店运营与电商业务中的技术应用与场景实践
  • LLM大模型时代:生活服务领域的“生存革命“与新生态重构
  • [论文阅读] 人工智能 + 教学 | 从代码到职业:用机器学习预测竞赛程序员的就业潜力
  • FLutter 如何在跨平台下实现国际化多语言开发
  • 安全扫描:目标使用过期的TLS1.0 版协议问题
  • Spring AI Alibaba Graph 深度解析:原理、架构与应用实践
  • 尚硅谷2025最新SpringCloud速通-操作步骤(详细)
  • [复习]计算机网络
  • 从原始 Import/Export 到 wasm-bindgen 与自定义 Section
  • Ethereum:拥抱开源,OpenZeppelin 未来的两大基石 Relayers 与 Monitor
  • 嵌入式硬件中三极管推挽电路控制与实现
  • 模型蒸馏(Distillation):原理、算法、应用
  • 突破Transformer局限!MICN:线性复杂度实现时序预测新高度
  • LeetCode 132:分割回文串 II
  • 作物生长模型Oryza V3实战19:场景模拟常见问题及解决