getFaceEmbeddings method
Generates face embeddings for multiple detected faces.
More efficient than calling getFaceEmbedding multiple times because it decodes the image only once in the isolate.
Returns a list of Float32List embeddings in the same order as faces.
Faces that fail to produce embeddings will have null entries.
Implementation
Future<List<Float32List?>> getFaceEmbeddings(
List<Face> faces,
Uint8List imageBytes,
) async {
_requireReady();
// Four doubles per face. A face whose eye landmarks are unavailable is
// marked with a NaN quad and comes back as a null entry, matching the
// previous behavior where the per-face failure happened in the isolate.
final Float64List eyes = Float64List(faces.length * 4);
for (int i = 0; i < faces.length; i++) {
try {
eyes.setRange(i * 4, i * 4 + 4, _embeddingEyesPayload(faces[i]));
} catch (_) {
// Preserve the old per-face failure contract: one malformed face must
// not abort embeddings for every other face in the batch.
eyes[i * 4] = double.nan;
eyes[i * 4 + 1] = double.nan;
eyes[i * 4 + 2] = double.nan;
eyes[i * 4 + 3] = double.nan;
}
}
final List<dynamic> result = await _sendDetectionRequest<List<dynamic>>(
'embeddings',
{
'bytes': TransferableTypedData.fromList([imageBytes]),
'eyes': eyes,
},
);
return result.map((dynamic item) => item as Float32List?).toList();
}