Passer au contenu du pied de page
VIDéOS

Comment améliorer la qualité d'une image pour de meilleurs résultats d'OCR à l'aide de C#

Ce guide accompagne les développeurs .NET à travers une migration complète de la famille de paquets Sdcb.PaddleOCR vers IronOCR. Il couvre l'intégralité du processus de remplacement : suppression de la pile PaddlePaddle multi-packages, élimination de la gestion des fichiers de modèles et de la configuration du GPU, et remplacement du pipeline d'inférence dépendant d'OpenCV par une seule installation NuGet . Chaque section est autonome — aucune lecture préalable de l'article comparatif n'est requise.

Pourquoi migrer depuis PaddleOCR ?

Le wrapper Sdcb.PaddleOCR est un pont maintenu par la communauté entre l'écosystème d'apprentissage profond Python de PaddlePaddle et .NET. Il remplit sa fonction, mais il supporte tout le poids de cette passerelle : les fichiers de modèle, les binaires d'inférence natifs, OpenCV pour le chargement des images et l'infrastructure CUDA optionnelle. Pour la plupart des charges de travail OCR .NET , il s'agit d'une infrastructure dont le projet n'a jamais eu besoin.

Trois répertoires de modèles sont utilisés avant même la lecture d'un seul caractère. Le pipeline d'inférence de PaddleOCR enchaîne trois réseaux neuronaux : un modèle de détection, un modèle de classification directionnelle et un modèle de reconnaissance. Chaque réseau est un répertoire distinct de fichiers .pdmodel et .pdiparams qui doivent exister sur le disque avant que new PaddleOcrAll(models) ne compile un moteur fonctionnel. Que ces fichiers arrivent via un appel de téléchargement asynchrone — qui se connecte au stockage bj.bcebos.com de Baidu en Chine — ou via un arbre de répertoires models/ maintenu manuellement, le développeur est en permanence responsable de la gestion des versions des modèles. Lorsque Sdcb.PaddleOCR met à jour, les modèles préalablement téléchargés de la version précédente peuvent nécessiter un nouveau téléchargement. IronOCR ne possède aucun fichier de modèle, aucun répertoire de modèles et aucun problème de synchronisation de version. Le moteur est intégré au package NuGet .

OpenCV n'est pas optionnel. Il n'y a pas de chemin d'un chemin de fichier à l'inférence PaddleOCR qui contourne OpenCvSharp. Chaque image, quel que soit son format, doit passer par Cv2.ImRead(path) pour devenir un objet Mat avant que ocr.Run(mat) puisse l'accepter. Cela signifie deux paquets NuGet supplémentaires (OpenCvSharp4 et OpenCvSharp4.runtime.win), des DLL natives spécifiques à la plateforme dans le résultat du déploiement, et une ligne apt-get install libopencv-dev dans le fichier Dockerfile. IronOCR accepte directement les chemins de fichiers, les flux, les tableaux d'octets, et System.Drawing.Bitmap. L'intermédiaire Mat n'existe pas.

La configuration du GPU est un projet qui prend plusieurs jours. Les performances annoncées par PaddleOCR pour le GPU (50 à 100 ms par image contre 300 à 500 ms pour le CPU) sont réelles. Pour y parvenir, il faut des pilotes NVIDIA d'une version spécifique, le kit d'outils CUDA 11.8 (et non 12.x), cuDNN 8.6+ placé dans les emplacements PATH corrects et un package NuGet d'exécution GPU séparé. Dans Docker, l'image de base doit être nvidia/cuda:11.8.0-cudnn8-runtime-ubuntu22.04 et l'hôte doit avoir nvidia-container-toolkit installé. Les équipes ne disposant pas d'infrastructure GPU existante consacrent entre 2 et 8 heures à la configuration CUDA par environnement. IronOCR est conçu pour l'inférence CPU, offre un temps de traitement de 150 à 300 ms par image sur du matériel standard et ne nécessite aucune configuration GPU.

Les artefacts de déploiement sont 4 à 6 fois plus grands. Le résultat de déploiement de PaddleOCR inclut paddle_inference.dll (~200 Mo), paddle2onnx.dll (~5 Mo), des fichiers opencv_world*.dll (~50 Mo au total), et les répertoires de modèles (~21 Mo). Une image Docker pèse environ 1,5 Go. Un déploiement IronOCR représente environ 80 Mo au total ; L'image Docker pèse environ 400 Mo. La différence s'accentue dans le cadre de l'intégration continue et de la livraison continue : chaque exécution de pipeline qui restaure des packages NuGet doit soit télécharger des modèles depuis Baidu, soit les extraire d'une couche de cache gérée séparément.

Aucun fichier PDF interrogeable. PaddleOCR extrait les zones de texte des images et ne propose aucun mécanisme pour réintégrer le texte reconnu dans un PDF sous forme de calque interrogeable. La création d'un PDF consultable à partir de la sortie PaddleOCR nécessite une bibliothèque PDF tierce, l'injection de la couche de texte page par page et le remappage des coordonnées. IronOCR produit un PDF entièrement indexable avec une seule ligne : result.SaveAsSearchablePdf("output.pdf").

Le problème fondamental

PaddleOCR nécessite la configuration de trois répertoires de modèles avant que l'inférence puisse commencer :

// 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);
// 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);
Imports OpenCvSharp
Imports PaddleOCR

' PaddleOCR: three model directories, all must exist and match the wrapper version
Dim models As 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 ocr As New PaddleOcrAll(models)
    Using mat As Mat = Cv2.ImRead("document.png")  ' OpenCvSharp required for every image
        Dim result As PaddleOcrResult = ocr.Run(mat)
    End Using
End Using
$vbLabelText   $csharpLabel

IronOCR ne possède aucun fichier de modèle, aucun répertoire de modèles et aucune dépendance à 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);
// 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);
Imports IronOcr

Dim ocr As New IronTesseract()
Using input As New OcrInput()
    input.LoadImage("document.png")
    Dim result = ocr.Read(input)
    Console.WriteLine(result.Text)
End Using
$vbLabelText   $csharpLabel

IronOCR vs PaddleOCR (.NET) : Comparaison des fonctionnalités

Le tableau ci-dessous récapitule les dimensions les plus importantes lors de la planification de la migration.

Fonction PaddleOCR (Sdcb) IronOCR
Packages NuGet requis 4-5 1
Fichiers de modèle requis Oui (3 répertoires, ~21 Mo) Non (inclus dans l'emballage)
Source de téléchargement du modèle Serveurs Baidu (bj.bcebos.com) Restauration NuGet (Iron Software)
Dépendance à OpenCV Requis (OpenCvSharp4) None
Entrée d'image Via Mat mat = Cv2.ImRead() Chemin de fichier direct, flux, tableau d'octets
Entrée PDF native Non Oui (input.LoadPdf())
Sortie PDF consultable Non Oui (result.SaveAsSearchablePdf())
Entrée TIFF multi-images boucle manuelle par image input.LoadImageFrames()
Prise en charge du GPU Oui (CUDA 11.8 + cuDNN requis) Optimisé pour le processeur (aucune carte graphique requise)
Prétraitement intégré Non (le réseau neuronal gère l'asymétrie/le bruit) Oui (Correction de l'inclinaison, réduction du bruit, contraste, binarisation, netteté)
Langues prises en charge 14 125+
méthode d'installation de la langue DownloadAsync() par modèle linguistique dotnet add package IronOcr.Languages.*
Multilingue simultané Non (un modèle distinct par langue) Oui (OcrLanguage.English + OcrLanguage.French)
Sortie structurée result.Regions (spatial, non trié) Pages, paragraphes, lignes, mots, caractères
Score de confiance Flottant par région (0-1) Pourcentage par mot (0-100)
Lecture de codes-barres Non Oui (ocr.Configuration.ReadBarCodes = true)
Exportation hOCR Non Oui
Taille du déploiement 300-500 Mo ~80MB
taille de l'image Docker ~1,5 Go (avec base CUDA) ~400 Mo
temps de démarrage à froid 3 à 5 secondes (chargement du modèle) Moins d'une seconde
Multiplateforme Windows, Linux (partiellement) Windows, Linux, macOS, Docker, Azure, AWS
Compatibilité .NET .NET 6+ (wrapper communautaire) .NET Framework 4.6.2+, .NET 5/6/7/8/9
Soutien commercial Problèmes liés à la communauté / à GitHub Oui (Iron Software, avec SLA)
Licence Apache 2.0 (gratuit) Perpétuel ($999 Lite / 1 499 $ Pro / 2 999 $ Enterprise)

Démarrage rapide : Migration de PaddleOCR (.NET) vers IronOCR

Étape 1 : Remplacer les paquets NuGet

Supprimez les cinq paquets liés à 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
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 le moteur d'exécution GPU était installé, supprimez-le également :

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

Installez IronOCR depuis la page du package NuGet :

dotnet add package IronOcr

Étape 2 : Mise à jour des espaces de noms

Remplacez toutes les importations d'espace de noms PaddleOCR et OpenCvSharp :

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

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

// After (IronOCR)
using IronOcr;
Imports IronOcr
Imports Sdcb.PaddleOCR
Imports Sdcb.PaddleOCR.Models
Imports Sdcb.PaddleOCR.Models.Online
Imports Sdcb.PaddleInference
Imports OpenCvSharp
$vbLabelText   $csharpLabel

Étape 3 : initialisation de la licence

Ajoutez l'initialisation de la licence une fois au démarrage de l'application, avant que toute instance IronTesseract ne soit créée :

IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
$vbLabelText   $csharpLabel

Une clé d'essai gratuite est disponible sur la page de licence d' IronOCR . La version d'essai génère un fichier filigrané et permet de tester toutes les fonctionnalités avant l'achat.

Exemples de migration de code

Élimination de la configuration du chemin du modèle local

Les projets qui pré-téléchargent les fichiers de modèle PaddleOCR pour éviter les connexions au serveur Baidu lors de l'exécution doivent configurer trois chemins de répertoire distincts. Cette configuration doit être mise à jour à chaque modification de la version du wrapper.

Approche 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);
// 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);
Imports System
Imports System.IO

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

Dim models As 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 ocr As New PaddleOcrAll(models) With {
    .AllowRotateDetection = True,
    .Enable180Classification = True
}

    Using mat As Mat = Cv2.ImRead("document.png")
        Dim result As PaddleOcrResult = ocr.Run(mat)
        Console.WriteLine(result.Text)
    End Using

End Using
$vbLabelText   $csharpLabel

Approche IronOCR :

// Non 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);
// Non 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);
Imports IronOcr

' Non model directories, no path configuration, no version matching
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"

Dim ocr As New IronTesseract()

Using input As New OcrInput()
    input.LoadImage("document.png")

    Dim result = ocr.Read(input)
    Console.WriteLine(result.Text)
End Using
$vbLabelText   $csharpLabel

L'arborescence de répertoires models/, les trois appels FromDirectory(), et la préoccupation de synchronisation de version disparaissent tous. Le moteur IronOCR est intégré au package NuGet lors de la restauration et ne nécessite aucune résolution de chemin d'exécution. Voir le guide d'installation IronTesseract pour les options d'initialisation, y compris le placement de la clé de licence dans appsettings.json.

Consolidation du pipeline de détection et de reconnaissance en deux étapes

Le pipeline de rotation et d'orientation de PaddleOCR est configuré par des propriétés sur PaddleOcrAll. Reproduire ce comportement dans IronOCR utilise les méthodes de prétraitement OcrInput, qui gèrent les mêmes problèmes de document avec une interface d'appel simplifiée.

Approche 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})");
}
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})");
}
Imports Sdcb.PaddleOCR
Imports Sdcb.PaddleOCR.Models.Online
Imports OpenCvSharp

' Separate async initialization step — blocks startup for 3-5 seconds on cold run
Dim models As FullOcrModel = Await OnlineFullModels.EnglishV4.DownloadAsync()

Using ocr As New PaddleOcrAll(models) With {
    .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 As Mat = Cv2.ImRead("rotated-scan.png")

        If mat.Empty() Then
            Throw New FileNotFoundException("Image could not be loaded by OpenCvSharp")
        End If

        ' Three neural network passes: detection → classification → recognition
        Dim result As PaddleOcrResult = ocr.Run(mat)

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

        For Each region In orderedRegions
            Console.WriteLine($"{region.Text} (confidence: {region.Score:P1})")
        Next
    End Using
End Using
$vbLabelText   $csharpLabel

Approche 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}%)");
    }
}
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}%)");
    }
}
Imports IronOcr

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

Dim ocr As New IronTesseract()

Using input As New OcrInput()
    input.LoadImage("rotated-scan.png")
    input.Deskew() ' Corrects rotation and skew automatically

    Dim result = ocr.Read(input)

    ' Output is already in reading order — no sort needed
    For Each page In result.Pages
        For Each line In page.Lines
            Console.WriteLine($"{line.Text} (confidence: {line.Confidence}%)")
        Next
    Next
End Using
$vbLabelText   $csharpLabel

La méthode Deskew() d'IronOCR gère la détection de rotation dans le cadre du pipeline de prétraitement. La collection Lines du résultat est livrée dans l'ordre de lecture par le moteur de mise en page Tesseract, éliminant le modèle de tri manuel. Le guide de correction de l'orientation de l'image documente l'ensemble des options de rotation et de redressement.

Suppression de la sélection du périphérique GPU et CPU

Les applications PaddleOCR qui exécutent l'inférence GPU portent la plus grande surface de migration : le paquet NuGet d'exécution GPU, les prérequis de l'environnement CUDA/cuDNN, et l'appel de configuration PaddleDevice.Gpu(). Tout ceci est supprimé lors de la migration.

Approche 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);
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);
Imports Sdcb.PaddleOCR
Imports Sdcb.PaddleOCR.Models.Online
Imports Sdcb.PaddleInference    ' GPU configuration namespace
Imports 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

Dim models As FullOcrModel = 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 ocr As New PaddleOcrAll(models, PaddleDevice.Gpu(deviceId:=0)) With {
    .AllowRotateDetection = True,
    .Enable180Classification = True
}

    Using mat As Mat = Cv2.ImRead("scanned-batch.png")
        Dim result As PaddleOcrResult = ocr.Run(mat)

        Console.WriteLine($"Text regions: {result.Regions.Length}")
        Console.WriteLine(result.Text)
    End Using
End Using
$vbLabelText   $csharpLabel

Approche IronOCR :

L'approche IronOCR est identique à l'exemple ci-dessus — IronTesseract traite ce scénario avec le même appel API. Aucun package GPU, aucun prérequis CUDA et aucune sélection de périphérique ne sont nécessaires. Remplacez new PaddleOcrAll(models, PaddleDevice.Gpu(deviceId: 0)) par new IronTesseract() et supprimez toute configuration liée au GPU.

IronOCR offre un temps de traitement de 150 à 300 ms par image sur CPU, plus rapide que PaddleOCR sur CPU (300 à 500 ms) et suffisant pour la majorité des charges de travail des API Web et des pipelines de documents sans infrastructure GPU. Pour les scénarios à haut débit, le guide d'optimisation de la vitesse couvre les options de configuration, notamment la gestion des threads et le réglage du mode de segmentation des pages.

Extraction de données structurées de documents

PaddleOCR renvoie un tableau plat d'objets PaddleOcrResultRegion ordonnés spatialement, non par flux de lecture. L'extraction de la structure au niveau du paragraphe ou de la ligne nécessite une logique de regroupement manuelle basée sur la proximité des boîtes englobantes. IronOCR fournit un arbre de résultats hiérarchique avec un ordre de lecture garanti.

Approche 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);

// Non 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);
}
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);

// Non 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);
}
Imports Sdcb.PaddleOCR
Imports Sdcb.PaddleOCR.Models.Online
Imports OpenCvSharp
Imports System.Collections.Generic

Dim models As FullOcrModel = Await OnlineFullModels.EnglishV4.DownloadAsync()
Using ocr As New PaddleOcrAll(models)
    Using mat As Mat = Cv2.ImRead("invoice.png")
        Dim result As PaddleOcrResult = ocr.Run(mat)

        ' Non paragraph or line grouping — must implement manually
        ' Group regions into lines by proximity on the Y axis
        Dim lineGroups As New Dictionary(Of Integer, List(Of PaddleOcrResultRegion))()

        For Each region In result.Regions
            ' Round Y center to nearest 15 pixels to approximate line grouping
            Dim lineKey As Integer = CInt(region.Rect.Center.Y / 15) * 15

            If Not lineGroups.ContainsKey(lineKey) Then
                lineGroups(lineKey) = New List(Of PaddleOcrResultRegion)()
            End If

            lineGroups(lineKey).Add(region)
        Next

        ' Sort lines top to bottom, then regions left to right within each line
        For Each line In lineGroups.OrderBy(Function(kv) kv.Key)
            Dim lineText As String = String.Join(" ", line.Value _
                .OrderBy(Function(r) r.Rect.Center.X) _
                .Select(Function(r) r.Text))

            Console.WriteLine(lineText)
        Next
    End Using
End Using
$vbLabelText   $csharpLabel

Approche 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}");
    }
}
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}");
    }
}
Imports IronOcr

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

Dim ocr As New IronTesseract()

Using input As New OcrInput()
    input.LoadImage("invoice.png")

    Dim result = ocr.Read(input)

    ' Hierarchical structure: Pages → Paragraphs → Lines → Words → Characters
    ' All delivered in reading order by the layout engine
    For Each page In result.Pages
        Console.WriteLine($"Page {page.PageNumber} — {page.Words.Count} words")

        For Each paragraph In page.Paragraphs
            Console.WriteLine($"  Paragraph at ({paragraph.X}, {paragraph.Y}):")
            Console.WriteLine($"  {paragraph.Text}")
        Next
    Next
End Using
$vbLabelText   $csharpLabel

L'approximation manuelle du regroupement des lignes — arrondi des coordonnées Y à une taille de pixel — est remplacée par la segmentation de paragraphe intégrée au moteur de mise en page Tesseract. Les coordonnées des boîtes englobantes sont disponibles à chaque niveau de la hiérarchie via paragraph.X, paragraph.Y, paragraph.Width, et paragraph.Height. Consultez le guide des résultats structurés et le tutoriel sur la lecture de texte à partir d'images pour une description complète de l'arbre de résultats.

Génération de PDF consultables

PaddleOCR ne produit aucun fichier PDF. Générer un PDF indexable à partir des résultats de PaddleOCR nécessite une bibliothèque PDF séparée, une correspondance manuelle des coordonnées de region.Rect aux unités de page PDF, et l'injection d'une couche de texte invisible. IronOCR génère un PDF consultable directement à partir du résultat de la reconnaissance optique de caractères (OCR).

Approche 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);

// Non 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.");
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);

// Non 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.");
Imports Sdcb.PaddleOCR
Imports Sdcb.PaddleOCR.Models.Online
Imports OpenCvSharp
' Requires additional package: PdfSharp, iTextSharp, or similar
' Manual coordinate remapping from OpenCV pixel space to PDF point space

Dim models As FullOcrModel = Await OnlineFullModels.EnglishV4.DownloadAsync()
Using ocr As New PaddleOcrAll(models)
    Using mat As Mat = Cv2.ImRead("scanned-page.png")
        Dim paddleResult As PaddleOcrResult = ocr.Run(mat)

        ' Non 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
        Dim dpiScale As Single = 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.")
    End Using
End Using
$vbLabelText   $csharpLabel

Approche 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}%");
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}%");
Imports IronOcr

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

Dim ocr As New IronTesseract()

Using input As New OcrInput()
    input.LoadImage("scanned-page.png")
    input.Deskew()
    input.DeNoise()

    Dim 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}%")
End Using
$vbLabelText   $csharpLabel

Le problème de mappage des coordonnées — la conversion des coordonnées de pixels OpenCV en espace de points PDF au DPI correct — n'existe pas dans IronOCR. Le guide PDF consultable couvre la sortie multipage, les PDF protégés par mot de passe et les paramètres de qualité de sortie. Pour les équipes qui numérisent des archives scannées ou qui créent des pipelines de conversion de fax en PDF consultables, cet appel de méthode unique remplace ce qui serait autrement un projet d'intégration conséquent.

Traitement par lots TIFF multi-images

Les fichiers TIFF multipages sont fréquents dans les flux de travail de numérisation de documents. PaddleOCR n'a pas de support direct pour les multi-images TIFF — chaque image doit être extraite individuellement à l'aide d'une bibliothèque d'imagerie externe et chargée en tant que Mat séparé. IronOCR gère nativement les fichiers TIFF multi-images.

Approche 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());
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());
Imports Sdcb.PaddleOCR
Imports Sdcb.PaddleOCR.Models.Online
Imports OpenCvSharp
Imports System.Drawing  ' For multi-frame TIFF extraction
Imports System.Drawing.Imaging
Imports System.Text

Dim models As FullOcrModel = Await OnlineFullModels.EnglishV4.DownloadAsync()
Using ocr As New PaddleOcrAll(models)
    Dim fullText As New StringBuilder()

    ' Must use System.Drawing to extract individual TIFF frames
    ' OpenCvSharp cannot enumerate TIFF frames directly
    Using tiff As Image = Image.FromFile("multipage-scan.tiff")
        Dim dimension As New FrameDimension(tiff.FrameDimensionsList(0))
        Dim frameCount As Integer = tiff.GetFrameCount(dimension)

        For i As Integer = 0 To frameCount - 1
            tiff.SelectActiveFrame(dimension, i)

            ' Save frame to temp file — OpenCvSharp needs a file path
            Dim tempPath As String = Path.GetTempFileName() & ".png"
            tiff.Save(tempPath, ImageFormat.Png)

            Try
                Using mat As Mat = Cv2.ImRead(tempPath)
                    Dim result As PaddleOcrResult = ocr.Run(mat)
                    fullText.AppendLine($"=== Frame {i + 1} ===")
                    fullText.AppendLine(result.Text)
                End Using
            Finally
                File.Delete(tempPath)  ' Must clean up temp files
            End Try
        Next
    End Using

    Console.WriteLine(fullText.ToString())
End Using
$vbLabelText   $csharpLabel

Approche 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");
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");
Imports IronOcr

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

Dim ocr As New IronTesseract()

Using input As New OcrInput()
    input.LoadImageFrames("multipage-scan.tiff")  ' All frames in one call

    Dim result = ocr.Read(input)

    For Each page In result.Pages
        Console.WriteLine($"=== Frame {page.PageNumber} ===")
        Console.WriteLine(page.Text)
    Next

    ' Optionally save the entire multi-frame result as searchable PDF
    result.SaveAsSearchablePdf("multipage-searchable.pdf")
End Using
$vbLabelText   $csharpLabel

La boucle d'extraction des images, la dépendance System.Drawing, la création de fichiers temporaires et la logique de nettoyage sont tous supprimés. IronOCR charge tous les cadres en un seul appel LoadImageFrames() et expose chaque cadre comme un Page dans le résultat. Le guide d'entrée TIFF et GIF couvre les options de chargement multi-images, les plages d'images sélectives et les considérations de mémoire pour les grandes archives TIFF.

Référence de mappage de l'API PaddleOCR (.NET) vers IronOCR

PaddleOCR (Sdcb) IronOCR Notes
Sdcb.PaddleOCR IronOcr Espace de noms
Sdcb.PaddleOCR.Models.Online N/A Aucun espace de noms d'acquisition de modèle n'est nécessaire.
Sdcb.PaddleInference N/A Aucun espace de noms de backend d'inférence requis
FullOcrModel N/A Aucun équivalent — les modèles sont regroupés
OnlineFullModels.ChineseV4.DownloadAsync() dotnet add package IronOcr.Languages.ChineseSimplified L'acquisition de modèles a été remplacée par NuGet.
LocalDetectionModel.FromDirectory(path) N/A Gestion des chemins de modèle inexistante
LocalClassificationModel.FromDirectory(path) N/A Gestion des chemins de modèle inexistante
LocalRecognitionModel.FromDirectory(path) N/A Gestion des chemins de modèle inexistante
new PaddleOcrAll(models) new IronTesseract() Instanciation du moteur
new PaddleOcrAll(models, PaddleDevice.Gpu(0)) N/A La sélection du périphérique GPU a été entièrement supprimée.
PaddleDevice.Cpu() N/A Le processeur est le seul mode disponible ; pas de sélection nécessaire
ocr.AllowRotateDetection = true input.Deskew() Correction de rotation
ocr.Enable180Classification = true Automatique La détection de l'envers est intégrée.
Cv2.ImRead(path) input.LoadImage(path) Chargement d'images — OpenCV n'est pas requis
ocr.Run(mat) ocr.Read(input) Exécuter la reconnaissance optique de caractères (OCR)
result.Text result.Text Chaîne de texte du document complet
result.Regions result.Pages[0].Lines ou .Words régions de texte structuré
region.Text word.Text / line.Text Contenu textuel d'une région
region.Score (float 0-1) word.Confidence (int 0-100) Valeur de confiance — l'échelle diffère
region.Rect.Center.X word.X Position horizontale
region.Rect.Center.Y word.Y Position verticale
region.Rect.Size.Width word.Width Largeur de la boîte englobante
region.Rect.Size.Height word.Height Hauteur de la boîte englobante
N/A input.LoadPdf(path) Saisie PDF native (pas d'équivalent PaddleOCR)
N/A input.LoadImageFrames(path) TIFF multi-images (pas d'équivalent PaddleOCR)
N/A result.SaveAsSearchablePdf(path) Sortie PDF consultable (pas d'équivalent à PaddleOCR)

Problèmes de migration courants et solutions

Problème n° 1 : Inadéquation de l'échelle de confiance

PaddleOCR : La confiance régionale est une float de 0,0 à 1,0. Un seuil commun est region.Score >= 0.8 pour filtrer les détections de mauvaise qualité.

Solution : La confiance IronOCR est un pourcentage int de 0 à 100. Multipliez le seuil PaddleOCR par 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);
// 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);
' PaddleOCR: filter at 0.8
Dim highConfidence = result.Regions.Where(Function(r) r.Score >= 0.8)

' IronOCR equivalent: filter at 80
Dim highConfidence = result.Pages _
    .SelectMany(Function(p) p.Words) _
    .Where(Function(w) w.Confidence >= 80)
$vbLabelText   $csharpLabel

La confiance au niveau du document est disponible comme result.Confidence pour un filtrage rapide de la qualité. Le guide des scores de confiance couvre les seuils par mot et au niveau du document.

Problème 2 : Hypothèses relatives à l'ordre de lecture

PaddleOCR : result.Regions est ordonné par séquence de détection, non par ordre de lecture. Tout code qui consomme result.Text en attendant une sortie de haut en bas, de gauche à droite repose sur le modèle de tri manuel utilisé dans tous les exemples de PaddleOCR.

Solution : result.Text d'IronOCR est déjà dans l'ordre de lecture. Supprimez le tri manuel. Pour les cas où le tri était utilisé pour construire une sortie ligne par ligne, utilisez result.Pages[0].Lines directement :

// 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);
// 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);
Imports System.Linq

' PaddleOCR: manual sort required for reading order
Dim lines = result.Regions _
    .OrderBy(Function(r) r.Rect.Center.Y) _
    .ThenBy(Function(r) r.Rect.Center.X) _
    .Select(Function(r) r.Text)

' IronOCR: reading order is the default
Dim lines = result.Pages(0).Lines.Select(Function(l) l.Text)
$vbLabelText   $csharpLabel

Problème 3 : Code de conversion de Mat d'OpenCV

PaddleOCR : Certaines bases de code contiennent des méthodes d'assistance qui chargent des images à partir de flux ou de tableaux d'octets en écrivant d'abord dans un fichier temporaire, puis en appelant Cv2.ImRead(). Ces modèles existent parce que Cv2.ImRead() n'accepte que les chemins de fichiers.

Solution : OcrInput d'IronOCR accepte directement les flux et les tableaux d'octets. Supprimez le fichier intermédiaire temporaire :

// 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);
// 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);
Imports System.IO
Imports OpenCvSharp
Imports IronOcr

' PaddleOCR: stream → temp file → Mat → OCR
Dim tempPath As String = Path.GetTempFileName() & ".png"
Using fs = File.Create(tempPath)
    Await imageStream.CopyToAsync(fs)
End Using
Using mat As Mat = Cv2.ImRead(tempPath)
    Dim result As PaddleOcrResult = ocr.Run(mat)
End Using
File.Delete(tempPath)

' IronOCR: stream → OCR (no temp file)
Using input As New OcrInput()
    input.LoadImage(imageStream)
    Dim result = ocr.Read(input)
End Using
$vbLabelText   $csharpLabel

Le guide d'entrée de flux couvre le chargement de flux à partir de réponses HTTP, de blobs de base de données et de flux de mémoire.

Problème 4 : Suppression du modèle d'initialisation asynchrone

PaddleOCR : L'initialisation du moteur est asynchrone car le téléchargement du modèle implique des E/S réseau. Cela impose l'asynchronisme tout au long de la chaîne d'appels, ce qui peut poser problème dans des contextes synchrones tels que les constructeurs ou les gestionnaires d'événements non asynchrones.

Solution : L'initialisation IronOCR est synchrone. new IronTesseract() n'effectue pas d'E/S. Supprimez le await et le modificateur async de toute méthode dont la seule opération asynchrone était le téléchargement du modèle :

// 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;
}
// 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;
}
Imports System.Threading.Tasks

' PaddleOCR: async forced by model download
Public Async Function ExtractTextAsync(imagePath As String) As Task(Of String)
    Dim models As FullOcrModel = Await OnlineFullModels.EnglishV4.DownloadAsync()
    Using ocr As New PaddleOcrAll(models)
        Using mat As Mat = Cv2.ImRead(imagePath)
            Return ocr.Run(mat).Text
        End Using
    End Using
End Function

' IronOCR: synchronous — no async required unless the caller needs it
Public Function ExtractText(imagePath As String) As String
    Dim ocr As New IronTesseract()
    Using input As New OcrInput()
        input.LoadImage(imagePath)
        Return ocr.Read(input).Text
    End Using
End Function
$vbLabelText   $csharpLabel

IronOCR fournit également une prise en charge asynchrone native via ocr.ReadAsync(input) lorsqu'une exécution non bloquante est réellement nécessaire dans un contexte asynchrone.

Problème 5 : Nettoyage de l'étape de construction Docker

PaddleOCR : Le Dockerfile contient apt-get install libopencv-dev, une instruction COPY models/ /app/models/, et souvent une étape de pré-téléchargement de modèle RUN. L'image de base est fréquemment l'image NVIDIA CUDA pour les déploiements GPU.

Solution : Supprimez toutes les instructions Dockerfile spécifiques à PaddleOCR. L'image Docker IronOCR ne nécessite aucune image de base spéciale ni aucune étape de copie de modèle :

# 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"]

L'image résultante passe d'environ 1,5 Go à environ 400 Mo. Le guide de déploiement Docker couvre les exigences des bibliothèques Linux et les constructions multi-architectures.

Problème n° 6 : Invalidation du cache du modèle CI/CD

PaddleOCR : les pipelines CI/CD qui mettent en cache l'étape de restauration NuGet doivent gérer séparément la mise en cache des fichiers de modèle. Un modèle courant consiste à mettre en cache un dossier models/ entre les exécutions. Lorsque la version du wrapper est mise à jour, la clé du cache change et les modèles doivent être retéléchargés depuis les serveurs de Baidu, ce qui ajoute 30 à 60 secondes au processus.

Solution : IronOCR ne possède pas de répertoire de cache de modèles. Le seul cache requis est le cache standard des packages NuGet . Pas d'étape de cache séparée, pas d'invalidation du cache lors des mises à jour du wrapper, pas de téléchargement depuis des serveurs tiers pendant l'intégration continue :

# 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')}}
# 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')}}
YAML

Liste de vérification de migration PaddleOCR (.NET)

Pré-migration

Avant d'apporter des modifications, auditez le code source afin d'identifier toutes les utilisations 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" .
# 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

Inventoriez les répertoires de modèles et notez la taille totale. Identifiez quels modèles linguistiques sont utilisés (chinois, anglais, japonais, etc.) pour déterminer quels paquets IronOcr.Languages.* ajouter. Vérifiez si la configuration du GPU est présente — ce sont ces fichiers qui présentent le plus de surface à nettoyer.

Migration de code

  1. Supprimez Sdcb.PaddleOCR, Sdcb.PaddleOCR.Models.Online, Sdcb.PaddleInference.runtime.*, OpenCvSharp4, et OpenCvSharp4.runtime.* du fichier .csproj
  2. Ajoutez IronOcr au fichier .csproj
  3. Ajoutez des paquets IronOcr.Languages.* pour chaque langue non anglaise précédemment téléchargée en tant que modèle PaddleOCR
  4. Remplacez toutes les directives using Sdcb.PaddleOCR* et using OpenCvSharp par using IronOcr
  5. Ajoutez IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"; au démarrage de l'application
  6. Remplacez FullOcrModel models = await OnlineFullModels.*.DownloadAsync() par rien — supprimez la ligne entièrement
  7. Remplacez new PaddleOcrAll(models) par new IronTesseract()
  8. Remplacez new PaddleOcrAll(models, PaddleDevice.Gpu(deviceId: 0)) par new IronTesseract()
  9. Replace Mat mat = Cv2.ImRead(path) with var input = new OcrInput(); input.LoadImage(chemin);
  10. Remplacez ocr.Run(mat) par ocr.Read(input)
  11. Remplacez l'accès result.Regions par result.Pages[0].Lines ou result.Pages[0].Words
  12. Remplacez region.Score >= threshold par word.Confidence >= threshold * 100
  13. Remplacez region.Rect.Center.X / .Center.Y par word.X / word.Y
  14. Supprimer la logique de tri manuel — La sortie IronOCR est déjà triée par ordre de lecture.
  15. Supprimez le répertoire models/ et tous les fichiers de modèle du dépôt et des scripts de déploiement

Après la migration

  • Vérifiez que dotnet build réussit sans aucune référence à Sdcb.*, OpenCvSharp, ou PaddleInference dans le résultat de la compilation
  • Effectuez une reconnaissance optique de caractères (OCR) sur le même ensemble de documents représentatifs que celui utilisé pour valider les résultats de PaddleOCR et comparez la précision du texte.
  • Vérifier que les valeurs de confiance sont lues comme des entiers de 0 à 100 (et non comme des nombres à virgule flottante de 0 à 1) à tous les points de filtrage.
  • Vérifiez que l'ordre de lecture est correct sans tri manuel — vérifiez spécifiquement la mise en page à plusieurs colonnes et la présentation des factures
  • Testez que la construction de l'image Docker s'achève sans l'image de base CUDA ou apt-get install libopencv-dev
  • Vérifiez que la taille de l'image Docker est inférieure à 500 Mo
  • Exécutez le pipeline CI/CD de bout en bout et vérifiez qu'aucun téléchargement externe n'a lieu pendant la compilation.
  • Tester le déploiement en mode isolé : vérifier que l'application démarre et traite les documents sans aucune connexion réseau sortante.
  • Pour tout fichier TIFF multi-images, vérifiez que toutes les images sont traitées et que le nombre d'images correspond à celui du fichier source.
  • Pour toute entrée PDF, vérifiez que input.LoadPdf() produit le même nombre de pages et de contenu texte que la conversion précédente basée sur PdfiumViewer

Principaux avantages de la migration vers IronOCR

Réduction de 80 % des artefacts de déploiement. L'empreinte de déploiement de PaddleOCR — paddle_inference.dll, DLLs OpenCV, et trois répertoires de modèles — ajoute 300-500 Mo à chaque cible de déploiement. Après la migration, le déploiement IronOCR pèse environ 80 Mo. La taille des images Docker passe d'environ 1,5 Go à environ 400 Mo. Le démarrage des conteneurs est plus rapide, les coûts de stockage sont plus faibles et les pipelines de déploiement qui transféraient auparavant 500 Mo d'artefacts n'en transfèrent plus que 80 Mo.

Le temps de démarrage à froid passe de quelques secondes à quelques millisecondes. PaddleOCR charge trois fichiers de modèle de réseau neuronal depuis le disque lors de la première inférence, ce qui ajoute une pause de 3 à 5 secondes avant le retour du premier appel. Dans les fonctions sans serveur, les scénarios de mise à l'échelle automatique ou tout contexte où de nouvelles instances sont créées à la demande, ce démarrage à froid est payé de manière répétée. Le moteur d'IronOCR est intégré et s'initialise en moins d'une seconde. L' exemple OCR de base illustre le modèle d'initialisation.

La couverture linguistique passe de 14 à 125 langues sans travaux d'infrastructure. PaddleOCR prend en charge 14 langues. L'ajout de l'une des 111 langues prises en charge par IronOCR au-delà de la limite de PaddleOCR se fait par l'ajout d'un seul package NuGet par langue — aucun téléchargement de modèle, aucune gestion de répertoire, aucune synchronisation de version. Les équipes dont le volume de documents s'étend à de nouveaux marchés n'ont pas à procéder à une réécriture ou à un nouveau projet d'infrastructure pour ajouter la prise en charge de la reconnaissance optique de caractères (OCR) en polonais, vietnamien, grec ou hébreu. Le catalogue complet des langues présente l'ensemble des plus de 125 packs disponibles.

La sortie PDF consultable ne nécessite qu'une seule ligne. PaddleOCR extrait les zones de texte. La conversion de ces régions en une couche PDF consultable nécessite une bibliothèque PDF distincte, une conversion des coordonnées pixel-point et un code d'injection de texte invisible qui devient une maintenance permanente. Après migration, result.SaveAsSearchablePdf("output.pdf") remplace tout ce sous-système. Les flux de travail d'archivage de documents numérisés, les pipelines de conversion fax-PDF et les intégrations de gestion documentaire en bénéficient tous directement. Le guide pratique PDF consultable et l' article de blog sur l'extraction de données PDF couvrent toutes les options de sortie.

Aucune connexion réseau externe à aucune étape. PaddleOCR se connecte au stockage bj.bcebos.com de Baidu pour les téléchargements de modèles. Dans les environnements où les connexions sortantes sont restreintes (réseaux gouvernementaux, systèmes isolés, infrastructures de services financiers), cette connexion nécessite soit une exception de pare-feu, soit un flux de travail de pré-téléchargement qui ajoute de la complexité à l'intégration continue et à la livraison continue. IronOCR ne fait aucune connexion externe au moment de l'exécution. Les modèles sont restaurés dans le cadre de dotnet restore depuis NuGet et sont présents dans le résultat du déploiement. Les guides de déploiement AWS et Azure couvrent la configuration spécifique au cloud pour les environnements présentant des restrictions réseau.

Un seul contact de support commercial pour toute la pile OCR. Les problèmes de PaddleOCR couvrent le wrapper Sdcb.PaddleOCR (GitHub communautaire), le framework PaddlePaddle (Baidu), OpenCvSharp (communauté), et CUDA/cuDNN (NVIDIA). Chaque niveau dispose d'un canal d'assistance différent, sans garantie de délai de réponse. IronOCR est un produit unique d' Iron Software offrant une assistance par e-mail et différents niveaux de réponse prioritaire. Le centre de documentation IronOCR regroupe en un seul endroit toute la documentation API, les guides pratiques et les ressources de dépannage.

Veuillez noterPDFium, PaddleOCR, PDFSharp, Tesseract et iText sont des marques déposées de leurs propriétaires respectifs. Ce site n'est pas affilié, approuvé ou sponsorisé par Baidu, le projet Chromium, Google, PaddlePaddle, empira Software GmbH ou le groupe iText. Tous les noms de produits, logos et marques sont la propriété de leurs propriétaires respectifs. Les comparaisons sont à titre informatif uniquement et reflètent les informations publiquement disponibles au moment de l'écriture.

Questions Fréquemment Posées

Pourquoi devrais-je migrer de l'IronOcr vers l'IronOCR ?

Parmi les motivations communes, citons l'élimination de la complexité de l'interopérabilité COM, le remplacement de la gestion des licences basée sur les fichiers, l'absence de facturation à la page, l'activation du déploiement Docker/conteneur et l'adoption d'un flux de travail NuGet-natif qui s'intègre à l'outillage .NET standard.

Quels sont les principaux changements de code lors de la migration de PaddleOCR vers IronOcr ?

Remplacer les séquences d'initialisation de PaddleOCR par l'instanciation d'IronTesseract, supprimer la gestion du cycle de vie de COM (modèles explicites Create/Load/Close) et mettre à jour les noms des propriétés des résultats. Le résultat est une réduction significative du nombre de lignes de code.

Comment installer IronOCR pour commencer la migration ?

Exécutez "Install-Package IronOcr" dans la console du Package Manager ou "dotnet add package IronOcr" dans le CLI. Les packs de langues sont des paquets distincts : 'dotnet add package IronOcr.Languages.French' pour le français, par exemple.

IronOCR offre-t-il la même précision d'OCR que PaddleOCR pour les documents commerciaux standard ?

IronOcr atteint un niveau de précision élevé pour les contenus commerciaux standard, notamment les factures, les contrats, les reçus et les formulaires dactylographiés. Les filtres de prétraitement d'image (désalignement, suppression du bruit, amélioration du contraste) améliorent encore la reconnaissance sur des données dégradées.

Comment IronOcr gère-t-il les données linguistiques que PaddleOCR installe séparément ?

Les données linguistiques de l'IronOcr sont distribuées sous forme de packages NuGet. 'dotnet add package IronOcr.Languages.German' installe la prise en charge de l'allemand. Il n'y a pas de placement manuel de fichiers ou de chemins d'accès aux répertoires.

La migration de l'IronOCR vers le PaddleOCR nécessite-t-elle des changements au niveau de l'infrastructure de déploiement ?

IronOCR nécessite moins de changements d'infrastructure que PaddleOCR. Il n'y a pas de chemins binaires SDK, de placements de fichiers de licence ou de configurations de serveurs de licence. Le package NuGet contient le moteur OCR complet, et la clé de licence est une chaîne de caractères définie dans le code de l'application.

Comment configurer les licences IronOCR après la migration ?

Attribuer IronOcr.License.LicenseKey = "YOUR-KEY" dans le code de démarrage de l'application. Dans Docker ou Kubernetes, stockez la clé dans une variable d'environnement et lisez-la au démarrage. Utilisez License.IsValidLicense pour valider avant d'accepter le trafic.

IronOcr peut-il traiter les PDF de la même manière que PaddleOCR ?

Oui, IronOCR lit aussi bien les PDF natifs que les PDF numérisés. Instanciez IronTesseract, appelez ocr.Read(input) où l'input est un chemin PDF ou OcrPdfInput, et itérez les pages OcrResult. Aucun pipeline de rendu PDF séparé n'est nécessaire.

Comment IronOcr gère-t-il le threading dans le cadre d'un traitement à haut volume ?

IronTesseract est sûr pour l'instanciation par thread. Créez une instance par thread dans un Parallel.ForEach ou un Task pool, exécutez l'OCR simultanément et disposez de chaque instance lorsque vous avez terminé. Aucun état global ou verrouillage n'est nécessaire.

Quels formats de sortie IronOCR prend-il en charge après l'extraction du texte ?

IronOCR renvoie des résultats structurés comprenant le texte, les coordonnées des mots, les scores de confiance et la structure des pages. Les options d'exportation comprennent le texte brut, le PDF interrogeable et les objets de résultats structurés pour le traitement en aval.

La tarification de l'IronOCR est-elle plus prévisible que celle du PaddleOCR pour la mise à l'échelle des charges de travail ?

IronOCR utilise des licences perpétuelles forfaitaires sans frais par page ou par volume. Que vous traitiez 10 000 ou 10 millions de pages, le coût de la licence reste constant. Les options de licence en volume et en équipe sont disponibles sur la page de tarification d'IronOcr.

Qu'advient-il de mes tests existants après la migration de PaddleOCR vers IronOcr ?

Les tests qui vérifient le contenu du texte extrait doivent continuer à passer après la migration. Les tests qui valident les modèles d'appel d'API ou le cycle de vie des objets COM devront être mis à jour pour refléter le modèle d'initialisation et de résultat plus simple d'IronOcr.

Kannaopat Udonpant
Ingénieur logiciel
Avant de devenir ingénieur logiciel, Kannapat a obtenu un doctorat en ressources environnementales à l'université d'Hokkaido au Japon. Pendant qu'il poursuivait son diplôme, Kannapat est également devenu membre du laboratoire de robotique de véhicules, qui fait partie du département de bioproduction. En 2022, il a utilisé ses compé...
Lire la suite

Équipe de soutien Iron

Nous sommes en ligne 24 heures sur 24, 5 jours sur 7.
Chat
Email
Appelez-moi