Face Detection In Flutter
Hello Everyone I’m Back again with an exciting article where in we will be developing a flutter application able to detect images using firebase ml kit in our flutter apps .
firstly we will set up the firebase project -:
- : Go to https://firebase.google.com/ and set up anew project.
- : After that add in your app and download google-services.json.
- : Add the lines in build.gradle and then you are done setting up firebase project.
Now we will work with what packages we need in the app :
- image_picker
- firebase_ml_vision
These 2 packages are required to work make this particular app
Now, we will go into detail how it works, so Firebase ml_kit has many modals like textRecognizer() , imageLabeler() , faceDetector() etc
Such modals are used to do various tasks (usually self explanatory), We will work with one of these modals to make a face detector app
So the basic idea of app will be for user to select an image from gallery and then we will check the images for faces using firebase_ml_vision package’s faceDetector().
So after your boilerplate code is ready we can start working on getting an image from users gallery,
var imageFile = await ImagePicker.pickImage(source: ImageSource.gallery);
This one line of code allows us to open gallery on click of a button, and we have applied await so that it will wait till the user picks one image,
So onto the next step, we need to convert what we got from image into a FirebaseVisionImage and we can use the .fromFile function from it, which will convert the file image into a firebaseVisionImage type
FirebaseVisionImage fbVisionImage = FirebaseVisionImage.fromFile(imageFile);
After we have a firebaseVisionImage by converting the image picked by user, we will need to initialize a faceDetector which will be done by
FaceDetector faceDetector = FirebaseVision.instance.faceDetector();
Alright after getting the instance of a FaceDetector we can finally work on our logic for the face detection
So we will require a list of Type Face.
Well Face class has many variables such as bindingBox , headEulerAngleY, headEulerAngleZ, leftEyeOpenProbability, rightEyeOpenProbability, we are only going to work with bindingBox which will give us a Rectangle or rather the coordinates of a rectangle around a face, which is what we will use to create a box around that face to show in an image that the rectangular box represents a face of a person
So to do this we need to first let our faceDetector isntance process the firebaseVisionImage and then return to us a list of face.
List<Face> listOfFaces = await faceDetector.processImage(fbVisionImage);
await once again here is important cause it will take time for it to go through the whole image and give us a list of all the possible faces in it.
after getting the listOfFaces, we will then use a simple for loop to get all the bindingBox from it. and then put them into another List which will contain a rectangles, since bindingBox gives us a rectangle.
List<Rect> rectArr = new List();
for (Face face in listOfFaces) {
rectArr.add(face.boundingBox);
}
Note : keep the rectArr outside of this function
So, now we have a list of rectangles that should be drawn on a face, what we need to do now is to simply convert an image into a ui.Image
So we will do that by using the readAsByteSync property of imageFile
var bytesFromImageFile = imageFile.readAsBytesSync();
Now we are going to use decodeImageFromList to get an image from a list of bytes of an image file
You will need to import dart ui as ui
import 'dart:ui' as ui;
After you are done with that, make an ui.Image
ui.Image image;
Note : declare image outside of the function as well
decodeImageFromList(bytesFromImageFile).then((img) {
setState(() {
image = img;
});
});
So after this we are done, with the hard part, now we will move onto the CustomPainter part.
class Painter extends CustomPainter {
Painter(@required this.rect, @required this.image);
final List<Rect> rect;
ui.Image image;
@override
void paint(Canvas canvas, Size size) {
var paint = Paint()
..color = Colors.red
..style = PaintingStyle.stroke
..strokeWidth = 7;
if (image != null) {
canvas.drawImage(image, Offset.zero, paint);
}
for (var i = 0; i <= rect.length - 1; i++) {
canvas.drawRect(rect[i], paint);
}
}
@override
bool shouldRepaint(oldDelegate) {
return true;
}
}
We have not done much here just make a class that extends custom painter and its constructor takes 2 parameters first is the ui.Image and the second is List<Rect> a list of rectangles, then we have a method called void paint, which is the main method where you draw,
To draw you first need to declare paint() then give it values such as the width of its stroke and size of the brush, the color of the brush etc, After that we check if the image is empty or not if its not then we tell the canvas to draw the image by using canvas.drawImage() method which takes 3 parameters, one is image which we get when we call painter, second is the offset, we set it to 0, third is the paint we declared earlier.
After drawing the image we now draw the rectangles using another loop and this time we use canvas.drawRect() and in it we pass the rect we get when we call the painter class and the paint.
With this you are almost ready, the final touch up is calling the painter method
For this in the build method we will put this sizedBox as a child
FittedBox(
child: SizedBox(
height: image == null ? height : image.height.toDouble(),
width: image == null ? width : image.width.toDouble(),
child: CustomPaint(
painter: Painter(rectArr, image),
),
),
),
So you must be asking why use fittedbox and sizedBox, well the answer is simple when flutter draws the image you will see the image as magnified and wont be fully contained inside your phone so to fix that we will need to give it bounded height and width and make it fit inside your device.
This will enable user to see the full image in the device.
With that piece of code we are finally done, don’t forget to wrap all the other code in a function and add a FAB that will help us pick images.
See the following gif to get in familiar with the application :
For any help, let me know in the comments below, I will try my best to help you out ASAP. Let’s meet in the next article.
Feel free to connect with us:
And read more articles from FlutterDevs.com.
FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! You can connect with us on Facebook, GitHub, Twitter, and LinkedIn for any flutter related queries.
We welcome feedback and hope that you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences.