원클릭으로
media-pipe-unity
MediaPipe Unity Plugin 集成。用于计算机视觉任务、手部/面部/姿态追踪、手势识别、目标检测以及 Unity 中的 ML 解决方案。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
MediaPipe Unity Plugin 集成。用于计算机视觉任务、手部/面部/姿态追踪、手势识别、目标检测以及 Unity 中的 ML 解决方案。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Unity Engine 游戏开发。适用于 Unity 项目、C# 脚本、场景设置、GameObject 系统、2D/3D 开发、物理、动画、UI、着色器 Shader、VR/AR 或任何 Unity 相关问题。
DOTween Unity 动画插件。用于补间动画、UI 过渡、相机震动、序列、TextMeshPro 动画以及 Unity 中任何动画需求。此 Skill 应用于 Unity 项目中与 DOTween 动画系统相关的所有任务。
PrimeTween Unity 高性能动画库。用于补间动画、UI 过渡、相机震动、序列以及 Unity 中任何零内存分配的动画需求。
创建有效 Skill 的指南。当用户想要创建新 Skill (或更新现有 Skill )以通过专业知识、工作流或工具集成扩展 Claude 能力时,应使用此 Skill 。
| name | media-pipe-unity |
| description | MediaPipe Unity Plugin 集成。用于计算机视觉任务、手部/面部/姿态追踪、手势识别、目标检测以及 Unity 中的 ML 解决方案。 |
Google MediaPipe 在 Unity 中的完整集成,提供手部追踪、面部检测、姿态识别、手势识别、目标检测等计算机视觉和机器学习解决方案。
在以下情况下触发此 Skill :
using Mediapipe;
using UnityEngine;
public sealed class HelloWorld : MonoBehaviour
{
private const string ConfigText = @"
input_stream: ""in""
output_stream: ""out""
node {
calculator: ""PassThroughCalculator""
input_stream: ""in""
output_stream: ""out1""
}
node {
calculator: ""PassThroughCalculator""
input_stream: ""out1""
output_stream: ""out""
}
";
private void Start()
{
using var graph = new CalculatorGraph(ConfigText);
using var poller = graph.AddOutputStreamPoller<string>("out");
graph.StartRun();
for (var i = 0; i < 10; i++)
{
graph.AddPacketToInputStream("in", Packet.CreateStringAt("Hello World!", i));
}
graph.CloseInputStream("in");
var packet = new Packet<string>();
while (poller.Next(packet))
{
Debug.Log(packet.Get());
}
graph.WaitUntilDone();
}
}
using Mediapipe;
using UnityEngine;
public class GraphExample : MonoBehaviour
{
private CalculatorGraph _graph;
void Start()
{
// 初始化图
var configText = @"
input_stream: ""input_video""
output_stream: ""output_video""
node {
calculator: ""PassThroughCalculator""
input_stream: ""input_video""
output_stream: ""output_video""
}
";
_graph = new CalculatorGraph(configText);
// 启用 GPU 推理(可选)
// var gpuResources = GpuResources.Create();
// _graph.SetGpuResources(gpuResources);
// 添加输出流监听器
_graph.StartRun();
}
void OnDestroy()
{
// 清理资源
_graph?.CloseAllPacketSources();
_graph?.WaitUntilDone();
_graph?.Dispose();
}
}
using Mediapipe.Tasks.Vision.HandLandmarker;
using Mediapipe.Tasks.Vision.Core;
using UnityEngine;
public class HandDetectionExample : MonoBehaviour
{
private HandLandmarker _handLandmarker;
void Start()
{
// 创建 Hand Landmarker
var options = new HandLandmarkerOptions
{
BaseOptions = new BaseOptions(ModelAssetPath: "hand_landmarker.task"),
RunningMode = RunningMode.LIVE_STREAM,
NumHands = 2,
MinHandDetectionConfidence = 0.5f,
MinHandPresenceConfidence = 0.5f,
MinTrackingConfidence = 0.5f
};
_handLandmarker = HandLandmarker.CreateFromOptions(options);
}
void Update()
{
// 检测手部关键点
var image = new Mediapipe.Tasks.Vision.Image();
// ... 设置图像数据
var result = _handLandmarker.Detect(image);
}
void OnDestroy()
{
_handLandmarker?.Dispose();
}
}
using Mediapipe.Unity.Sample;
using UnityEngine;
public class SolutionRunner : GraphRunner
{
// 配置文件在 Inspector 中设置
// [SerializeField] private TextAsset _cpuConfig;
protected override void ConfigureCalculatorGraph(CalculatorGraphConfig config)
{
// 配置输出流
calculatorGraph.Initialize(config);
// 输出流设置...
}
public override void StartRun(ImageSource imageSource)
{
// 启动推理
StartRun(new PacketMap());
}
protected override IList<WaitForResult> RequestDependentAssets()
{
// 加载模型文件
return new List<WaitForResult>
{
WaitForAsset("model.binarypb")
};
}
}
using Mediapipe;
using Mediapipe.Unity.Sample;
using UnityEngine;
public class ImageInputExample : MonoBehaviour
{
private ImageSource _imageSource;
void Start()
{
// 使用 WebCam 作为输入源
_imageSource = ImageSourceProvider.ImageSource;
StartCoroutine(_imageSource.Play());
}
void Update()
{
if (!_imageSource.isPrepared) return;
// 获取当前帧
var currentTexture = _imageSource.GetCurrentTexture();
// 创建 ImageFrame
var imageFrame = new ImageFrame(
ImageFormat.Types.Format.SRGBA,
currentTexture.width,
currentTexture.height,
currentTexture.GetRawTextureData(),
ImageFrame.Types.GlFormatInfo.ForUnityTextureFormat(currentTexture.format)
);
// 发送到 CalculatorGraph
// graph.AddPacketToInputStream("input_video", Packet.CreateImageFrameAt(imageFrame, timestamp));
}
}
using Mediapipe;
using UnityEngine;
public class OutputHandler : MonoBehaviour
{
// 使用 OutputStreamPoller 同步获取结果
void ProcessOutputSync()
{
var poller = _graph.AddOutputStreamPoller<float[]>("landmarks");
while (true)
{
var packet = new Packet<float[]>();
if (poller.Next(packet))
{
var landmarks = packet.Get();
// 处理关键点数据
}
}
}
// 使用 NativePacketCallback 异步获取结果
void ProcessOutputAsync()
{
_graph.ObserveOutputStream("landmarks", LandmarkCallback);
[AOT.MonoPInvokeCallback(typeof(CalculatorGraph.NativePacketCallback))]
private static IntPtr LandmarkCallback(IntPtr graphPtr, int streamId, IntPtr packetPtr)
{
using (var packet = Packet.CreateForReference<float[]>(packetPtr))
{
var landmarks = packet.Get();
// 处理关键点数据(注意:在非主线程执行)
}
return IntPtr.Zero;
}
}
}
| Solution | Description | Android | iOS | Linux | macOS | Windows |
|---|---|---|---|---|---|---|
| Object Detection | 目标检测 | ✓ | ✓ | ✓ | ✓ | ✓ |
| Face Detection | 面部检测 | ✓ | ✓ | ✓ | ✓ | ✓ |
| Face Landmark Detection | 面部关键点检测 (468点) | ✓ | ✓ | ✓ | ✓ | ✓ |
| Hand Landmark Detection | 手部关键点检测 (21点) | ✓ | ✓ | ✓ | ✓ | ✓ |
| Gesture Recognition | 手势识别 | ✓ | ✓ | ✓ | ✓ | ✓ |
| Pose Landmark Detection | 姿态关键点检测 (33点) | ✓ | ✓ | ✓ | ✓ | ✓ |
| Image Segmentation | 图像分割 | ✓ | ✓ | ✓ | ✓ | ✓ |
| Image Classification | 图像分类 | - | - | - | - | - |
| Image Embedding | 图像嵌入 | - | - | - | - | - |
| Solution | Description | Android | iOS | Linux | macOS | Windows |
|---|---|---|---|---|---|---|
| Audio Classification | 音频分类 | ✓ | ✓ | ✓ | ✓ | ✓ |
以下解决方案可通过 MediaPipe Framework 使用,但官方已停止支持:
MediaPipe Framework 的主要 API,用于构建和运行计算图。
快速开始:
// 初始化
var graph = new CalculatorGraph(configText);
// GPU 模式
var gpuResources = GpuResources.Create();
graph.SetGpuResources(gpuResources);
// 运行
graph.StartRun();
graph.AddPacketToInputStream("input", packet);
graph.CloseInputStream("input");
graph.WaitUntilDone();
详细文档: references/API-Overview.md
MediaPipe 中数据传递的基本单位。
类型支持:
// 基本类型
Packet.CreateString("text")
Packet.CreateInt(42)
Packet.CreateBool(true)
Packet.CreateFloat(3.14f)
// 媒体类型
Packet.CreateImageFrame(imageFrame)
Packet.CreateGpuBuffer(gpuBuffer)
// 自定义时间戳
Packet.CreateStringAt("text", timestampMicrosec)
详细文档: references/API-Overview.md
同步轮询输出流的数据。
// 创建轮询器
var poller = graph.AddOutputStreamPoller<float[]>("landmarks");
// 获取数据(阻塞直到有新数据)
var packet = new Packet<float[]>();
if (poller.Next(packet)) {
var data = packet.Get();
}
// 使用 observeTimestampBounds 处理空包
var poller = graph.AddOutputStreamPoller<float[]>("landmarks", true);
详细文档: references/API-Overview.md
Task API 提供了更高级的接口,简化了常见任务的使用。
手部关键点检测和手势识别。
var options = new HandLandmarkerOptions {
BaseOptions = new BaseOptions(ModelAssetPath: "hand_landmarker.task"),
NumHands = 2,
MinHandDetectionConfidence = 0.5f
};
var landmarker = HandLandmarker.CreateFromOptions(options);
var result = landmarker.Detect(image);
// 访问结果
foreach (var landmarks in result.Landmarks) {
foreach (var landmark in landmarks) {
Debug.Log($"({landmark.X}, {landmark.Y}, {landmark.Z})");
}
}
面部检测和关键点识别。
// Face Detection
var detector = FaceDetector.CreateFromOptions(options);
var detectionResult = detector.Detect(image);
// Face Landmark Detection
var landmarker = FaceLandmarker.CreateFromOptions(options);
var landmarkResult = landmarker.Detect(image);
姿态关键点检测。
var landmarker = PoseLandmarker.CreateFromOptions(options);
var result = landmarker.Detect(image);
// 33 个姿态关键点
// PoseLandmark 类定义了所有关键点索引
更多 Task API: references/Tutorial-Task-API.md
图像输入源管理(Webcam、视频文件、静态图片)。
// 获取图像源
var imageSource = ImageSourceProvider.ImageSource;
// 配置图像源
imageSource.SourceType = ImageSourceType.WebCamera;
imageSource.WebCameraDeviceIndex = 0;
// 启动
yield return imageSource.Play();
// 获取当前帧
var texture = imageSource.GetCurrentTexture();
Unity 中 CalculatorGraph 的抽象基类,简化了图的生命周期管理。
public class MyGraphRunner : GraphRunner
{
protected override void ConfigureCalculatorGraph(CalculatorGraphConfig config)
{
// 配置图
calculatorGraph.Initialize(config);
}
public override void StartRun(ImageSource imageSource)
{
// 启动推理
}
protected override IList<WaitForResult> RequestDependentAssets()
{
// 加载模型和资源
return new List<WaitForResult> {
WaitForAsset("model.binarypb")
};
}
}
此 Skill 包含来自 homuler/MediaPipeUnityPlugin 的完整文档,位于 references/ 目录:
Assets/MediaPipeUnity/Samples/Scenes/)Assets/MediaPipeUnity/Tutorial/Hello World/HelloWorld.cs)HandLandmarkerRunner.cs 和 Hand Landmark Detection 场景FaceDetectorRunner.cs 和 Face Detection 场景PoseLandmarkerRunner.cs 和 Pose Landmark Detection 场景ObjectDetectorRunner.cs 和 Object Detection 场景| Platform | CPU | GPU | Notes |
|---|---|---|---|
| Linux (x86_64) | ✓ | ✓ | 推荐用于开发 |
| macOS (Intel) | ✓ | ✗ | GPU 不支持 |
| macOS (ARM64) | ✓ | ✗ | GPU 不支持 |
| Windows (x86_64) | ✓ | ✗ | GPU 实验性支持 |
| Android | ✓ | ✓ | 需要 OpenGL ES 3.0+ |
| iOS | ✓ | ✓ | 需要 Metal |
| WebGL | ✗ | ✗ | 不支持 |
注意: GPU 模式在 macOS 和 Windows 上不支持。Windows 上 GPU 推理为实验性功能。
由于 MediaPipe 使用原生库,某些错误可能导致 UnityEditor 崩溃(尤其是在 Windows 上)。
使用 GPU 推理时,不能使用 OpenGL Core API,否则会出现错误:
InternalException: INTERNAL: ; eglMakeCurrent() returned error 0x3000
解决方案: 在 PC Standalone 构建中切换到 Vulkan。
StreamingAssets/ 目录需要确保 APK 中包含 libstdc++_shared.so,否则会抛出 DllNotFoundException。
使用文本格式配置计算图:
input_stream: "input_video"
output_stream: "output_video"
node {
calculator: "PassThroughCalculator"
input_stream: "input_video"
output_stream: "output_video"
}
CoordinateSystem 类)示例场景位于项目中的 Assets/MediaPipeUnity/Samples/Scenes/:
Face Detection/Face Landmark Detection/Hand Landmark Detection/Pose Landmark Detection/Object Detection/Image Segmentation/Legacy/ (传统解决方案)using Mediapipe; // 核心 API
using Mediapipe.Tasks.Vision; // 视觉任务
using Mediapipe.Tasks.Vision.HandLandmarker; // 手部检测
using Mediapipe.Unity.Sample; // 示例代码
帮助脚本和自动化工具可放在此处。
模板、样板代码或示例 Unity 项目文件可放在此处。
此 Skill 基于 homuler/MediaPipeUnityPlugin 的官方文档和示例生成。