mediapipe-rs

mediapipe-rs

MediaPipe任务的Rust库 为WasmEdge WASI-NN提供支持

mediapipe-rs是一个为WasmEdge WASI-NN设计的Rust库,实现MediaPipe任务。该库提供简单易用的API,支持多种视觉、音频和文本处理任务,包括对象检测、图像分类和手势识别等。它具有低开销和灵活性,支持TfLite模型,可在CPU、GPU和TPU上运行。mediapipe-rs为开发者提供了在WebAssembly环境中高效执行机器学习任务的解决方案。

MediaPipe-rsWasmEdge计算机视觉机器学习音频处理Github开源项目
<div align="center"> <h1><code>MediaPipe-rs</code></h1> <p> <a href="https://github.com/WasmEdge/mediapipe-rs/actions?query=workflow%3ACI"> <img src="https://yellow-cdn.veclightyear.com/835a84d5/9d82ad9a-e36a-4c35-b1f6-cb2d9f1c3366.svg" alt="CI状态" height="20"/> </a> <a href="https://crates.io/crates/mediapipe-rs"> <img src="https://yellow-cdn.veclightyear.com/835a84d5/409942db-260c-463a-9cca-3c0a762fb46b.svg" alt="crates.io状态" height="20"/> </a> <a href="https://docs.rs/mediapipe-rs"> <img src="https://img.shields.io/docsrs/mediapipe-rs" alt="doc.rs状态" height="20"/> </a> </p> </div>

用于WasmEdge WASI-NN的MediaPipe任务的Rust库

介绍

  • 易于使用:类似mediapipe-python的低代码API。
  • 低开销:处理过程中无不必要的数据复制、分配和释放。
  • 灵活:用户可以使用自定义媒体字节作为输入。
  • 对于TfLite模型,该库不仅支持从[MediaPipe Solutions]下载的所有模型,还支持带有基本信息的**TF Hub模型和自定义模型**。

状态

  • 物体检测
  • 图像分类
  • 图像分割
  • 交互式图像分割
  • 手势识别
  • 手部关键点检测
  • 图像嵌入
  • 人脸检测
  • 人脸关键点检测
  • 姿势关键点检测
  • 音频分类
  • 文本分类
  • 文本嵌入
  • 语言检测

任务API

每个任务有三种类型:XxxBuilderXxxXxxSession。(Xxx是任务名称)

  • XxxBuilder用于创建任务实例Xxx,有多个选项可设置。

    示例:使用ImageClassifierBuilder构建ImageClassifier任务。

    let classifier = ImageClassifierBuilder::new()
          .max_results(3) // 设置最大结果数
          .category_deny_list(vec!["denied label".into()]) // 设置拒绝列表
          .gpu() // 设置运行设备
          .build_from_file(model_path)?; // 创建图像分类器
    
  • Xxx是任务实例,包含任务信息和模型信息。

    示例:使用ImageClassifier创建新的ImageClassifierSession

    let classifier_session = classifier.new_session()?;
    
  • XxxSession是执行预处理、推理和后处理的运行会话,有缓冲区存储中间结果。

    示例:使用ImageClassifierSession运行图像分类任务并返回分类结果:

    let classification_result = classifier_session.classify(&image::open(img_path)?)?;
    

    注意:可重复使用会话以提高速度,如果代码只使用会话一次,可以使用任务的包装函数来简化。

    // let classifier_session = classifier.new_session()?;
    // let classification_result = classifier_session.classify(&image::open(img_path)?)?;
    // 上面两行代码等同于:
    let classification_result = classifier.classify(&image::open(img_path)?)?;
    

可用任务

  • 视觉:
    • 手势识别:GestureRecognizerBuilder -> GestureRecognizer -> GestureRecognizerSession
    • 手部检测:HandDetectorBuilder -> HandDetector -> HandDetectorSession
    • 图像分类:ImageClassifierBuilder -> ImageClassifier -> ImageClassifierSession
    • 图像嵌入:ImageEmbedderBuilder -> ImageEmbedder -> ImageEmbedderSession
    • 图像分割:ImageSegmenterBuilder -> ImageSegmenter -> ImageSegmenterSession
    • 物体检测:ObjectDetectorBuilder -> ObjectDetector -> ObjectDetectorSession
  • 音频:
    • 音频分类:AudioClassifierBuilder -> AudioClassifier -> AudioClassifierSession
  • 文本:
    • 文本分类:TextClassifierBuilder -> TextClassifier -> TextClassifierSession

示例

图像分类

use mediapipe_rs::tasks::vision::ImageClassifierBuilder; fn main() -> Result<(), Box<dyn std::error::Error>> { let (model_path, img_path) = parse_args()?; let classification_result = ImageClassifierBuilder::new() .max_results(3) // 设置最大结果数 .build_from_file(model_path)? // 创建图像分类器 .classify(&image::open(img_path)?)?; // 执行推理并生成结果 // 显示格式化的结果信息 println!("{}", classification_result); Ok(()) }

示例输入:(图像下载自 https://yellow-cdn.veclightyear.com/835a84d5/eda7dfa2-8039-406e-84ff-c1b833fff26b.jpg)

<img height="30%" src="https://yellow-cdn.veclightyear.com/835a84d5/eda7dfa2-8039-406e-84ff-c1b833fff26b.jpg" width="30%" alt="burger.jpg" />

控制台示例输出:

$ cargo run --release --example image_classification -- ./assets/models/image_classification/efficientnet_lite0_fp32.tflite ./assets/testdata/img/burger.jpg 已完成 release [优化] 目标在 0.01 秒内 运行 `/mediapipe-rs/./scripts/wasmedge-runner.sh target/wasm32-wasi/release/examples/image_classification.wasm ./assets/models/image_classification/efficientnet_lite0_fp32.tflite ./assets/testdata/img/burger.jpg` 分类结果: 分类 #0: 类别 #0: 类别名称: "芝士汉堡" 显示名称: 无 得分: 0.70625573 索引: 933

物体检测

use mediapipe_rs::postprocess::utils::draw_detection; use mediapipe_rs::tasks::vision::ObjectDetectorBuilder; fn main() -> Result<(), Box<dyn std::error::Error>> { let (model_path, img_path, output_path) = parse_args()?; let mut input_img = image::open(img_path)?; let detection_result = ObjectDetectorBuilder::new() .max_results(2) // 设置最大结果数 .build_from_file(model_path)? // 创建物体检测器 .detect(&input_img)?; // 进行推理并生成结果 // 显示格式化的结果信息 println!("{}", detection_result); if let Some(output_path) = output_path { // 在图像上绘制检测结果 draw_detection(&mut input_img, &detection_result); // 保存输出图像 input_img.save(output_path)?; } Ok(()) }

示例输入:(图片下载自 https://yellow-cdn.veclightyear.com/835a84d5/3c8fc365-b65d-4b4e-a71e-2c840b48416b.jpg)

<img alt="cat_and_dog.jpg" height="30%" src="https://yellow-cdn.veclightyear.com/835a84d5/3c8fc365-b65d-4b4e-a71e-2c840b48416b.jpg" width="30%"/>

控制台输出示例:

$ cargo run --release --example object_detection -- ./assets/models/object_detection/efficientdet_lite0_fp32.tflite ./assets/testdata/img/cat_and_dog.jpg 已完成 release [优化] 目标在 0.00 秒内 运行 `/mediapipe-rs/./scripts/wasmedge-runner.sh target/wasm32-wasi/release/examples/object_detection.wasm ./assets/models/object_detection/efficientdet_lite0_fp32.tflite ./assets/testdata/img/cat_and_dog.jpg` 检测结果: 检测 #0: 边界框: (左: 0.12283102, 上: 0.38476586, 右: 0.51069236, 下: 0.851197) 类别 #0: 类别名称: "猫" 显示名称: 无 得分: 0.8460574 索引: 16 检测 #1: 边界框: (左: 0.47926134, 上: 0.06873521, 右: 0.8711677, 下: 0.87927735) 类别 #0: 类别名称: "狗" 显示名称: 无 得分: 0.8375256 索引: 17

输出示例: <img height="30%" src="https://yellow-cdn.veclightyear.com/835a84d5/12f24475-02f5-4b61-9441-49e726ab4b4f.jpg" width="30%"/>

文本分类

fn main() -> Result<(), Box<dyn std::error::Error>> { let model_path = parse_args()?; let text_classifier = TextClassifierBuilder::new() .max_results(1) // 设置最大结果数 .build_from_file(model_path)?; // 创建文本分类器 let positive_str = "我非常喜欢编程!"; let negative_str = "我不喜欢下雨。"; // 分类并显示格式化的结果信息 let result = text_classifier.classify(&positive_str)?; println!("`{}` -- {}", positive_str, result); let result = text_classifier.classify(&negative_str)?; println!("`{}` -- {}", negative_str, result); Ok(()) }

控制台输出示例(使用 bert 模型):

$ cargo run --release --example text_classification -- ./assets/models/text_classification/bert_text_classifier.tflite 已完成 release [优化] 目标在 0.01 秒内 运行 `/mediapipe-rs/./scripts/wasmedge-runner.sh target/wasm32-wasi/release/examples/text_classification.wasm ./assets/models/text_classification/bert_text_classifier.tflite` `我非常喜欢编程!` -- 分类结果: 分类 #0: 类别 #0: 类别名称: "积极" 显示名称: 无 得分: 0.99990463 索引: 1 `我不喜欢下雨。` -- 分类结果: 分类 #0: 类别 #0: 类别名称: "消极" 显示名称: 无 得分: 0.99541473 索引: 0

手势识别

use mediapipe_rs::tasks::vision::GestureRecognizerBuilder; fn main() -> Result<(), Box<dyn std::error::Error>> { let (model_path, img_path) = parse_args()?; let gesture_recognition_results = GestureRecognizerBuilder::new() .num_hands(1) // 设置只识别一只手 .max_results(1) // 设置最大结果数 .build_from_file(model_path)? // 创建任务实例 .recognize(&image::open(img_path)?)?; // 进行推理并生成结果 for g in gesture_recognition_results { println!("{}", g.gestures.classifications[0].categories[0]); } Ok(()) }

示例输入:(图片下载自 https://yellow-cdn.veclightyear.com/835a84d5/f3e27d24-b3d5-452a-83a3-3474a4e6b18a.jpg)

<img alt="victory.jpg" height="30%" src="https://yellow-cdn.veclightyear.com/835a84d5/f3e27d24-b3d5-452a-83a3-3474a4e6b18a.jpg" width="30%"/>

控制台输出示例:

$ cargo run --release --example gesture_recognition -- ./assets/models/gesture_recognition/gesture_recognizer.task ./assets/testdata/img/gesture_recognition_google_samples/victory.jpg Finished release [optimized] target(s) in 0.02s Running `/mediapipe-rs/./scripts/wasmedge-runner.sh target/wasm32-wasi/release/examples/gesture_recognition.wasm ./assets/models/gesture_recognition/gesture_recognizer.task ./assets/testdata/img/gesture_recognition_google_samples/victory.jpg` 类别名称: "Victory" 显示名称: None 得分: 0.9322255 索引: 6

音频输入

任何实现了AudioData特征的音频媒体都可以作为音频任务的输入。 目前,该库内置了支持symphoniaffmpeg和原始音频数据作为输入的实现。

音频分类示例:

use mediapipe_rs::tasks::audio::AudioClassifierBuilder; #[cfg(feature = "ffmpeg")] use mediapipe_rs::preprocess::audio::FFMpegAudioData; #[cfg(not(feature = "ffmpeg"))] use mediapipe_rs::preprocess::audio::SymphoniaAudioData; #[cfg(not(feature = "ffmpeg"))] fn read_audio_using_symphonia(audio_path: String) -> SymphoniaAudioData { let file = std::fs::File::open(audio_path).unwrap(); let probed = symphonia::default::get_probe() .format( &Default::default(), symphonia::core::io::MediaSourceStream::new(Box::new(file), Default::default()), &Default::default(), &Default::default(), ) .unwrap(); let codec_params = &probed.format.default_track().unwrap().codec_params; let decoder = symphonia::default::get_codecs() .make(codec_params, &Default::default()) .unwrap(); SymphoniaAudioData::new(probed.format, decoder) } #[cfg(feature = "ffmpeg")] fn read_video_using_ffmpeg(audio_path: String) -> FFMpegAudioData { ffmpeg_next::init().unwrap(); FFMpegAudioData::new(ffmpeg_next::format::input(&audio_path.as_str()).unwrap()).unwrap() } fn main() -> Result<(), Box<dyn std::error::Error>> { let (model_path, audio_path) = parse_args()?; #[cfg(not(feature = "ffmpeg"))] let audio = read_audio_using_symphonia(audio_path); #[cfg(feature = "ffmpeg")] let audio = read_video_using_ffmpeg(audio_path); let classification_results = AudioClassifierBuilder::new() .max_results(3) // 设置最大结果数 .build_from_file(model_path)? // 创建任务实例 .classify(audio)?; // 进行推理并生成结果 // 显示格式化的结果消息 for c in classification_results { println!("{}", c); } Ok(()) }

使用会话加速

会话包括推理会话(如TfLite解释器)、输入和输出缓冲区等。 显式使用会话可以重用这些资源以加快速度。

示例:文本分类

原始方法:

use mediapipe_rs::tasks::text::TextClassifier; use mediapipe_rs::postprocess::ClassificationResult; use mediapipe_rs::Error; fn inference( text_classifier: &TextClassifier, inputs: &Vec<String> ) -> Result<Vec<ClassificationResult>, Error> { let mut res = Vec::with_capacity(inputs.len()); for input in inputs { // text_classifier 每次都会创建新的会话 res.push(text_classifier.classify(input.as_str())?); } Ok(res) }

使用会话加速:

use mediapipe_rs::tasks::text::TextClassifier; use mediapipe_rs::postprocess::ClassificationResult; use mediapipe_rs::Error; fn inference( text_classifier: &TextClassifier, inputs: &Vec<String> ) -> Result<Vec<ClassificationResult>, Error> { let mut res = Vec::with_capacity(inputs.len()); // 只创建一个会话并重用会话中的资源 let mut session = text_classifier.new_session()?; for input in inputs { res.push(session.classify(input.as_str())?); } Ok(res) }

使用FFMPEG功能处理视频和音频

使用cargo构建带有ffmpeg功能的库时,用户必须设置以下环境变量:

示例:

export FFMPEG_DIR=/path/to/ffmpeg/library export WASI_SDK=/opt/wasi-sdk export BINDGEN_EXTRA_CLANG_ARGS="--sysroot=/opt/wasi-sdk/share/wasi-sysroot --target=wasm32-wasi -fvisibility=default" # 然后运行cargo

GPU和TPU支持

默认设备是CPU,用户可以使用API选择要使用的设备:

use mediapipe_rs::tasks::vision::ObjectDetectorBuilder; fn create_gpu(model_blob: Vec<u8>) { let detector_gpu = ObjectDetectorBuilder::new() .gpu() .build_from_buffer(model_blob) .unwrap(); } fn create_tpu(model_blob: Vec<u8>) { let detector_tpu = ObjectDetectorBuilder::new() .tpu() .build_from_buffer(model_blob) .unwrap(); }

注意

本项目由Google在Mediapipe上的工作使之成为可能。

相关链接

许可证

本项目采用Apache 2.0许可证。更多详情请参阅LICENSE

编辑推荐精选

讯飞智文

讯飞智文

一键生成PPT和Word,让学习生活更轻松

讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。

AI办公办公工具AI工具讯飞智文AI在线生成PPTAI撰写助手多语种文档生成AI自动配图热门
讯飞星火

讯飞星火

深度推理能力全新升级,全面对标OpenAI o1

科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。

热门AI开发模型训练AI工具讯飞星火大模型智能问答内容创作多语种支持智慧生活
Spark-TTS

Spark-TTS

一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型

Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。

Trae

Trae

字节跳动发布的AI编程神器IDE

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

AI工具TraeAI IDE协作生产力转型热门
咔片PPT

咔片PPT

AI助力,做PPT更简单!

咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。

讯飞绘文

讯飞绘文

选题、配图、成文,一站式创作,让内容运营更高效

讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。

热门AI辅助写作AI工具讯飞绘文内容运营AI创作个性化文章多平台分发AI助手
材料星

材料星

专业的AI公文写作平台,公文写作神器

AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。

openai-agents-python

openai-agents-python

OpenAI Agents SDK,助力开发者便捷使用 OpenAI 相关功能。

openai-agents-python 是 OpenAI 推出的一款强大 Python SDK,它为开发者提供了与 OpenAI 模型交互的高效工具,支持工具调用、结果处理、追踪等功能,涵盖多种应用场景,如研究助手、财务研究等,能显著提升开发效率,让开发者更轻松地利用 OpenAI 的技术优势。

Hunyuan3D-2

Hunyuan3D-2

高分辨率纹理 3D 资产生成

Hunyuan3D-2 是腾讯开发的用于 3D 资产生成的强大工具,支持从文本描述、单张图片或多视角图片生成 3D 模型,具备快速形状生成能力,可生成带纹理的高质量 3D 模型,适用于多个领域,为 3D 创作提供了高效解决方案。

3FS

3FS

一个具备存储、管理和客户端操作等多种功能的分布式文件系统相关项目。

3FS 是一个功能强大的分布式文件系统项目,涵盖了存储引擎、元数据管理、客户端工具等多个模块。它支持多种文件操作,如创建文件和目录、设置布局等,同时具备高效的事件循环、节点选择和协程池管理等特性。适用于需要大规模数据存储和管理的场景,能够提高系统的性能和可靠性,是分布式存储领域的优质解决方案。

下拉加载更多