use super::base::FaceDetectorTrait;
use super::location::FaceLocations;
use crate::matrix::ImageMatrix;
use std::cell::UnsafeCell;
use std::marker::PhantomData;
#[derive(Clone)]
pub struct FaceDetector {
inner: FaceDetectorInner,
data: PhantomData<UnsafeCell<()>>,
}
cpp_class!(unsafe struct FaceDetectorInner as "dlib::frontal_face_detector");
impl FaceDetector {
pub fn new() -> Self {
let inner = unsafe {
cpp!([] -> FaceDetectorInner as "dlib::frontal_face_detector" {
return dlib::get_frontal_face_detector();
})
};
Self {
inner,
data: std::marker::PhantomData::default(),
}
}
}
impl Default for FaceDetector {
fn default() -> Self {
Self::new()
}
}
impl FaceDetectorTrait for FaceDetector {
fn face_locations(&self, image: &ImageMatrix) -> FaceLocations {
let detector = &self.inner;
unsafe {
cpp!([detector as "dlib::frontal_face_detector*", image as "dlib::matrix<dlib::rgb_pixel>*"] -> FaceLocations as "std::vector<dlib::rectangle>" {
return (*detector)(*image);
})
}
}
}
#[test]
fn test_face_detection() {
use crate::geometry::Rectangle;
let image = image::open("assets/obama_1.jpg").unwrap().to_rgb8();
let matrix = ImageMatrix::from_image(&image);
let detector = FaceDetector::new();
let locations = detector.face_locations(&matrix);
assert_eq!(locations.len(), 1);
assert_eq!(
locations[0],
Rectangle {
left: 305,
top: 113,
right: 520,
bottom: 328
}
);
}