Hamidou Bah
@gdgratoma
@altgras
https://github.com/hams94
https://www.linkedin.com/in/hamidou-bah-80910011b/
https://twitter.com/yalagueya
https://www.youtube.com/channel/UCNcn0E8QLeyVTdmwgM6
Vlfw
Qu’est ce que Flutter ?
•Flutter est un Framework de développement
d’applications mobiles
•Ce Framework est proposé en Open Source par
Google
•Il propose un moyen unifié de développer des
applications Android et iOS à partir d’un code
commun
•Il permet également de simplifier la gestion
des compatibilités entre versions d’OS différentes.
C’est quoi Firebase ?
Firebase est essentiellement une
plate-forme de développement
d'applications mobiles et Web
utilisée pour aider à créer des
applications de haute qualité
Quelques produits de Firebase
Mais C’est quoi le ML Kit ?
ML Kit est une collection de
puissantes API d'apprentissage
automatique mises à la
disposition du public par Google
à IO 18 sous la marque
Firebase. .
Quelques Puissantes API de ML Kit
Reconnaissance optique de caractères
C’est une api qui permet de
détecter du texte dans les
images et l'extraire
Détection des visages
C’est une api qui permet de
détecter les visages et les
repères faciaux à l'aide de la
fonctionnalité Contours de
visage
Détection d'objets et suivi
C’est une api qui permet de
détecter, suivre et classer des
objets dans des images
statiques ou en direct de
l'appareil photo
Ajout de libellés à des images
C’est une api qui permet
d’identifier des objets, des lieux,
des activités, des espèces
animales, des produits et plus
encore
Auto ML Vision Edge
C’est une api qui vous permet
d’entraîner et publiez vos
propres modèles de
classification d'images.
Lecture de codes-barres
C’est une api qui vous permet d’
analyser et traitez des codes-
barres
Reconnaissance de points de repère
Identifiez les points de repère
populaires dans une image
Traduction sur l'appareil
Traduire du texte d'une langue à
une autre
Réponse suggérée
Générez des réponses par SMS
en fonction des messages
précédents
Intégration du ML Kit de Firebase à une application Flutter
Exemple: Détection de visages
Plan de travail
● Obtenir une image et la convertir en un format pouvant être compris
par notre ML Kit
● Envoyez l'image au détecteur et lui demander de scanner l'image
pour rechercher des visages possibles.
● Récupérer les visages trouvés et les transmettre au CustomPainter.
● Autorisez le CustomPainter à obtenir les coordonnées des faces,
puis les utiliser pour dessiner des effets.
Mise en Œuvre
Etape 1: Projet Firebase et dépendances
Créer un projet flutter
Créer un projet Firebase et ajouter une application au projet (voir la documentation )
Ajouter les dépendances image_picker et firebase_ml_vision
Ajouter également la dépendance du modèle de visage dans le fichier build.gradle niveau
application: implementation ‘com.google.firebase:firebase-ml-vision-face-model:19.0.0’
Etape 2: Récupération de l’image
final imageFile = await
ImagePicker.pickImage(source:ImageSource.gallery);
seState((){
isLoading = true;
});
Etape 3: Traitement de l’image
final data = await file.readAsBytes();
await decodeImageFromList(data).then( (value) =>
setState(() {
_image = value;
isLoading = false;
}), );
Etape 4: Détection des visages
final faceDetector = FirebaseVision.instance.faceDetector();
List<Face> faces = await faceDetector.processImage(image);
Etape 5: Le CustomPainter
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 = 15.0
..color = Colors.yellow;
canvas.drawImage(image, Offset.zero, Paint());
for (var i = 0; i < faces.length; i++) {
canvas.drawRect(rects[i], paint);
}
}
@override bool shouldRepaint(FacePainter oldDelegate) {
return image != oldDelegate.image || faces != oldDelegate.faces;
}
}
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 = 15.0
..color = Colors.yellow;
canvas.drawImage(image, Offset.zero, Paint());
for (var i = 0; i < faces.length; i++) {
canvas.drawRect(rects[i], paint);
}
}
@override bool shouldRepaint(FacePainter oldDelegate) {
return image != oldDelegate.image || faces != oldDelegate.faces;
}
}
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 = 15.0
..color = Colors.yellow;
canvas.drawImage(image, Offset.zero, Paint());
for (var i = 0; i < faces.length; i++) {
canvas.drawRect(rects[i], paint);
}
}
@override bool shouldRepaint(FacePainter oldDelegate) {
return image != oldDelegate.image || faces != oldDelegate.faces;
}
}
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 = 15.0
..color = Colors.yellow;
canvas.drawImage(image, Offset.zero, Paint());
for (var i = 0; i < faces.length; i++) {
canvas.drawRect(rects[i], paint);
}
}
@override bool shouldRepaint(FacePainter oldDelegate) {
return image != oldDelegate.image || faces != oldDelegate.faces;
}
}
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 = 15.0
..color = Colors.yellow;
canvas.drawImage(image, Offset.zero, Paint());
for (var i = 0; i < faces.length; i++) {
canvas.drawRect(rects[i], paint);
}
}
@override bool shouldRepaint(FacePainter oldDelegate) {
return image != oldDelegate.image || faces != oldDelegate.faces;
}
}
Etape 6: Le UI
@override
Widget build(BuildContext context) {
return Scaffold(
body: isLoading
? Center(child: CircularProgressIndicator())
: (_imageFile == null)
? Center(child: Text(‘Aucune image sélectionné'))
: Center(
child: FittedBox(
child: SizedBox(
width: _image.width.toDouble(),
height: _image.height.toDouble(),
child: CustomPaint(
painter: FacePainter(_image, _faces),
),
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _getImageAndDetectFaces,
tooltip: ‘Sélect. Image',
child: Icon(Icons.add_a_photo),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: isLoading
? Center(child: CircularProgressIndicator())
: (_imageFile == null)
? Center(child: Text(‘Aucune image sélectionné'))
: Center(
child: FittedBox(
child: SizedBox(
width: _image.width.toDouble(),
height: _image.height.toDouble(),
child: CustomPaint(
painter: FacePainter(_image, _faces),
),
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _getImageAndDetectFaces,
tooltip: ‘Sélect. Image',
child: Icon(Icons.add_a_photo),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: isLoading
? Center(child: CircularProgressIndicator())
: (_imageFile == null)
? Center(child: Text(‘Aucune image sélectionné'))
: Center(
child: FittedBox(
child: SizedBox(
width: _image.width.toDouble(),
height: _image.height.toDouble(),
child: CustomPaint(
painter: FacePainter(_image, _faces),
),
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _getImageAndDetectFaces,
tooltip: ‘Sélect. Image',
child: Icon(Icons.add_a_photo),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: isLoading
? Center(child: CircularProgressIndicator())
: (_imageFile == null)
? Center(child: Text(‘Aucune image sélectionné'))
: Center(
child: FittedBox(
child: SizedBox(
width: _image.width.toDouble(),
height: _image.height.toDouble(),
child: CustomPaint(
painter: FacePainter(_image, _faces),
),
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _getImageAndDetectFaces,
tooltip: ‘Sélect. Image',
child: Icon(Icons.add_a_photo),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: isLoading
? Center(child: CircularProgressIndicator())
: (_imageFile == null)
? Center(child: Text(‘Aucune image sélectionné'))
: Center(
child: FittedBox(
child: SizedBox(
width: _image.width.toDouble(),
height: _image.height.toDouble(),
child: CustomPaint(
painter: FacePainter(_image, _faces),
),
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _getImageAndDetectFaces,
tooltip: ‘Sélect. Image',
child: Icon(Icons.add_a_photo),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: isLoading
? Center(child: CircularProgressIndicator())
: (_imageFile == null)
? Center(child: Text(‘Aucune image sélectionné'))
: Center(
child: FittedBox(
child: SizedBox(
width: _image.width.toDouble(),
height: _image.height.toDouble(),
child: CustomPaint(
painter: FacePainter(_image, _faces),
),
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _getImageAndDetectFaces,
tooltip: ‘Sélect. Image',
child: Icon(Icons.add_a_photo),
),
);
}
PRATIQUE
MERCI BEAUCOUP
POUR VOTRE
ATTENTION

Flutter and ML Kit For Firebase

  • 2.
  • 4.
    Qu’est ce queFlutter ? •Flutter est un Framework de développement d’applications mobiles •Ce Framework est proposé en Open Source par Google •Il propose un moyen unifié de développer des applications Android et iOS à partir d’un code commun •Il permet également de simplifier la gestion des compatibilités entre versions d’OS différentes.
  • 5.
    C’est quoi Firebase? Firebase est essentiellement une plate-forme de développement d'applications mobiles et Web utilisée pour aider à créer des applications de haute qualité
  • 6.
  • 7.
    Mais C’est quoile ML Kit ? ML Kit est une collection de puissantes API d'apprentissage automatique mises à la disposition du public par Google à IO 18 sous la marque Firebase. .
  • 8.
  • 9.
    Reconnaissance optique decaractères C’est une api qui permet de détecter du texte dans les images et l'extraire
  • 10.
    Détection des visages C’estune api qui permet de détecter les visages et les repères faciaux à l'aide de la fonctionnalité Contours de visage
  • 11.
    Détection d'objets etsuivi C’est une api qui permet de détecter, suivre et classer des objets dans des images statiques ou en direct de l'appareil photo
  • 12.
    Ajout de libellésà des images C’est une api qui permet d’identifier des objets, des lieux, des activités, des espèces animales, des produits et plus encore
  • 13.
    Auto ML VisionEdge C’est une api qui vous permet d’entraîner et publiez vos propres modèles de classification d'images.
  • 14.
    Lecture de codes-barres C’estune api qui vous permet d’ analyser et traitez des codes- barres
  • 15.
    Reconnaissance de pointsde repère Identifiez les points de repère populaires dans une image
  • 16.
    Traduction sur l'appareil Traduiredu texte d'une langue à une autre
  • 17.
    Réponse suggérée Générez desréponses par SMS en fonction des messages précédents
  • 18.
    Intégration du MLKit de Firebase à une application Flutter
  • 19.
  • 20.
    Plan de travail ●Obtenir une image et la convertir en un format pouvant être compris par notre ML Kit ● Envoyez l'image au détecteur et lui demander de scanner l'image pour rechercher des visages possibles. ● Récupérer les visages trouvés et les transmettre au CustomPainter. ● Autorisez le CustomPainter à obtenir les coordonnées des faces, puis les utiliser pour dessiner des effets.
  • 21.
  • 22.
    Etape 1: ProjetFirebase et dépendances Créer un projet flutter Créer un projet Firebase et ajouter une application au projet (voir la documentation ) Ajouter les dépendances image_picker et firebase_ml_vision Ajouter également la dépendance du modèle de visage dans le fichier build.gradle niveau application: implementation ‘com.google.firebase:firebase-ml-vision-face-model:19.0.0’
  • 23.
    Etape 2: Récupérationde l’image final imageFile = await ImagePicker.pickImage(source:ImageSource.gallery); seState((){ isLoading = true; });
  • 24.
    Etape 3: Traitementde l’image final data = await file.readAsBytes(); await decodeImageFromList(data).then( (value) => setState(() { _image = value; isLoading = false; }), );
  • 25.
    Etape 4: Détectiondes visages final faceDetector = FirebaseVision.instance.faceDetector(); List<Face> faces = await faceDetector.processImage(image);
  • 26.
    Etape 5: LeCustomPainter
  • 27.
    class FacePainter extendsCustomPainter { 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 = 15.0 ..color = Colors.yellow; canvas.drawImage(image, Offset.zero, Paint()); for (var i = 0; i < faces.length; i++) { canvas.drawRect(rects[i], paint); } } @override bool shouldRepaint(FacePainter oldDelegate) { return image != oldDelegate.image || faces != oldDelegate.faces; } }
  • 28.
    class FacePainter extendsCustomPainter { 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 = 15.0 ..color = Colors.yellow; canvas.drawImage(image, Offset.zero, Paint()); for (var i = 0; i < faces.length; i++) { canvas.drawRect(rects[i], paint); } } @override bool shouldRepaint(FacePainter oldDelegate) { return image != oldDelegate.image || faces != oldDelegate.faces; } }
  • 29.
    class FacePainter extendsCustomPainter { 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 = 15.0 ..color = Colors.yellow; canvas.drawImage(image, Offset.zero, Paint()); for (var i = 0; i < faces.length; i++) { canvas.drawRect(rects[i], paint); } } @override bool shouldRepaint(FacePainter oldDelegate) { return image != oldDelegate.image || faces != oldDelegate.faces; } }
  • 30.
    class FacePainter extendsCustomPainter { 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 = 15.0 ..color = Colors.yellow; canvas.drawImage(image, Offset.zero, Paint()); for (var i = 0; i < faces.length; i++) { canvas.drawRect(rects[i], paint); } } @override bool shouldRepaint(FacePainter oldDelegate) { return image != oldDelegate.image || faces != oldDelegate.faces; } }
  • 31.
    class FacePainter extendsCustomPainter { 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 = 15.0 ..color = Colors.yellow; canvas.drawImage(image, Offset.zero, Paint()); for (var i = 0; i < faces.length; i++) { canvas.drawRect(rects[i], paint); } } @override bool shouldRepaint(FacePainter oldDelegate) { return image != oldDelegate.image || faces != oldDelegate.faces; } }
  • 32.
  • 33.
    @override Widget build(BuildContext context){ return Scaffold( body: isLoading ? Center(child: CircularProgressIndicator()) : (_imageFile == null) ? Center(child: Text(‘Aucune image sélectionné')) : Center( child: FittedBox( child: SizedBox( width: _image.width.toDouble(), height: _image.height.toDouble(), child: CustomPaint( painter: FacePainter(_image, _faces), ), ), ), ), floatingActionButton: FloatingActionButton( onPressed: _getImageAndDetectFaces, tooltip: ‘Sélect. Image', child: Icon(Icons.add_a_photo), ), ); }
  • 34.
    @override Widget build(BuildContext context){ return Scaffold( body: isLoading ? Center(child: CircularProgressIndicator()) : (_imageFile == null) ? Center(child: Text(‘Aucune image sélectionné')) : Center( child: FittedBox( child: SizedBox( width: _image.width.toDouble(), height: _image.height.toDouble(), child: CustomPaint( painter: FacePainter(_image, _faces), ), ), ), ), floatingActionButton: FloatingActionButton( onPressed: _getImageAndDetectFaces, tooltip: ‘Sélect. Image', child: Icon(Icons.add_a_photo), ), ); }
  • 35.
    @override Widget build(BuildContext context){ return Scaffold( body: isLoading ? Center(child: CircularProgressIndicator()) : (_imageFile == null) ? Center(child: Text(‘Aucune image sélectionné')) : Center( child: FittedBox( child: SizedBox( width: _image.width.toDouble(), height: _image.height.toDouble(), child: CustomPaint( painter: FacePainter(_image, _faces), ), ), ), ), floatingActionButton: FloatingActionButton( onPressed: _getImageAndDetectFaces, tooltip: ‘Sélect. Image', child: Icon(Icons.add_a_photo), ), ); }
  • 36.
    @override Widget build(BuildContext context){ return Scaffold( body: isLoading ? Center(child: CircularProgressIndicator()) : (_imageFile == null) ? Center(child: Text(‘Aucune image sélectionné')) : Center( child: FittedBox( child: SizedBox( width: _image.width.toDouble(), height: _image.height.toDouble(), child: CustomPaint( painter: FacePainter(_image, _faces), ), ), ), ), floatingActionButton: FloatingActionButton( onPressed: _getImageAndDetectFaces, tooltip: ‘Sélect. Image', child: Icon(Icons.add_a_photo), ), ); }
  • 37.
    @override Widget build(BuildContext context){ return Scaffold( body: isLoading ? Center(child: CircularProgressIndicator()) : (_imageFile == null) ? Center(child: Text(‘Aucune image sélectionné')) : Center( child: FittedBox( child: SizedBox( width: _image.width.toDouble(), height: _image.height.toDouble(), child: CustomPaint( painter: FacePainter(_image, _faces), ), ), ), ), floatingActionButton: FloatingActionButton( onPressed: _getImageAndDetectFaces, tooltip: ‘Sélect. Image', child: Icon(Icons.add_a_photo), ), ); }
  • 38.
    @override Widget build(BuildContext context){ return Scaffold( body: isLoading ? Center(child: CircularProgressIndicator()) : (_imageFile == null) ? Center(child: Text(‘Aucune image sélectionné')) : Center( child: FittedBox( child: SizedBox( width: _image.width.toDouble(), height: _image.height.toDouble(), child: CustomPaint( painter: FacePainter(_image, _faces), ), ), ), ), floatingActionButton: FloatingActionButton( onPressed: _getImageAndDetectFaces, tooltip: ‘Sélect. Image', child: Icon(Icons.add_a_photo), ), ); }
  • 39.
  • 40.