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

Flutter安装google_mlkit_face_detection后仍报GoogleMlKit未定义错误

问题描述

开发Flutter人脸检测功能时,实现拍照后检测图片中的人脸,已安装google_mlkit_face_detection包并完成导入,但调用GoogleMlKit.vision.faceDetector()时出现错误:

error: Undefined name 'GoogleMlKit'. (undefined_identifier at [rtwo] lib\face_detection_screen.dart:18)

以下是完整代码及pubspec.yaml依赖配置:

原代码

import 'dart:async';
import 'dart:ui';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:google_mlkit_face_detection/google_mlkit_face_detection.dart';
import 'package:image_picker/image_picker.dart';
import 'package:google_mlkit_commons/google_mlkit_commons.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';

class FaceDetectionScreen extends StatefulWidget {
  @override
  _FaceDetectionScreenState createState() => _FaceDetectionScreenState();
}

class _FaceDetectionScreenState extends State<FaceDetectionScreen> {
  final FaceDetector faceDetector = GoogleMlKit.vision.faceDetector();
  late CameraController _cameraController;
  final ImagePicker _picker = ImagePicker();
  bool _isDetecting = false;

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

  Future<void> _initializeCamera() async {
    final cameras = await availableCameras();
    final camera = cameras.first;
    _cameraController = CameraController(camera, ResolutionPreset.medium);
    await _cameraController.initialize();
  }

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

  Future<XFile?> _pickImage() async {
    try {
      final XFile? photo = await _picker.pickImage(source: ImageSource.camera);
      return photo;
    } catch (e) {
      print('Error picking image: $e');
      return null;
    }
  }

  Future<void> _detectFaces(XFile? imageFile) async {
    if (_isDetecting || imageFile == null) return;

    setState(() {
      _isDetecting = true;
    });

    try {
      final inputImage = InputImage.fromFilePath(imageFile.path);
      final List<Face> faces = await faceDetector().processImage(inputImage);

      // Handle the detected faces
      for (Face face in faces) {
        final Rect boundingBox = face.boundingBox;
        print('Face detected: $boundingBox');
      }
    } catch (e) {
      print('Error detecting faces: $e');
    } finally {
      setState(() {
        _isDetecting = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Face Detection'),
      ),
      body: _cameraPreview(),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          final imageFile = await _pickImage();
          _detectFaces(imageFile);
        },
        child: Icon(Icons.camera_alt),
      ),
    );
  }

  Widget _cameraPreview() {
    if (_cameraController.value.isInitialized) {
      return CameraPreview(_cameraController);
    } else {
      return Center(
        child: CircularProgressIndicator(),
      );
    }
  }
}

pubspec.yaml依赖

dependencies:
  flutter:
    sdk: flutter
  google_fonts: ^6.2.1
  cupertino_icons: ^1.0.6
  firebase_messaging: ^14.9.1
  firebase_core: ^2.30.1
  camera: ^0.10.6
  path_provider: ^2.1.3
  path: ^1.9.0
  image_picker: ^1.1.1
  google_mlkit_face_detection: ^0.11.0
错误原因

google_mlkit_face_detection 0.11.0版本已移除GoogleMlKit全局类的API,改为直接通过FaceDetector构造函数创建实例,旧调用方式不再生效。此外代码中还有一处错误:faceDetector是已初始化的实例,调用processImage时错误添加了括号,写成了faceDetector()。

修复方案
  1. 修改FaceDetector初始化方式:直接使用FaceDetector构造函数创建实例,可按需传入FaceDetectorOptions配置检测参数;
  2. 修复processImage调用错误:移除实例调用时多余的括号;
  3. 添加资源释放:在dispose方法中释放faceDetector,避免内存泄漏。

修改后的完整代码

import 'dart:async';
import 'dart:ui';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:google_mlkit_face_detection/google_mlkit_face_detection.dart';
import 'package:image_picker/image_picker.dart';
import 'package:google_mlkit_commons/google_mlkit_commons.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';

class FaceDetectionScreen extends StatefulWidget {
  @override
  _FaceDetectionScreenState createState() => _FaceDetectionScreenState();
}

class _FaceDetectionScreenState extends State<FaceDetectionScreen> {
  // 直接通过构造函数创建FaceDetector实例,可配置检测选项
  final FaceDetector faceDetector = FaceDetector(
    options: FaceDetectorOptions(
      enableContours: true,
      enableClassification: true,
    ),
  );
  late CameraController _cameraController;
  final ImagePicker _picker = ImagePicker();
  bool _isDetecting = false;

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

  Future<void> _initializeCamera() async {
    final cameras = await availableCameras();
    final camera = cameras.first;
    _cameraController = CameraController(camera, ResolutionPreset.medium);
    await _cameraController.initialize();
    // 初始化后触发重绘,避免预览不刷新
    if (mounted) setState(() {});
  }

  @override
  void dispose() {
    _cameraController.dispose();
    // 释放FaceDetector资源
    faceDetector.close();
    super.dispose();
  }

  Future<XFile?> _pickImage() async {
    try {
      final XFile? photo = await _picker.pickImage(source: ImageSource.camera);
      return photo;
    } catch (e) {
      print('Error picking image: $e');
      return null;
    }
  }

  Future<void> _detectFaces(XFile? imageFile) async {
    if (_isDetecting || imageFile == null) return;

    setState(() {
      _isDetecting = true;
    });

    try {
      final inputImage = InputImage.fromFilePath(imageFile.path);
      // 修复:直接调用实例的processImage方法,不需要加括号
      final List<Face> faces = await faceDetector.processImage(inputImage);

      // 处理检测到的人脸
      for (Face face in faces) {
        final Rect boundingBox = face.boundingBox;
        print('Face detected: $boundingBox');
        // 可根据需求获取更多人脸特征,比如表情、轮廓等
        if (face.smilingProbability != null) {
          print('Smiling probability: ${face.smilingProbability}');
        }
      }
    } catch (e) {
      print('Error detecting faces: $e');
    } finally {
      setState(() {
        _isDetecting = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Face Detection'),
      ),
      body: _cameraPreview(),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          final imageFile = await _pickImage();
          _detectFaces(imageFile);
        },
        child: Icon(Icons.camera_alt),
      ),
    );
  }

  Widget _cameraPreview() {
    if (_cameraController.value.isInitialized) {
      return CameraPreview(_cameraController);
    } else {
      return const Center(
        child: CircularProgressIndicator(),
      );
    }
  }
}

说明

  • FaceDetectorOptions可根据需求配置,比如是否检测轮廓、表情、关键点等,默认参数也可满足基础检测需求;
  • 新增faceDetector.close()在dispose中释放资源,符合Flutter内存管理规范;
  • 初始化相机后添加setState,避免相机预览未及时刷新的问题。

内容的提问来源于stack exchange,提问作者Jena.T

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 14:40:59