# Luxand FaceSDK 8.3 Luxand FaceSDK is a cross-platform face detection and recognition library designed for easy integration into applications across Windows, Linux, macOS, iOS, and Android. The SDK provides comprehensive APIs for detecting and tracking faces, recognizing facial features (70 points including eyes, eyebrows, mouth, nose, and face contours), identifying gender, age, and facial expressions, and performing face matching for identity verification. FaceSDK supports both still images and live video streams, with specialized Tracker API for real-time face recognition and tracking in video applications. The library offers multiple detection capabilities including standard RGB face detection, thermal image face detection, and advanced liveness detection (both passive and active) to prevent spoofing attacks. With multi-core processing support and optimized performance (up to 649 FPS for real-time detection), FaceSDK is suitable for access control systems, surveillance applications, identity verification, and user authentication scenarios. The SDK includes wrappers for C/C++, .NET (C#, VB), Java, Python, Delphi, Flutter, React Native, and WebAssembly. ## FSDK_ActivateLibrary Activates the FaceSDK library with a license key. This function must be called before using any other FaceSDK functions, otherwise all API calls will return `FSDKE_NOT_ACTIVATED`. License keys can be requested from Luxand for evaluation or obtained through purchase. ```cpp // C++ - Activate the library before any face detection operations #include "LuxandFaceSDK.h" int main() { // Activate with your license key (required before initialization) int result = FSDK_ActivateLibrary("YOUR_LICENSE_KEY_HERE"); if (result != FSDKE_OK) { printf("Activation failed with error code: %d\n", result); return 1; } // Initialize the library result = FSDK_Initialize(""); if (result != FSDKE_OK) { printf("Initialization failed\n"); return 1; } // Get license information char licenseInfo[256]; FSDK_GetLicenseInfo(licenseInfo); printf("Licensed to: %s\n", licenseInfo); // Your face detection code here... FSDK_Finalize(); return 0; } ``` ```python # Python - Library activation and initialization from fsdk import FSDK # Activate and initialize FSDK.ActivateLibrary("YOUR_LICENSE_KEY_HERE") FSDK.Initialize() # Get license info license_info = FSDK.GetLicenseInfo() print(f"Licensed to: {license_info}") # Your face detection code here... FSDK.Finalize() ``` ## FSDK_LoadImageFromFile Loads an image from a file (JPG, PNG, or BMP format) and returns an internal handle for use with other FaceSDK functions. The handle must be freed with `FSDK_FreeImage` when no longer needed to prevent memory leaks. ```cpp // C++ - Load image and get dimensions #include "LuxandFaceSDK.h" int main() { FSDK_ActivateLibrary("YOUR_LICENSE_KEY"); FSDK_Initialize(""); HImage image; int result = FSDK_LoadImageFromFile(&image, "photo.jpg"); if (result == FSDKE_OK) { int width, height; FSDK_GetImageWidth(image, &width); FSDK_GetImageHeight(image, &height); printf("Image loaded: %dx%d pixels\n", width, height); // Process image... FSDK_FreeImage(image); // Always free when done } else if (result == FSDKE_FILE_NOT_FOUND) { printf("File not found\n"); } else if (result == FSDKE_UNSUPPORTED_IMAGE_EXTENSION) { printf("Unsupported image format\n"); } FSDK_Finalize(); return 0; } ``` ```python # Python - Load and manipulate images from fsdk import FSDK FSDK.ActivateLibrary("YOUR_LICENSE_KEY") FSDK.Initialize() # Load image using constructor image = FSDK.Image("photo.jpg") print(f"Loaded image: {image.width}x{image.height}") # Alternative static method image2 = FSDK.Image.FromFile("another_photo.png") # Resize and save resized = image.Resize(0.5) # 50% of original size resized.SaveToFile("resized_photo.jpg", quality=85) # Copy rectangular region cropped = image.CopyRect(100, 100, 300, 300) # Rotate image rotated = image.Rotate(45.0) # 45 degrees # Free images (automatic in Python, but can be explicit) image.Free() FSDK.Finalize() ``` ## FSDK_DetectFace Detects a single frontal face in an image and returns its position (center coordinates, width, and rotation angle). For detecting multiple faces, use `FSDK_DetectMultipleFaces` instead. Returns `FSDKE_FACE_NOT_FOUND` if no face is detected. ```cpp // C++ - Detect a single face in an image #include "LuxandFaceSDK.h" int main() { FSDK_ActivateLibrary("YOUR_LICENSE_KEY"); FSDK_Initialize(""); // Configure face detection for digital camera photos FSDK_SetFaceDetectionParameters( true, // HandleArbitraryRotations: support -30..30 degrees true, // DetermineFaceRotationAngle: detect rotation 500 // InternalResizeWidth: higher = better quality, slower ); HImage image; FSDK_LoadImageFromFile(&image, "portrait.jpg"); TFacePosition facePos; int result = FSDK_DetectFace(image, &facePos); if (result == FSDKE_OK) { printf("Face detected at center (%d, %d)\n", facePos.xc, facePos.yc); printf("Face width: %d pixels\n", facePos.w); printf("Rotation angle: %.2f degrees\n", facePos.angle); // Calculate bounding box int left = facePos.xc - facePos.w / 2; int top = facePos.yc - facePos.w / 2; int right = facePos.xc + facePos.w / 2; int bottom = facePos.yc + facePos.w / 2; printf("Bounding box: (%d,%d) to (%d,%d)\n", left, top, right, bottom); } else if (result == FSDKE_FACE_NOT_FOUND) { printf("No face detected in image\n"); } FSDK_FreeImage(image); FSDK_Finalize(); return 0; } ``` ```python # Python - Face detection with error handling from fsdk import FSDK FSDK.ActivateLibrary("YOUR_LICENSE_KEY") FSDK.Initialize() # Set detection parameters for webcam (fast detection) FSDK.SetFaceDetectionParameters( handleArbitraryRotations=False, # -15..15 degrees only determineFaceRotationAngle=False, internalResizeWidth=100 ) image = FSDK.Image("selfie.jpg") try: face_pos = image.DetectFace() print(f"Face center: ({face_pos.xc}, {face_pos.yc})") print(f"Face width: {face_pos.w}") print(f"Rotation: {face_pos.angle:.1f} degrees") # Get bounding rectangle as tuple (x1, y1, x2, y2) rect = face_pos.rect print(f"Bounding box: {rect}") except FSDK.FaceNotFound: print("No face found in image") except FSDK.ImageTooSmall: print("Image is too small (minimum 20x20 pixels)") FSDK.Finalize() ``` ## FSDK_DetectMultipleFaces Detects all visible faces in an image and returns an array of face positions. This is essential for group photos or surveillance scenarios where multiple people may be present simultaneously. ```cpp // C++ - Detect multiple faces in a group photo #include "LuxandFaceSDK.h" int main() { FSDK_ActivateLibrary("YOUR_LICENSE_KEY"); FSDK_Initialize(""); // Configure for reliable detection in digital photos FSDK_SetFaceDetectionParameters(true, true, 512); FSDK_SetFaceDetectionThreshold(3); // Lower = more sensitive HImage image; FSDK_LoadImageFromFile(&image, "group_photo.jpg"); TFacePosition faces[100]; // Array to hold detected faces int faceCount; int result = FSDK_DetectMultipleFaces( image, &faceCount, faces, sizeof(faces) // MaxSizeInBytes ); if (result == FSDKE_OK) { printf("Detected %d faces:\n", faceCount); for (int i = 0; i < faceCount; i++) { printf(" Face %d: center=(%d,%d), width=%d, angle=%.1f\n", i + 1, faces[i].xc, faces[i].yc, faces[i].w, faces[i].angle); } } else if (result == FSDKE_FACE_NOT_FOUND) { printf("No faces detected\n"); } FSDK_FreeImage(image); FSDK_Finalize(); return 0; } ``` ```python # Python - Process multiple faces in an image from fsdk import FSDK FSDK.ActivateLibrary("YOUR_LICENSE_KEY") FSDK.Initialize() FSDK.SetFaceDetectionParameters(True, True, 512) FSDK.SetFaceDetectionThreshold(3) image = FSDK.Image("crowd.jpg") faces = image.DetectMultipleFaces() print(f"Found {len(faces)} faces") for i, face in enumerate(faces): print(f"Face {i+1}: center=({face.xc}, {face.yc}), " f"width={face.w}, angle={face.angle:.1f}") # Get bounding rectangle x1, y1, x2, y2 = face.rect print(f" Bounding box: ({x1}, {y1}) to ({x2}, {y2})") FSDK.Finalize() ``` ## FSDK_DetectFacialFeatures Detects 70 facial feature points including eyes, eyebrows, nose, mouth, and face contour. First detects a face, then locates all facial landmarks. Use `FSDK_DetectFacialFeaturesInRegion` when you already know the face position for better performance. ```cpp // C++ - Detect all 70 facial feature points #include "LuxandFaceSDK.h" int main() { FSDK_ActivateLibrary("YOUR_LICENSE_KEY"); FSDK_Initialize(""); HImage image; FSDK_LoadImageFromFile(&image, "face.jpg"); FSDK_Features features; // Array of 70 TPoint structures int result = FSDK_DetectFacialFeatures(image, &features); if (result == FSDKE_OK) { // Access key facial feature points printf("Left eye center: (%d, %d)\n", features[FSDKP_LEFT_EYE].x, features[FSDKP_LEFT_EYE].y); printf("Right eye center: (%d, %d)\n", features[FSDKP_RIGHT_EYE].x, features[FSDKP_RIGHT_EYE].y); printf("Nose tip: (%d, %d)\n", features[FSDKP_NOSE_TIP].x, features[FSDKP_NOSE_TIP].y); printf("Mouth left corner: (%d, %d)\n", features[FSDKP_MOUTH_LEFT_CORNER].x, features[FSDKP_MOUTH_LEFT_CORNER].y); printf("Mouth right corner: (%d, %d)\n", features[FSDKP_MOUTH_RIGHT_CORNER].x, features[FSDKP_MOUTH_RIGHT_CORNER].y); printf("Chin bottom: (%d, %d)\n", features[FSDKP_CHIN_BOTTOM].x, features[FSDKP_CHIN_BOTTOM].y); // Calculate inter-pupillary distance int ipd = abs(features[FSDKP_RIGHT_EYE].x - features[FSDKP_LEFT_EYE].x); printf("Inter-pupillary distance: %d pixels\n", ipd); } FSDK_FreeImage(image); FSDK_Finalize(); return 0; } ``` ```python # Python - Facial feature detection with confidence levels from fsdk import FSDK FSDK.ActivateLibrary("YOUR_LICENSE_KEY") FSDK.Initialize() image = FSDK.Image("portrait.jpg") # Detect facial features with confidence levels features = image.DetectFacialFeatures(confidenceLevels=True) # Access specific landmarks print(f"Left eye: {features[FSDK.FSDKP_LEFT_EYE]}") print(f"Right eye: {features[FSDK.FSDKP_RIGHT_EYE]}") print(f"Nose tip: {features[FSDK.FSDKP_NOSE_TIP]}") print(f"Mouth top: {features[FSDK.FSDKP_MOUTH_TOP]}") # Check confidence if available if hasattr(features, 'confidenceLevels'): print(f"Left eye confidence: {features.confidenceLevels[FSDK.FSDKP_LEFT_EYE]:.2f}") print(f"Right eye confidence: {features.confidenceLevels[FSDK.FSDKP_RIGHT_EYE]:.2f}") # Detect features for multiple faces faces = image.DetectMultipleFaces() for i, face in enumerate(faces): face_features = image.DetectFacialFeatures(facePosition=face) print(f"Face {i+1} left eye: {face_features[FSDK.FSDKP_LEFT_EYE]}") FSDK.Finalize() ``` ## FSDK_GetFaceTemplate and FSDK_MatchFaces Extracts a facial template (biometric signature) from an image for face matching. Templates are compact representations (1040 bytes) that can be stored and compared. Use `FSDK_MatchFaces` to compare two templates and get a similarity score (0.0 to 1.0). ```cpp // C++ - Complete face matching workflow #include "LuxandFaceSDK.h" int main() { FSDK_ActivateLibrary("YOUR_LICENSE_KEY"); FSDK_Initialize(""); // Load two images for comparison HImage image1, image2; FSDK_LoadImageFromFile(&image1, "person_enrolled.jpg"); FSDK_LoadImageFromFile(&image2, "person_probe.jpg"); // Extract templates FSDK_FaceTemplate template1, template2; if (FSDK_GetFaceTemplate(image1, &template1) != FSDKE_OK) { printf("Could not extract template from first image\n"); return 1; } if (FSDK_GetFaceTemplate(image2, &template2) != FSDKE_OK) { printf("Could not extract template from second image\n"); return 1; } // Compare faces float similarity; FSDK_MatchFaces(&template1, &template2, &similarity); printf("Similarity score: %.4f (%.2f%%)\n", similarity, similarity * 100); // Determine if same person using threshold float threshold; FSDK_GetMatchingThresholdAtFAR(0.01f, &threshold); // 1% false acceptance printf("Threshold at 1%% FAR: %.4f\n", threshold); if (similarity >= threshold) { printf("MATCH: Same person detected\n"); } else { printf("NO MATCH: Different persons\n"); } // Alternative: use FRR-based threshold float frrThreshold; FSDK_GetMatchingThresholdAtFRR(0.01f, &frrThreshold); // 1% false rejection printf("Threshold at 1%% FRR: %.4f\n", frrThreshold); FSDK_FreeImage(image1); FSDK_FreeImage(image2); FSDK_Finalize(); return 0; } ``` ```python # Python - Face verification system from fsdk import FSDK FSDK.ActivateLibrary("YOUR_LICENSE_KEY") FSDK.Initialize() # Load images enrolled_image = FSDK.Image("enrolled_user.jpg") probe_image = FSDK.Image("login_attempt.jpg") # Extract templates try: enrolled_template = enrolled_image.GetFaceTemplate() probe_template = probe_image.GetFaceTemplate() except FSDK.FaceNotFound: print("Face not found in one of the images") exit(1) # Compare faces similarity = FSDK.MatchFaces(enrolled_template, probe_template) print(f"Similarity: {similarity:.4f} ({similarity*100:.2f}%)") # Get threshold for desired security level threshold = FSDK.GetMatchingThresholdAtFAR(0.001) # 0.1% FAR (high security) print(f"Threshold (0.1% FAR): {threshold:.4f}") # Verification decision if similarity >= threshold: print("ACCESS GRANTED - Identity verified") else: print("ACCESS DENIED - Identity not verified") # For convenience-focused applications lenient_threshold = FSDK.GetMatchingThresholdAtFAR(0.05) # 5% FAR print(f"Lenient threshold (5% FAR): {lenient_threshold:.4f}") FSDK.Finalize() ``` ## FSDK_DetectFacialAttributeUsingFeatures Detects facial attributes including gender, age, and expression (smile, eyes open/closed) using detected facial features. Returns a string with attribute values and confidence levels that can be parsed with `FSDK_GetValueConfidence`. ```cpp // C++ - Complete facial attribute detection #include "LuxandFaceSDK.h" #include int main() { FSDK_ActivateLibrary("YOUR_LICENSE_KEY"); FSDK_Initialize(""); HImage image; FSDK_LoadImageFromFile(&image, "person.jpg"); // First detect facial features FSDK_Features features; if (FSDK_DetectFacialFeatures(image, &features) != FSDKE_OK) { printf("No face detected\n"); return 1; } // Detect all attributes at once char attrValues[1024]; FSDK_DetectFacialAttributeUsingFeatures( image, &features, "Gender;Age;Expression", attrValues, sizeof(attrValues) ); printf("Raw attributes: %s\n", attrValues); // Parse individual values float confMale, confFemale, age, confSmile, confEyesOpen; FSDK_GetValueConfidence(attrValues, "Male", &confMale); FSDK_GetValueConfidence(attrValues, "Female", &confFemale); FSDK_GetValueConfidence(attrValues, "Age", &age); FSDK_GetValueConfidence(attrValues, "Smile", &confSmile); FSDK_GetValueConfidence(attrValues, "EyesOpen", &confEyesOpen); // Interpret results printf("\n=== Analysis Results ===\n"); printf("Gender: %s (%.1f%% confidence)\n", confMale > confFemale ? "Male" : "Female", (confMale > confFemale ? confMale : confFemale) * 100); printf("Age: %.0f years\n", age); printf("Smiling: %s (%.1f%% confidence)\n", confSmile > 0.5 ? "Yes" : "No", confSmile * 100); printf("Eyes Open: %s (%.1f%% confidence)\n", confEyesOpen > 0.5 ? "Yes" : "No", confEyesOpen * 100); FSDK_FreeImage(image); FSDK_Finalize(); return 0; } ``` ```python # Python - Facial attribute analysis from fsdk import FSDK FSDK.ActivateLibrary("YOUR_LICENSE_KEY") FSDK.Initialize() image = FSDK.Image("photo.jpg") features = image.DetectFacialFeatures() # Get attributes as dictionary (easier to work with) attrs = image.DetectFacialAttributeUsingFeatures( features, "Gender;Age;Expression", ret_dict=True ) print("=== Facial Analysis ===") # Gender gender = "Male" if attrs["Male"] > 0.5 else "Female" confidence = attrs["Male"] if attrs["Male"] > 0.5 else attrs["Female"] print(f"Gender: {gender} ({confidence:.1%} confidence)") # Age print(f"Estimated Age: {attrs['Age']:.0f} years") # Expression print(f"Smiling: {'Yes' if attrs['Smile'] > 0.5 else 'No'} ({attrs['Smile']:.1%})") print(f"Eyes Open: {'Yes' if attrs['EyesOpen'] > 0.5 else 'No'} ({attrs['EyesOpen']:.1%})") # Process multiple faces for i, face in enumerate(image.DetectMultipleFaces()): features = image.DetectFacialFeatures(facePosition=face) attrs = image.DetectFacialAttributeUsingFeatures( features, "Gender;Age", ret_dict=True ) print(f"Face {i+1}: {'Male' if attrs['Male'] > 0.5 else 'Female'}, Age: {attrs['Age']:.0f}") FSDK.Finalize() ``` ## Passive Liveness Detection Detects whether a face is from a live person or a spoofing attempt (photo/video attack) without requiring user interaction. The liveness probability is available as the "Liveness" attribute. Works best with RGB color images. ```cpp // C++ - Passive liveness check on a single image #include "LuxandFaceSDK.h" int main() { FSDK_ActivateLibrary("YOUR_LICENSE_KEY"); FSDK_Initialize(""); HImage image; FSDK_LoadImageFromFile(&image, "login_attempt.jpg"); FSDK_Features features; if (FSDK_DetectFacialFeatures(image, &features) != FSDKE_OK) { printf("No face detected\n"); return 1; } // Get liveness attribute char attrValues[512]; FSDK_DetectFacialAttributeUsingFeatures( image, &features, "Liveness", attrValues, sizeof(attrValues) ); float liveness; FSDK_GetValueConfidence(attrValues, "Liveness", &liveness); printf("Liveness probability: %.4f (%.2f%%)\n", liveness, liveness * 100); if (liveness > 0.5) { printf("LIVE PERSON DETECTED - Proceed with authentication\n"); } else { printf("SPOOF ATTACK DETECTED - Reject authentication\n"); } FSDK_FreeImage(image); FSDK_Finalize(); return 0; } ``` ```python # Python - Liveness detection for anti-spoofing from fsdk import FSDK FSDK.ActivateLibrary("YOUR_LICENSE_KEY") FSDK.Initialize() image = FSDK.Image("verification_photo.jpg") features = image.DetectFacialFeatures() # Check liveness attrs = image.DetectFacialAttributeUsingFeatures( features, "Liveness", ret_dict=True ) liveness = attrs["Liveness"] print(f"Liveness Score: {liveness:.4f} ({liveness*100:.2f}%)") # Security decision LIVENESS_THRESHOLD = 0.5 if liveness >= LIVENESS_THRESHOLD: print("PASS: Live person detected") # Proceed with face matching/verification else: print("FAIL: Potential spoofing attack detected") print("Please try again with a live camera feed") FSDK.Finalize() ``` ## Tracker API - CreateTracker and FeedFrame The Tracker API provides real-time face tracking and recognition in video streams. It automatically assigns unique IDs to each detected face and can learn/recognize subjects over time. Use `FSDK_CreateTracker` to initialize and `FSDK_FeedFrame` to process each video frame. ```cpp // C++ - Complete Tracker API setup for video processing #include "LuxandFaceSDK.h" #include int main() { FSDK_ActivateLibrary("YOUR_LICENSE_KEY"); FSDK_Initialize(""); FSDK_InitializeCapturing(); // Create and configure tracker HTracker tracker; FSDK_CreateTracker(&tracker); int errpos; FSDK_SetTrackerMultipleParameters(tracker, "RecognizeFaces=true;" "DetectGender=true;" "DetectAge=true;" "DetectExpression=true;" "DetectLiveness=true;" "Threshold=0.992;" "MemoryLimit=2150", &errpos ); // Open camera char** cameraNames; int cameraCount; FSDK_GetCameraList(&cameraNames, &cameraCount); int camera; FSDK_OpenVideoCamera(cameraNames[0], &camera); FSDK_FreeCameraList(cameraNames, cameraCount); // Frame processing loop HImage frame; long long ids[256]; long long faceCount; for (int i = 0; i < 500; i++) { // Process 500 frames if (FSDK_GrabFrame(camera, &frame) != FSDKE_OK) continue; FSDK_FeedFrame(tracker, camera, frame, &faceCount, ids, sizeof(ids)); for (int j = 0; j < faceCount; j++) { // Get face position TFacePosition pos; FSDK_GetTrackerFacePosition(tracker, camera, ids[j], &pos); // Get name (if assigned) char name[256]; FSDK_GetAllNames(tracker, ids[j], name, sizeof(name)); // Get attributes char attrs[1024]; FSDK_GetTrackerFacialAttribute(tracker, camera, ids[j], "Gender;Age;Expression;Liveness", attrs, sizeof(attrs)); printf("ID %lld: %s at (%d,%d) - %s\n", ids[j], strlen(name) > 0 ? name : "Unknown", pos.xc, pos.yc, attrs); } FSDK_FreeImage(frame); } // Cleanup FSDK_SaveTrackerMemoryToFile(tracker, "faces.db"); FSDK_CloseVideoCamera(camera); FSDK_FreeTracker(tracker); FSDK_Finalize(); return 0; } ``` ```python # Python - Video stream face tracking from fsdk import FSDK import time FSDK.ActivateLibrary("YOUR_LICENSE_KEY") FSDK.Initialize() FSDK.InitializeCapturing() # Create tracker with recognition enabled tracker = FSDK.Tracker() tracker.SetParameters( RecognizeFaces=True, DetectGender=True, DetectAge=True, DetectExpression=True, DetectLiveness=True, Threshold=0.992, MemoryLimit=2150 ) # Open webcam cameras = FSDK.GetCameraList() camera = FSDK.OpenVideoCamera(cameras[0]) # Process frames try: frame_count = 0 while frame_count < 500: frame = FSDK.GrabFrame(camera) if frame is None: time.sleep(0.01) continue ids = tracker.FeedFrame(frame) for face_id in ids: pos = tracker.GetFacePosition(face_id) name = tracker.GetAllNames(face_id) attrs = tracker.GetFacialAttribute(face_id, "Gender;Age;Liveness") display_name = name if name else "Unknown" print(f"ID {face_id}: {display_name} at ({pos.xc},{pos.yc}) - {attrs}") FSDK.FreeImage(frame) frame_count += 1 except KeyboardInterrupt: pass # Save and cleanup tracker.SaveMemoryToFile("faces.db") FSDK.CloseVideoCamera(camera) FSDK.FreeTracker(tracker) FSDK.Finalize() ``` ## FSDK_SetName and Subject Enrollment Associates a name with a tracked face ID for future recognition. When the same person appears again, the tracker will return their assigned name. Names can be retrieved with `FSDK_GetAllNames`. ```cpp // C++ - Enrolling subjects with the Tracker API #include "LuxandFaceSDK.h" int main() { FSDK_ActivateLibrary("YOUR_LICENSE_KEY"); FSDK_Initialize(""); FSDK_InitializeCapturing(); HTracker tracker; FSDK_CreateTracker(&tracker); int errpos; FSDK_SetTrackerMultipleParameters(tracker, "RecognizeFaces=true;Threshold=0.992", &errpos); // Load existing database if available if (FSDK_LoadTrackerMemoryFromFile(&tracker, "employees.db") == FSDKE_OK) { printf("Loaded existing face database\n"); } int camera; char** cameraNames; int count; FSDK_GetCameraList(&cameraNames, &count); FSDK_OpenVideoCamera(cameraNames[0], &camera); FSDK_FreeCameraList(cameraNames, count); HImage frame; long long ids[256]; long long faceCount; // Enrollment mode - assign name to first detected face printf("Looking for face to enroll...\n"); while (true) { if (FSDK_GrabFrame(camera, &frame) != FSDKE_OK) continue; FSDK_FeedFrame(tracker, camera, frame, &faceCount, ids, sizeof(ids)); if (faceCount > 0) { // Lock the ID to prevent purging during enrollment FSDK_LockID(tracker, ids[0]); // Check if already enrolled char existingName[256]; FSDK_GetAllNames(tracker, ids[0], existingName, sizeof(existingName)); if (strlen(existingName) > 0) { printf("Person already enrolled as: %s\n", existingName); } else { // Enroll as new person int result = FSDK_SetName(tracker, ids[0], "John Smith"); if (result == FSDKE_OK) { printf("Successfully enrolled: John Smith (ID: %lld)\n", ids[0]); } else if (result == FSDKE_INSUFFICIENT_TRACKER_MEMORY_LIMIT) { printf("Error: Not enough memory to enroll new subject\n"); } } FSDK_UnlockID(tracker, ids[0]); FSDK_FreeImage(frame); break; } FSDK_FreeImage(frame); } // Save updated database FSDK_SaveTrackerMemoryToFile(tracker, "employees.db"); FSDK_CloseVideoCamera(camera); FSDK_FreeTracker(tracker); FSDK_Finalize(); return 0; } ``` ```python # Python - Subject enrollment and recognition from fsdk import FSDK import time FSDK.ActivateLibrary("YOUR_LICENSE_KEY") FSDK.Initialize() FSDK.InitializeCapturing() tracker = FSDK.Tracker() tracker.SetParameters(RecognizeFaces=True, Threshold=0.992) # Try to load existing database try: tracker.LoadMemoryFromFile("employees.db") print("Loaded existing database") except: print("Starting with empty database") cameras = FSDK.GetCameraList() camera = FSDK.OpenVideoCamera(cameras[0]) # Enrollment function def enroll_person(tracker, face_id, name): tracker.LockID(face_id) # Prevent ID from being purged existing = tracker.GetAllNames(face_id) if existing: print(f"Already enrolled as: {existing}") tracker.UnlockID(face_id) return False tracker.SetName(face_id, name) print(f"Enrolled {name} with ID {face_id}") tracker.UnlockID(face_id) return True # Recognition loop try: while True: frame = FSDK.GrabFrame(camera) if frame is None: time.sleep(0.01) continue ids = tracker.FeedFrame(frame) for face_id in ids: names = tracker.GetAllNames(face_id) pos = tracker.GetFacePosition(face_id) if names: print(f"Recognized: {names} (ID {face_id})") else: print(f"Unknown person (ID {face_id}) at ({pos.xc}, {pos.yc})") # Uncomment to auto-enroll: # enroll_person(tracker, face_id, "New Person") FSDK.FreeImage(frame) except KeyboardInterrupt: print("\nSaving database...") tracker.SaveMemoryToFile("employees.db") FSDK.CloseVideoCamera(camera) FSDK.FreeTracker(tracker) FSDK.Finalize() ``` ## Working with Cameras FaceSDK provides functions to work with webcams (DirectShow/v4l2) and IP cameras (MJPEG). Use `FSDK_GetCameraList` to enumerate available cameras, `FSDK_OpenVideoCamera` or `FSDK_OpenIPVideoCamera` to connect, and `FSDK_GrabFrame` to capture frames. ```cpp // C++ - Camera setup and frame capture #include "LuxandFaceSDK.h" int main() { FSDK_ActivateLibrary("YOUR_LICENSE_KEY"); FSDK_Initialize(""); FSDK_InitializeCapturing(); // List available webcams char** cameraNames; int cameraCount; FSDK_GetCameraList(&cameraNames, &cameraCount); printf("Available cameras (%d):\n", cameraCount); for (int i = 0; i < cameraCount; i++) { printf(" %d: %s\n", i, cameraNames[i]); } if (cameraCount == 0) { printf("No cameras found\n"); return 1; } // Get supported video formats for first camera FSDK_VideoFormatInfo* formats; int formatCount; FSDK_GetVideoFormatList(cameraNames[0], &formats, &formatCount); printf("\nSupported formats:\n"); for (int i = 0; i < formatCount; i++) { printf(" %dx%d @ %d bpp\n", formats[i].Width, formats[i].Height, formats[i].BPP); } // Set preferred format (e.g., 1280x720) for (int i = 0; i < formatCount; i++) { if (formats[i].Width == 1280 && formats[i].Height == 720) { FSDK_SetVideoFormat(cameraNames[0], formats[i]); break; } } FSDK_FreeVideoFormatList(formats); // Open webcam int cameraHandle; if (FSDK_OpenVideoCamera(cameraNames[0], &cameraHandle) != FSDKE_OK) { printf("Failed to open camera\n"); return 1; } printf("\nCamera opened successfully\n"); FSDK_FreeCameraList(cameraNames, cameraCount); // Capture and process frames HImage frame; for (int i = 0; i < 100; i++) { if (FSDK_GrabFrame(cameraHandle, &frame) == FSDKE_OK) { int width, height; FSDK_GetImageWidth(frame, &width); FSDK_GetImageHeight(frame, &height); printf("Frame %d: %dx%d\n", i + 1, width, height); // Save a sample frame if (i == 50) { FSDK_SaveImageToFile(frame, "sample_frame.jpg"); } FSDK_FreeImage(frame); } } FSDK_CloseVideoCamera(cameraHandle); FSDK_FinalizeCapturing(); FSDK_Finalize(); return 0; } ``` ```cpp // C++ - IP Camera connection #include "LuxandFaceSDK.h" int main() { FSDK_ActivateLibrary("YOUR_LICENSE_KEY"); FSDK_Initialize(""); FSDK_InitializeCapturing(); // Optional: Set HTTP proxy if needed // FSDK_SetHTTPProxy("proxy.company.com", 8080, "user", "pass"); // Open IP camera with MJPEG stream int cameraHandle; int result = FSDK_OpenIPVideoCamera( FSDK_MJPEG, // Compression type "http://192.168.1.100/video.mjpg", // Camera URL "admin", // Username "password123", // Password 10, // Timeout in seconds &cameraHandle ); if (result != FSDKE_OK) { printf("Failed to connect to IP camera (error: %d)\n", result); return 1; } printf("Connected to IP camera\n"); // Process frames HImage frame; while (true) { if (FSDK_GrabFrame(cameraHandle, &frame) == FSDKE_OK) { // Process frame (face detection, etc.) TFacePosition facePos; if (FSDK_DetectFace(frame, &facePos) == FSDKE_OK) { printf("Face detected at (%d, %d)\n", facePos.xc, facePos.yc); } FSDK_FreeImage(frame); } } FSDK_CloseVideoCamera(cameraHandle); FSDK_FinalizeCapturing(); FSDK_Finalize(); return 0; } ``` ```python # Python - Camera operations from fsdk import FSDK FSDK.ActivateLibrary("YOUR_LICENSE_KEY") FSDK.Initialize() FSDK.InitializeCapturing() # List webcams cameras = FSDK.GetCameraList() print(f"Found {len(cameras)} cameras:") for i, name in enumerate(cameras): print(f" {i}: {name}") if cameras: # Get video formats formats = FSDK.GetVideoFormatList(cameras[0]) print(f"\nSupported formats for {cameras[0]}:") for fmt in formats: print(f" {fmt.Width}x{fmt.Height} @ {fmt.BPP}bpp") # Set format and open camera if formats: FSDK.SetVideoFormat(cameras[0], formats[0]) camera = FSDK.OpenVideoCamera(cameras[0]) # Capture frames for i in range(100): frame = camera.GrabFrame() if frame: print(f"Frame {i+1}: {frame.width}x{frame.height}") frame.Free() camera.Close() # IP camera example ip_camera = FSDK.OpenIPVideoCamera( compression=FSDK.FSDK_MJPEG, URL="http://192.168.1.100/video.mjpg", userName="admin", password="password", timeoutSeconds=10 ) FSDK.FinalizeCapturing() FSDK.Finalize() ``` ## Thermal Face Detection FaceSDK supports face detection on thermal (infrared) images by loading a specialized detection model. This is useful for low-light conditions, temperature screening, and as an additional liveness verification method. ```cpp // C++ - Thermal image face detection #include "LuxandFaceSDK.h" int main() { FSDK_ActivateLibrary("YOUR_LICENSE_KEY"); FSDK_Initialize(""); // Load thermal face detection model int errpos; int result = FSDK_SetParameters( "FaceDetectionModel=thermal.bin;" "TrimOutOfScreenFaces=false;" "TrimFacesWithUncertainFacialFeatures=false", &errpos ); if (result != FSDKE_OK) { printf("Failed to load thermal model (error at pos %d)\n", errpos); printf("Make sure thermal.bin is in the working directory\n"); return 1; } printf("Thermal face detection model loaded\n"); // Load grayscale thermal image // Note: Convert your thermal camera's output to 8-bit grayscale // Normalize: 0=20C, 255=40C for best results HImage thermalImage; FSDK_LoadImageFromFile(&thermalImage, "thermal_capture.png"); // Detect faces in thermal image TFacePosition faces[50]; int faceCount; result = FSDK_DetectMultipleFaces( thermalImage, &faceCount, faces, sizeof(faces) ); if (result == FSDKE_OK && faceCount > 0) { printf("Detected %d faces in thermal image:\n", faceCount); for (int i = 0; i < faceCount; i++) { printf(" Face %d: center=(%d,%d), width=%d\n", i + 1, faces[i].xc, faces[i].yc, faces[i].w); } } else { printf("No faces detected in thermal image\n"); } FSDK_FreeImage(thermalImage); // Switch back to default visual model FSDK_SetParameters("FaceDetectionModel=default", &errpos); FSDK_Finalize(); return 0; } ``` ```python # Python - Thermal face detection from fsdk import FSDK FSDK.ActivateLibrary("YOUR_LICENSE_KEY") FSDK.Initialize() # Load thermal detection model FSDK.SetParameters( FaceDetectionModel="thermal.bin", TrimOutOfScreenFaces=False, TrimFacesWithUncertainFacialFeatures=False ) print("Thermal model loaded") # Process thermal image thermal_img = FSDK.Image("thermal_scan.png") faces = thermal_img.DetectMultipleFaces() print(f"Detected {len(faces)} faces in thermal image") for i, face in enumerate(faces): print(f" Face {i+1}: ({face.xc}, {face.yc}), width={face.w}") # Switch back to visual model FSDK.SetParameters(FaceDetectionModel="default") FSDK.Finalize() ``` ## Error Handling FaceSDK functions return integer error codes. Always check return values for robust applications. Common error codes include `FSDKE_OK` (success), `FSDKE_FACE_NOT_FOUND`, `FSDKE_NOT_ACTIVATED`, and `FSDKE_IO_ERROR`. ```cpp // C++ - Comprehensive error handling #include "LuxandFaceSDK.h" const char* GetErrorMessage(int errorCode) { switch (errorCode) { case FSDKE_OK: return "Success"; case FSDKE_FAILED: return "General failure"; case FSDKE_NOT_ACTIVATED: return "Library not activated"; case FSDKE_OUT_OF_MEMORY: return "Out of memory"; case FSDKE_INVALID_ARGUMENT: return "Invalid argument"; case FSDKE_IO_ERROR: return "I/O error"; case FSDKE_IMAGE_TOO_SMALL: return "Image too small (min 20x20)"; case FSDKE_FACE_NOT_FOUND: return "No face found"; case FSDKE_INSUFFICIENT_BUFFER_SIZE: return "Buffer too small"; case FSDKE_UNSUPPORTED_IMAGE_EXTENSION: return "Unsupported image format"; case FSDKE_CANNOT_OPEN_FILE: return "Cannot open file"; case FSDKE_FILE_NOT_FOUND: return "File not found"; case FSDKE_BAD_FILE_FORMAT: return "Bad file format"; case FSDKE_INVALID_TEMPLATE: return "Invalid face template"; case FSDKE_UNSUPPORTED_TEMPLATE_VERSION: return "Unsupported template version"; case FSDKE_INSUFFICIENT_TRACKER_MEMORY_LIMIT: return "Tracker memory limit reached"; default: return "Unknown error"; } } int main() { int result; // Activation result = FSDK_ActivateLibrary("YOUR_LICENSE_KEY"); if (result != FSDKE_OK) { printf("Activation failed: %s (%d)\n", GetErrorMessage(result), result); return 1; } // Initialization result = FSDK_Initialize(""); if (result != FSDKE_OK) { printf("Init failed: %s\n", GetErrorMessage(result)); return 1; } // Load image HImage image; result = FSDK_LoadImageFromFile(&image, "photo.jpg"); if (result != FSDKE_OK) { printf("Load failed: %s\n", GetErrorMessage(result)); FSDK_Finalize(); return 1; } // Face detection with specific error handling TFacePosition facePos; result = FSDK_DetectFace(image, &facePos); switch (result) { case FSDKE_OK: printf("Face found at (%d, %d)\n", facePos.xc, facePos.yc); break; case FSDKE_FACE_NOT_FOUND: printf("No face detected - try different image\n"); break; case FSDKE_IMAGE_TOO_SMALL: printf("Image too small - minimum 20x20 pixels\n"); break; default: printf("Detection error: %s\n", GetErrorMessage(result)); } FSDK_FreeImage(image); FSDK_Finalize(); return 0; } ``` ```python # Python - Exception-based error handling from fsdk import FSDK try: FSDK.ActivateLibrary("YOUR_LICENSE_KEY") FSDK.Initialize() image = FSDK.Image("photo.jpg") try: face = image.DetectFace() print(f"Face at ({face.xc}, {face.yc})") features = image.DetectFacialFeatures() print(f"Left eye: {features[FSDK.FSDKP_LEFT_EYE]}") template = image.GetFaceTemplate() print("Template extracted successfully") except FSDK.FaceNotFound: print("No face detected in image") except FSDK.ImageTooSmall: print("Image is too small (min 20x20 pixels)") except FSDK.NotActivated: print("Invalid license key") except FSDK.FileNotFound: print("Image file not found") except FSDK.BadFileFormat: print("Unsupported or corrupted image file") except FSDK.IOError as e: print(f"I/O error: {e}") finally: FSDK.Finalize() ``` ## Summary Luxand FaceSDK 8.3 provides a comprehensive solution for face detection, recognition, and analysis across multiple platforms. The SDK excels in three primary use cases: identity verification systems (using face templates and matching with configurable FAR/FRR thresholds), real-time surveillance and tracking (via the Tracker API with automatic subject learning and recognition), and demographic analysis (gender, age, and expression detection). The passive liveness detection adds crucial anti-spoofing capabilities for security-sensitive applications, while thermal camera support extends functionality to specialized environments. For integration, developers should follow the standard workflow: activate the library, initialize, load/capture images, perform detection/recognition operations, and properly finalize with resource cleanup. The Tracker API simplifies video stream processing by handling face tracking, identity persistence, and attribute smoothing automatically. When building face verification systems, use `FSDK_GetMatchingThresholdAtFAR` to select appropriate thresholds based on security requirements (0.001 FAR for high security, 0.01 for balanced, 0.05 for convenience). For best recognition performance with Tracker API, configure `Threshold` and `MemoryLimit` parameters according to expected subject count and desired FAR/recognition rate balance. Always free image handles after processing to prevent memory leaks, and save tracker memory to persist enrolled subjects across sessions.