FlutterWithMediaPipe icon indicating copy to clipboard operation
FlutterWithMediaPipe copied to clipboard

FaceDetector stuck if multiple faces present

Open Pasmikh opened this issue 4 years ago • 0 comments

Thank you for this repository! Face Detector works fine when there is one face present, but when there are 2 or more Non maximum supression algorithm gets stuck in infinite while loop. It doesn't filter out non-intersecting boxes properly. I have slightly modified your code in non_maximum_supression.dart to

var picks = <int>[];
  while (I.isNotEmpty) {
    var ind0 = positions.sublist(positions.length - 1, positions.length);
    var ind1 = positions.sublist(0, positions.length - 1);

    var xx1 = _maximum(_itemIndex(_x1, ind0)[0], _itemIndex(_x1, ind1));
    var yy1 = _maximum(_itemIndex(_y1, ind0)[0], _itemIndex(_y1, ind1));
    var xx2 = _minimum(_itemIndex(_x2, ind0)[0], _itemIndex(_x2, ind1));
    var yy2 = _minimum(_itemIndex(_y2, ind0)[0], _itemIndex(_y2, ind1));
    var w = _maximum(0.0, xx2 - xx1);
    var h = _maximum(0.0, yy2 - yy1);
    var inter = w * h;
    var o = inter /
        (_sum(_itemIndex(area, ind0)[0], _itemIndex(area, ind1)) - inter);

    picks.add(ind0[0]);

    List<double> newI = [];
    List<int> newPositions = [];
    o.asMap().forEach((key, value) {
      if (value <= threshold) {
        newI.add(I[key]);
        newPositions.add(positions[key]);
      }
    });

    I = newI;
    positions = newPositions;
  }

  List<Detection> results = [];

  for (var pick in picks) {
    results.add(detections[pick]);
  }
  return results;

and also in face_detection_service.dart


    for (var detection in detections) {
      Rect? bbox;
      final score = detection.score;
      if (score > threshold) {
        bbox = Rect.fromLTRB(
          inputImage.width * detection.xMin,
          inputImage.height * detection.yMin,
          inputImage.width * detection.width,
          inputImage.height * detection.height,
        );

        bbox = _imageProcessor.inverseTransformRect(
            bbox, image.height, image.width);
      }
      rectFaces.add({'bbox': bbox, 'score': score});
    }
    rectFaces.sort((a, b) => b['score'].compareTo(a['score']));

    return rectFaces;

It detects and returns multiple boxes for each face present. I hope it helps, thanks again for this project.

Pasmikh avatar Dec 02 '21 14:12 Pasmikh