use std::path::{Path, PathBuf};
use image::imageops::FilterType;
pub const ENV_MODEL_PATH: &str = "OUTLINE_MODEL_PATH";
pub const DEFAULT_MODEL_PATH: &str = "model.onnx";
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[non_exhaustive]
pub enum InferenceBackend {
#[cfg(feature = "backend-ort")]
#[default]
Ort,
#[cfg(feature = "backend-rten")]
#[cfg_attr(not(feature = "backend-ort"), default)]
Rten,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ModelInputSize {
height: usize,
width: usize,
}
impl ModelInputSize {
pub fn new(height: usize, width: usize) -> Self {
assert!(height > 0 && width > 0, "model input size must be non-zero");
Self { height, width }
}
pub fn height(&self) -> usize {
self.height
}
pub fn width(&self) -> usize {
self.width
}
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct InferenceSettings {
model_path: PathBuf,
backend: InferenceBackend,
input_resize_filter: FilterType,
output_resize_filter: FilterType,
model_input_size: Option<ModelInputSize>,
intra_threads: Option<usize>,
}
impl InferenceSettings {
pub fn new(model_path: impl Into<PathBuf>) -> Self {
Self {
model_path: model_path.into(),
backend: InferenceBackend::default(),
input_resize_filter: FilterType::Triangle,
output_resize_filter: FilterType::Lanczos3,
model_input_size: None,
intra_threads: None,
}
}
pub fn model_path(&self) -> &Path {
&self.model_path
}
pub fn backend(&self) -> InferenceBackend {
self.backend
}
pub fn input_resize_filter(&self) -> FilterType {
self.input_resize_filter
}
pub fn output_resize_filter(&self) -> FilterType {
self.output_resize_filter
}
pub fn model_input_size(&self) -> Option<ModelInputSize> {
self.model_input_size
}
pub fn intra_threads(&self) -> Option<usize> {
self.intra_threads
}
pub fn with_backend(mut self, backend: InferenceBackend) -> Self {
self.backend = backend;
self
}
pub fn with_model_input_size(mut self, height: usize, width: usize) -> Self {
self.model_input_size = Some(ModelInputSize::new(height, width));
self
}
pub fn with_input_resize_filter(mut self, filter: FilterType) -> Self {
self.input_resize_filter = filter;
self
}
pub fn with_output_resize_filter(mut self, filter: FilterType) -> Self {
self.output_resize_filter = filter;
self
}
pub fn with_intra_threads(mut self, intra_threads: Option<usize>) -> Self {
self.intra_threads = intra_threads;
self
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum ErosionBorderMode {
#[default]
OutsideIsBackground,
OutsideIsUnknown,
}
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub struct MaskProcessingDefaults {
pub blur_sigma: f32,
pub mask_threshold: u8,
pub dilation_radius: f32,
pub erosion_radius: f32,
pub erosion_border_mode: ErosionBorderMode,
}
impl Default for MaskProcessingDefaults {
fn default() -> Self {
Self {
blur_sigma: 6.0,
mask_threshold: 120,
dilation_radius: 5.0,
erosion_radius: 5.0,
erosion_border_mode: ErosionBorderMode::default(),
}
}
}