文章目录
前言
MediaPipe 为直播和流媒体提供开源跨平台、可定制的 ML(机器学习) 解决方案。
本文是接我上两篇文章:
1、Ubuntu上安装MediaPipe
2、Ubuntu上构建Android的MediaPipe
一、MediaPipe Android Archive (AAR) 是什么?
官方的解释:
The MediaPipe Android Archive (AAR) library is a convenient way to use MediaPipe with Android Studio and Gradle. MediaPipe doesn’t publish a general AAR that can be used by all projects. Instead, developers need to add a mediapipe_aar() target to generate a custom AAR file for their own projects. This is necessary in order to include specific resources such as MediaPipe calculators needed for each project.
大体意思就是:
MediaPipe Android Archive (AAR) 库是一种将 MediaPipe 与 Android Studio 和 Gradle 结合使用的便捷方式。
MediaPipe 没有发布可供所有项目使用的通用 AAR。开发人员需要添加一个 mediapipe_aar() 目标来为他们自己的项目生成一个自定义 AAR 文件。这是必要的,以便包含每个项目所需的特定资源。
二、构建 MediaPipe AAR 的步骤
1.创建一个 mediapipe_aar() 目标
在 MediaPipe 目录中,在 BUILD 文件中创建一个新的 mediapipe_aar() 目标。您需要弄清楚图中使用了哪些计算器,并将计算器依赖项提供给 mediapipe_aar()。
官方的描述还是挺官方,我们以人脸检测为例子,演示这个过程。
步骤:
$ cd mediapipe
$ cd mediapipe/examples/android/src/java/com/google/mediapipe/apps/
$ mkdir aar_example
$ cd aar_example
$ touch BUILD
然后使用你擅长的手段,将如下内容写入BUILD文件:
# 这是固定的,加载mediapipe_aar.bzl脚本文件,这个脚本你可以在MediaPipe的如下目录找到
load("//mediapipe/java/com/google/mediapipe:mediapipe_aar.bzl", "mediapipe_aar")
# name:你编译的aar的名称
# calculators:这个配置你可以在如下目录mediapipe/graphs/根据你要编辑的aar去寻找需要的calculators
mediapipe_aar(
name = "mediapipe_face_detection",
calculators = ["//mediapipe/graphs/face_detection:mobile_calculators"],
)
以face_detection的calculators为例,解释mediapipe_aar为何如此配置:
cd mediapipe/graphs/
cd face_detectionge
gedit BUILD
从BUILD中找到我们需要的计算器,因为我们是Android的aar,因此就找到移动端的计算器
2.运行 Bazel 构建命令以生成 AAR
2.1 命令如下,构建solution_core.aar:
solution_core的aar配置文件Google已经帮我们实现好了,不用我们自己配置。
在当前文件中配置:mediapipe/java/com/google/mediapipe/solutioncore/BUILD
bazel build -c opt --strip=ALWAYS \
--host_crosstool_top=@bazel_tools//tools/cpp:toolchain \
--fat_apk_cpu=arm64-v8a,armeabi-v7a \
--legacy_whole_archive=0 \
--features=-legacy_whole_archive \
--copt=-fvisibility=hidden \
--copt=-ffunction-sections \
--copt=-fdata-sections \
--copt=-fstack-protector \
--copt=-Oz \
--copt=-fomit-frame-pointer \
--copt=-DABSL_MIN_LOG_LEVEL=2 \
--linkopt=-Wl,--gc-sections,--strip-all \
--verbose_failures \
//mediapipe/java/com/google/mediapipe/solutioncore:solution_core.aar
2.2 命令如下,构建mediapipe_face_detection.aar:
$ bazel build -c opt --strip=ALWAYS \
--host_crosstool_top=@bazel_tools//tools/cpp:toolchain \
--fat_apk_cpu=arm64-v8a,armeabi-v7a \
--legacy_whole_archive=0 \
--features=-legacy_whole_archive \
--copt=-fvisibility=hidden \
--copt=-ffunction-sections \
--copt=-fdata-sections \
--copt=-fstack-protector \
--copt=-Oz \
--copt=-fomit-frame-pointer \
--copt=-DABSL_MIN_LOG_LEVEL=2 \
--linkopt=-Wl,--gc-sections,--strip-all \
--verbose_failures \
//mediapipe/examples/android/src/java/com/google/mediapipe/apps/aar_example:mediapipe_face_detection.aar
解释下最后一句命令:
# 第一步配置的aar的BUILD文件所在目录:第一步配置的BUILD文件中aar的名称
# BUILD目录:BUILD中配置的aar名称.aar
//mediapipe/examples/android/src/java/com/google/mediapipe/apps/aar_example:mediapipe_face_detection.aar
构建过程出现的错误
1、我在构建过程中运行上述构建命令出现了一个脚本问题,希望你们不会碰到
ERROR: /home/silicon/code/mediapipe/mediapipe/mediapipe/examples/android/src/java/com/google/mediapipe/apps/aar_example/BUILD:3:14: Executing genrule //mediapipe/examples/android/src/java/com/google/mediapipe/apps/aar_example:mediapipe_face_detection_binary_manifest_generator failed: (Exit 127): bash failed: error executing command
(cd /home/silicon/.cache/bazel/_bazel_silicon/dc627073c9c97a85c1d325052ea10bb0/sandbox/linux-sandbox/2173/execroot/mediapipe && \
exec env - \
PATH=/home/silicon/.cache/bazelisk/downloads/bazelbuild/bazel-5.0.0-linux-x86_64/bin:/home/silicon/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin \
/bin/bash -c 'source external/bazel_tools/tools/genrule/genrule-setup.sh;
cat > bazel-out/k8-opt/bin/mediapipe/examples/android/src/java/com/google/mediapipe/apps/aar_example/mediapipe_face_detection_generated_AndroidManifest.xml <<EOF
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="dummy.package.for.so">
<uses-sdk android:minSdkVersion="21"/>
</manifest>
EOF
')
# Configuration: 42b5acd92d1adc889d3cf875a6930269a8b5b2c1cf2b927a64f9fccc558a0369
# Execution platform: @local_execution_config_platform//:platform
Use --sandbox_debug to see verbose messages from the sandbox
/bin/bash: $'\r': command not found
Target //mediapipe/examples/android/src/java/com/google/mediapipe/apps/aar_example:mediapipe_face_detection.aar failed to build
INFO: Elapsed time: 17.616s, Critical Path: 17.08s
INFO: 196 processes: 129 internal, 67 linux-sandbox.
FAILED: Build did NOT complete successfully
我们关注如下图中圈出的错误:
- 绿色框中的错误输出是aar构建脚本(
mediapipe_aar.bzl
)中的输出 - 红色框圈出是告诉我们此时
换行符多了\r
,由于windows系统下换行符为 \r\n,linux下换行符为 \n,所以导致在windows下编写的文件会比linux下多回车符号 \r。
因此我们猜测错误是mediapipe_aar.bzl
脚本的问题,脚本中的换行符有问题,执行如下命令解决了问题:
$ cd mediapipe
$ cd mediapipe/java/com/google/mediapipe/
$ sed -i 's/\r$//' mediapipe_aar.bzl
构建成功:
执行到最后看到如图结果就已经成功了,aar包存放在红框圈出来的目录中:
bazel-bin/mediapipe/examples/android/src/java/com/google/mediapipe/apps/aar_example/mediapipe_face_detection.aar
3.将AAR导入Android studio项目中
1、将aar导入app/libs中,如果没有libs文件夹就新建一个
2、制作 app/src/main/assets 并将资产(图形、模型等)复制到 app/src/main/assets 中。
- 执行如下命令:
# 执行如下命令构建face_detection_mobile_gpu.binarypb
bazel build -c opt mediapipe/graphs/face_detection:face_detection_mobile_gpu_binary_graph
编译成功输出文件路径:bazel-bin/mediapipe/graphs/face_detection/face_detection_mobile_gpu.binarypb
2.将如下两个文件拷贝到项目中的assets文件夹中,没有assets就自己创建一个
文件路径:
$ cd mediapipe
# 找到文件face_detection_mobile_gpu.binarypb
$ cd bazel-bin/mediapipe/graphs/face_detection/
# 找到文件face_detection_short_range.tflite
$ cd mediapipe/modules/face_detection/
然后将上述文件导入Android studio:
3、修改 app/build.gradle 以添加 MediaPipe 依赖项和 MediaPipe AAR
// 引入libs中的jar、aar包
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
// MediaPipe deps
implementation 'com.google.flogger:flogger:latest.release'
implementation 'com.google.flogger:flogger-system-backend:latest.release'
implementation 'com.google.code.findbugs:jsr305:latest.release'
implementation 'com.google.guava:guava:27.0.1-android'
implementation 'com.google.protobuf:protobuf-javalite:3.19.1'
// CameraX core library
def camerax_version = "1.0.0-beta10"
implementation "androidx.camera:camera-core:$camerax_version"
implementation "androidx.camera:camera-camera2:$camerax_version"
implementation "androidx.camera:camera-lifecycle:$camerax_version"
// AutoValue
def auto_value_version = "1.8.1"
implementation "com.google.auto.value:auto-value-annotations:$auto_value_version"
annotationProcessor "com.google.auto.value:auto-value:$auto_value_version"
到此为止aar包已经编译完成,MediaPipe Hands或者Face Mesh等等都是如此,使用上上述方式编译即可。
代码用法参考MediaPipe的官网
总结
如果我们需要查看例子,直接将MediaPipe的代码克隆到本地。
git clone git@github.com:google/mediapipe.git
或者
git clone https://github.com/google/mediapipe.git
$ cd mediapipe
$ cd mediapipe/examples/android/solutions
将solutions这个项目导入你的Android studio,其中就包含MediaPipe的Hands,face detection,face mesh的例子。
这例子中引入了Google上传到Maven的Hands、face detection、face mesh的aar,如果我们不需要自己做修改,我挺建议直接用Google打包好的aar。
如果是Windows上操作,在运行solutions
这个项目之前,记得使用管理员权限打开命令行 ,然后执行
create_win_symlinks.bat脚本。
参考
1、MediaPipe官方构建MediaPipe Android Archive步骤
2、MediaPipe各个aar库的使用方式