Reputation: 9
I am facing bug in flutter face dectection and recognition app where the it provide registerd face for new face which have no existing image but it match with other images.... while i am picking image from gallery for recognizing how to resolve these issue while i am get embedding okay but may something wrong with threshold setting or embedding normalization.
List<int> _getEmbedding(Uint8List faceImageBytes) {
final faceImage = img.decodeImage(faceImageBytes);
if (faceImage == null) {
log("Error decoding face image");
return [];
}
// Preprocess the image to create a 4D input tensor.
List<List<List<List<int>>>> input = _preprocessImage(faceImage)
.map((e) => e
.map((e) => e.map((e) => e.map((e) => e.toInt()).toList()).toList())
.toList())
.toList();
// Get the output tensor shape from the interpreter.
var outputShape = _interpreter.getOutputTensor(0).shape; // e.g. [1, 512]
int outputLength = outputShape.reduce((a, b) => a * b);
// Create the output container with the correct shape.
var output = List.filled(outputLength, 0.0).reshape(outputShape);
// Run inference.
_interpreter.run(input, output);
// Return the first (and only) row of the output.
return List<int>.from(output[0]);
}
/// Recognize the provided face by comparing its embedding to registered faces.
void recognizeFace() {
if (embedding.isEmpty) {
Get.snackbar("Error", "No face embedding computed.");
return;
}
if (registeredFacesData.isEmpty) {
Get.snackbar("Error", "No registered face data available.");
return;
}
// double minDistance = 1.0;
double minDistance = double.infinity;
RegisteredFace? bestMatch;
for (var face in registeredFacesData) {
double distance = euclideanDistance(face.embedding, embedding);
if (distance < minDistance) {
minDistance = distance;
bestMatch = face;
}
}
// double threshold = 0.3; // Stricter threshold for accurate matching
double threshold = 1.1;
if (minDistance < threshold && bestMatch != null) {
matchedRegisteredImageUrl.value = bestMatch.imageUrl;
matchDistance.value = minDistance;
Get.to(() => FaceRecognitionView());
} else {
matchedRegisteredImageUrl.value = "assets/no_match.png";
matchDistance.value = minDistance;
Get.snackbar(
"No Match",
"No matching face found (min distance: ${minDistance.toStringAsFixed(2)}).",
);
}
}
double euclideanDistance(List<double> emb1, List<double> emb2) {
if (emb1.length != emb2.length) {
throw ArgumentError('Embedding vectors must be of the same length');
}
double sum = 0.0;
for (int i = 0; i < emb1.length; i++) {
sum += math.pow(emb1[i] - emb2[i], 2);
}
return math.sqrt(sum);
}
List<double> _normalize(List<double> embedding) {
double magnitude = math.sqrt(embedding.fold(0, (sum, e) => sum + e * e));
return magnitude == 0
? embedding
: embedding.map((e) => e / magnitude).toList();
}
I am fixing the face recognition error it gives well result for faces which have existing face in backend while it also give a face image for unregistered face when I recognize it. but with some pics it also give sometime wrong face for as its existing face is available.
Upvotes: 0
Views: 21