La detección de rostros es una técnica mediante la cual podemos localizar los rostros humanos en la imagen dada. La detección de rostros se usa en muchos lugares hoy en día, especialmente en los sitios web que alojan imágenes como Picasa, Photobucket y Facebook. La función de etiquetado automático agrega una nueva dimensión al intercambio de imágenes entre las personas que están en la imagen y también les da una idea a otras personas sobre quién es la persona en la imagen. Y en este artículo, no estamos utilizando nuestro propio algoritmo de aprendizaje automático de detección de rostros creado. Pero estaremos usando el kit Firebase ML que nos da para usar el algoritmo de detección de rostros en Flutter.
Implementación paso a paso
En primer lugar, creó un proyecto vacío en Flutter. Puede consultar este artículo para lo mismo. Antes de continuar, agreguemos algunas dependencias en el archivo pubspec.yaml .
firebase_ml_vision: ^0.12.0+3 image_picker: ^0.8.5+3 firebase_core: ^1.19.2
Estamos usando tres dependencias para el proyecto que nos ayudarán.
firebase_ml_vision y firebase_core se usan para la detección de rostros en una imagen y image_picker se usa para seleccionar la imagen de la cámara o galería y cualquier otra fuente. Nuestro objetivo es elegir la imagen de la galería usando el botón o desde la cámara y luego mostrar esa imagen como una salida con un rostro humano detectado.
Nota : cuando esté leyendo, la versión de los paquetes puede cambiar.
Ahora importe estos siguientes paquetes adicionales que ayudan a usar las funciones de base de fuego incorporadas en nuestro proyecto flutter.
import 'package:firebase_ml_vision/firebase_ml_vision.dart'; import 'package:image_picker/image_picker.dart';
Ahora, en la función void main() , llame al método runApp() y llame a la clase MyApp() . Ahora cree una nueva clase llamada MyApp( ). Esta será una clase o widget con estado porque nuestra aplicación cambia su estado en tiempo de ejecución. Y devuelve el Scaffold() . En andamio, tenemos AppBar con texto de título Detección de rostros . Además, agregue el botón de acción flotante para tomar la imagen, estamos tomando de la galería en este proyecto.
Dart
// runapp void main() => runApp( // MaterialApp with debugbannner false MaterialApp( debugShowCheckedModeBanner: false, theme: ThemeData(primarySwatch: Colors.teal), // this will going to our main class. home: MyApp(), ), ); class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { @override Widget build(BuildContext context) { // scaffold with appbar return Scaffold( appBar: AppBar( automaticallyImplyLeading: true, title: Text('Face Detection'), ), // flaoting action button floatingActionButton: FloatingActionButton( onPressed: _getImagegallery, tooltip: 'camera', child: Icon(Icons.add_a_photo), ), ); } }
Nuestra pantalla de interfaz de usuario se ve así:
Ahora vamos a crear el método _getImagegallery para tomar imágenes . y llame al método setState para hacer que la variable isLoading sea verdadera. Y detectar caras en la imagen usando firebaseVision .
Dart
_getImagegallery() async { // picking image imageFile = await picker.getImage(source: ImageSource.gallery); setState(() { // set isLoading to true isLoading = true; }); // detecting faces in the images final image = FirebaseVisionImage.fromFile(File(imageFile.path)); final faceDetector = FirebaseVision.instance.faceDetector(); List<Face> faces = await faceDetector.processImage(image); if (mounted) { setState(() { _imageFile = File(imageFile.path); _faces = faces; _loadImage(File(imageFile.path)); }); } } _loadImage(File file) async { final data = await file.readAsBytes(); await decodeImageFromList(data).then((value) => setState(() { _image = value; isLoading = false; })); } }
Ahora tenemos que usar lienzo para pintar cada cara en el color rectangular que se detecta y se muestra en el cuerpo del Andamio.
Código completo
Dart
// @dart=2.9 import 'package:flutter/material.dart'; import 'package:firebase_ml_vision/firebase_ml_vision.dart'; import 'package:image_picker/image_picker.dart'; import 'dart:io'; import 'dart:ui' as ui; // main method that runs the our main app void main() => runApp( MaterialApp( debugShowCheckedModeBanner: false, theme: ThemeData(primarySwatch: Colors.teal), home: MyApp(), ), ); class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { File _imageFile; List<Face> _faces; bool isLoading = false; ui.Image _image; final picker = ImagePicker(); var imageFile; @override Widget build(BuildContext context) { // scaffold with appbar return Scaffold( appBar: AppBar( automaticallyImplyLeading: true, // title of the appbar title: Text('Face Detection'), ), // foating button for picking image floatingActionButton: FloatingActionButton( onPressed: _getImagegallery, tooltip: 'camera', child: Icon(Icons.add_a_photo), ), // if file is null print no image // selected others wise show image body: isLoading ? Center(child: CircularProgressIndicator()) : (_imageFile == null) ? Center(child: Text('no image selected')) : Center( child: FittedBox( child: SizedBox( width: _image.width.toDouble(), height: _image.height.toDouble(), child: CustomPaint( painter: FacePainter(_image, _faces), ), ), ), ), ); } // function for pick the image // and detect faces in the image _getImagegallery() async { imageFile = await picker.getImage(source: ImageSource.gallery); setState(() { isLoading = true; }); final image = FirebaseVisionImage.fromFile(File(imageFile.path)); final faceDetector = FirebaseVision.instance.faceDetector(); List<Face> faces = await faceDetector.processImage(image); if (mounted) { setState(() { _imageFile = File(imageFile.path); _faces = faces; _loadImage(File(imageFile.path)); }); } } _loadImage(File file) async { final data = await file.readAsBytes(); await decodeImageFromList(data).then((value) => setState(() { _image = value; isLoading = false; })); } } // paint the face class FacePainter extends CustomPainter { final ui.Image image; final List<Face> faces; final List<Rect> rects = []; FacePainter(this.image, this.faces) { for (var i = 0; i < faces.length; i++) { rects.add(faces[i].boundingBox); } } @override void paint(ui.Canvas canvas, ui.Size size) { final Paint paint = Paint() ..style = PaintingStyle.stroke ..strokeWidth = 2.0 ..color = Colors.red; canvas.drawImage(image, Offset.zero, Paint()); for (var i = 0; i < faces.length; i++) { canvas.drawRect(rects[i], paint); } } @override bool shouldRepaint(FacePainter old) { return image != old.image || faces != old.faces; } }