feat: 字符集限制枚举优化与核心解码器对接

- 新增 model_metadata.rs
- 优化 charset.rs
- 其他优化
This commit is contained in:
2026-06-05 17:30:10 +08:00
parent cb786a7a1a
commit 15ce068025
5 changed files with 345 additions and 89 deletions

View File

@@ -8,92 +8,13 @@ use tract_onnx::prelude::tract_ndarray::s;
use tract_onnx::prelude::{
DatumType, Graph, IntoTensor, RunnableModel, Tensor, TypedFact, TypedOp, tract_ndarray, tvec,
};
use crate::charset::CharsetRange;
// 颜色过滤的自定义范围:(低值RGB, 高值RGB)
pub type ColorRange = ((u8, u8, u8), (u8, u8, u8));
// 字符集范围类型
#[derive(Debug, Clone)]
pub enum CharsetRange {
All, // 所有字符
Digit, // 数字
Letter, // 字母
Alphanumeric, // 字母数字
Single(String), // 单字符串
Multiple(Vec<String>), // 多个字符串
Range(char, char), // 字符范围
Custom(Vec<char>), // 自定义字符列表
}
#[derive(Debug, Clone)]
pub struct PredictArgs {
/// 是否修复PNG格式问题
pub png_fix: bool,
/// 是否返回概率信息
pub probability: bool,
/// 颜色过滤:保留的颜色列表
pub color_filter_colors: Option<Vec<String>>,
/// 颜色过滤自定义RGB范围
pub color_filter_custom_ranges: Option<Vec<ColorRange>>,
/// 字符集范围
pub charset_range: Option<CharsetRange>,
}
impl Default for PredictArgs {
fn default() -> Self {
Self {
png_fix: false,
probability: false,
color_filter_colors: None,
color_filter_custom_ranges: None,
charset_range: None,
}
}
}
impl PredictArgs {
pub fn new() -> Self {
Self::default()
}
// Builder 模式方法
pub fn png_fix(mut self, enabled: bool) -> Self {
self.png_fix = enabled;
self
}
pub fn probability(mut self, enabled: bool) -> Self {
self.probability = enabled;
self
}
pub fn color_filter_colors(mut self, colors: Vec<String>) -> Self {
self.color_filter_colors = Some(colors);
self
}
pub fn color_filter_custom_ranges(mut self, ranges: Vec<ColorRange>) -> Self {
self.color_filter_custom_ranges = Some(ranges);
self
}
pub fn charset_range(mut self, range: CharsetRange) -> Self {
self.charset_range = Some(range);
self
}
// 便捷构造方法
pub fn quick() -> Self {
Self::default()
}
pub fn with_probability() -> Self {
Self::default().probability(true)
}
pub fn with_png_fix() -> Self {
Self::default().png_fix(true)
}
}
pub struct Ocr {
pub session: RunnableModel<TypedFact, Box<dyn TypedOp>, Graph<TypedFact, Box<dyn TypedOp>>>,
pub charset: Vec<String>,
@@ -111,28 +32,38 @@ impl Ocr {
let session = ModelLoader::load_model(&model_path)?.session;
Ok(Self { session, charset })
}
pub fn task<'a>(&'a self, image: &'a DynamicImage) -> OcrTask {
OcrTask::new(self, image)
pub fn predict<'a>(&'a self, image: &'a DynamicImage) -> OcrBuilder<'a> {
OcrBuilder::new(self, image)
}
}
pub struct OcrTask<'a> {
pub struct OcrBuilder<'a> {
ocr: &'a Ocr,
image: &'a DynamicImage,
/// 是否修复PNG格式问题
png_fix: bool,
/// 是否返回概率信息
#[allow(dead_code)]
probability: bool,
/// 颜色过滤:保留的颜色列表
color_filter_colors: Option<Vec<ColorRange>>,
/// 颜色过滤自定义RGB范围
color_filter_custom_ranges: Option<Vec<ColorRange>>,
/// 字符集范围
charset_range: Option<CharsetRange>,
}
impl<'a> OcrTask<'a> {
impl<'a> OcrBuilder<'a> {
// 初始化任务,设置默认参数
pub fn new(ocr: &'a Ocr, image: &'a DynamicImage) -> Self {
Self {
ocr,
image,
png_fix: false, // 默认值
probability: false,
color_filter_colors: None,
color_filter_custom_ranges: None,
charset_range: None
}
}
pub fn png_fix(mut self, value: bool) -> Self {
@@ -147,9 +78,13 @@ impl<'a> OcrTask<'a> {
self.color_filter_custom_ranges = Some(value);
self
}
pub fn charset_range(mut self, range: CharsetRange) -> Self {
self.charset_range = Some(range);
self
}
pub fn predict(&self, image: &DynamicImage, png_fix: bool) -> Result<String, anyhow::Error> {
let tensor = self.preprocess_image(image, png_fix)?;
pub fn run(&self) -> Result<String, anyhow::Error> {
let tensor = self.preprocess_image(self.image, self.png_fix)?;
//
// let result = self.session.run(tvec!(tensor.into()))?;
// // 3. 解析结果