slamkit_rs/feature/
detector.rs

1use opencv::{
2    core::{KeyPoint, Mat, Vector},
3    features2d::ORB,
4    prelude::*,
5};
6
7/// Simple ORB feature detector wrapper
8pub struct OrbDetector {
9    orb: opencv::core::Ptr<ORB>,
10    max_features: i32,
11}
12
13impl OrbDetector {
14    /// Create a new ORB detector with specified max features
15    pub fn new(max_features: i32) -> Result<Self, Box<dyn std::error::Error>> {
16        let orb = ORB::create_def()?;
17        Ok(Self { orb, max_features })
18    }
19
20    pub fn detect(&mut self, image: &Mat) -> Result<Vector<KeyPoint>, Box<dyn std::error::Error>> {
21        let mut keypoints = Vector::new();
22        self.orb.detect(image, &mut keypoints, &Mat::default())?;
23        Ok(keypoints)
24    }
25
26    pub fn detect_and_compute(
27        &mut self,
28        image: &Mat,
29    ) -> Result<(Vector<KeyPoint>, Mat), Box<dyn std::error::Error>> {
30        let mut keypoints = Vector::new();
31        let mut descriptors = Mat::default();
32        self.orb.detect_and_compute(
33            image,
34            &Mat::default(),
35            &mut keypoints,
36            &mut descriptors,
37            false,
38        )?;
39        Ok((keypoints, descriptors))
40    }
41
42    pub fn max_features(&self) -> i32 {
43        self.max_features
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50
51    #[test]
52    fn test_orb_detector_creation() {
53        let detector = OrbDetector::new(500);
54        assert!(detector.is_ok());
55        assert_eq!(detector.unwrap().max_features(), 500);
56    }
57
58    #[test]
59    fn test_detect_on_blank_image() {
60        let mut detector = OrbDetector::new(100).unwrap();
61        let blank = Mat::zeros(480, 640, opencv::core::CV_8UC1)
62            .unwrap()
63            .to_mat()
64            .unwrap();
65        let keypoints = detector.detect(&blank).unwrap();
66        assert_eq!(keypoints.len(), 0);
67    }
68
69    #[test]
70    fn test_detect_and_compute() {
71        let mut detector = OrbDetector::new(500).unwrap();
72        let blank = Mat::zeros(480, 640, opencv::core::CV_8UC1)
73            .unwrap()
74            .to_mat()
75            .unwrap();
76        let result = detector.detect_and_compute(&blank);
77        assert!(result.is_ok());
78        let (keypoints, descriptors) = result.unwrap();
79        assert_eq!(keypoints.len(), descriptors.rows() as usize);
80    }
81}