Prepare public release v0.1.0

This commit is contained in:
2026-01-30 09:44:12 +01:00
parent 75be95fdf7
commit 2034281ad7
41 changed files with 2137 additions and 1028 deletions

View File

@@ -19,7 +19,7 @@ use linux_hello_daemon::onnx::{
FaceAligner, OnnxEmbeddingExtractor, OnnxFaceDetector, OnnxModelConfig, OnnxPipeline,
REFERENCE_LANDMARKS_112,
};
use linux_hello_daemon::{FaceDetect, EmbeddingExtractor};
use linux_hello_daemon::{EmbeddingExtractor, FaceDetect};
use std::path::Path;
/// Model directory path
@@ -118,10 +118,10 @@ mod alignment_tests {
&image,
TEST_WIDTH,
TEST_HEIGHT,
100, // face_x
100, // face_y
200, // face_width
200, // face_height
100, // face_x
100, // face_y
200, // face_width
200, // face_height
);
assert!(result.is_ok());
@@ -251,7 +251,11 @@ mod integration_with_models {
}
let result = OnnxFaceDetector::load(model_path("retinaface.onnx"));
assert!(result.is_ok(), "Failed to load detection model: {:?}", result.err());
assert!(
result.is_ok(),
"Failed to load detection model: {:?}",
result.err()
);
}
#[test]
@@ -263,7 +267,11 @@ mod integration_with_models {
}
let result = OnnxEmbeddingExtractor::load(model_path("mobilefacenet.onnx"));
assert!(result.is_ok(), "Failed to load embedding model: {:?}", result.err());
assert!(
result.is_ok(),
"Failed to load embedding model: {:?}",
result.err()
);
}
#[test]
@@ -274,13 +282,17 @@ mod integration_with_models {
return;
}
let detector = OnnxFaceDetector::load(model_path("retinaface.onnx"))
.expect("Failed to load detector");
let detector =
OnnxFaceDetector::load(model_path("retinaface.onnx")).expect("Failed to load detector");
let image = create_test_image(TEST_WIDTH, TEST_HEIGHT);
let detections = detector.detect(&image, TEST_WIDTH, TEST_HEIGHT);
assert!(detections.is_ok(), "Detection failed: {:?}", detections.err());
assert!(
detections.is_ok(),
"Detection failed: {:?}",
detections.err()
);
// Note: synthetic image may or may not trigger detections
}
@@ -299,14 +311,22 @@ mod integration_with_models {
let face_data = vec![128u8; 112 * 112];
let result = extractor.extract_from_bytes(&face_data, 112, 112);
assert!(result.is_ok(), "Embedding extraction failed: {:?}", result.err());
assert!(
result.is_ok(),
"Embedding extraction failed: {:?}",
result.err()
);
let embedding = result.unwrap();
assert_eq!(embedding.len(), extractor.embedding_dimension());
// Check embedding is normalized (L2 norm should be ~1)
let norm: f32 = embedding.iter().map(|x| x * x).sum::<f32>().sqrt();
assert!((norm - 1.0).abs() < 0.1, "Embedding not normalized: norm = {}", norm);
assert!(
(norm - 1.0).abs() < 0.1,
"Embedding not normalized: norm = {}",
norm
);
}
#[test]
@@ -326,7 +346,11 @@ mod integration_with_models {
let image = create_test_image(TEST_WIDTH, TEST_HEIGHT);
let results = pipeline.process_frame(&image, TEST_WIDTH, TEST_HEIGHT);
assert!(results.is_ok(), "Pipeline processing failed: {:?}", results.err());
assert!(
results.is_ok(),
"Pipeline processing failed: {:?}",
results.err()
);
}
#[test]
@@ -343,9 +367,11 @@ mod integration_with_models {
// Same face should produce similar embeddings
let face_data = vec![128u8; 112 * 112];
let embedding1 = extractor.extract_from_bytes(&face_data, 112, 112)
let embedding1 = extractor
.extract_from_bytes(&face_data, 112, 112)
.expect("First extraction failed");
let embedding2 = extractor.extract_from_bytes(&face_data, 112, 112)
let embedding2 = extractor
.extract_from_bytes(&face_data, 112, 112)
.expect("Second extraction failed");
// Compute cosine similarity
@@ -377,9 +403,11 @@ mod integration_with_models {
let face1 = vec![100u8; 112 * 112];
let face2 = vec![200u8; 112 * 112];
let embedding1 = extractor.extract_from_bytes(&face1, 112, 112)
let embedding1 = extractor
.extract_from_bytes(&face1, 112, 112)
.expect("First extraction failed");
let embedding2 = extractor.extract_from_bytes(&face2, 112, 112)
let embedding2 = extractor
.extract_from_bytes(&face2, 112, 112)
.expect("Second extraction failed");
// Compute cosine similarity