1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
use crate::{nms::Nms, Rect};
use ndarray::ArrayViewD;
use thiserror::Error;

#[derive(Error, Debug)]
pub enum RustFacesError {
    #[error("IO error: {0}")]
    IoError(std::io::Error),
    #[error("Image error: {0}")]
    ImageError(String),
    #[error("Inference error: {0}")]
    InferenceError(String),
    #[error("Other error: {0}")]
    Other(String),
}

impl From<std::io::Error> for RustFacesError {
    fn from(err: std::io::Error) -> Self {
        RustFacesError::IoError(err)
    }
}

pub type RustFacesResult<R> = Result<R, RustFacesError>;

#[derive(Debug, Clone)]
pub struct Face {
    pub rect: Rect,
    pub confidence: f32,
    pub landmarks: Option<Vec<(f32, f32)>>,
}

pub trait FaceDetector: Sync + Send {
    fn detect(&self, image: ArrayViewD<u8>) -> RustFacesResult<Vec<Face>>;
}

#[derive(Debug, Copy, Clone)]
pub struct DetectionParams {
    pub score_threshold: f32,
    pub nms: Nms,
}

impl Default for DetectionParams {
    fn default() -> Self {
        Self {
            score_threshold: 0.95,
            nms: Nms::default(),
        }
    }
}