slamkit_rs/feature/
detector.rs1use opencv::{
2 core::{KeyPoint, Mat, Vector},
3 features2d::ORB,
4 prelude::*,
5};
6
7pub struct OrbDetector {
9 orb: opencv::core::Ptr<ORB>,
10 max_features: i32,
11}
12
13impl OrbDetector {
14 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}