call method
Predicts iris and eye contour landmarks from a cv.Mat eye crop.
Accepts a cv.Mat directly, providing better performance by avoiding image format conversions.
The eyeCrop parameter should contain a tight crop around a single eye as cv.Mat.
The Mat is NOT disposed by this method - caller is responsible for disposal.
The optional buffer parameter allows reusing a pre-allocated Float32List
for the tensor conversion to reduce GC pressure.
Returns a list of 3D landmark points in normalized coordinates.
Example:
final eyeCropMat = cv.imdecode(bytes, cv.IMREAD_COLOR);
final irisPoints = await irisLandmark.call(eyeCropMat);
eyeCropMat.dispose();
Implementation
Future<List<List<double>>> call(cv.Mat eyeCrop, {Float32List? buffer}) async {
final CompiledModel? compiledModel = _compiledModel;
if (compiledModel != null) {
// Copying runAsync is the official LiteRT pattern for host-side data
// (the C++ Write/Read API is lock+memcpy+unlock); the Metal accelerator
// only supports MetalBufferPacked tensor buffers, so host zero-copy is
// not available on the GPU path.
final ImageTensor pack = convertImageToTensor(
eyeCrop,
outW: _inW,
outH: _inH,
buffer: buffer ?? _scratchBuf,
);
final List<Float32List> outputs = await compiledModel.runAsync([
pack.tensorNHWC,
]);
final List<List<double>> lm = <List<double>>[];
for (final Float32List flat in outputs) {
lm.addAll(
_unpackLandmarks(flat, _inW, _inH, pack.padding, clamp: false),
);
}
return lm;
}
final ImageTensor pack = convertImageToTensor(
eyeCrop,
outW: _inW,
outH: _inH,
buffer: buffer ?? _scratchBuf,
);
return _inferAndUnpack(pack);
}