From 9f5c5fde4938eb019382bcd18cfb5cdf16c6a970 Mon Sep 17 00:00:00 2001 From: laurenspriem Date: Tue, 30 Apr 2024 10:59:45 +0530 Subject: [PATCH] [mob][photos] Parallelize the cropping and encoding of faces --- mobile/lib/utils/image_ml_util.dart | 51 ++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/mobile/lib/utils/image_ml_util.dart b/mobile/lib/utils/image_ml_util.dart index 5d479d1519..f16d59f035 100644 --- a/mobile/lib/utils/image_ml_util.dart +++ b/mobile/lib/utils/image_ml_util.dart @@ -1133,8 +1133,11 @@ Future<(Float32List, List, List, List, Size)> alignedImageIndex += 3 * width * height; final grayscalems = blurDetectionStopwatch.elapsedMilliseconds; log('creating grayscale matrix took $grayscalems ms'); - final (isBlur, blurValue) = await BlurDetectionService.instance - .predictIsBlurGrayLaplacian(faceGrayMatrix, faceDirection: face.getFaceDirection()); + final (isBlur, blurValue) = + await BlurDetectionService.instance.predictIsBlurGrayLaplacian( + faceGrayMatrix, + faceDirection: face.getFaceDirection(), + ); final blurms = blurDetectionStopwatch.elapsedMilliseconds - grayscalems; log('blur detection took $blurms ms'); log( @@ -1283,8 +1286,7 @@ Future> generateFaceThumbnailsUsingCanvas( int i = 0; try { - final List faceThumbnails = []; - + final futureFaceThumbnails = >[]; for (final faceBox in faceBoxes) { // Note that the faceBox values are relative to the image size, so we need to convert them to absolute values first final double xMinAbs = faceBox.xMin * img.width; @@ -1292,20 +1294,19 @@ Future> generateFaceThumbnailsUsingCanvas( final double widthAbs = faceBox.width * img.width; final double heightAbs = faceBox.height * img.height; - final Image faceThumbnail = await cropImageWithCanvas( - img, - x: xMinAbs - widthAbs / 2, - y: yMinAbs - heightAbs / 2, - width: widthAbs * 2, - height: heightAbs * 2, + futureFaceThumbnails.add( + cropAndEncodeCanvas( + img, + x: xMinAbs - widthAbs / 2, + y: yMinAbs - heightAbs / 2, + width: widthAbs * 2, + height: heightAbs * 2, + ), ); - final Uint8List faceThumbnailPng = await encodeImageToUint8List( - faceThumbnail, - format: ImageByteFormat.png, - ); - faceThumbnails.add(faceThumbnailPng); i++; } + final List faceThumbnails = + await Future.wait(futureFaceThumbnails); return faceThumbnails; } catch (e) { log('[ImageMlUtils] Error generating face thumbnails: $e'); @@ -1314,6 +1315,26 @@ Future> generateFaceThumbnailsUsingCanvas( } } +Future cropAndEncodeCanvas( + Image image, { + required double x, + required double y, + required double width, + required double height, +}) async { + final croppedImage = await cropImageWithCanvas( + image, + x: x, + y: y, + width: width, + height: height, + ); + return await encodeImageToUint8List( + croppedImage, + format: ImageByteFormat.png, + ); +} + @Deprecated('For second pass of BlazeFace, no longer used') /// Generates cropped and padded image data from [imageData] and a [faceBox].