Use full file on face detection
This commit is contained in:
parent
f0ad363895
commit
74d1cbb01f
5 changed files with 30 additions and 21 deletions
|
@ -1,6 +1,5 @@
|
|||
import 'dart:async';
|
||||
import "dart:math";
|
||||
import "dart:typed_data";
|
||||
|
||||
import "package:collection/collection.dart";
|
||||
import "package:flutter/foundation.dart";
|
||||
|
@ -335,7 +334,7 @@ class FaceMLDataDB {
|
|||
///
|
||||
/// Only selects faces with score greater than [minScore] and blur score greater than [minClarity]
|
||||
Future<Map<String, (int?, Uint8List)>> getFaceEmbeddingMap({
|
||||
double minScore = 0.8,
|
||||
double minScore = 0.78,
|
||||
int minClarity = kLaplacianThreshold,
|
||||
int maxRows = 20000,
|
||||
}) async {
|
||||
|
|
|
@ -34,7 +34,7 @@ class YoloOnnxFaceDetection {
|
|||
static const kInputWidth = 640;
|
||||
static const kInputHeight = 640;
|
||||
static const kIouThreshold = 0.4;
|
||||
static const kMinScoreSigmoidThreshold = 0.8;
|
||||
static const kMinScoreSigmoidThreshold = 0.7;
|
||||
|
||||
bool isInitialized = false;
|
||||
|
||||
|
@ -373,6 +373,10 @@ class YoloOnnxFaceDetection {
|
|||
|
||||
final relativeDetections = _yoloPostProcessOutputs(outputs, newSize);
|
||||
|
||||
dev.log(
|
||||
'${relativeDetections.length} faces detected, with scores ${relativeDetections.map((e) => e.score).toList()}',
|
||||
);
|
||||
|
||||
stopwatch.stop();
|
||||
_logger.info(
|
||||
'predict() face detection executed in ${stopwatch.elapsedMilliseconds}ms',
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:developer' as dev show log;
|
||||
|
||||
import "package:photos/services/face_ml/face_detection/detection.dart";
|
||||
|
||||
List<FaceDetectionRelative> yoloOnnxFilterExtractDetections(
|
||||
|
@ -23,6 +25,18 @@ List<FaceDetectionRelative> yoloOnnxFilterExtractDetections(
|
|||
output.add(rawDetection);
|
||||
}
|
||||
|
||||
if (output.isEmpty) {
|
||||
double maxScore = 0;
|
||||
for (final result in results) {
|
||||
if (result[4] > maxScore) {
|
||||
maxScore = result[4];
|
||||
}
|
||||
}
|
||||
dev.log(
|
||||
'No face detections found above the minScoreSigmoidThreshold of $minScoreSigmoidThreshold. The max score was $maxScore.',
|
||||
);
|
||||
}
|
||||
|
||||
for (final List<double> rawDetection in output) {
|
||||
// Get absolute bounding box coordinates in format [xMin, yMin, xMax, yMax] https://github.com/deepcam-cn/yolov5-face/blob/eb23d18defe4a76cc06449a61cd51004c59d2697/utils/general.py#L216
|
||||
final xMinAbs = rawDetection[0] - rawDetection[2] / 2;
|
||||
|
|
|
@ -195,8 +195,7 @@ class FaceMlService {
|
|||
switch (function) {
|
||||
case FaceMlOperation.analyzeImage:
|
||||
final int enteFileID = args["enteFileID"] as int;
|
||||
final String smallDataPath = args["smallDataPath"] as String;
|
||||
final String largeDataPath = args["largeDataPath"] as String;
|
||||
final String imagePath = args["filePath"] as String;
|
||||
final int faceDetectionAddress =
|
||||
args["faceDetectionAddress"] as int;
|
||||
final int faceEmbeddingAddress =
|
||||
|
@ -214,13 +213,13 @@ class FaceMlService {
|
|||
// Get the faces
|
||||
final List<FaceDetectionRelative> faceDetectionResult =
|
||||
await FaceMlService.detectFacesSync(
|
||||
smallDataPath,
|
||||
imagePath,
|
||||
faceDetectionAddress,
|
||||
resultBuilder: resultBuilder,
|
||||
);
|
||||
|
||||
dev.log(
|
||||
"${faceDetectionResult.length} faces detected: completed `detectFaces` function, in "
|
||||
"${faceDetectionResult.length} faces detected: completed `detectFacesSync` function, in "
|
||||
"${stopwatch.elapsedMilliseconds} ms");
|
||||
|
||||
// If no faces were detected, return a result with no faces. Otherwise, continue.
|
||||
|
@ -236,7 +235,7 @@ class FaceMlService {
|
|||
// Align the faces
|
||||
final Float32List faceAlignmentResult =
|
||||
await FaceMlService.alignFacesSync(
|
||||
largeDataPath,
|
||||
imagePath,
|
||||
faceDetectionResult,
|
||||
resultBuilder: resultBuilder,
|
||||
);
|
||||
|
@ -478,7 +477,9 @@ class FaceMlService {
|
|||
}
|
||||
final List<Face> faces = [];
|
||||
if (!result.hasFaces) {
|
||||
debugPrint('No faces detected for file with name:${enteFile.displayName}');
|
||||
debugPrint(
|
||||
'No faces detected for file with name:${enteFile.displayName}',
|
||||
);
|
||||
faces.add(
|
||||
Face(
|
||||
'${result.fileId}-0',
|
||||
|
@ -721,23 +722,16 @@ class FaceMlService {
|
|||
_checkEnteFileForID(enteFile);
|
||||
await ensureInitialized();
|
||||
|
||||
final String? thumbnailPath = await _getImagePathForML(
|
||||
enteFile,
|
||||
typeOfData: FileDataForML.thumbnailData,
|
||||
);
|
||||
final String? filePath =
|
||||
await _getImagePathForML(enteFile, typeOfData: FileDataForML.fileData);
|
||||
|
||||
if (thumbnailPath == null && filePath == null) {
|
||||
if (filePath == null) {
|
||||
_logger.severe(
|
||||
"Failed to get any data for enteFile with uploadedFileID ${enteFile.uploadedFileID}",
|
||||
);
|
||||
throw CouldNotRetrieveAnyFileData();
|
||||
}
|
||||
|
||||
final String smallDataPath = thumbnailPath ?? filePath!;
|
||||
final String largeDataPath = filePath ?? thumbnailPath!;
|
||||
|
||||
final Stopwatch stopwatch = Stopwatch()..start();
|
||||
late FaceMlResult result;
|
||||
|
||||
|
@ -747,8 +741,7 @@ class FaceMlService {
|
|||
FaceMlOperation.analyzeImage,
|
||||
{
|
||||
"enteFileID": enteFile.uploadedFileID ?? -1,
|
||||
"smallDataPath": smallDataPath,
|
||||
"largeDataPath": largeDataPath,
|
||||
"filePath": filePath,
|
||||
"faceDetectionAddress":
|
||||
YoloOnnxFaceDetection.instance.sessionAddress,
|
||||
"faceEmbeddingAddress": FaceEmbeddingOnnx.instance.sessionAddress,
|
||||
|
|
|
@ -658,8 +658,7 @@ Future<(Num3DInputMatrix, Size, Size)> preprocessImageToMatrix(
|
|||
return (imageMatrix, originalSize, newSize);
|
||||
}
|
||||
|
||||
Future<(Float32List, Size, Size)>
|
||||
preprocessImageToFloat32ChannelsFirst(
|
||||
Future<(Float32List, Size, Size)> preprocessImageToFloat32ChannelsFirst(
|
||||
Uint8List imageData, {
|
||||
required int normalization,
|
||||
required int requiredWidth,
|
||||
|
|
Loading…
Add table
Reference in a new issue