Detección de rostros en Flutter con Firebase ML Kit

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;
  }
}

Producción:

Publicación traducida automáticamente

Artículo escrito por ms471841 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *