如何在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
相关产品推荐
相关产品推荐

