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
use crate::image::Image;
use darknet_sys as sys;
pub use darknet_sys::box_ as BBox;
use std::ffi::CString;
use std::iter::Iterator;
use std::mem;
use std::os::raw::c_char;
use std::sync::Arc;
fn get_max_prob_label(labels: &Vec<String>, det: &sys::detection) -> (String, f32) {
let probs =
unsafe { Vec::from_raw_parts(det.prob, det.classes as usize, det.classes as usize) };
let (max_label, max_prob) = Iterator::zip(labels.iter(), probs.iter())
.max_by(|x, y| x.1.partial_cmp(y.1).unwrap())
.expect("No labels found!");
let max_prob = *max_prob;
mem::forget(probs);
return (max_label.to_string(), max_prob);
}
#[derive(Debug)]
pub struct Detections {
detections: Vec<sys::detection>,
names: Arc<Vec<String>>,
thresh: f32,
}
impl Detections {
pub fn new(
detections: Vec<sys::detection>,
names: &Arc<Vec<String>>,
thresh: f32,
) -> Detections {
Detections {
detections,
names: names.clone(),
thresh,
}
}
pub fn get_boxes(&self) -> Vec<BBox> {
self.detections.iter().map(|x| x.bbox).collect()
}
pub fn get_labels(&self) -> Vec<String> {
self.detections
.iter()
.map(|x| get_max_prob_label(&self.names, &x))
.filter(|x| x.1 > self.thresh)
.map(|x| x.0)
.collect()
}
pub fn get_raw_vec(&self) -> Vec<sys::detection> {
self.detections.clone()
}
pub fn draw_on_image(&self, image: &mut Image) {
let mut names_raw: Vec<*mut c_char> = self
.names
.iter()
.map(|x| {
CString::new(&x[..])
.expect("CString::new failed")
.into_raw()
})
.collect();
unsafe {
sys::draw_detections(
image.image,
self.get_raw_vec().as_mut_ptr(),
self.count() as i32,
0.0,
names_raw.as_mut_ptr(),
sys::load_alphabet(),
names_raw.len() as i32,
);
}
}
pub fn crop_from(&self, img: &Image) -> Vec<(String, Image)> {
self.detections
.iter()
.map(|x| (get_max_prob_label(&self.names, &x), x.bbox))
.filter(|x| (x.0).1 > self.thresh)
.map(|x| ((x.0).0.to_string(), img.crop_bbox(&x.1)))
.collect()
}
pub fn count(&self) -> usize {
self.detections.len()
}
}