use crate::frame::Frame;
use kornia_algebra::Vec3F64;
use kornia_sensors::imu::ImuBias;
#[derive(Debug, Clone)]
pub struct Keyframe {
pub frame: Frame,
pub map_point_by_desc_idx: Vec<Option<usize>>,
pub velocity_world: Vec3F64,
pub imu_bias: ImuBias,
}
impl Keyframe {
pub fn from_frame(frame: Frame) -> Self {
let map_point_by_desc_idx = vec![None; frame.features.descriptors.len()];
Self {
frame,
map_point_by_desc_idx,
velocity_world: Vec3F64::ZERO,
imu_bias: ImuBias::default(),
}
}
pub fn associate_map_point(&mut self, desc_idx: usize, mp_idx: usize) {
if let Some(slot) = self.map_point_by_desc_idx.get_mut(desc_idx) {
*slot = Some(mp_idx);
}
}
pub fn clear_map_point(&mut self, desc_idx: usize) {
if let Some(slot) = self.map_point_by_desc_idx.get_mut(desc_idx) {
*slot = None;
}
}
pub fn map_point(&self, desc_idx: usize) -> Option<usize> {
self.map_point_by_desc_idx.get(desc_idx).copied().flatten()
}
pub fn num_associated_points(&self) -> usize {
self.map_point_by_desc_idx
.iter()
.filter(|slot| slot.is_some())
.count()
}
}
#[cfg(test)]
mod tests {
use super::super::tests::test_frame;
use super::*;
#[test]
fn keyframe_from_frame_initializes_map_point_slots() {
let keyframe = Keyframe::from_frame(test_frame(7, vec![[0u8; 32], [1u8; 32], [2u8; 32]]));
assert_eq!(keyframe.frame.idx, 7);
assert_eq!(keyframe.map_point_by_desc_idx.len(), 3);
assert!(
keyframe
.map_point_by_desc_idx
.iter()
.all(|slot| slot.is_none())
);
}
#[test]
fn keyframe_association_helpers_work() {
let mut keyframe = Keyframe::from_frame(test_frame(1, vec![[0u8; 32], [1u8; 32]]));
keyframe.associate_map_point(1, 42);
assert_eq!(keyframe.map_point(1), Some(42));
assert_eq!(keyframe.num_associated_points(), 1);
keyframe.clear_map_point(1);
assert_eq!(keyframe.map_point(1), None);
assert_eq!(keyframe.num_associated_points(), 0);
}
}