import 'smile_painter.dart'; import 'package:flutter/material.dart'; import 'package:camera/camera.dart'; import 'package:firebase_ml_vision/firebase_ml_vision.dart'; import 'package:flutter/foundation.dart'; import 'dart:ui' as ui show Image; import 'utils.dart'; class FaceDetectionFromLiveCamera extends StatefulWidget { FaceDetectionFromLiveCamera({Key key}) : super(key: key); @override _FaceDetectionFromLiveCameraState createState() => _FaceDetectionFromLiveCameraState(); } class _FaceDetectionFromLiveCameraState extends State { final FaceDetector faceDetector = FirebaseVision.instance.faceDetector(); List faces; CameraController _camera; bool _isDetecting = false; CameraLensDirection _direction = CameraLensDirection.back; @override void initState() { super.initState(); _initializeCamera(); } void _initializeCamera() async { CameraDescription description = await getCamera(_direction); ImageRotation rotation = rotationIntToImageRotation( description.sensorOrientation, ); _camera = CameraController( description, defaultTargetPlatform == TargetPlatform.iOS ? ResolutionPreset.low : ResolutionPreset.medium, ); await _camera.initialize(); _camera.startImageStream((CameraImage image) { if (_isDetecting) return; _isDetecting = true; detect( image, FirebaseVision.instance .faceDetector(FaceDetectorOptions( mode: FaceDetectorMode.accurate, enableClassification: true)) .processImage, rotation) .then( (dynamic result) { setState(() { faces = result; }); _isDetecting = false; }, ).catchError( (_) { _isDetecting = false; }, ); }); } Widget _buildResults() { const Text noResultsText = const Text('No results!'); const Text multipleFaceText = const Text('Multiple faces!'); const Text pleaseSmileText = const Text('Please smile!'); if (faces == null || _camera == null || !_camera.value.isInitialized) { return noResultsText; } CustomPainter painter; final Size imageSize = Size( _camera.value.previewSize.height, _camera.value.previewSize.width, ); if (faces is! List || faces.isEmpty || faces == null || faces.length == 0) return noResultsText; if (faces.length > 1) return multipleFaceText; var face = faces[0]; if (face.smilingProbability == null || face.smilingProbability < 0.8) { return pleaseSmileText; } painter = SmilePainterLiveCamera(imageSize, faces); return CustomPaint( painter: painter, ); } Widget _buildImage() { return Container( constraints: const BoxConstraints.expand(), child: _camera == null ? const Center( child: Text( 'Initializing Camera...', style: TextStyle( color: Colors.green, fontSize: 30.0, ), ), ) : Stack( fit: StackFit.expand, children: [ CameraPreview(_camera), _buildResults(), Positioned( bottom: 0.0, left: 0.0, right: 0.0, child: Container( color: Colors.white, height: 50.0, child: ListView( children: faces .map((face) => Text( "${face.boundingBox.center.toString()}, Smile:${face.smilingProbability}")) .toList(), ), ), ), ], ), ); } void _toggleCameraDirection() async { if (_direction == CameraLensDirection.back) { _direction = CameraLensDirection.front; } else { _direction = CameraLensDirection.back; } await _camera.stopImageStream(); await _camera.dispose(); setState(() { _camera = null; }); _initializeCamera(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Face Detection with Smile"), ), body: _buildImage(), floatingActionButton: FloatingActionButton( onPressed: _toggleCameraDirection, child: _direction == CameraLensDirection.back ? const Icon(Icons.camera_front) : const Icon(Icons.camera_rear), ), ); } }