赞
踩
我们直接引用前人的智慧:MediaPipe介绍
而 MediaPipeUnityPlugin,则帮我们把MediaPipe(C++)移植到了C#,使其能被Unity调用
使用这个插件,你可以:
– 用 C# 编写 MediaPipe 代码
– 在Unity上运行 MediaPipe 的官方解决方案
– 在Unity上运行您的自定义 Calculator 和 CalculatorGraph
(根据输入/输出的类型,您可能需要编写 C++ 代码)
github地址:https://github.com/homuler/MediaPipeUnityPlugin
下载地址:https://github.com/homuler/MediaPipeUnityPlugin/releases
本文使用的版本:MediaPipeUnity.0.11.0
建议Unity版本:2021.3以上
当然,该插件已经提供了案例,此处目的是了解它的运作方式,以便你想要按自己的需求搭一个环境
Graph运行基类,封装了config的加载及初始化配置、MediaPipe数据流的输入输出,相当于MVC中的M
操作基类,负责图像处理程序的生命周期,管理并获取图像源,相当于MVC中的C
派生类 ImageSourceSolution<T> : Solution
-T : GraphRunner
-管理GraphRunner实例及一些组件
-实现具体的每帧更新逻辑
– 抽象接口:
– OnStartRun() 初始化
– AddTextureFrameToInputStream(TextureFrame textureFrame) 将图像传给输入流
– WaitForNextValue() 获取同步输出
应用层 xxxSolution : ImageSourceSolution<xxxGraph>
-声明回调,在 OnStartRun() 中绑定Graph的异步监听接口,获取异步输出,并处理
-在 AddTextureFrameToInputStream() 中将得到的图像传给自己的Graph实例
-在 WaitForNextValue() 中获取Graph的同步输出,并处理
引导程序,选择图像输入源、资源加载方式、CPU或GPU计算,由Solution在Start()中调用
TextureFrame 的对象池,ImageSourceSolution 会用到
将图像源输出到一个 RawImage,由 ImageSourceSolution 管理
插件文档:https://github.com/homuler/MediaPipeUnityPlugin/wiki/Getting-Started
MediaPipe的核心计算器
方式一:声明时直接传入文本
new CalculatorGraph("Config文本");
方式二:构建一个CalculatorGraphConfig然后传入
var graph = new CalculatorGraph();
var config = CalculatorGraphConfig.Parser.ParseFromTextFormat("Config文本");
graph.Initialize(config);
如下为一个简单的config:
var 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"" } "; var graph = new CalculatorGraph(configText);
插件中已预设多个config可以直接使用
graph.StartRun().AssertOk();
StartRun会返回一个 Status 表示结果
调用 Status.AssertOk() 检查结果,如果不正常则抛出异常
插件中大部分方法都会返回一个Status
如果我们的config中配置了副产物 SidePacket,则启动时还需要传一个进去
graph.StartRun(sidePacket).AssertOk();
在 MediaPipe 中,输入输出是数据包Packet的形式进行传输
Packet需要具体的派生,并指定数据的类型
var input = new StringPacket("Hello World!"); // 这是一个字符串Packet
graph.AddPacketToInputStream("输入流的名称", input).AssertOk();
(这部分也由GraphRunner帮我们完成,但需要xxxGraph提供一个外部输入接口)
其中 “输入流的名称” 在config中定义,即 “input_stream”,同理下面的 “输出流的名称” 为config中的 “output_stream”
var poller = graph.AddOutputStreamPoller<string>("输出流的名称").Value();
实际使用时建议先检查一下status
var statusOfPoller = graph.AddOutputStreamPoller<string>("输出流的名称");
if (statusOfPoller.Ok())
{
var poller = statusOfPoller.Value();
}
然后可以获取输出
var output = new StringPacket();
poller.Next(output); // 输出到这个Packet
Debug.Log(output.Get()); // 获取Packet里的数据
(这部分封装了一个OutputStream类帮我们完成)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。