kataglyphis_rustprojecttemplate/api/
onnx.rs1use log::error;
2
3pub use crate::Detection;
4
5#[flutter_rust_bridge::frb(sync)]
6pub fn detect_persons_rgba(
7 model_path: String,
8 rgba: Vec<u8>,
9 width: u32,
10 height: u32,
11 score_threshold: f32,
12) -> Result<Vec<Detection>, String> {
13 let resolved_model_path = {
16 #[cfg(onnx)]
17 {
18 crate::person_detection::resolve_model_path(Some(&model_path))
19 }
20
21 #[cfg(not(onnx))]
22 {
23 model_path
24 }
25 };
26
27 detect_persons_rgba_impl(&resolved_model_path, &rgba, width, height, score_threshold).map_err(
28 |e| {
29 error!("detect_persons_rgba failed: {e:#}");
30 format!("detect_persons_rgba failed: {e:#}")
31 },
32 )
33}
34
35#[cfg(onnx)]
36fn detect_persons_rgba_impl(
37 model_path: &str,
38 rgba: &[u8],
39 width: u32,
40 height: u32,
41 score_threshold: f32,
42) -> anyhow::Result<Vec<Detection>> {
43 use std::sync::{Mutex, OnceLock};
44
45 use crate::person_detection::PersonDetector;
46
47 struct Cached {
48 model_path: String,
49 detector: PersonDetector,
50 }
51
52 static DETECTOR: OnceLock<Mutex<Option<Cached>>> = OnceLock::new();
53 let mutex = DETECTOR.get_or_init(|| Mutex::new(None));
54
55 let lock_guard = || {
56 mutex
57 .lock()
58 .unwrap_or_else(|poisoned| poisoned.into_inner())
59 };
60
61 let needs_reload = {
63 let guard = lock_guard();
64 guard
65 .as_ref()
66 .map(|c| c.model_path != model_path)
67 .unwrap_or(true)
68 };
69
70 if needs_reload {
73 let detector = PersonDetector::new(model_path)?;
74 let mut guard = lock_guard();
75 let still_needs = guard
78 .as_ref()
79 .map(|c| c.model_path != model_path)
80 .unwrap_or(true);
81 if still_needs {
82 *guard = Some(Cached {
83 model_path: model_path.to_string(),
84 detector,
85 });
86 }
87 }
88
89 let mut guard = lock_guard();
90 let Some(cached) = guard.as_mut() else {
91 return Ok(Vec::new());
92 };
93 cached
94 .detector
95 .infer_persons_rgba(rgba, width, height, score_threshold)
96}
97
98#[cfg(not(onnx))]
99fn detect_persons_rgba_impl(
100 _model_path: &str,
101 _rgba: &[u8],
102 _width: u32,
103 _height: u32,
104 _score_threshold: f32,
105) -> anyhow::Result<Vec<Detection>> {
106 anyhow::bail!("ONNX inference is disabled. Build with --features onnx_tract (or onnxruntime*)")
107}