IRONSOFTWAREHOME
VIDEOS

Cómo mejorar la calidad de la imagen para obtener mejores resultados de OCR con C#

Kannaopat Udonpant
Kannapat Udonpant
Updated: 1 de agosto de 2026

Esta guía guía a los desarrolladores de .NET a través de una migración completa desde la familia de paquetes Sdcb.PaddleOCR a IronOCR. Cubre todo el proceso de reemplazo: eliminar la pila de múltiples paquetes PaddlePaddle, eliminar la gestión de archivos de modelo y la configuración de la GPU, y reemplazar la canalización de inferencia dependiente de OpenCV con una única instalación de NuGet . Cada sección es independiente; no es necesario leer previamente el artículo comparativo.

¿Por qué migrar desde PaddleOCR?

El contenedor Sdcb.PaddleOCR es un puente mantenido por la comunidad entre el ecosistema de aprendizaje profundo en Python de PaddlePaddle y .NET. Cumple su función, pero conlleva todo el peso de ese puente: archivos de modelo, binarios de inferencia nativos, OpenCV para la carga de imágenes e infraestructura CUDA opcional. Para la mayoría de las cargas de trabajo de OCR en .NET , esa es una infraestructura que el proyecto nunca necesitó.

Tres directorios de modelos antes de leer un solo carácter. El proceso de inferencia de PaddleOCR encadena tres redes neuronales: un modelo de detección, un modelo de clasificación de dirección y un modelo de reconocimiento. Cada red es un directorio separado de archivos .pdmodel y .pdiparams que deben existir en disco antes de que new PaddleOcrAll(models) compile a un motor funcional. Ya sea que esos archivos lleguen mediante una llamada de descarga asíncrona, que conecta al almacenamiento de bj.bcebos.com de Baidu en China, o mediante un árbol de directorio mantenido manualmente models/, el desarrollador es permanentemente responsable de la versionado de modelos. Cuando Sdcb.PaddleOCR se actualiza, los modelos pre-descargados de la versión anterior pueden requerir una re-descarga.IronOCR no tiene archivos de modelo, ni directorios de modelo, ni problemas de sincronización de versiones. El motor viene incluido en el paquete NuGet .

OpenCV no es opcional. No hay un camino desde una ruta de archivo a la inferencia de PaddleOCR que pase por alto OpenCvSharp. Cada imagen, independientemente del formato, debe pasar a través de Cv2.ImRead(path) para convertirse en un objeto Mat antes de que ocr.Run(mat) pueda aceptarlo. Eso significa dos paquetes NuGet adicionales (OpenCvSharp4 y OpenCvSharp4.runtime.win), DLLs nativas específicas de plataforma en el resultado de implementación y una línea apt-get install libopencv-dev en el Dockerfile.IronOCR acepta rutas de archivo, flujos, matrices de bytes y System.Drawing.Bitmap directamente. No existe el intermediario Mat.

La configuración de la GPU es un proyecto que lleva varios días. Las cifras de rendimiento de la GPU que anuncia PaddleOCR (50-100 ms por imagen frente a 300-500 ms en la CPU) son reales. Para ello se requieren controladores NVIDIA de una versión específica, CUDA Toolkit 11.8 (no 12.x), cuDNN 8.6+ ubicado en las rutas PATH correctas y un paquete NuGet de tiempo de ejecución de GPU independiente. En Docker, la imagen base debe ser nvidia/cuda:11.8.0-cudnn8-runtime-ubuntu22.04 y el host debe tener instalado nvidia-container-toolkit. Los equipos que no disponen de infraestructura de GPU invierten entre 2 y 8 horas en la configuración de CUDA por entorno.IronOCR está diseñado para la inferencia por CPU, ofrece un tiempo de procesamiento de 150 a 300 ms por imagen en hardware estándar y no requiere ninguna configuración de GPU.

Los artefactos de implementación son 4-6x más grandes. El resultado de implementación de PaddleOCR incluye paddle_inference.dll (~200MB), paddle2onnx.dll (~5MB), archivos opencv_world*.dll (~50MB combinados) y los directorios de modelo (~21MB). Una imagen de Docker ocupa aproximadamente 1,5 GB. El tamaño total de una instalación de IronOCR es de aproximadamente 80 MB. La imagen de Docker ocupa aproximadamente 400 MB. La diferencia se agrava en CI/CD: cada ejecución del pipeline que restaura paquetes NuGet debe descargar los modelos de Baidu o extraerlos de una capa de caché mantenida por separado.

No genera archivos PDF con capacidad de búsqueda. PaddleOCR extrae regiones de texto de las imágenes, pero no dispone de ningún mecanismo para incrustar el texto reconocido en un PDF como una capa con capacidad de búsqueda. Para crear un PDF con capacidad de búsqueda a partir de la salida de PaddleOCR, se requiere una biblioteca de PDF de terceros, la inyección de capas de texto página por página y la reasignación de coordenadas.IronOCR produce un PDF completamente buscable con una línea: result.SaveAsSearchablePdf("output.pdf").

El problema fundamental

PaddleOCR requiere que se configuren tres directorios de modelos antes de que pueda comenzar la inferencia:

// PaddleOCR: three model directories, all must exist and match the wrapper version
FullOcrModel models = new FullOcrModel(
    LocalDetectionModel.FromDirectory("models/ch_PP-OCRv4_det_infer"),       // ~5MB
    LocalClassificationModel.FromDirectory("models/ch_ppocr_mobile_v2.0_cls_infer"), // ~2MB
    LocalRecognitionModel.FromDirectory("models/ch_PP-OCRv4_rec_infer")      // ~15MB
);
using PaddleOcrAll ocr = new PaddleOcrAll(models);
using Mat mat = Cv2.ImRead("document.png");  // OpenCvSharp required for every image
PaddleOcrResult result = ocr.Run(mat);
C#

IronOCR no tiene archivos de modelo, ni directorios de modelo, ni dependencia de OpenCV:

// IronOCR: one package, zero model management
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("document.png");
var result = ocr.Read(input);
Console.WriteLine(result.Text);
C#

IronOCR vs PaddleOCR (.NET): Comparación de características

La tabla que aparece a continuación recoge las dimensiones más importantes a la hora de planificar la migración.

CaracterísticaPaddleOCR (Sdcb)IronOCR
Se requieren paquetes NuGet4-51
Se requieren archivos de modeloSí (3 directorios, ~21 MB)No (incluido en el paquete)
Fuente de descarga del modeloServidores de Baidu (bj.bcebos.com)Restauración de NuGet (Iron Software)
dependencia de OpenCVRequerido (OpenCvSharp4)None
Entrada de imagenA través de Mat mat = Cv2.ImRead()Ruta de archivo directa, flujo, matriz de bytes
Entrada nativa de PDFNoSí (input.LoadPdf())
Salida en PDF con capacidad de búsquedaNoSí (result.SaveAsSearchablePdf())
Entrada TIFF multifotogramaBucle manual por fotogramainput.LoadImageFrames()
Compatibilidad con GPUSí (se requiere CUDA 11.8 + cuDNN)Optimizado para CPU (no requiere GPU)
Preprocesamiento integradoNo (la red neuronal maneja la asimetría/el ruido)Sí (Desinclinar, Reducir ruido, Contraste, Binarizar, Nitidez)
Idiomas compatibles14125+
Método de instalación del idiomaDownloadAsync() por modelo de idiomadotnet add package IronOcr.Languages.*
Multilingüe simultáneoNo (modelo independiente por idioma)Sí (OcrLanguage.English + OcrLanguage.French)
Salida estructuradaresult.Regions (espacial, desordenado)Páginas, párrafos, líneas, palabras, caracteres
Puntuación de confianzaValor flotante por región (0-1)Porcentaje por palabra (0-100)
Lectura de códigos de barrasNoSí (ocr.Configuration.ReadBarCodes = true)
Exportación hOCRNo
Tamaño de despliegue300-500 MB~80MB
Tamaño de la imagen de Docker~1,5 GB (con base CUDA)~400 MB
Tiempo de arranque en frío3-5 segundos (carga del modelo)Menos de 1 segundo
Plataforma cruzadaWindows, Linux (parcial)Windows, Linux, macOS, Docker, Azure, AWS
Compatibilidad con .NET.NET 6+ (envoltorio comunitario).NET Framework 4.6.2+, .NET 5/6/7/8/9
Apoyo comercialProblemas de la comunidad/GitHubSí (Iron Software, con SLA)
LicenciaApache 2.0 (gratuito)Perpetual ($999 Lite / $1,499 Pro / $2,999 Enterprise)

Inicio rápido: Migración de PaddleOCR (.NET) a IronOCR

Paso 1: Sustituir paquetes NuGet

Elimine los cinco paquetes relacionados con PaddleOCR:

dotnet remove package Sdcb.PaddleOCR
dotnet remove package Sdcb.PaddleOCR.Models.Online
dotnet remove package Sdcb.PaddleInference.runtime.win64.mkl
dotnet remove package OpenCvSharp4
dotnet remove package OpenCvSharp4.runtime.win
SHELL

Si el entorno de ejecución de la GPU estaba instalado, elimínelo también:

dotnet remove package Sdcb.PaddleInference.runtime.win64.cuda118
SHELL

Instale IronOCR desde la página del paquete NuGet :

dotnet add package IronOcr

Paso 2: Actualizar los espacios de nombres

Reemplace todas las importaciones de espacios de nombres de PaddleOCR y OpenCvSharp:

// Before (PaddleOCR)
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models;
using Sdcb.PaddleOCR.Models.Online;
using Sdcb.PaddleInference;
using OpenCvSharp;

// After (IronOCR)
using IronOcr;
C#

Paso 3: Inicializar licencia

Agrega la inicialización de la licencia una vez al inicio de la aplicación, antes de que se cree cualquier instancia de IronTesseract:

IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

Puede obtener una clave de prueba gratuita en la página de licencias de IronOCR . La versión de prueba genera un resultado con marca de agua y permite probar todas las funciones antes de la compra.

Ejemplos de migración de código

Eliminación de la configuración de la ruta del modelo local

Los proyectos que descargan previamente los archivos del modelo PaddleOCR para evitar conexiones con el servidor Baidu durante la ejecución deben configurar tres rutas de directorio separadas. Esta configuración debe actualizarse cada vez que cambie la versión del envoltorio.

Enfoque PaddleOCR:

// Local model configuration — developer owns the directory structure
// Each wrapper update may require re-downloading model files
string modelsRoot = Path.Combine(AppContext.BaseDirectory, "models");

FullOcrModel models = new FullOcrModel(
    LocalDetectionModel.FromDirectory(
        Path.Combine(modelsRoot, "ch_PP-OCRv4_det_infer")),
    LocalClassificationModel.FromDirectory(
        Path.Combine(modelsRoot, "ch_ppocr_mobile_v2.0_cls_infer")),
    LocalRecognitionModel.FromDirectory(
        Path.Combine(modelsRoot, "ch_PP-OCRv4_rec_infer"))
);

// Fails at runtime if any of the three directories is missing or stale
using PaddleOcrAll ocr = new PaddleOcrAll(models)
{
    AllowRotateDetection = true,
    Enable180Classification = true
};

using Mat mat = Cv2.ImRead("document.png");
PaddleOcrResult result = ocr.Run(mat);
Console.WriteLine(result.Text);
C#

Enfoque IronOCR:

// No model directories, no path configuration, no version matching
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

var ocr = new IronTesseract();

using var input = new OcrInput();
input.LoadImage("document.png");

var result = ocr.Read(input);
Console.WriteLine(result.Text);
C#

El árbol de directorio models/, las tres llamadas FromDirectory() y la preocupación de sincronización de versiones desaparecen. El motor IronOCR viene incluido en el paquete NuGet en el momento de la restauración y no requiere resolución de ruta en tiempo de ejecución. Consulta la guía de configuración de IronTesseract para opciones de inicialización, incluyendo la colocación de la llave de licencia en appsettings.json.

Consolidación del sistema de detección y reconocimiento en dos etapas

La canalización de rotación y orientación de PaddleOCR se configura a través de propiedades en PaddleOcrAll. Replicar este comportamiento en IronOCR utiliza los métodos de preprocesamiento de OcrInput, que manejan los mismos problemas del documento con una superficie de llamada más simple.

Enfoque PaddleOCR:

using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models.Online;
using OpenCvSharp;

// Separate async initialization step — blocks startup for 3-5 seconds on cold run
FullOcrModel models = await OnlineFullModels.EnglishV4.DownloadAsync();

using PaddleOcrAll ocr = new PaddleOcrAll(models)
{
    AllowRotateDetection = true,        // Enables 0/90/180/270 degree rotation detection
    Enable180Classification = true      // Additional pass for upside-down text
};

// OpenCV Mat required — no direct file path support
using Mat mat = Cv2.ImRead("rotated-scan.png");

if (mat.Empty())
{
    throw new FileNotFoundException("Image could not be loaded by OpenCvSharp");
}

// Three neural network passes: detection → classification → recognition
PaddleOcrResult result = ocr.Run(mat);

// Regions arrive in spatial order, not reading order
// Manual sort required for top-to-bottom, left-to-right output
var orderedRegions = result.Regions
    .OrderBy(r => r.Rect.Center.Y)
    .ThenBy(r => r.Rect.Center.X);

foreach (var region in orderedRegions)
{
    Console.WriteLine($"{region.Text} (confidence: {region.Score:P1})");
}
C#

Enfoque IronOCR:

using IronOcr;

IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

var ocr = new IronTesseract();

using var input = new OcrInput();
input.LoadImage("rotated-scan.png");
input.Deskew();    // Corrects rotation and skew automatically

var result = ocr.Read(input);

// Output is already in reading order — no sort needed
foreach (var page in result.Pages)
{
    foreach (var line in page.Lines)
    {
        Console.WriteLine($"{line.Text} (confidence: {line.Confidence}%)");
    }
}
C#

El método Deskew() de IronOCR maneja la detección de rotación como parte de la canalización de preprocesamiento. La colección de resultados Lines se entrega en orden de lectura por el motor de diseño Tesseract, eliminando el patrón de ordenamiento manual. La guía de corrección de la orientación de la imagen documenta toda la gama de opciones de rotación y corrección de la inclinación.

Eliminación de la selección de dispositivos GPU y CPU

Las aplicaciones de PaddleOCR que ejecutan inferencia en GPU tienen la mayor superficie de migración: el paquete NuGet de tiempo de ejecución de GPU, los requisitos previos del entorno CUDA/cuDNN y la llamada de configuración PaddleDevice.Gpu(). Todo esto se elimina durante la migración.

Enfoque PaddleOCR:

using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models.Online;
using Sdcb.PaddleInference;    // GPU configuration namespace
using OpenCvSharp;

// Prerequisites must exist on every deployment environment:
// - NVIDIA Driver 452.39+ (Windows) / 450.80.02+ (Linux)
// - CUDA Toolkit 11.8 (not 12.x — version must match exactly)
// - cuDNN 8.6.0+ placed in CUDA bin directory
// - dotnet add package Sdcb.PaddleInference.runtime.win64.cuda118

FullOcrModel models = await OnlineFullModels.ChineseV4.DownloadAsync();

// GPU device 0, 1000MB initial memory pool
// Throws native load exception if CUDA_PATH not set or cuDNN DLL missing
using PaddleOcrAll ocr = new PaddleOcrAll(models, PaddleDevice.Gpu(deviceId: 0))
{
    AllowRotateDetection = true,
    Enable180Classification = true
};

using Mat mat = Cv2.ImRead("scanned-batch.png");
PaddleOcrResult result = ocr.Run(mat);

Console.WriteLine($"Text regions: {result.Regions.Length}");
Console.WriteLine(result.Text);
C#

Enfoque IronOCR:

El enfoque de IronOCR es idéntico al ejemplo anterior: IronTesseract maneja este escenario con la misma llamada API. No se requieren paquetes de GPU, ni requisitos previos de CUDA, ni selección de dispositivo. Reemplace new PaddleOcrAll(models, PaddleDevice.Gpu(deviceId: 0)) con new IronTesseract() y elimine toda la configuración relacionada con GPU.

IronOCR ofrece un tiempo de procesamiento de 150 a 300 ms por imagen en la CPU, más rápido que PaddleOCR en la CPU (300-500 ms) y suficiente para la mayoría de las cargas de trabajo de API web y procesamiento de documentos sin necesidad de infraestructura de GPU. Para escenarios de alto rendimiento, la guía de optimización de velocidad abarca opciones de configuración que incluyen la gestión de subprocesos y el ajuste del modo de segmentación de páginas.

Extracción de datos de documentos estructurados

PaddleOCR devuelve una matriz plana de objetos PaddleOcrResultRegion ordenados espacialmente, no por flujo de lectura. La extracción de la estructura a nivel de párrafo o de línea requiere una lógica de agrupación manual basada en la proximidad de los cuadros delimitadores.IronOCR proporciona un árbol de resultados jerárquico con el orden de lectura garantizado.

Enfoque PaddleOCR:

using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models.Online;
using OpenCvSharp;
using System.Collections.Generic;

FullOcrModel models = await OnlineFullModels.EnglishV4.DownloadAsync();
using PaddleOcrAll ocr = new PaddleOcrAll(models);
using Mat mat = Cv2.ImRead("invoice.png");

PaddleOcrResult result = ocr.Run(mat);

// No paragraph or line grouping — must implement manually
// Group regions into lines by proximity on the Y axis
var lineGroups = new Dictionary<int, List<PaddleOcrResultRegion>>();

foreach (var region in result.Regions)
{
    // Round Y center to nearest 15 pixels to approximate line grouping
    int lineKey = (int)(region.Rect.Center.Y / 15) * 15;

    if (!lineGroups.ContainsKey(lineKey))
        lineGroups[lineKey] = new List<PaddleOcrResultRegion>();

    lineGroups[lineKey].Add(region);
}

// Sort lines top to bottom, then regions left to right within each line
foreach (var line in lineGroups.OrderBy(kv => kv.Key))
{
    var lineText = string.Join(" ", line.Value
        .OrderBy(r => r.Rect.Center.X)
        .Select(r => r.Text));

    Console.WriteLine(lineText);
}
C#

Enfoque IronOCR:

using IronOcr;

IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

var ocr = new IronTesseract();

using var input = new OcrInput();
input.LoadImage("invoice.png");

var result = ocr.Read(input);

// Hierarchical structure: Pages → Paragraphs → Lines → Words → Characters
// All delivered in reading order by the layout engine
foreach (var page in result.Pages)
{
    Console.WriteLine($"Page {page.PageNumber}{page.Words.Count} words");

    foreach (var paragraph in page.Paragraphs)
    {
        Console.WriteLine($"  Paragraph at ({paragraph.X}, {paragraph.Y}):");
        Console.WriteLine($"  {paragraph.Text}");
    }
}
C#

La aproximación manual de agrupación de líneas —que consiste en redondear las coordenadas Y al tamaño de un cubo de píxeles— se sustituye por la segmentación de párrafos integrada del motor de maquetación Tesseract. Las coordenadas de cuadro delimitador están disponibles en cada nivel de la jerarquía a través de paragraph.X, paragraph.Y, paragraph.Width y paragraph.Height. Consulte la guía de resultados estructurados y el tutorial sobre cómo leer texto de imágenes para obtener una cobertura completa del árbol de resultados.

Generación de PDF con capacidad de búsqueda

PaddleOCR no genera ningún archivo PDF. Generar un PDF buscable a partir de los resultados de PaddleOCR requiere una biblioteca PDF separada, mapeo manual de coordenadas de region.Rect a unidades de página PDF y una inyección de capa de texto invisible.IronOCR genera un PDF con capacidad de búsqueda directamente a partir del resultado del OCR.

Enfoque PaddleOCR:

using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models.Online;
using OpenCvSharp;
// Requires additional package: PdfSharp, iTextSharp, or similar
// Manual coordinate remapping from OpenCV pixel space to PDF point space

FullOcrModel models = await OnlineFullModels.EnglishV4.DownloadAsync();
using PaddleOcrAll ocr = new PaddleOcrAll(models);
using Mat mat = Cv2.ImRead("scanned-page.png");

PaddleOcrResult paddleResult = ocr.Run(mat);

// No built-in searchable PDF output — must build with external library
// region.Rect coordinates are in pixel space, PDF uses points (1 point = 1/72 inch)
// DPI conversion required for coordinate mapping
float dpiScale = 72.0f / 96.0f;  // Assuming 96 DPI source image

// ... hundreds of lines of PDF construction code using external library ...
// This is permanent maintenance, not a one-time cost
Console.WriteLine("Searchable PDF output requires external PDF library and coordinate mapping.");
C#

Enfoque IronOCR:

using IronOcr;

IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

var ocr = new IronTesseract();

using var input = new OcrInput();
input.LoadImage("scanned-page.png");
input.Deskew();
input.DeNoise();

var result = ocr.Read(input);

// Searchable PDF in one line — no external PDF library, no coordinate mapping
result.SaveAsSearchablePdf("searchable-output.pdf");

Console.WriteLine($"Searchable PDF created. Confidence: {result.Confidence}%");
C#

El problema del mapeo de coordenadas —convertir las coordenadas de píxeles de OpenCV al espacio de puntos PDF con la resolución DPI correcta— no existe en IronOCR. La guía en formato PDF, que permite realizar búsquedas, abarca la impresión de documentos de varias páginas, los archivos PDF protegidos con contraseña y la configuración de la calidad de impresión. Para los equipos que digitalizan archivos escaneados o que crean sistemas de conversión de fax a PDF con capacidad de búsqueda, esta única llamada a un método sustituye lo que de otro modo sería un proyecto de integración sustancial.

Procesamiento por lotes de TIFF multifotograma

Los archivos TIFF de varias páginas aparecen con frecuencia en los flujos de trabajo de escaneo de documentos. PaddleOCR no tiene soporte directo para múltiples marcos TIFF — cada marco debe extraerse individualmente usando una biblioteca de imágenes externa y cargarse como un Mat separado.IronOCR maneja archivos TIFF multifotograma de forma nativa.

Enfoque PaddleOCR:

using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models.Online;
using OpenCvSharp;
using System.Drawing;  // For multi-frame TIFF extraction
using System.Drawing.Imaging;
using System.Text;

FullOcrModel models = await OnlineFullModels.EnglishV4.DownloadAsync();
using PaddleOcrAll ocr = new PaddleOcrAll(models);

var fullText = new StringBuilder();

// Must use System.Drawing to extract individual TIFF frames
// OpenCvSharp cannot enumerate TIFF frames directly
using var tiff = Image.FromFile("multipage-scan.tiff");
FrameDimension dimension = new FrameDimension(tiff.FrameDimensionsList[0]);
int frameCount = tiff.GetFrameCount(dimension);

for (int i = 0; i < frameCount; i++)
{
    tiff.SelectActiveFrame(dimension, i);

    // Save frame to temp file — OpenCvSharp needs a file path
    string tempPath = Path.GetTempFileName() + ".png";
    tiff.Save(tempPath, ImageFormat.Png);

    try
    {
        using Mat mat = Cv2.ImRead(tempPath);
        PaddleOcrResult result = ocr.Run(mat);
        fullText.AppendLine($"=== Frame {i + 1} ===");
        fullText.AppendLine(result.Text);
    }
    finally
    {
        File.Delete(tempPath);  // Must clean up temp files
    }
}

Console.WriteLine(fullText.ToString());
C#

Enfoque IronOCR:

using IronOcr;

IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

var ocr = new IronTesseract();

using var input = new OcrInput();
input.LoadImageFrames("multipage-scan.tiff");  // All frames in one call

var result = ocr.Read(input);

foreach (var page in result.Pages)
{
    Console.WriteLine($"=== Frame {page.PageNumber} ===");
    Console.WriteLine(page.Text);
}

// Optionally save the entire multi-frame result as searchable PDF
result.SaveAsSearchablePdf("multipage-searchable.pdf");
C#

El bucle de extracción de cuadros, la dependencia System.Drawing, la creación de archivos temporales y la lógica de limpieza son eliminados.IronOCR carga todos los marcos en una sola llamada LoadImageFrames() y expone cada marco como Page en el resultado. La guía de entrada de archivos TIFF y GIF abarca las opciones de carga de múltiples fotogramas, los rangos de fotogramas selectivos y las consideraciones de memoria para archivos TIFF grandes.

Referencia de mapeo de la API de PaddleOCR (.NET) a IronOCR

PaddleOCR (Sdcb)IronOCRNotas
Sdcb.PaddleOCRIronOcrEspacio de nombres
Sdcb.PaddleOCR.Models.OnlineN/ANo se necesita espacio de nombres para la adquisición del modelo.
Sdcb.PaddleInferenceN/ANo se necesita espacio de nombres de backend de inferencia
FullOcrModelN/ANo existe un equivalente: los modelos se ofrecen en paquetes.
OnlineFullModels.ChineseV4.DownloadAsync()dotnet add package IronOcr.Languages.ChineseSimplifiedLa adquisición de modelos se reemplaza por NuGet.
LocalDetectionModel.FromDirectory(path)N/ASin gestión de rutas de modelos
LocalClassificationModel.FromDirectory(path)N/ASin gestión de rutas de modelos
LocalRecognitionModel.FromDirectory(path)N/ASin gestión de rutas de modelos
new PaddleOcrAll(models)new IronTesseract()Instanciación del motor
new PaddleOcrAll(models, PaddleDevice.Gpu(0))N/ASe eliminó por completo la selección del dispositivo GPU.
PaddleDevice.Cpu()N/ALa CPU es el único modo; no es necesario seleccionar
ocr.AllowRotateDetection = trueinput.Deskew()Corrección de rotación
ocr.Enable180Classification = trueAutomáticoLa detección de posición invertida está integrada.
Cv2.ImRead(path)input.LoadImage(path)Carga de imágenes: no se requiere OpenCV.
ocr.Run(mat)ocr.Read(input)Ejecutar OCR
result.Textresult.TextCadena de texto completa del documento
result.Regionsresult.Pages[0].Lines o .WordsRegiones de texto estructurado
region.Textword.Text / line.TextContenido de texto de una región
region.Score (flotar 0-1)word.Confidence (entero 0-100)Valor de confianza: la escala difiere.
region.Rect.Center.Xword.XPosición horizontal
region.Rect.Center.Yword.YPosición vertical
region.Rect.Size.Widthword.WidthAncho del cuadro delimitador
region.Rect.Size.Heightword.HeightAltura del cuadro delimitador
N/Ainput.LoadPdf(path)Entrada de PDF nativa (sin equivalente en PaddleOCR)
N/Ainput.LoadImageFrames(path)TIFF multifotograma (sin equivalente en PaddleOCR)
N/Aresult.SaveAsSearchablePdf(path)Salida PDF con capacidad de búsqueda (sin equivalente en PaddleOCR)

Problemas comunes de migración y soluciones

Problema 1: Discrepancia en la escala de confianza

PaddleOCR: La confianza de la región es un float de 0.0 a 1.0. Un umbral común es region.Score >= 0.8 para filtrar detecciones de baja calidad.

Solución: La confianza de IronOCR es un porcentaje de int de 0 a 100. Multiplique el umbral de PaddleOCR por 100:

// PaddleOCR: filter at 0.8
var highConfidence = result.Regions.Where(r => r.Score >= 0.8);

//IronOCR equivalent: filter at 80
var highConfidence = result.Pages
    .SelectMany(p => p.Words)
    .Where(w => w.Confidence >= 80);
C#

La confianza a nivel de documento está disponible como result.Confidence para un filtrado rápido de calidad. La guía de puntuaciones de confianza abarca umbrales por palabra y a nivel de documento.

Número 2: Supuestos sobre el orden de lectura

PaddleOCR: result.Regions se ordena por secuencia de detección, no por orden de lectura. Cualquier código que consuma result.Text esperando salida de arriba hacia abajo, de izquierda a derecha, depende del patrón de ordenamiento manual utilizado en los ejemplos de PaddleOCR.

Solución: El de IronOCRresult.Text ya está en orden de lectura. Eliminar la clasificación manual. Para los casos donde el ordenamiento se utilizó para construir una salida línea por línea, utilice result.Pages[0].Lines directamente:

// PaddleOCR: manual sort required for reading order
var lines = result.Regions
    .OrderBy(r => r.Rect.Center.Y)
    .ThenBy(r => r.Rect.Center.X)
    .Select(r => r.Text);

// IronOCR: reading order is the default
var lines = result.Pages[0].Lines.Select(l => l.Text);
C#

Problema 3: Código de conversión de matriz de OpenCV

PaddleOCR: Algunas bases de código contienen métodos de ayuda que cargan imágenes desde flujos o matrices de bytes primero escribiendo en un archivo temporal y luego llamando a Cv2.ImRead(). Estos patrones existen porque Cv2.ImRead() solo acepta rutas de archivo.

Solución: OcrInput de IronOCR acepta flujos y matrices de bytes directamente. Elimine el archivo intermedio temporal:

// PaddleOCR: stream → temp file → Mat → OCR
string tempPath = Path.GetTempFileName() + ".png";
using (var fs = File.Create(tempPath))
    await imageStream.CopyToAsync(fs);
using Mat mat = Cv2.ImRead(tempPath);
PaddleOcrResult result = ocr.Run(mat);
File.Delete(tempPath);

// IronOCR: stream → OCR (no temp file)
using var input = new OcrInput();
input.LoadImage(imageStream);
var result = ocr.Read(input);
C#

La guía de entrada de flujos abarca la carga de flujos desde respuestas HTTP, blobs de bases de datos y flujos en memoria.

Problema 4: Eliminación del patrón de inicialización asíncrona

PaddleOCR: La inicialización del motor es asíncrona porque la descarga del modelo implica E/S de red. Esto fuerza la asincronía en toda la cadena de llamadas, lo que puede resultar problemático en contextos síncronos como constructores o controladores de eventos no asíncronos.

Solución: La inicialización de IronOCR es síncrona. new IronTesseract() no realiza E/S. Elimine el await y el modificador async de cualquier método cuya única operación asíncrona fuera la descarga del modelo:

// PaddleOCR: async forced by model download
public async Task<string> ExtractTextAsync(string imagePath)
{
    FullOcrModel models = await OnlineFullModels.EnglishV4.DownloadAsync();
    using PaddleOcrAll ocr = new PaddleOcrAll(models);
    using Mat mat = Cv2.ImRead(imagePath);
    return ocr.Run(mat).Text;
}

// IronOCR: synchronous — no async required unless the caller needs it
public string ExtractText(string imagePath)
{
    var ocr = new IronTesseract();
    using var input = new OcrInput();
    input.LoadImage(imagePath);
    return ocr.Read(input).Text;
}
C#

IronOCR también proporciona soporte asíncrono nativo a través de ocr.ReadAsync(input) cuando se necesita ejecución no bloqueante en un contexto asíncrono.

Problema 5: Limpieza del paso de compilación de Docker

PaddleOCR: El Dockerfile contiene apt-get install libopencv-dev, una instrucción COPY models/ /app/models/ y a menudo un paso de pre-descarga del modelo RUN. La imagen base es con frecuencia la imagen NVIDIA CUDA para implementaciones GPU.

Solución: Eliminar todas las instrucciones del Dockerfile específicas de PaddleOCR. La imagen Docker de IronOCR no requiere ninguna imagen base especial ni ningún paso de copia de modelo:

# PaddleOCR Dockerfile (remove all of this)
FROM nvidia/cuda:11.8.0-cudnn8-runtime-ubuntu22.04
RUN apt-get update && apt-get install -y libopencv-dev libgdiplus
COPY models/ /app/models/
COPY . /app

#IronOCR Dockerfile (clean)
FROM mcr.microsoft.com/dotnet/aspnet:8.0
COPY . /app
WORKDIR /app
ENTRYPOINT ["dotnet", "YourApp.dll"]
Text

La imagen resultante reduce su tamaño de aproximadamente 1,5 GB a aproximadamente 400 MB. La guía de implementación de Docker cubre los requisitos de las bibliotecas de Linux y las compilaciones multiarquitectura.

Problema 6: Invalidación de la caché del modelo CI/CD

PaddleOCR: Las canalizaciones de CI/CD que almacenan en caché el paso de restauración de NuGet deben gestionar por separado el almacenamiento en caché de los archivos del modelo. Un patrón común es almacenar en caché una carpeta models/ entre ejecuciones. Cuando se actualiza la versión del envoltorio, la clave de caché cambia y los modelos deben volver a descargarse de los servidores de Baidu, lo que añade entre 30 y 60 segundos al proceso.

**Solución:**IronOCR no tiene directorio de caché de modelos. La única caché necesaria es la caché estándar de paquetes NuGet . Sin paso de caché separado, sin invalidación de caché en actualizaciones de envoltura, sin descarga desde servidores de terceros durante la CI:

# Remove from CI/CD pipeline:
# - name: Cache PaddleOCR models
#   uses: actions/cache@v3
#   with:
#     path: models/
#     key: paddleocr-models-${{env.PADDLEOCR_VERSION}}

#IronOCR only needs standard NuGet caching:
- name: Cache NuGet packages
  uses: actions/cache@v3
  with:
    path: ~/.nuget/packages
    key: nuget-${{hashFiles('**/*.csproj')}}
Text

Lista de verificación para la migración de PaddleOCR (.NET)

Pre-Migración

Antes de realizar cualquier cambio, revise el código fuente para identificar todos los usos de PaddleOCR:

# Find all PaddleOCR namespace imports
grep -rn "using Sdcb.PaddleOCR" --include="*.cs" .

# Find all OpenCvSharp imports (added as PaddleOCR dependency)
grep -rn "using OpenCvSharp" --include="*.cs" .

# Find all Mat usage patterns
grep -rn "Cv2\.ImRead\|new Mat\|Mat mat" --include="*.cs" .

# Find all async model download calls
grep -rn "DownloadAsync\|OnlineFullModels\|LocalDetectionModel" --include="*.cs" .

# Find all GPU device configuration
grep -rn "PaddleDevice\|EnableUseGpu\|cuda" --include="*.cs" .

# Find all result region access patterns
grep -rn "result\.Regions\|region\.Score\|region\.Rect" --include="*.cs" .

# Locate model directory references in configuration files
grep -rn "PP-OCRv4\|cls_infer\|det_infer\|rec_infer" --include="*.cs" --include="*.json" --include="*.yaml" .
SHELL

Inventarie los directorios del modelo y anote el tamaño total. Identifique qué modelos de idioma están en uso (chino, inglés, japonés, etc.) para determinar qué paquetes IronOcr.Languages.* agregar. Tenga en cuenta si la configuración de la GPU está presente; esos archivos son los que tienen mayor superficie que limpiar.

Migración de código

  1. Elimine Sdcb.PaddleOCR, Sdcb.PaddleOCR.Models.Online, Sdcb.PaddleInference.runtime.*, OpenCvSharp4 y OpenCvSharp4.runtime.* del archivo .csproj
  2. Agregue IronOcr al archivo .csproj
  3. Agregue paquetes IronOcr.Languages.* para cada idioma no inglés descargado previamente como modelo PaddleOCR
  4. Reemplace todas las directivas using Sdcb.PaddleOCR* y using OpenCvSharp por using IronOcr
  5. Agregue IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"; al inicio de la aplicación
  6. Reemplace FullOcrModel models = await OnlineFullModels.*.DownloadAsync() con nada — elimine completamente la línea
  7. Reemplace new PaddleOcrAll(models) con new IronTesseract()
  8. Reemplace new PaddleOcrAll(models, PaddleDevice.Gpu(deviceId: 0)) con new IronTesseract()
  9. Replace Mat mat = Cv2.ImRead(path) with var input = new OcrInput(); input.LoadImage(ruta);
  10. Reemplace ocr.Run(mat) con ocr.Read(input)
  11. Reemplace el acceso result.Regions con result.Pages[0].Lines o result.Pages[0].Words
  12. Reemplace region.Score >= threshold con word.Confidence >= threshold * 100
  13. Reemplace region.Rect.Center.X / .Center.Y con word.X / word.Y
  14. Eliminar la lógica de ordenación manual: la salida de IronOCR ya está en orden de lectura.
  15. Elimine el directorio models/ y todos los archivos de modelo del repositorio y los scripts de implementación

Posmigración

  • Verifique que dotnet build tenga éxito con cero referencias a Sdcb.*, OpenCvSharp o PaddleInference en el resultado de la compilación
  • Ejecutar el OCR en el mismo conjunto de documentos representativos utilizado para validar la salida de PaddleOCR y comparar la precisión del texto.
  • Confirme que los valores de confianza se estén leyendo como números enteros de 0 a 100 (no como números de coma flotante de 0 a 1) en todos los puntos de filtrado.
  • Verifique que el orden de lectura sea correcto sin ordenar manualmente; revise específicamente los diseños de varias columnas y de facturas.
  • Pruebe que la compilación de la imagen muy Docker se complete sin la imagen base de CUDA o apt-get install libopencv-dev
  • Confirma que el tamaño de la imagen de Docker sea inferior a 500 MB.
  • Ejecuta la canalización de CI/CD de principio a fin y verifica que no se produzcan descargas externas durante la compilación.
  • Prueba de implementación aislada: verifica que la aplicación se inicie y procese documentos sin conexiones de red salientes.
  • Para cualquier entrada TIFF de múltiples fotogramas, verifique que todos los fotogramas se procesen y que el número de fotogramas coincida con el archivo de origen.
  • Para cualquier entrada de PDF, verifique que input.LoadPdf() produzca la misma cantidad de páginas y contenido de texto que la conversión anterior basada en PdfiumViewer

Principales ventajas de migrar a IronOCR

Los artefactos de implementación se reducen en un 80 por ciento. La huella de implementación de PaddleOCR — paddle_inference.dll, DLLs de OpenCV, y tres directorios de modelo — añade 300-500 MB a cada destino de implementación. Tras la migración, el despliegue de IronOCR ocupa aproximadamente 80 MB. Las imágenes de Docker se reducen de aproximadamente 1,5 GB a aproximadamente 400 MB. El inicio de los contenedores es más rápido, los costes de almacenamiento son menores y las canalizaciones de despliegue que antes transferían 500 MB de artefactos ahora transfieren 80 MB.

El tiempo de arranque en frío se reduce de segundos a milisegundos. PaddleOCR carga tres archivos de modelo de red neuronal desde el disco en la primera inferencia, añadiendo una pausa de 3 a 5 segundos antes de que finalice la primera llamada. En funciones sin servidor, escenarios de escalado automático o cualquier contexto donde se inicien nuevas instancias bajo demanda, ese arranque en frío se paga repetidamente. El motor de IronOCR viene integrado y se inicializa en menos de un segundo. El ejemplo básico de OCR demuestra el patrón de inicialización.

La cobertura lingüística se amplía de 14 a 125 sin necesidad de infraestructura adicional. PaddleOCR admite 14 idiomas. Agregar cualquiera de los 111 idiomas que admite IronOCR más allá del límite de PaddleOCR requiere la adición de un único paquete NuGet por idioma; no se requiere la descarga del modelo, la gestión de directorios ni la sincronización de versiones. Los equipos cuyo volumen de documentos se expande a nuevos mercados no tienen que reescribir el texto ni iniciar un nuevo proyecto de infraestructura para añadir compatibilidad con OCR en polaco, vietnamita, griego o hebreo. El catálogo completo de idiomas muestra los más de 125 paquetes disponibles.

La salida PDF con capacidad de búsqueda requiere una línea. PaddleOCR devuelve regiones de texto. Convertir esas regiones en una capa PDF con capacidad de búsqueda requiere una biblioteca PDF independiente, una conversión de coordenadas de píxeles a puntos y un código de inyección de texto invisible que implica un mantenimiento permanente. Después de la migración, result.SaveAsSearchablePdf("output.pdf") reemplaza todo ese subsistema. Los flujos de trabajo de archivo de documentos escaneados, las canalizaciones de fax a PDF y las integraciones de gestión documental se benefician directamente. El tutorial en formato PDF con función de búsqueda y la entrada del blog sobre la extracción de datos en PDF cubren todas las opciones de salida.

No hay conexiones de red externas en ninguna etapa. PaddleOCR se conecta al almacenamiento de bj.bcebos.com de Baidu para descargas de modelos. En entornos donde las conexiones salientes están restringidas (redes gubernamentales, sistemas aislados, infraestructura de servicios financieros), esa conexión requiere una excepción en el firewall o un flujo de trabajo previo a la descarga que añade complejidad a la integración y entrega continuas (CI/CD).IronOCR no realiza conexiones externas en tiempo de ejecución. Los modelos se restauran como parte de dotnet restore desde NuGet y están presentes en el resultado de implementación. La guía de implementación de AWS y la guía de implementación de Azure cubren la configuración específica de la nube para entornos con restricciones de red.

Un único contacto de soporte comercial para toda la pila OCR. Los problemas de PaddleOCR abarcan el contenedor Sdcb.PaddleOCR (GitHub comunitario), el framework PaddlePaddle (Baidu), OpenCvSharp (comunitario), y CUDA/cuDNN (NVIDIA). Cada capa tiene un canal de soporte diferente, sin garantía de tiempo de respuesta.IronOCR es un producto único de Iron Software con soporte comercial por correo electrónico y niveles de respuesta prioritaria. El centro de documentación de IronOCR consolida toda la documentación de la API, las guías prácticas y los recursos para la resolución de problemas en un solo lugar.

Por favor nota: PDFium, PaddleOCR, PDFSharp, Tesseract e iText son marcas registradas de sus respectivos propietarios. Este sitio no está afiliado, respaldado ni patrocinado por Baidu, Chromium Project, Google, PaddlePaddle, empira Software GmbH ni iText Group. Todos los nombres de productos, logotipos y marcas son propiedad de sus respectivos dueños. Las comparaciones son solo para fines informativos y reflejan información públicamente disponible en el momento de la redacción.

Artículos Relacionados

Key in blue circle

Obtenga su clave de prueba gratuita de 30 días al instante.

Your trial license will be sent to your email address

Sin limitaciones. 100 % desbloqueado. Sin tarjeta de crédito.

bullet_checkedNo se requiere tarjeta de crédito ni creación de cuentaSin limitaciones. 100 % desbloqueado. Sin tarjeta de crédito.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
Obtén tu Consulta Sin Compromiso
Completa el formulario a continuación o envía un correo a sales@ironsoftware.com
Tus detalles siempre serán mantenidos confidenciales.
Confiado por millones de ingenieros en todo el mundo
Logos de clientes de Iron Software
Obtenga su Clave de Prueba de 30 días gratis al instante.
No se requiere tarjeta de crédito ni creación de cuenta