Rust语言封装chineseocr_lite:安全高效的系统级OCR库

Rust语言封装chineseocr_lite:安全高效的系统级OCR库

【免费下载链接】chineseocr_lite 超轻量级中文ocr,支持竖排文字识别, 支持ncnn、mnn、tnn推理 ( dbnet(1.8M) + crnn(2.5M) + anglenet(378KB)) 总模型仅4.7M 【免费下载链接】chineseocr_lite 项目地址: https://gitcode.com/gh_mirrors/ch/chineseocr_lite

chineseocr_lite是一个超轻量级中文OCR项目,支持竖排文字识别,总模型仅4.7M,包含dbnet(1.8M)、crnn(2.5M)和anglenet(378KB)三个模型。本文将介绍如何使用Rust语言封装chineseocr_lite,构建安全高效的系统级OCR库。

项目概述

chineseocr_lite项目提供了多种推理框架的支持,包括ncnn、mnn、tnn等。项目结构清晰,包含多个子项目,如C++ Demo、Jvm Demo、Android Demo等。原始项目使用Python实现,部署简单,支持多种操作系统。

核心模型文件

项目的核心模型文件位于models/目录下,包括:

这些模型文件是OCR功能的核心,Rust封装将基于这些模型进行推理实现。

现有C++实现参考

项目中已经提供了C++版本的实现,位于cpp_projects/目录下,包括OcrLiteMnn、OcrLiteNcnn和OcrLiteOnnx等子项目。这些实现可以作为Rust封装的重要参考,特别是:

Rust封装方案

整体架构设计

Rust封装chineseocr_lite将采用以下架构:

  1. FFI层:使用Rust的FFI(Foreign Function Interface)能力,封装现有的C++推理代码
  2. 安全抽象层:在FFI之上构建Rust安全抽象,提供类型安全的API
  3. 高层API:设计易用的Rust API,支持文本检测、识别等核心功能

依赖选择

  1. ncnn-rs:ncnn的Rust绑定,用于模型推理
  2. image:Rust图像处理库,用于图像加载和预处理
  3. ndarray:Rust数值计算库,用于张量操作
  4. thiserror:错误处理库,定义清晰的错误类型

核心模块设计

  1. ocr_engine:OCR引擎核心模块,封装检测、识别等功能
  2. preprocess:图像预处理模块,实现图像缩放、归一化等操作
  3. postprocess:后处理模块,实现文本框提取、识别结果处理等
  4. model_loader:模型加载模块,负责加载和管理ONNX或ncnn模型

实现步骤

1. 模型加载

使用ncnn-rs加载ncnn模型文件,模型文件位于models_ncnn/目录下:

use ncnn::Net;

pub struct ModelLoader {
    dbnet: Net,
    crnn: Net,
    anglenet: Net,
}

impl ModelLoader {
    pub fn new() -> Self {
        let mut dbnet = Net::new();
        dbnet.load_param("models_ncnn/dbnet_op.param").unwrap();
        dbnet.load_model("models_ncnn/dbnet_op.bin").unwrap();
        
        let mut crnn = Net::new();
        crnn.load_param("models_ncnn/crnn_lite_op.param").unwrap();
        crnn.load_model("models_ncnn/crnn_lite_op.bin").unwrap();
        
        let mut anglenet = Net::new();
        anglenet.load_param("models_ncnn/angle_op.param").unwrap();
        anglenet.load_model("models_ncnn/angle_op.bin").unwrap();
        
        ModelLoader { dbnet, crnn, anglenet }
    }
}

2. 图像预处理

使用image库加载图像并进行预处理:

use image::{DynamicImage, GenericImageView, ImageBuffer, Luma};

pub fn preprocess_image(image: &DynamicImage, target_size: (u32, u32)) -> ImageBuffer<Luma<u8>, Vec<u8>> {
    // 调整图像大小
    let resized = image.resize(target_size.0, target_size.1, image::imageops::FilterType::Triangle);
    
    // 转换为灰度图
    let gray = resized.to_luma8();
    
    // 归一化处理
    let mut processed = ImageBuffer::new(gray.width(), gray.height());
    for (x, y, pixel) in gray.enumerate_pixels() {
        processed.put_pixel(x, y, Luma([pixel.0[0] as f32 / 255.0 * 2.0 - 1.0]));
    }
    
    processed
}

3. 文本检测与识别

实现文本检测和识别的核心功能:

pub struct OcrEngine {
    model_loader: ModelLoader,
}

impl OcrEngine {
    pub fn new() -> Self {
        OcrEngine {
            model_loader: ModelLoader::new(),
        }
    }
    
    pub fn detect_text(&self, image: &DynamicImage) -> Vec<TextBox> {
        // 图像预处理
        let processed = preprocess_image(image, (640, 640));
        
        // 使用dbnet进行文本检测
        let mut input = ncnn::Mat::from_bytes(
            processed.as_raw(),
            processed.width() as i32,
            processed.height() as i32,
            1,
            ncnn::PixelType::PIXEL_GRAY,
        ).unwrap();
        
        let mut output = ncnn::Mat::new();
        self.model_loader.dbnet.forward(&mut input, &mut output).unwrap();
        
        // 后处理获取文本框
        let text_boxes = postprocess_dbnet_output(&output);
        
        text_boxes
    }
    
    pub fn recognize_text(&self, image: &DynamicImage, text_boxes: &[TextBox]) -> Vec<String> {
        let mut results = Vec::new();
        
        for box in text_boxes {
            // 裁剪文本区域
            let cropped = crop_image(image, box);
            
            // 预处理
            let processed = preprocess_crnn_input(&cropped);
            
            // 使用crnn进行文本识别
            let result = self.model_loader.crnn.forward(&processed).unwrap();
            
            // 解码识别结果
            let text = decode_crnn_output(&result);
            
            results.push(text);
        }
        
        results
    }
}

性能优化

多线程处理

利用Rust的并发特性,实现图像预处理和文本识别的并行处理:

use rayon::prelude::*;

pub fn recognize_text_parallel(&self, image: &DynamicImage, text_boxes: &[TextBox]) -> Vec<String> {
    text_boxes.par_iter()
        .map(|box| {
            let cropped = crop_image(image, box);
            let processed = preprocess_crnn_input(&cropped);
            let result = self.model_loader.crnn.forward(&processed).unwrap();
            decode_crnn_output(&result)
        })
        .collect()
}

内存管理优化

使用Rust的所有权系统,优化内存管理,避免内存泄漏:

// 使用RAII模式管理模型资源
struct ModelResource<T> {
    inner: T,
}

impl<T> Drop for ModelResource<T> {
    fn drop(&mut self) {
        // 释放模型资源
        unsafe {
            // 调用C++析构函数或释放函数
            release_model(&mut self.inner);
        }
    }
}

应用示例

基本OCR功能

use chineseocr_lite_rs::OcrEngine;
use image::open;

fn main() {
    // 创建OCR引擎
    let engine = OcrEngine::new();
    
    // 加载图像
    let image = open("test.jpg").unwrap();
    
    // 检测文本
    let text_boxes = engine.detect_text(&image);
    
    // 识别文本
    let texts = engine.recognize_text(&image, &text_boxes);
    
    // 输出结果
    for text in texts {
        println!("识别结果: {}", text);
    }
}

实际识别效果

chineseocr_lite项目提供了多个测试图像和识别效果展示,例如:

身份证识别

车牌识别

IMEI识别

这些动图展示了OCR在不同场景下的识别效果,Rust封装将保持类似的识别精度和性能。

总结与展望

Rust语言封装chineseocr_lite可以充分发挥Rust的安全、高效特性,为系统级OCR应用提供可靠的解决方案。未来可以进一步优化:

  1. 纯Rust实现:逐步替换C++依赖,实现纯Rust的推理引擎
  2. WebAssembly支持:编译为WebAssembly,支持浏览器端OCR
  3. 移动端支持:结合Rust的跨平台能力,支持Android和iOS平台

通过Rust封装,chineseocr_lite将获得更好的安全性、性能和跨平台能力,为更多场景提供高质量的OCR解决方案。

【免费下载链接】chineseocr_lite 超轻量级中文ocr,支持竖排文字识别, 支持ncnn、mnn、tnn推理 ( dbnet(1.8M) + crnn(2.5M) + anglenet(378KB)) 总模型仅4.7M 【免费下载链接】chineseocr_lite 项目地址: https://gitcode.com/gh_mirrors/ch/chineseocr_lite

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值