NiiLx
NiiLx

Reputation: 676

Detect face and crop face image flutter firebase ml

Here I need to crop detected faces and save as image/file. I am able to detecting face with rounded rectangle. How to crop the area of detected face? I am using flutter_firebase_ml_kit to detect faces. Here is my code:

getImageAndDetectFaces() async {
    setState(() {
      isLoading = true;
    });
    final image = FirebaseVisionImage.fromFile(widget.cardImage);
    final faceDetector = FirebaseVision.instance.faceDetector(
        FaceDetectorOptions(
            mode: FaceDetectorMode.fast,
            enableLandmarks: true
        )
    );
    List<Face> faces = await faceDetector.processImage(image);
    if (mounted) {
      setState(() {
        _faces = faces;
        _loadImage(widget.cardImage);
      });
    }
  }

  _loadImage(File file) async {
    final data = await file.readAsBytes();
    await decodeImageFromList(data).then(
          (value) => setState(() {
        img = value;
        isLoading = false;
      }),
    );
  }


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.blue;

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

}

Need solution on how to crop the detected face area. Thanks in advance.

Upvotes: 3

Views: 3693

Answers (2)

StuckInPhDNoMore
StuckInPhDNoMore

Reputation: 2679

After running the faceDetector using List<Face> faces = await faceDetector.processImage(image); you need to extract the information from each detected face. Since we are only interested in the bounding boxes you can use something like:

List<Map<String, int>> faceMaps = [];
for (Face face in faces) {
      int x = face.boundingBox.left.toInt();
      int y = face.boundingBox.top.toInt();
      int w = face.boundingBox.width.toInt();
      int h = face.boundingBox.height.toInt();
      Map<String, int> thisMap = {'x': x, 'y': y, 'w': w, 'h':h};
      faceMaps.add(thisMap);
    }

The above will create a list of Map<String, int> and then this is populated with the bounding box information of each detected face.

You can then use the copyCrop function of the Image package to extract the face from the bounding box

// add dart package as
import 'package:image/image.dart' as img;
// create an img.Image from your original image file for processing
img.Image originalImage = img.decodeImage(File(_imageFile.path).readAsBytesSync());
// now crop out only the detected face boundry, below will crop out the first face from the list
img.Image faceCrop = img.copyCrop(originalImage, faceMaps[0]['x'], faceMaps[0]['y'], faceMaps[0]['w'], faceMaps[0]['h']);

Upvotes: 5

Shiyu
Shiyu

Reputation: 935

Once you have the bounding box, you should be able to crop the face with it. Not familiar with flutter, but here is some discussion about the image cropping with Dart: How do I crop an image in Flutter?

Upvotes: 2

Related Questions