bye_abow_rs 0.1.0

Visual bag of words for fast image matching without opencv.
Documentation
#![allow(dead_code)]
#![allow(unused_variables)]
#![allow(unused_imports)]
#![allow(non_fmt_panics)]
#![allow(unused_mut)]
#![allow(unused_assignments)]
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
#![allow(rustdoc::missing_crate_level_docs)]
#![allow(unsafe_code)]
#![allow(clippy::undocumented_unsafe_blocks)]
#![allow(unused_must_use)]
#![allow(non_snake_case)]
#![allow(clippy::upper_case_acronyms)]

use smallvec::SmallVec;
use thiserror::Error;
use serde::{
    Deserialize, Serialize
};

/// vocabulary模块
pub mod vocabulary;

/// keypoint模块
pub mod keypoint;

/// 支持的描述符类型是256位数组
pub type Desc = [u8; 32];

/// 图像或描述符集的词袋表示。
/// 索引: 词汇表中的单词/叶子ID。
/// 值: 在提供的特征中该单词的总权重。
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct BoW(pub Vec<f32>);

/// 从特征到词汇树中对应节点的映射。
/// 每个特征映射到多个节点,每个树层最多一个。
/// `feature[i]`的直接索引是`di = DirectIdx[i]`,其中
/// `di.len() <= l`(层数)。
/// `di[j]`是与`feature[i]`匹配的节点在词汇树中
/// 第`j`层的ID。
pub type DirectIdx = Vec<IdPath>;

/// 给定特征从根到叶子的路径。
/// 只有5个条目是堆栈分配的,因此层数>5时性能较差。
pub type IdPath = SmallVec<[usize; 5]>;

/// BoW的实现
impl BoW {
    /// 计算两个BoW之间的L1范数。(用于Galvez(方程2))。
    pub fn l1(&self, other: &Self) -> f32 {
        let values = self.0.iter().zip(&other.0);
        1. - 0.5 * (values.fold(0., |a, (b, c)| a + (b - c).abs()))
    }
}

/// 定义报错类型
type BowResult<T> = std::result::Result<T, BowErr>;
#[derive(Error, Debug)]
pub enum BowErr {
    // 未提供任何特征
    #[error("No Features Provided")]
    NoFeatures,

    // IO错误
    #[error("Io Error")]
    Io(#[from] std::io::Error),

    // 序列化错误
    #[error("Vocabulary Serialization Error")]
    Bincode(#[from] bincode::Error),

}