You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter中结合MediaPipe实现摄像头功能?

Flutter集成MediaPipe摄像头实现方案

1. 依赖配置

在项目的pubspec.yaml中添加所需依赖:

dependencies:
  flutter:
    sdk: flutter
  camera: ^0.10.0+1          # 基础摄像头功能依赖
  mediapipe_selfie_segmentation: ^0.5.0  # 以自拍分割为例,可根据需求替换为对应MediaPipe包(如人脸/手势识别)

执行命令安装依赖:

flutter pub get

2. 权限配置

Android端

在android/app/src/main/AndroidManifest.xml中添加摄像头权限:

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

iOS端

在ios/Runner/Info.plist中添加摄像头权限描述:

<key>NSCameraUsageDescription</key>
<string>需要使用摄像头进行AI处理</string>

3. 核心代码实现

以下是集成摄像头预览+MediaPipe图像处理的完整示例(以自拍分割为例):

import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:mediapipe_selfie_segmentation/mediapipe_selfie_segmentation.dart';

class MediaPipeCameraPage extends StatefulWidget {
  const MediaPipeCameraPage({super.key});

  @override
  State<MediaPipeCameraPage> createState() => _MediaPipeCameraPageState();
}

class _MediaPipeCameraPageState extends State<MediaPipeCameraPage> {
  late CameraController _cameraController;
  late SelfieSegmentation _mediapipeProcessor;
  bool _isReady = false;
  CameraImage? _latestCameraImage;
  SegmentationMask? _latestResult;

  @override
  void initState() {
    super.initState();
    _initCameraAndMediaPipe();
  }

  Future<void> _initCameraAndMediaPipe() async {
    // 获取前置摄像头
    final cameras = await availableCameras();
    final frontCamera = cameras.firstWhere(
      (cam) => cam.lensDirection == CameraLensDirection.front,
    );

    // 初始化摄像头控制器
    _cameraController = CameraController(
      frontCamera,
      ResolutionPreset.high,
      enableAudio: false,
    );
    await _cameraController.initialize();

    // 初始化MediaPipe组件
    _mediapipeProcessor = SelfieSegmentation();
    await _mediapipeProcessor.initialize();

    // 监听摄像头帧数据
    _cameraController.startImageStream((image) {
      if (!mounted) return;
      setState(() => _latestCameraImage = image);
      _processFrame(image);
    });

    setState(() => _isReady = true);
  }

  Future<void> _processFrame(CameraImage image) async {
    // 使用MediaPipe处理图像帧
    final result = await _mediapipeProcessor.processImage(image);
    if (!mounted) return;
    setState(() => _latestResult = result);
  }

  @override
  void dispose() {
    _cameraController.dispose();
    _mediapipeProcessor.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (!_isReady) {
      return const Scaffold(body: Center(child: CircularProgressIndicator()));
    }

    return Scaffold(
      body: Stack(
        children: [
          // 摄像头预览层
          CameraPreview(_cameraController),
          // 叠加MediaPipe处理结果(示例:半透明红色蒙版)
          if (_latestResult != null)
            Positioned.fill(
              child: CustomPaint(painter: ResultPainter(_latestResult!)),
            ),
        ],
      ),
    );
  }
}

// 自定义绘制MediaPipe结果的Painter
class ResultPainter extends CustomPainter {
  final SegmentationMask mask;

  ResultPainter(this.mask);

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.red.withOpacity(0.5)
      ..style = PaintingStyle.fill;

    // 蒙版坐标映射到屏幕尺寸
    final widthRatio = size.width / mask.width;
    final heightRatio = size.height / mask.height;

    // 绘制高置信度区域
    for (int y = 0; y < mask.height; y++) {
      for (int x = 0; x < mask.width; x++) {
        if (mask.getConfidence(x, y) > 0.5) {
          canvas.drawRect(
            Rect.fromLTWH(
              x * widthRatio,
              y * heightRatio,
              widthRatio,
              heightRatio,
            ),
            paint,
          );
        }
      }
    }
  }

  @override
  bool shouldRepaint(covariant ResultPainter oldDelegate) {
    return oldDelegate.mask != mask;
  }
}

4. 关键注意事项

  • 选择对应MediaPipe包:根据你的AI功能需求,替换示例中的mediapipe_selfie_segmentation,比如人脸检测用mediapipe_face_mesh,手势识别用mediapipe_hand_landmarker,各包的初始化和帧处理逻辑基本一致。
  • 性能优化:图像处理属于计算密集型操作,可通过compute函数将处理逻辑移至后台 isolate,避免阻塞主线程导致界面卡顿。
  • 设备兼容性:确保测试设备支持MediaPipe的硬件加速,低端设备可能需要降低摄像头分辨率或调整MediaPipe的运行模式来提升流畅度。

内容的提问来源于stack exchange,提问作者Raşit Eşdemir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 06:06:13