mot_rs/utils/
utils.rs

1#[derive(Clone, Default, Debug)]
2pub struct Rect {
3    pub x: f32,
4    pub y: f32,
5    pub width: f32,
6    pub height: f32,
7}
8
9impl Rect {
10    pub fn new(_x: f32, _y: f32, _width: f32, _height: f32) -> Self {
11        Rect {
12            x: _x,
13            y: _y,
14            width: _width,
15            height: _height,
16        }
17    }
18}
19
20#[derive(Clone, Default, Debug)]
21pub struct Point {
22    pub x: f32,
23    pub y: f32,
24}
25
26impl Point {
27    pub fn new(_x: f32, _y: f32) -> Self {
28        Point { x: _x, y: _y }
29    }
30}
31
32pub fn euclidean_distance(p1: &Point, p2: &Point) -> f32 {
33    let x_squared = f32::powf(f32::abs(p1.x - p2.x), 2.0);
34    let y_squared = f32::powf(f32::abs(p1.y - p2.y), 2.0);
35    let sum_f32 = (x_squared + y_squared) as f32;
36    f32::sqrt(sum_f32)
37}
38
39pub fn iou(r1: &Rect, r2: &Rect) -> f32 {
40    let x1 = r1.x;
41    let y1 = r1.y;
42    let x2 = r1.x + r1.width;
43    let y2 = r1.y + r1.height;
44
45    let x3 = r2.x;
46    let y3 = r2.y;
47    let x4 = r2.x + r2.width;
48    let y4 = r2.y + r2.height;
49
50    let x_overlap_width = f32::max(0.0, f32::min(x2, x4) - f32::max(x1, x3));
51    let y_overlap_height = f32::max(0.0, f32::min(y2, y4) - f32::max(y1, y3));
52
53    if x_overlap_width <= 0.0 || y_overlap_height <= 0.0 {
54        return 0.0;
55    }
56
57    let intersection_area = x_overlap_width * y_overlap_height;
58    let r1_area = r1.width * r1.height;
59    let r2_area = r2.width * r2.height;
60    let union_area = r1_area + r2_area - intersection_area;
61
62    if union_area <= 0.0 {
63        return 0.0;
64    }
65
66    let iou = intersection_area / union_area;
67
68    f32::max(0.0, f32::min(iou, 1.0))
69}
70
71mod tests {
72    #[test]
73    fn test_euclidean_distance() {
74        let p1 = super::Point::new(341.0, 264.0);
75        let p2 = super::Point::new(421.0, 427.0);
76        let ans = super::euclidean_distance(&p1, &p2);
77        assert_eq!(181.57367, ans);
78    }
79
80    #[test]
81    fn test_iou() {
82        // Test cases with known IoU values for validation
83        let rect1 = super::Rect::new(0.0, 0.0, 10.0, 10.0);
84        let rect2 = super::Rect::new(5.0, 5.0, 10.0, 10.0);
85        assert_eq!(super::iou(&rect1, &rect2), 0.14285715);
86
87        let rect3 = super::Rect::new(10.0, 10.0, 10.0, 10.0);
88        let rect4 = super::Rect::new(20.0, 20.0, 10.0, 10.0);
89        assert_eq!(super::iou(&rect3, &rect4), 0.0);
90
91        let rect5 = super::Rect::new(0.0, 0.0, 20.0, 20.0);
92        let rect6 = super::Rect::new(5.0, 5.0, 10.0, 10.0);
93        assert_eq!(super::iou(&rect5, &rect6), 0.25);
94
95        let rect7 = super::Rect::new(0.0, 0.0, 10.0, 10.0);
96        let rect8 = super::Rect::new(0.0, 0.0, 10.0, 10.0);
97        assert_eq!(super::iou(&rect7, &rect8), 1.0);
98
99        // Test case with two rectangles having zero width and height
100        let rect9 = super::Rect::new(0.0, 0.0, 0.0, 0.0);
101        let rect10 = super::Rect::new(5.0, 5.0, 0.0, 0.0);
102        assert_eq!(super::iou(&rect9, &rect10), 0.0);
103
104        // Test case with two rectangles are the same
105        let rect11 = super::Rect::new(4.5, 2.0, 10.0, 10.0);
106        let rect12 = super::Rect::new(4.5, 2.0, 10.0, 10.0);
107        assert_eq!(super::iou(&rect11, &rect12), 1.0);
108    }
109}