use crate::error::Result;
use crate::types::{Image, OcrResult, Point, Quad, TextLine};
use super::ReadOptions;
pub trait OcrEngine: Send + Sync {
fn recognize(&self, image: &Image, options: &ReadOptions) -> Result<OcrResult>;
fn detect(&self, image: &Image, options: &ReadOptions) -> Result<Vec<Quad>> {
Ok(self
.recognize(image, options)?
.lines
.into_iter()
.map(|line| line.quad)
.collect())
}
fn recognize_line(&self, image: &Image, options: &ReadOptions) -> Result<TextLine> {
Ok(merge_lines_into_one(image, self.recognize(image, options)?))
}
}
fn merge_lines_into_one(image: &Image, result: OcrResult) -> TextLine {
let width = image.width() as f32;
let height = image.height() as f32;
let quad = Quad {
points: [
Point::new(0.0, 0.0),
Point::new(width, 0.0),
Point::new(width, height),
Point::new(0.0, height),
],
};
if result.lines.is_empty() {
return TextLine {
quad,
text: String::new(),
confidence: 0.0,
};
}
let count = result.lines.len() as f32;
let confidence = result.lines.iter().map(|line| line.confidence).sum::<f32>() / count;
let text = result
.lines
.into_iter()
.map(|line| line.text)
.collect::<Vec<_>>()
.join(" ");
TextLine { quad, text, confidence }
}