135 lines
3.9 KiB
Rust
135 lines
3.9 KiB
Rust
//! Integration tests for face detection
|
|
|
|
use linux_hello_common::Result;
|
|
use linux_hello_daemon::detection::{
|
|
detect_face_simple, FaceDetect, FaceDetection, SimpleFaceDetector,
|
|
};
|
|
|
|
#[test]
|
|
fn test_simple_face_detection() {
|
|
// Create a test image with reasonable contrast
|
|
let width = 640u32;
|
|
let height = 480u32;
|
|
let mut image = Vec::new();
|
|
|
|
// Create a gradient pattern (simulates a face-like region)
|
|
for y in 0..height {
|
|
for x in 0..width {
|
|
// Center region with higher intensity (face-like)
|
|
let center_x = width / 2;
|
|
let center_y = height / 2;
|
|
let dist =
|
|
((x as i32 - center_x as i32).pow(2) + (y as i32 - center_y as i32).pow(2)) as f32;
|
|
let max_dist = ((width / 2).pow(2) + (height / 2).pow(2)) as f32;
|
|
|
|
let intensity = (128.0 + (1.0 - dist / max_dist) * 100.0) as u8;
|
|
image.push(intensity);
|
|
}
|
|
}
|
|
|
|
let detection = detect_face_simple(&image, width, height);
|
|
assert!(detection.is_some(), "Should detect face in test image");
|
|
|
|
if let Some(det) = detection {
|
|
println!(
|
|
"Face detected: x={:.2}, y={:.2}, w={:.2}, h={:.2}, conf={:.2}",
|
|
det.x, det.y, det.width, det.height, det.confidence
|
|
);
|
|
|
|
// Verify detection is within image bounds
|
|
assert!(det.x >= 0.0 && det.x <= 1.0);
|
|
assert!(det.y >= 0.0 && det.y <= 1.0);
|
|
assert!(det.width > 0.0 && det.width <= 1.0);
|
|
assert!(det.height > 0.0 && det.height <= 1.0);
|
|
assert!(det.confidence >= 0.0 && det.confidence <= 1.0);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_face_detection_empty_image() {
|
|
let image = Vec::<u8>::new();
|
|
let detection = detect_face_simple(&image, 0, 0);
|
|
assert!(detection.is_none(), "Should not detect face in empty image");
|
|
}
|
|
|
|
#[test]
|
|
fn test_face_detection_low_contrast() {
|
|
// Very low contrast image (all same value)
|
|
let width = 100u32;
|
|
let height = 100u32;
|
|
let image = vec![10u8; (width * height) as usize];
|
|
|
|
let detection = detect_face_simple(&image, width, height);
|
|
// May or may not detect, but shouldn't crash
|
|
if let Some(det) = detection {
|
|
println!("Low contrast detection: conf={:.2}", det.confidence);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_face_detection_high_contrast() {
|
|
// Very high contrast (all white)
|
|
let width = 100u32;
|
|
let height = 100u32;
|
|
let image = vec![255u8; (width * height) as usize];
|
|
|
|
let detection = detect_face_simple(&image, width, height);
|
|
// Should not detect (too bright)
|
|
if let Some(det) = detection {
|
|
println!("High contrast detection: conf={:.2}", det.confidence);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_simple_face_detector_trait() -> Result<()> {
|
|
let detector = SimpleFaceDetector::new(0.3);
|
|
|
|
// Test with reasonable image
|
|
let width = 200u32;
|
|
let height = 200u32;
|
|
let image: Vec<u8> = (0..width * height)
|
|
.map(|i| ((i % 200) + 50) as u8)
|
|
.collect();
|
|
|
|
let detections = detector.detect(&image, width, height)?;
|
|
println!("Detector found {} face(s)", detections.len());
|
|
|
|
// Test with threshold too high
|
|
let strict_detector = SimpleFaceDetector::new(0.9);
|
|
let strict_detections = strict_detector.detect(&image, width, height)?;
|
|
println!("Strict detector found {} face(s)", strict_detections.len());
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn test_face_detection_pixel_conversion() {
|
|
let detection = FaceDetection {
|
|
x: 0.25,
|
|
y: 0.1,
|
|
width: 0.5,
|
|
height: 0.8,
|
|
confidence: 0.95,
|
|
};
|
|
|
|
let (x, y, w, h) = detection.to_pixels(640, 480);
|
|
assert_eq!(x, 160);
|
|
assert_eq!(y, 48);
|
|
assert_eq!(w, 320);
|
|
assert_eq!(h, 384);
|
|
|
|
// Test edge cases
|
|
let edge = FaceDetection {
|
|
x: 0.0,
|
|
y: 0.0,
|
|
width: 1.0,
|
|
height: 1.0,
|
|
confidence: 1.0,
|
|
};
|
|
let (x, y, w, h) = edge.to_pixels(100, 100);
|
|
assert_eq!(x, 0);
|
|
assert_eq!(y, 0);
|
|
assert_eq!(w, 100);
|
|
assert_eq!(h, 100);
|
|
}
|