版本: 1.1 | 日期: 2026-04-08 | 平台: Android (minSdk 26)-理论最低是API24/Andorid 7.0

本文档基于 FacePPTest 项目的实际集成经验编写,覆盖从依赖配置到各模型的使用方式、预处理细节、精度调优和资源开销,可直接复用到其他 Android 项目。


一、架构总览

┌─────────────────────────────────────────────────────┐
│                   Application Layer                  │
│  BeautyScoreActivity / FaceCompareActivity / ...     │
├─────────────────────────────────────────────────────┤
│                   LiteRTManager (Facade)             │
│  init() / release() / detectFaces() / compareFaces() │
├──────────┬──────────────────────────────────────────┤
│ MediaPipe Tasks Vision          │  LiteRT Interpreter │
│ ┌──────────────────────┐        │  ┌────────────────┐ │
│ │ FaceDetector         │        │  │ FaceNet-512    │ │
│ │ FaceLandmarker       │        │  │ (TFLite model) │ │
│ │ ObjectDetector       │        │  └────────────────┘ │
│ │ ImageClassifier      │        │                     │
│ └──────────────────────┘        │                     │
├──────────┴──────────────────────┴─────────────────────┤
│              Android Assets (模型文件)                 │
│  blaze_face_short_range.tflite | face_landmarker.task │
│  efficientdet_lite0.tflite | efficientnet_lite0.tflite│
│  facenet_512.tflite                                   │
└─────────────────────────────────────────────────────┘

核心原则:完全离线,不依赖 Google Play Services、云 API 或任何第三方服务。


二、依赖配置

build.gradle.kts

dependencies {
    // MediaPipe Tasks Vision — 人脸检测/特征点/物体检测/图像分类
    // 内含 FaceDetector, FaceLandmarker, ObjectDetector, ImageClassifier    implementation("com.google.mediapipe:tasks-vision:0.10.33")
    // LiteRT 1.x Interpreter — 运行自定义 TFLite 模型(如 FaceNet)
    implementation("com.google.ai.edge.litert:litert-api:1.0.1")    implementation("com.google.ai.edge.litert:litert:1.0.1")
    // GPU 加速(可选)
    implementation("com.google.ai.edge.litert:litert-gpu:1.0.1")    implementation("com.google.ai.edge.litert:litert-gpu-api:1.0.1")}

关键说明

依赖用途说明
mediapipe:tasks-visionMediaPipe 所有视觉任务包含 FaceDetector, FaceLandmarker, ObjectDetector, ImageClassifier 等 Task API
litert-apiTFLite Interpreter API提供 org.tensorflow.lite.Interpreter
litertTFLite 运行时包含原生 .so 库(libtensorflowlite_jni.so)
litert-gpuGPU Delegate 原生库包含 libtensorflowlite_gpu_jni.so
litert-gpu-apiGPU Delegate API提供 GpuDelegateCompatibilityList

版本兼容注意

  • 不要同时使用 litert:2.xmediapipe:tasks-vision,两者的原生库可能冲突。
  • 不要添加 litert-support,它与 litert-support-api(MediaPipe 的传递依赖)存在 namespace 冲突。
  • GPU 加速需额外添加 litert-gpu:1.0.1 + litert-gpu-api:1.0.1
  • MediaPipe tasks-vision:0.10.33 不需要 Google Play Services。

三、模型清单与资源大小

所有模型存放在 app/src/main/assets/ 目录,打包进 APK。

模型文件大小来源输入输出用途
blaze_face_short_range.tflite224 KBMediaPipeBitmap (any size)Bounding Box + 置信度人脸检测
face_landmarker.task3.6 MBMediaPipeBitmap (any size)478 landmarks + 52 blendshapes特征点 + 表情分析
efficientdet_lite0.tflite4.4 MBMediaPipe320×320COCO 80 类 + Box物体检测
efficientnet_lite0.tflite18 MBMediaPipe224×224ImageNet 1000 类图像分类
facenet_512.tflite45 MBdeepface160×160 RGB512-D float vector人脸嵌入

Assets 合计: ~71 MB

缩小体积方案

当前模型替代方案新大小精度影响
facenet_512.tflite (45MB)facenet.tflite (128维)~11MB精度略低
efficientnet_lite0.tflite (18MB, float32)int8 量化版~5MB精度基本不变
efficientdet_lite0.tflite (4.4MB, int8)已是 int8--

四、各功能模块详解

4.1 人脸检测 — MediaPipe FaceDetector

Helper 类: MediaPipeFaceHelper.kt

功能: 在图片中定位所有人脸的 Bounding Box 和置信度。

初始化:

val baseOptions = BaseOptions.builder()
    .setModelAssetPath("blaze_face_short_range.tflite")    .build()val options = FaceDetector.FaceDetectorOptions.builder()
    .setBaseOptions(baseOptions)    .setRunningMode(RunningMode.IMAGE)    .setMinDetectionConfidence(0.5f)    .build()val detector = FaceDetector.createFromOptions(context, options)

使用:

val mpImage = BitmapImageBuilder(bitmap).build()
val result = detector.detect(mpImage)
for (det in result.detections()) {
    val box = det.boundingBox()          // android.graphics.Rect    val score = det.categories()[0].score() // Float 0~1}

输出: List<FaceRect(rect: RectF, confidence: Float)>

性能: CPU ~5-15ms (Pixel 级设备)


4.2 人脸特征点 + 表情 (Blendshapes) — MediaPipe FaceLandmarker

Helper 类: FaceLandmarkerHelper.kt

功能: 478 个 3D 面部特征点 + 52 种 Blendshape 系数(可用于情感推断)。

初始化:

val options = FaceLandmarker.FaceLandmarkerOptions.builder()
    .setBaseOptions(BaseOptions.builder()        .setModelAssetPath("face_landmarker.task").build())    .setRunningMode(RunningMode.IMAGE)    .setNumFaces(1)    .setMinFaceDetectionConfidence(0.5f)    .setOutputFaceBlendshapes(true)       // 关键:开启 Blendshapes    .setOutputFacialTransformationMatrixes(false)    .build()val landmarker = FaceLandmarker.createFromOptions(context, options)

52 种 Blendshapes 关键系数:

系数名含义情感用途
mouthSmileLeft/Right嘴角上扬开心
mouthFrownLeft/Right嘴角下垂悲伤
jawOpen张嘴程度惊讶
browDownLeft/Right眉头下压生气
browInnerUp眉头上挑悲伤/忧虑
eyeWideLeft/Right眼睛睁大惊讶/恐惧
eyeSquintLeft/Right眯眼生气/笑
eyeBlinkLeft/Right眨眼活体检测
mouthPucker嘟嘴
cheekPuff鼓腮

情感推断逻辑(规则引擎):

开心: mouthSmileAvg > 0.3
惊讶: jawOpen > 0.5 && eyeWideAvg > 0.3
生气: browDownAvg > 0.3 && eyeSquintAvg > 0.3
悲伤: mouthFrownAvg > 0.3 && browInnerUp > 0.3
恐惧: browOuterUpAvg > 0.3 && eyeWideAvg > 0.2
中性: 以上均不满足

性能: CPU ~30-70ms


4.3 人脸嵌入 (Face Embedding) — LiteRT + FaceNet-512

Helper 类: FaceEmbeddingHelper.kt

功能: 将裁切的人脸图像转换为 512 维向量,用于人脸比对和搜索。

流水线:

原图 → MediaPipe 检测人脸框 → 裁切(+15% margin) → 缩放到 160×160 → FaceNet → 512-D L2归一化向量

预处理(极其关键):

// deepface 导出的 FaceNet-512 使用 pixel / 255.0 归一化
for (px in pixels) {
    buf.putFloat((px shr 16 and 0xFF) / 255f)  // R    buf.putFloat((px shr 8 and 0xFF) / 255f)   // G    buf.putFloat((px and 0xFF) / 255f)          // B}

警告: 不同来源的 FaceNet 模型预处理不同!

  • deepface 导出版: pixel / 255.0 → [0, 1]
  • 原版 Google FaceNet: per-image standardization (pixel - mean) / std
  • 错误的预处理会导致精度大幅下降!

模型加载:

val fd = context.assets.openFd("facenet_512.tflite")
val model = FileInputStream(fd.fileDescriptor).channel.map(
    FileChannel.MapMode.READ_ONLY, fd.startOffset, fd.declaredLength)
val options = Interpreter.Options().apply {
    setNumThreads(4)    setUseXNNPACK(true)   // 启用 XNNPACK 加速
}
val interpreter = Interpreter(model, options)

比对逻辑:

val sim = cosineSimilarity(embedding1, embedding2)  // [-1, 1]
// 置信度映射:
//   cosine ≤ 0.0 → 0 分
//   cosine = 0.72 → 90 分 (同一人阈值)
//   cosine ≥ 0.9 → 100 分

阈值建议:

场景推荐 cosine 阈值置信度
高安全(支付)≥ 0.8≥ 95
标准匹配≥ 0.72≥ 90
宽松匹配(搜索)≥ 0.5≥ 63

性能: CPU ~150-300ms (Pixel 级), ~80-150ms (with XNNPACK)


4.4 物体检测 — MediaPipe ObjectDetector (EfficientDet-Lite0)

Helper 类: ObjectDetectorHelper.kt

功能: 识别图片中的物体(COCO 80 类),返回标签 + 置信度 + Bounding Box。

初始化:

val options = ObjectDetector.ObjectDetectorOptions.builder()
    .setBaseOptions(BaseOptions.builder()        .setModelAssetPath("efficientdet_lite0.tflite").build())    .setRunningMode(RunningMode.IMAGE)    .setScoreThreshold(0.3f)    .setMaxResults(10)    .build()val detector = ObjectDetector.createFromOptions(context, options)

COCO 80 类常见标签: person, bicycle, car, motorcycle, bus, cat, dog, chair, laptop, cell phone, book, cup, bottle, clock, tie, handbag, backpack, umbrella, scissors, …

性能: CPU ~30ms (int8 量化版)


4.5 图像分类 — MediaPipe ImageClassifier (EfficientNet-Lite0)

Helper 类: ImageClassifierHelper.kt

功能: 返回图片的 ImageNet 1000 类分类标签和概率。

初始化:

val options = ImageClassifier.ImageClassifierOptions.builder()
    .setBaseOptions(BaseOptions.builder()        .setModelAssetPath("efficientnet_lite0.tflite").build())    .setRunningMode(RunningMode.IMAGE)    .setMaxResults(10)    .setScoreThreshold(0.05f)    .build()val classifier = ImageClassifier.createFromOptions(context, options)

典型输出示例(人脸照片):

1. suit (23.5%)
2. bow tie (8.2%)
3. Windsor tie (5.1%)
4. sunglasses (3.8%)

性能: CPU ~24ms (float32), ~10ms (int8)


4.6 图像质量评估 — 纯算法

Helper 类: ImageQualityHelper.kt

功能: 评估图像亮度和清晰度,不依赖任何模型。

亮度计算:

luminance = 0.299 * R + 0.587 * G + 0.114 * B  // ITU-R BT.601 标准
brightness = mean(luminance_all_pixels)
亮度值等级
< 50过暗
50-80偏暗
80-180正常
180-220偏亮
> 220过亮

清晰度计算 (Laplacian 方差):

Laplacian 核: [0,1,0; 1,-4,1; 0,1,0]
sharpness = variance(laplacian_output)
清晰度值等级
< 20模糊
20-80略模糊
80-300清晰
> 300非常清晰

性能: < 10ms


五、Facade 模式 — LiteRTManager

object LiteRTManager {
    fun init(context: Context, useGpu: Boolean = false) // 初始化 FaceDetector + FaceNet    fun release()                                       // 释放资源
    fun detectFaces(bitmap): List<FaceRect>    fun hasFace(bitmap): Boolean    fun extractEmbedding(bitmap, faceRect): FloatArray    fun extractFirstFaceEmbedding(bitmap): FloatArray?    fun compareFaces(bitmap1, bitmap2): CompareResult    val useGpu: Boolean                                 // 当前是否启用 GPU}

使用方式:

// Activity.onCreate — CPU 模式
LiteRTManager.init(this)
 
// Activity.onCreate — GPU 加速模式
LiteRTManager.init(this, useGpu = true)
 
// 比对
val result = LiteRTManager.compareFaces(bitmap1, bitmap2)
if (result.isSamePerson) { /* cosine >= 0.72 */ }
 
// Activity.onDestroy
LiteRTManager.release()

六、本地向量存储 — EmbeddingDbHelper

Helper 类: EmbeddingDbHelper.kt

使用轻量 SQLite 存储人脸嵌入(无 Room、无 Google 依赖)。

val db = EmbeddingDbHelper(context)
db.insertFace("张三", embedding)           // 保存
val faces = db.getAllFaces()               // 查询所有
db.deleteById(id)                          // 删除
db.deleteAll()                             // 清空
 
// 向量序列化: FloatArray ↔ ByteArray (Little-Endian)

七、复用到新项目的步骤

Step 1: 添加依赖

implementation("com.google.mediapipe:tasks-vision:0.10.33")
implementation("com.google.ai.edge.litert:litert-api:1.0.1")
implementation("com.google.ai.edge.litert:litert:1.0.1")
 
// 如需 GPU 加速(推荐)
implementation("com.google.ai.edge.litert:litert-gpu:1.0.1")
implementation("com.google.ai.edge.litert:litert-gpu-api:1.0.1")

Step 2: 下载模型到 app/src/main/assets/

按需选择(见第三节模型清单)。

Step 3: 复制 Helper 类

com.example.facepptest.ml 包中按需复制:

  • MediaPipeFaceHelper.kt — 人脸检测
  • FaceLandmarkerHelper.kt — 特征点 + 表情
  • FaceEmbeddingHelper.kt — 人脸嵌入(需 LiteRT)
  • ObjectDetectorHelper.kt — 物体检测
  • ImageClassifierHelper.kt — 图像分类
  • ImageQualityHelper.kt — 图像质量(纯算法,无依赖)
  • EmbeddingDbHelper.kt — 向量存储

Step 4: 初始化

// MediaPipe 的 Helper 需要在后台线程初始化(首次加载模型较慢)
Thread {
    LiteRTManager.init(applicationContext)}.start()

八、GPU 加速

8.1 概述

所有 MediaPipe Tasks 和 LiteRT Interpreter 均支持 GPU 加速。GPU delegate 利用 OpenGL ES 3.1 / OpenCL 在移动设备 GPU 上执行推理,可显著降低延迟。

8.2 MediaPipe Tasks GPU 配置

MediaPipe 通过 BaseOptions.setDelegate(Delegate.GPU) 启用 GPU:

val baseOptions = BaseOptions.builder()
    .setModelAssetPath("blaze_face_short_range.tflite")    .setDelegate(Delegate.GPU)   // 切换为 GPU    .build()
val options = FaceDetector.FaceDetectorOptions.builder()
    .setBaseOptions(baseOptions)    .setRunningMode(RunningMode.IMAGE)    .build()val detector = FaceDetector.createFromOptions(context, options)

适用于:FaceDetectorFaceLandmarkerObjectDetectorImageClassifier

8.3 LiteRT Interpreter GPU 配置

LiteRT 通过 GpuDelegate 启用 GPU,需先检查设备兼容性:

import org.tensorflow.lite.gpu.CompatibilityListimport org.tensorflow.lite.gpu.GpuDelegate
val compatList = CompatibilityList()val options = Interpreter.Options().apply {
    if (compatList.isDelegateSupportedOnThisDevice) {
        val delegateOptions = compatList.bestOptionsForThisDevice
        addDelegate(GpuDelegate(delegateOptions))
    } else {        setNumThreads(4)        setUseXNNPACK(true)   // GPU 不可用时回退到 CPU + XNNPACK    }}
val interpreter = Interpreter(modelFile, options)

8.4 注意事项

  1. GPU delegate 必须在创建它的线程上使用,不可跨线程传递。
  2. 不是所有 TFLite ops 都支持 GPU,不支持的 op 会自动回退到 CPU(可能导致 CPU-GPU 同步开销)。
  3. int8 量化模型的 GPU 兼容性因设备而异efficientdet_lite0.tflite(int8)在部分设备上 GPU 推理可能失败,此时自动回退 CPU。
  4. 首次 GPU 推理较慢(需编译 shader),第二次起才能体现加速效果。benchmark 应排除首次 warmup。
  5. 内存:GPU delegate 会额外占用显存,在低端设备上注意 OOM。

8.5 GPU vs CPU 实测 Benchmark

测试设备:Android 手机 | 图片:含单张人脸的照片
时间:2026-04-08

========== GPU vs CPU Benchmark ==========
Module                            CPU      GPU  Speedup
------------------------------------------------------------
人脸检测 (BlazeFace)                 27ms     18ms    1.50x特征点+情感 (FaceLandmarker)          30ms     22ms    1.36x人脸嵌入 (FaceNet-512)               63ms     45ms    1.40x物体检测 (EfficientDet)              33ms      N/A        -图像分类 (EfficientNet)              22ms      7ms    3.14x------------------------------------------------------------
TOTAL (comparable)              175ms     92ms    1.90x
Total analysis time: 353ms
Image quality: 75ms (algorithm only, no GPU)
==========================================

分析

模块CPU 耗时GPU 耗时加速比备注
人脸检测 (BlazeFace)27ms18ms1.50x模型极小(224KB),GPU 优势有限
特征点+情感 (FaceLandmarker)30ms22ms1.36x模型 3.6MB,GPU 加速稳定
人脸嵌入 (FaceNet-512)63ms45ms1.40x45MB 大模型,LiteRT GpuDelegate
物体检测 (EfficientDet)33msN/A-int8 量化模型,设备 GPU 不兼容
图像分类 (EfficientNet)22ms7ms3.14xfloat32 模型,GPU 加速最显著
可对比项合计175ms92ms1.90x整体提速约 47%

关键结论

  1. float32 模型受益最大:EfficientNet-Lite0(float32)GPU 加速达 3.14x。
  2. int8 量化模型兼容性差:EfficientDet-Lite0(int8)GPU 推理失败,回退到 CPU。如需 GPU 加速物体检测,应使用 float16 或 float32 版本。
  3. 小模型加速有限:BlazeFace(224KB)在 CPU 上已很快(27ms),GPU 的初始化和数据传输开销减少了加速效果。
  4. 综合推荐:对延迟敏感的场景建议开启 GPU(整体约 1.9x);对稳定性优先的场景可仅用 CPU + XNNPACK。

九、已知问题与注意事项

  1. ABI 兼容性: LiteRT 1.0.1 的 .so 支持 armeabi-v7aarm64-v8a。在 x86 模拟器上可能报 UnsatisfiedLinkError
  2. 首次推理延迟: 模型首次加载需要时间(FaceNet ~500ms),建议 App 启动时预热。
  3. 内存占用: FaceNet-512 模型较大(45MB),在低内存设备上注意 OOM。可考虑 128 维版本。
  4. 线程安全: MediaPipe Task 对象不是线程安全的。如需多线程,每个线程创建独立实例。GPU delegate 同样有线程亲和性限制。
  5. Bitmap 格式: MediaPipe 要求 ARGB_8888 格式的 Bitmap。BitmapFactory 默认就是此格式。
  6. 预处理一致性: FaceNet 模型的预处理方式必须与训练时一致(见 4.3 节警告)。
  7. GPU 兼容性: int8 量化模型在部分设备 GPU 上不支持(如 EfficientDet-Lite0),会自动回退 CPU。

十、性能基准

CPU 模式

功能模型延迟
人脸检测BlazeFace short-range27ms
特征点+BlendshapesFaceLandmarker30ms
人脸嵌入FaceNet-512 (XNNPACK)63ms
物体检测EfficientDet-Lite0 int833ms
图像分类EfficientNet-Lite0 float3222ms
图像质量Laplacian (纯算法)75ms
综合分析(全部)~353ms

GPU 加速模式

功能CPU 耗时GPU 耗时加速比
人脸检测27ms18ms1.50x
特征点+Blendshapes30ms22ms1.36x
人脸嵌入63ms45ms1.40x
物体检测33msN/A (int8不兼容)-
图像分类22ms7ms3.14x
可对比项合计175ms92ms1.90x

详细分析见第八章 GPU 加速。


十一、模型下载 URL 汇总

# 人脸检测 (BlazeFace)curl -O https://storage.googleapis.com/mediapipe-models/face_detector/blaze_face_short_range/float16/latest/blaze_face_short_range.tflite
 
# 人脸特征点 + Blendshapescurl -O https://storage.googleapis.com/mediapipe-models/face_landmarker/face_landmarker/float16/1/face_landmarker.task
 
# 物体检测 (EfficientDet-Lite0, int8)curl -O https://storage.googleapis.com/mediapipe-models/object_detector/efficientdet_lite0/int8/1/efficientdet_lite0.tflite
 
# 图像分类 (EfficientNet-Lite0, float32)curl -O https://storage.googleapis.com/mediapipe-models/image_classifier/efficientnet_lite0/float32/1/efficientnet_lite0.tflite
 
# 人脸嵌入 (FaceNet-512) — 从 deepface 导出
# 来源: https://github.com/shubham0204/OnDevice-Face-Recognition-Android
curl -O https://github.com/shubham0204/OnDevice-Face-Recognition-Android/raw/main/app/src/main/assets/facenet_512.tflite

十二、项目文件结构

app/src/main/
├── assets/
│   ├── blaze_face_short_range.tflite    (224K)
│   ├── face_landmarker.task             (3.6M)
│   ├── efficientdet_lite0.tflite        (4.4M)
│   ├── efficientnet_lite0.tflite        (18M)
│   └── facenet_512.tflite               (45M)
├── java/com/example/facepptest/
│   ├── LiteRTManager.kt                 ← Facade
│   ├── MainActivity.kt
│   ├── BeautyScoreActivity.kt           ← 综合分析
│   ├── FaceDetectActivity.kt
│   ├── FaceCompareActivity.kt
│   ├── FaceSearchActivity.kt
│   └── ml/
│       ├── MediaPipeFaceHelper.kt       ← 人脸检测
│       ├── FaceLandmarkerHelper.kt      ← 特征点+表情
│       ├── FaceEmbeddingHelper.kt       ← FaceNet 嵌入
│       ├── ObjectDetectorHelper.kt      ← 物体检测
│       ├── ImageClassifierHelper.kt     ← 图像分类
│       ├── ImageQualityHelper.kt        ← 质量评估
│       └── EmbeddingDbHelper.kt         ← 向量存储
└── res/layout/...