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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
// This file is part of the open-source port of SeetaFace engine, which originally includes three modules:
// SeetaFace Detection, SeetaFace Alignment, and SeetaFace Identification.
//
// This file is part of the SeetaFace Detection module, containing codes implementing the face detection method described in the following paper:
//
// Funnel-structured cascade for multi-view face detection with alignment awareness,
// Shuzhe Wu, Meina Kan, Zhenliang He, Shiguang Shan, Xilin Chen.
// In Neurocomputing (under review)
//
// Copyright (C) 2016, Visual Information Processing and Learning (VIPL) group,
// Institute of Computing Technology, Chinese Academy of Sciences, Beijing, China.
//
// As an open-source face recognition engine: you can redistribute SeetaFace source codes
// and/or modify it under the terms of the BSD 2-Clause License.
//
// You should have received a copy of the BSD 2-Clause License along with the software.
// If not, see < https://opensource.org/licenses/BSD-2-Clause>.
mod classifier;
mod common;
mod detector;
mod feat;
pub mod math;
pub mod model;
pub use crate::common::FaceInfo;
pub use crate::common::ImageData;
pub use crate::common::Rectangle;
pub use crate::model::{read_model, Model};
use crate::detector::FuStDetector;
use image::DynamicImage;
use std::io;
#[cfg(feature = "include_default_model")]
/// Create a face detector with the default model file
pub fn create_default_detector() -> Result<Box<dyn Detector>, io::Error> {
let bytes = include_bytes!("../model/seeta_fd_frontal_v1.0.bin");
create_detector(bytes)
}
/// Create a face detector from model loaded to memory
pub fn create_detector(buf: &[u8]) -> Result<Box<dyn Detector>, io::Error> {
let cursor = io::Cursor::new(buf.to_owned());
let model = read_model(cursor)?;
Ok(create_detector_with_model(model))
}
/// Create a face detector, based on the provided model.
pub fn create_detector_with_model(model: Model) -> Box<dyn Detector> {
Box::new(FuStDetector::new(model))
}
/// detect face bounding boxes
pub fn detect_faces(detector: &mut dyn Detector, img: DynamicImage) -> Vec<FaceInfo> {
let gray = &img.to_luma8();
let (width, height) = gray.dimensions();
let mut image = ImageData::new(gray, width, height);
let faces = detector.detect(&mut image);
faces
}
pub trait Detector {
/// Detect faces on input image.
///
/// (1) The input image should be gray-scale, i.e. `num_channels` set to 1.
/// (2) Currently this function does not give the Euler angles, which are
/// left with invalid values.
///
/// # Panics
///
/// Panics if `image` is not a legal image, e.g. it
/// - is not gray-scale (`num_channels` is not equal to 1)
/// - has `width` or `height` equal to 0
fn detect(&mut self, image: &ImageData) -> Vec<FaceInfo>;
/// Set the size of the sliding window.
///
/// The minimum size is constrained as no smaller than 20.
///
/// # Panics
///
/// Panics if `wnd_size` is less than 20.
fn set_window_size(&mut self, wnd_size: u32);
/// Set the sliding window step in horizontal and vertical directions.
///
/// The steps should take positive values.
/// Usually a step of 4 is a reasonable choice.
///
/// # Panics
///
/// Panics if `step_x` or `step_y` is less than or equal to 0.
fn set_slide_window_step(&mut self, step_x: u32, step_y: u32);
/// Set the minimum size of faces to detect.
///
/// The minimum size is constrained as no smaller than 20.
///
/// # Panics
///
/// Panics if `min_face_size` is less than 20.
fn set_min_face_size(&mut self, min_face_size: u32);
/// Set the maximum size of faces to detect.
///
/// The maximum face size actually used is computed as the minimum among:
/// user specified size, image width, image height.
fn set_max_face_size(&mut self, max_face_size: u32);
/// Set the factor between adjacent scales of image pyramid.
///
/// The value of the factor lies in (0.1, 0.99). For example, when it is set as 0.5,
/// an input image of size w x h will be resized to 0.5w x 0.5h, 0.25w x 0.25h, 0.125w x 0.125h, etc.
///
/// # Panics
///
/// Panics if `scale_factor` is less than 0.01 or greater than 0.99
fn set_pyramid_scale_factor(&mut self, scale_factor: f32);
/// Set the score threshold of detected faces.
///
/// Detections with scores smaller than the threshold will not be returned.
/// Typical threshold values include 0.95, 2.8, 4.5. One can adjust the
/// threshold based on his or her own test set.
///
/// Smaller values result in more detections (possibly increasing the number of false positives),
/// larger values result in fewer detections (possibly increasing the number of false negatives).
///
/// # Panics
///
/// Panics if `thresh` is less than or equal to 0.
fn set_score_thresh(&mut self, thresh: f64);
}