refactor(slide,det): 优化项目结构,移除不必要的逻辑

- 优化 项目结构,移除不必要的逻辑
This commit is contained in:
2026-07-07 09:55:00 +08:00
parent 7f1ce04f50
commit 31271e80db
9 changed files with 312 additions and 166 deletions

View File

@@ -1,4 +1,4 @@
use anyhow::Context;
use anyhow::{anyhow, Context};
use image::DynamicImage;
use tract_onnx::onnx;
use tract_onnx::prelude::*;
@@ -6,10 +6,12 @@ use tract_onnx::prelude::*;
use crate::utils::image_io::png_rgba_white_preprocess;
use crate::utils::image_processor::{convert_to_grayscale, resize_image};
use std::collections::HashMap;
use std::io::Cursor;
use tract_onnx::prelude::tract_ndarray::s;
use crate::ModelMetadata;
/// OCR 模型:包含路径和字符集
const DEFAULT_OCR_PATH: &'static str = "common_sml2h3_f32.onnx";
pub enum ModelType {
Ocr,
Det,
@@ -26,7 +28,7 @@ pub struct ModelLoader {
}
impl ModelLoader {
pub fn load_model<P>(model_path: P) -> anyhow::Result<Self>
pub fn model_for_path<P>(model_path: P) -> anyhow::Result<Self>
where
P: AsRef<std::path::Path>,
{
@@ -37,4 +39,74 @@ impl ModelLoader {
.into_runnable()?;
Ok(Self { session })
}
/// 策略 B从内存字节流加载模型配合 include_bytes! 使用)
pub fn model_from_bytes(model_bytes: &[u8]) -> anyhow::Result<Self> {
// 使用 std::io::Cursor 将 &[u8] 包装为可读的流(实现 std::io::Read
let mut cursor = Cursor::new(model_bytes);
let session = onnx()
.model_for_read(&mut cursor)
.with_context(|| "从内存字节流解析 ONNX 模型失败")?
.into_optimized()?
.into_runnable()?;
Ok(Self { session })
}
}
// impl ModelLoader {
// pub fn find_model_path(env_var: &str, default_filename: &str) -> Option<std::path::PathBuf> {
// // 1. 策略一:优先尝试读取环境变量
// if let Ok(env_path) = std::env::var(env_var) {
// let path = std::path::PathBuf::from(env_path);
// if path.exists() {
// return Some(path);
// }
// }
// // 2. 策略二:尝试在当前工作目录寻找
// if let Ok(mut path) = std::env::current_dir() {
// path.push(default_filename);
// if path.exists() {
// return Some(path);
// }
// }
//
// // 3. 策略三:尝试在当前可执行文件同级目录寻找
// if let Ok(mut exe_path) = std::env::current_exe() {
// exe_path.pop(); // 弹出可执行文件名,拿到所在的父目录
// exe_path.push(default_filename);
// if exe_path.exists() {
// return Some(exe_path);
// }
// }
// // 4. 所有本地探测策略均落空
// None
// }
// }
// pub fn new_default() -> anyhow::Result<Self> {
// let metadata = ModelMetadata::from_builtin_beta(); // 绑定自带的 BETA 字符集
//
// // 1. 策略一:优先尝试读取环境变量
// if let Some(path) = ModelLoader::find_model_path("DDDD_OCR_MODEL", DEFAULT_OCR_PATH) {
// return Self::new(path, metadata);
// }
//
// // 4. 策略四:开启了 embed-models 特征时的编译期死穴保底
// // 如果开启了 feature 但根目录下没有该模型,编译时会在此处直接中断失败
//
// #[cfg(feature = "embed-models")]
// {
// let model_bytes = include_bytes!("../models/common_sml2h3_f32.onnx");
// // 注意:这里需要你的 InternalOcr 扩展一个 from_bytes 的方法
// return Self::model_from_bytes(model_bytes, metadata);
//
// }
//
// // 5. 所有策略落空,抛出保姆级错误
// #[cfg(not(feature = "embed-models"))]
// {
// Err(anyhow!(MODEL_DOWNLOAD_HELP))
// }
// }