refactor: 重构 OcrBuilder 过滤机制,实现零克隆、高性能的局部白名单

- 将有状态的有效索引缓存 `valid_indices` 从全局 `Charset` 剥离至局部 `OcrBuilder`
- 解码函数 `ctc_decode_to_string` 内部复用策略计算,通过 `has_any_match` 布尔开关实现全量免检短路加速
- 优化内存分配,根据 `CharsetRestrict` 策略动态精准计算 `HashSet` 初始容量,规避大词表空置浪费
- 增强鲁棒性,在策略与字库完全无交集时,自动触发智能降级,一键恢复全量识别并保持接口自洽
This commit is contained in:
2026-06-09 18:12:02 +08:00
parent 15ce068025
commit 0c96fbedbf
5 changed files with 133 additions and 98 deletions

View File

@@ -14,6 +14,7 @@ use crate::models::ocr::ColorRange;
use models::det::Det;
use models::loader::ModelSession;
use models::ocr::Ocr;
use crate::model_metadata::ModelMetadata;
pub enum ModelSpec {
/// 默认 OCR (使用内置路径)
@@ -22,7 +23,7 @@ pub enum ModelSpec {
/// 自定义 OCR (路径由用户提供)
CustomOcrModel {
path: String,
charset: Vec<String>,
model_metadata: ModelMetadata,
},
}
impl ModelSpec {
@@ -61,9 +62,9 @@ impl DdddOcrBuilder {
}
/// 设置自定义 OCR 路径
pub fn custom_ocr(mut self, path: String, charset: Vec<String>) -> Self {
pub fn custom_ocr(mut self, path: String, model_metadata: ModelMetadata) -> Self {
// 直接重写枚举,替换掉之前的 Ocr 或 Det
self.mode = ModelSpec::CustomOcrModel { path, charset };
self.mode = ModelSpec::CustomOcrModel { path, model_metadata };
self
}
@@ -72,10 +73,10 @@ impl DdddOcrBuilder {
let runtime = match self.mode {
ModelSpec::OcrModel => Runtime::Ocr(Ocr::new(
ModelSpec::DEFAULT_OCR_PATH.into(),
get_default_charset(),
ModelMetadata::from_builtin_beta(),
)?),
ModelSpec::DetModel => Runtime::Det(Det::new(ModelSpec::DEFAULT_DET_PATH.into())?),
ModelSpec::CustomOcrModel { path, charset } => Runtime::Ocr(Ocr::new(path, charset)?),
ModelSpec::CustomOcrModel { path, model_metadata } => Runtime::Ocr(Ocr::new(path, model_metadata)?),
};
Ok(DdddOcr { runtime })