initialize method
Future<void>
initialize({
- HandMode mode = HandMode.boxesAndLandmarks,
- HandLandmarkModel landmarkModel = HandLandmarkModel.full,
- double detectorConf = 0.45,
- double palmNmsIou = 0.45,
- double palmRoiScale = 2.6,
- int maxDetections = 10,
- double minLandmarkScore = 0.5,
- bool enableTracking = false,
- TrackingConfig trackingConfig = const TrackingConfig(),
- int interpreterPoolSize = 1,
- PerformanceConfig performanceConfig = const PerformanceConfig(),
- bool enableGestures = false,
- double gestureMinConfidence = 0.5,
- bool useCompiledModel = false,
- String liteRtAccelerator = 'auto',
- Set<
Accelerator> accelerators = const {Accelerator.gpu, Accelerator.cpu}, - Precision precision = Precision.fp16,
Initializes the hand detector by loading TensorFlow Lite models.
Must be called before detect or detectFromMat. Calling initialize twice without dispose throws StateError.
Parameters:
mode: Detection mode (boxes only or boxes + landmarks). Default: HandMode.boxesAndLandmarkslandmarkModel: Hand landmark model variant. Default: HandLandmarkModel.fulldetectorConf: Palm detection confidence threshold (0.0-1.0). Default: 0.45palmNmsIou: IoU threshold for palm non-maximum suppression (0.0-1.0). Higher keeps more overlapping detections; lower merges them harder. Default: 0.45palmRoiScale: Expansion factor for the palm ROI fed to the landmark model. Larger includes more context around the palm. Default: 2.6maxDetections: Maximum number of hands to detect. Default: 10minLandmarkScore: Minimum landmark confidence score (0.0-1.0). Default: 0.5interpreterPoolSize: Number of landmark model interpreter instances (1-10). Default: 1. Forced to 1 when a performance delegate (XNNPACK/auto) is enabled.performanceConfig: TensorFlow Lite performance configuration. Default: auto (optimal per platform)enableGestures: Whether to run gesture recognition. Default: falsegestureMinConfidence: Minimum confidence for gesture recognition (0.0-1.0). Default: 0.5useCompiledModel: Use the LiteRT NextCompiledModelengine (GPU with CPU fallback) instead of the classic Interpreter engine. Default: false. When enabled, the landmark model runs on a pool ofinterpreterPoolSizeCompiledModel instances (default 1) — one model per concurrently-detected hand, each with its own input buffer.enableTracking: Enable MediaPipe-style detection + tracking. When true, each detected hand is followed frame-to-frame via a landmark-derived region of interest, and the palm detector only runs to find new hands. This greatly reduces overlay drop-outs on video. Call resetTracking between unrelated inputs. Default: false (palm detection every frame).trackingConfig: Tuning for the ROI carried between frames whenenableTrackingis true (expansion, shift, association IoU, size bounds). Ignored when tracking is off. Default: TrackingConfig (MediaPipe values).
Implementation
Future<void> initialize({
HandMode mode = HandMode.boxesAndLandmarks,
HandLandmarkModel landmarkModel = HandLandmarkModel.full,
double detectorConf = 0.45,
double palmNmsIou = 0.45,
double palmRoiScale = 2.6,
int maxDetections = 10,
double minLandmarkScore = 0.5,
bool enableTracking = false,
TrackingConfig trackingConfig = const TrackingConfig(),
int interpreterPoolSize = 1,
PerformanceConfig performanceConfig = const PerformanceConfig(),
bool enableGestures = false,
double gestureMinConfidence = 0.5,
bool useCompiledModel = false,
// Web-only (LiteRT.js accelerator); accepted for cross-platform API parity
// and ignored on native, which selects its engine via useCompiledModel.
String liteRtAccelerator = 'auto',
Set<Accelerator> accelerators = const {Accelerator.gpu, Accelerator.cpu},
Precision precision = Precision.fp16,
}) async {
if (isReady) {
throw StateError('HandDetector already initialized');
}
const palmPath =
'packages/hand_detection/assets/models/hand_detection.tflite';
const landmarkPath =
'packages/hand_detection/assets/models/hand_landmark_full.tflite';
final assetFutures = <Future<ByteData>>[
rootBundle.load(palmPath),
rootBundle.load(landmarkPath),
];
if (enableGestures) {
const embedderPath =
'packages/hand_detection/assets/models/gesture_embedder.tflite';
const classifierPath =
'packages/hand_detection/assets/models/canned_gesture_classifier.tflite';
assetFutures.add(rootBundle.load(embedderPath));
assetFutures.add(rootBundle.load(classifierPath));
}
final results = await Future.wait(assetFutures);
final palmBytes = results[0].buffer.asUint8List();
final landmarkBytes = results[1].buffer.asUint8List();
Uint8List? gestureEmbedderBytes;
Uint8List? gestureClassifierBytes;
if (enableGestures && results.length > 2) {
gestureEmbedderBytes = results[2].buffer.asUint8List();
gestureClassifierBytes = results[3].buffer.asUint8List();
}
final effectivePoolSize = performanceConfig.mode == PerformanceMode.disabled
? interpreterPoolSize
: 1;
await initializeFromBuffers(
palmDetectionBytes: palmBytes,
handLandmarkBytes: landmarkBytes,
gestureEmbedderBytes: gestureEmbedderBytes,
gestureClassifierBytes: gestureClassifierBytes,
mode: mode,
landmarkModel: landmarkModel,
detectorConf: detectorConf,
palmNmsIou: palmNmsIou,
palmRoiScale: palmRoiScale,
maxDetections: maxDetections,
minLandmarkScore: minLandmarkScore,
enableTracking: enableTracking,
trackingConfig: trackingConfig,
interpreterPoolSize: effectivePoolSize,
performanceConfig: performanceConfig,
enableGestures: enableGestures,
gestureMinConfidence: gestureMinConfidence,
useCompiledModel: useCompiledModel,
accelerators: accelerators,
precision: precision,
);
}