processCameraImage method
Future<Face?>
processCameraImage(})
stabilityCount Number of continuous steady shots required.
eyeOpenProbability Probability of eyes being open.
Implementation
Future<Face?> processCameraImage(
InputImage inputImage, {
required Size screenSize,
required Size regionSize,
int stabilityCount = 10,
double eyeOpenProbability = 0.75,
Function(FaceStatus)? onFaceLiveStatusChange,
}) async {
final List<Face> faces = await _faceDetector.processImage(inputImage);
if (faces.isNotEmpty && faces.length == 1) {
Face face = faces.first;
/// Complete organ and part check.
bool isLandmarks = _checkLandmarks(face);
var isFaceRegionInside = _isFaceRegionInside(
boundingBox: face.boundingBox,
screenSize: screenSize,
cameraSize: inputImage.metadata!.size,
regionSize: regionSize);
if (isLandmarks && isFaceRegionInside) {
_tempFaces.add(face);
if (_tempFaces.length > stabilityCount) {
// Detect Smile
if (!_isSmilePassed) {
onFaceLiveStatusChange?.call(FaceStatus.smile);
bool isSmiling = (face.smilingProbability ?? 0.0) > 0.8;
if (isSmiling) {
_isSmilePassed = true;
} else {
return null;
}
}
// A blink is defined as closing and reopening the eyes within 2 seconds.
bool eyesOpen = (face.leftEyeOpenProbability ?? 0.0) > 0.75 &&
(face.rightEyeOpenProbability ?? 0.0) > 0.75;
bool eyesClosed = (face.leftEyeOpenProbability ?? 1.0) < 0.25 &&
(face.rightEyeOpenProbability ?? 1.0) < 0.25;
onFaceLiveStatusChange?.call(FaceStatus.blink);
if (_handleBlinkState(eyesOpen, eyesClosed)) {
_faceDetector.close();
_tempFaces.clear();
onFaceLiveStatusChange?.call(FaceStatus.finish);
return face;
}
}
} else {
/// Not in the frame, need restart the process
_resetAllStates();
onFaceLiveStatusChange?.call(FaceStatus.outside);
}
} else {
_tempFaces.clear();
onFaceLiveStatusChange?.call(FaceStatus.outside);
}
return null;
}