df_ocr_switcher/engine/mod.rs
1//! Trait comune e tipi condivisi per tutti gli engine OCR.
2//!
3//! Layout analysis (PP-DocLayoutV3) e orientamento (PP-LCNet) sono SEMPRE
4//! eseguiti da ppocr-rs, indipendentemente dall'engine di text recognition.
5//! L'engine scambiabile riguarda solo il passo "immagine → testo + bbox".
6
7use image::RgbImage;
8use ppocr_rs::{LayoutAnalyzer, SemanticClass};
9use serde::{Deserialize, Serialize};
10
11use crate::error::Result;
12
13pub mod ppocr;
14#[cfg(feature = "tesseract-engine")]
15pub mod tesseract;
16
17// ─── Tipi comuni ─────────────────────────────────────────────────────────────
18
19/// Parola singola con AABB e confidence.
20#[derive(Debug, Clone, Serialize, Deserialize)]
21pub struct OcrWord {
22 pub text: String,
23 pub x1: u32, pub y1: u32, pub x2: u32, pub y2: u32,
24 pub confidence: f32,
25 /// Indice in `OcrPageResult.layout_boxes`; -1 se nessuna regione.
26 pub layout_idx: i32,
27}
28
29/// Blocco di testo (linea o paragrafo) già assemblato.
30/// Il testo è già riconosciuto; bbox AABB del blocco intero.
31#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct OcrBlock {
33 pub text: String,
34 pub x1: u32, pub y1: u32, pub x2: u32, pub y2: u32,
35 pub confidence: f32,
36 /// Indice in `OcrPageResult.layout_boxes`; -1 se orfano.
37 pub layout_idx: i32,
38}
39
40/// Regione di layout rilevata da PP-DocLayoutV3.
41#[derive(Debug, Clone, Serialize, Deserialize)]
42pub struct OcrLayoutBox {
43 /// Classe grezza PP-DocLayoutV3 (es. `"Text"`, `"Title"`, `"Table"`, …).
44 pub class_name: String,
45 /// Categoria semantica semplificata (8 classi).
46 pub semantic: SemanticClass,
47 pub x1: u32, pub y1: u32, pub x2: u32, pub y2: u32,
48 /// Ordine di lettura assegnato dal modello; -1 se non disponibile.
49 pub reading_order: i32,
50}
51
52/// Tabella strutturata estratta da una regione `SemanticClass::Table`.
53/// Disponibile solo con `PpOcrEngine` (richiede SLANeXt model).
54#[derive(Debug, Clone, Serialize, Deserialize)]
55pub struct OcrTable {
56 /// Indice in `OcrPageResult.layout_boxes` della regione sorgente.
57 pub layout_idx: i32,
58 /// Tabella in GitHub Flavored Markdown (righe `| cell | cell |`).
59 /// Stringa vuota se la struttura non è riconoscibile.
60 pub gfm: String,
61}
62
63/// Formula matematica estratta da una regione `SemanticClass::Equation`.
64/// Disponibile solo con `PpOcrEngine` + `enable_formula_decoder = true`.
65#[derive(Debug, Clone, Serialize, Deserialize)]
66pub struct OcrFormula {
67 /// Indice in `OcrPageResult.layout_boxes` della regione sorgente.
68 pub layout_idx: i32,
69 /// Stringa LaTeX. Vuota se il decoder è disabilitato o fallisce.
70 pub latex: String,
71}
72
73/// Risultato OCR per una singola pagina.
74#[derive(Debug, Clone, Serialize, Deserialize)]
75pub struct OcrPageResult {
76 /// Gradi di rotazione applicati (0/90/180/270). 0 = già upright.
77 pub page_angle: u32,
78 pub page_width: u32,
79 pub page_height: u32,
80 /// Layout boxes ordinati per `reading_order`.
81 pub layout_boxes: Vec<OcrLayoutBox>,
82 /// Blocchi di testo (line-level).
83 pub blocks: Vec<OcrBlock>,
84 /// Parole word-level (solo se l'engine supporta `return_word_box`).
85 pub words: Vec<OcrWord>,
86 /// Tabelle strutturate GFM (solo `PpOcrEngine` con SLANeXt caricato).
87 pub tables: Vec<OcrTable>,
88 /// Formule LaTeX (solo `PpOcrEngine` con `enable_formula_decoder`).
89 pub formulas: Vec<OcrFormula>,
90}
91
92// ─── Trait ───────────────────────────────────────────────────────────────────
93
94/// Interfaccia comune per engine OCR.
95///
96/// L'engine riceve sempre un'immagine già upright (rotazione gestita dal
97/// [`crate::pipeline::DocPipeline`]) e un `LayoutAnalyzer` da ppocr-rs.
98/// Restituisce [`OcrPageResult`] con blocks e opzionalmente words.
99pub trait OcrEngine: Send {
100 fn process_page(
101 &mut self,
102 img: &RgbImage,
103 layout: &mut LayoutAnalyzer,
104 ) -> Result<OcrPageResult>;
105}