Reconocer texto en imágenes (OCR) en Rust
El reconocimiento óptico de caracteres (OCR, por sus siglas en inglés) es una tecnología potente que permite a las computadoras extraer texto de imágenes. En este DevTip exploramos cómo implementar OCR en Rust con la biblioteca Tesseract y técnicas eficaces de procesamiento de imágenes para lograr una extracción de texto precisa.
Introducción
El rendimiento y las garantías de seguridad de Rust lo convierten en una excelente opción para implementar soluciones de OCR. Ya sea que estés creando un sistema de procesamiento de documentos o añadiendo capacidades de extracción de texto a tu aplicación, Rust ofrece un ecosistema robusto para gestionar estas tareas de forma eficiente.
Requisitos previos
- Rust estable actual (
image0.25.10 requiere Rust 1.88 o posterior) - Tesseract 5.0 o posterior
- pkg-config, un compilador de C y libclang (Xcode Command Line Tools en macOS)
- Datos de idioma inglés para Tesseract (
eng.traineddata) - Conocimientos básicos de Rust y Cargo
Configurar el proyecto
Primero, crea un nuevo proyecto de Rust y añade las dependencias necesarias a tu Cargo.toml:
[dependencies]
tesseract = "0.15.2"
image = "0.25.10"
anyhow = "1.0"
tempfile = "3"
Mantén Cargo.lock en el repositorio de tu aplicación para reproducir las versiones de dependencias resueltas.
Instalar Tesseract
Antes de usar los bindings de Rust, instala Tesseract en tu sistema.
En Ubuntu/Debian
sudo apt-get install tesseract-ocr tesseract-ocr-eng tesseract-ocr-osd libtesseract-dev libleptonica-dev pkg-config libclang-dev build-essential
En macOS
brew install tesseract pkgconf
Implementación básica de OCR
Este ejemplo muestra cómo extraer texto de una imagen con Tesseract en Rust.
use anyhow::Result;
use tesseract::Tesseract;
fn main() -> Result<()> {
// Initialize Tesseract for English language
let mut ocr = Tesseract::new(None, Some("eng"))?
.set_image("input.png")?;
// Retrieve the extracted text
let text = ocr.get_text()?;
println!("{}", text);
Ok(())
}
Manejar distintos formatos de imagen
Preprocesar las imágenes puede mejorar la precisión del OCR. La siguiente función convierte una imagen a escala de grises, la guarda temporalmente y ejecuta el OCR. Cada llamada es propietaria de un directorio temporal independiente, que se elimina cuando sale del ámbito, incluso cuando una operación devuelve un error.
use anyhow::{Context, Result};
use tesseract::Tesseract;
fn prepare_image_for_ocr(image_path: &str) -> Result<String> {
// Load the image and convert it to grayscale
let img = image::open(image_path)?.grayscale();
// Save the preprocessed image to a temporary file
let temp_dir = tempfile::tempdir()?;
let temp_path = temp_dir.path().join("processed.png");
img.save(&temp_path)?;
// Leptonica rewrites /tmp paths on macOS; resolve symlinks before passing the filename.
let temp_path = temp_path.canonicalize()?;
// Perform OCR on the processed image
let mut ocr = Tesseract::new(None, Some("eng"))?
.set_image(temp_path.to_str().context("Temporary path is not valid UTF-8")?)?;
let text = ocr.get_text()?;
Ok(text)
}
Configuración avanzada de OCR
Tesseract se puede ajustar con precisión especificando opciones de configuración, como listas blancas de caracteres o modos de segmentación de página.
use anyhow::Result;
use tesseract::Tesseract;
fn configure_ocr() -> Result<String> {
let mut ocr = Tesseract::new(None, Some("eng"))?
.set_variable("tessedit_char_whitelist", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")?
.set_variable("tessedit_pageseg_mode", "1")?
.set_image("input.png")?;
let text = ocr.get_text()?;
Ok(text)
}
- La opción
tessedit_char_whitelistrestringe el reconocimiento a los caracteres especificados, lo que reduce los posibles errores. - Ajustar
tessedit_pageseg_modepuede optimizar la forma en que Tesseract segmenta la imagen para distintos diseños.
Buenas prácticas para OCR en Rust
-
Preprocesamiento de imágenes
- Convierte las imágenes a escala de grises para mejorar la visibilidad del texto.
- Asegura una resolución de al menos 300 DPI para obtener texto nítido.
- Elimina el ruido aplicando filtros de imagen.
-
Optimización del rendimiento
- Usa una instancia de Tesseract independiente para cada imagen procesada de forma concurrente.
- Implementa una caché para los documentos que se procesan con frecuencia.
- Considera el procesamiento por lotes cuando manejes grandes volúmenes de imágenes.
-
Manejo de errores
Un manejo de errores adecuado garantiza que tu aplicación resuelva con elegancia los problemas que surjan durante las operaciones de OCR.
use anyhow::{Context, Result};
use tesseract::Tesseract;
fn robust_ocr(image_path: &str) -> Result<String> {
let image_path = std::fs::canonicalize(image_path)
.context("Failed to load image")?;
let mut ocr = Tesseract::new(None, Some("eng"))
.context("Failed to initialize Tesseract")?
.set_image(image_path.to_str().context("Image path is not valid UTF-8")?)
.context("Failed to load image")?;
let text = ocr.get_text()
.context("Failed to perform OCR")?;
Ok(text)
}
Manejar varios idiomas
Tesseract admite varios idiomas. Este ejemplo muestra el reconocimiento de texto en inglés, francés
y alemán. Primero instala los tres modelos de idioma: en Ubuntu/Debian, añade
tesseract-ocr-fra y tesseract-ocr-deu; en macOS, brew install tesseract-lang proporciona
idiomas adicionales. Ejecuta tesseract --list-langs para verificarlos. Para un directorio de modelos personalizado, define
TESSDATA_PREFIX con el directorio que contiene los archivos .traineddata.
use anyhow::{Context, Result};
use tesseract::Tesseract;
fn multilingual_ocr(image_path: &str) -> Result<String> {
// Initialize Tesseract with multiple languages: English, French, and German
let image_path = std::fs::canonicalize(image_path)?;
let mut ocr = Tesseract::new(None, Some("eng+fra+deu"))?
.set_image(image_path.to_str().context("Image path is not valid UTF-8")?)?;
let text = ocr.get_text()?;
Ok(text)
}
Conclusión
Implementar OCR en Rust con Tesseract ofrece una solución robusta para extraer texto de imágenes. La seguridad y el rendimiento de Rust, junto con las maduras capacidades de OCR de Tesseract, te permiten crear sistemas eficientes de extracción de texto.
Para obtener funcionalidad adicional, puedes complementar tu solución de OCR con el servicio de procesamiento de documentos de Transloadit.
