Zum Fußzeileninhalt springen
VIDEOS

Verbessern der Bildqualität für bessere OCR-Ergebnisse mit C#

Dieser Leitfaden führt .NET-Entwickler durch eine vollständige Migration von der Sdcb.PaddleOCR-Paketfamilie zu IronOCR. Es umfasst den gesamten Austauschprozess: Entfernung des aus mehreren Paketen bestehenden PaddlePaddle-Stacks, Eliminierung der Modelldateiverwaltung und GPU-Konfiguration sowie Ersetzung der OpenCV-abhängigen Inferenzpipeline durch eine einzige NuGet Installation. Jeder Abschnitt ist in sich abgeschlossen – eine vorherige Lektüre des Vergleichsartikels ist nicht erforderlich.

Warum von PaddleOCR migrieren?

Der Sdcb.PaddleOCR-Wrapper ist eine von der Community gepflegte Brücke zwischen PaddlePaddles Python-Ökosystem für Deep Learning und .NET. Es erfüllt zwar seinen Zweck, aber es bringt auch die gesamte Last dieser Brücke mit sich – Modelldateien, native Inferenzbinärdateien, OpenCV zum Laden von Bildern und optionale CUDA-Infrastruktur. Für die meisten .NET OCR-Workloads ist das eine Infrastruktur, die das Projekt nie benötigt hat.

Drei Modellverzeichnisse, bevor ein einzelnes Zeichen gelesen wird. Die Inferenzpipeline von PaddleOCR verknüpft drei neuronale Netze: ein Detektionsmodell, ein Richtungsklassifizierungsmodell und ein Erkennungsmodell. Jedes Netzwerk ist ein separates Verzeichnis von .pdmodel- und .pdiparams-Dateien, die auf der Festplatte vorhanden sein müssen, bevor new PaddleOcrAll(models) zu einer funktionierenden Engine kompiliert wird. Ob diese Dateien über einen asynchronen Download-Aufruf – der sich mit Baidus bj.bcebos.com-Speicher in China verbindet – oder über einen manuell gepflegten models/-Verzeichnisbaum geladen werden, der Entwickler ist dauerhaft für die Modellversionierung verantwortlich. Bei Aktualisierungen von Sdcb.PaddleOCR müssen möglicherweise die vorgeladenen Modelle aus der vorherigen Version erneut heruntergeladen werden.IronOCR verfügt über keine Modelldateien, keine Modellverzeichnisse und es gibt kein Problem mit der Versionssynchronisierung. Die Engine ist im NuGet Paket enthalten.

OpenCV ist nicht optional. Es gibt keinen Weg von einem Dateipfad zur PaddleOCR-Inferenz, der OpenCvSharp umgeht. Jedes Bild, unabhängig vom Format, muss durch Cv2.ImRead(path) gehen, um ein Mat-Objekt zu werden, bevor ocr.Run(mat) es akzeptieren kann. Das bedeutet zwei zusätzliche NuGet-Pakete (OpenCvSharp4 und OpenCvSharp4.runtime.win), plattformspezifische native DLLs im Bereitstellungsausgang und eine apt-get install libopencv-dev-Zeile im Dockerfile.IronOCR akzeptiert direkte Dateipfade, Streams, Byte-Arrays und System.Drawing.Bitmap. Der Mat-Zwischenschritt existiert nicht.

Die GPU-Konfiguration ist ein mehrtägiges Projekt. Die von PaddleOCR beworbenen GPU-Leistungswerte – 50–100 ms pro Bild gegenüber 300–500 ms auf der CPU – sind real. Um dies zu erreichen, werden NVIDIA-Treiber in einer bestimmten Version, das CUDA Toolkit 11.8 (nicht 12.x), cuDNN 8.6+, das sich an den richtigen PATH-Speicherorten befindet, und ein separates GPU-Runtime NuGet Paket benötigt. In Docker muss das Basisbild nvidia/cuda:11.8.0-cudnn8-runtime-ubuntu22.04 sein und der Host muss nvidia-container-toolkit installiert haben. Teams ohne vorhandene GPU-Infrastruktur benötigen 2-8 Stunden für die CUDA-Konfiguration pro Umgebung.IronOCR ist für die CPU-Inferenz ausgelegt, liefert 150-300 ms pro Bild auf Standardhardware und benötigt keinerlei GPU-Konfiguration.

Bereitstellungsartefakte sind 4-6x größer. Die PaddleOCR-Bereitstellungsausgabe enthält paddle_inference.dll (~200MB), paddle2onnx.dll (~5MB), opencv_world*.dll-Dateien (~50MB kombiniert) und die Modellverzeichnisse (~21MB). Ein Docker-Image hat eine Größe von ungefähr 1,5 GB. Eine IronOCR Installation umfasst insgesamt etwa 80 MB; Das Docker-Image hat eine Größe von ungefähr 400 MB. Der Unterschied verstärkt sich bei CI/CD: Jeder Pipeline-Lauf, der NuGet Pakete wiederherstellt, muss entweder Modelle von Baidu herunterladen oder sie aus einer separat verwalteten Cache-Ebene abrufen.

Keine durchsuchbare PDF-Ausgabe. PaddleOCR extrahiert Textbereiche aus Bildern und bietet keine Möglichkeit, erkannten Text als durchsuchbare Ebene in ein PDF einzubetten. Um aus PaddleOCR-Ausgaben ein durchsuchbares PDF zu erstellen, ist eine PDF-Bibliothek eines Drittanbieters, das Einfügen von Textebenen für jede Seite und eine Koordinatenneuzuordnung erforderlich.IronOCR erzeugt ein vollständig durchsuchbares PDF mit einer Zeile: result.SaveAsSearchablePdf("output.pdf").

Das grundsätzliche Problem

PaddleOCR benötigt drei konfigurierte Modellverzeichnisse, bevor die Inferenz beginnen kann:

// 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 hat keine Modelldateien, keine Modellverzeichnisse und keine OpenCV-Abhängigkeit:

// 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): Funktionsvergleich

Die folgende Tabelle behandelt die wichtigsten Dimensionen bei der Migrationsplanung.

Feature PaddleOCR (Sdcb) IronOCR
Erforderliche NuGet Pakete 4-5 1
Modelldateien erforderlich Ja (3 Verzeichnisse, ~21 MB) Nein (im Paket enthalten)
Modell-Downloadquelle Baidu-Server (bj.bcebos.com) NuGet -Wiederherstellung (Iron Software)
OpenCV-Abhängigkeit Erforderlich (OpenCvSharp4) None
Bildeingabe Über Mat mat = Cv2.ImRead() Direkter Dateipfad, Datenstrom, Byte-Array
Native PDF-Eingabe Nein Ja (input.LoadPdf())
Durchsuchbare PDF-Ausgabe Nein Ja (result.SaveAsSearchablePdf())
Mehrbild-TIFF-Eingabe Manuelle Einzelbildschleife input.LoadImageFrames()
GPU-Unterstützung Ja (CUDA 11.8 + cuDNN erforderlich) CPU-optimiert (keine GPU erforderlich)
Integrierte Vorverarbeitung Nein (das neuronale Netzwerk gleicht Verzerrungen/Rauschen aus) Ja (Entzerren, Rauschen entfernen, Kontrast, Binarisieren, Schärfen)
Unterstützte Sprachen 14 125+
Methode zur Sprachinstallation DownloadAsync() pro Sprachmodell dotnet add package IronOcr.Languages.*
Mehrsprachige Simultanübertragung Nein (separates Modell pro Sprache) Ja (OcrLanguage.English + OcrLanguage.French)
Strukturierte Ausgabe result.Regions (räumlich, unsortiert) Seiten, Absätze, Zeilen, Wörter, Zeichen
Konfidenzbewertung Gleitkommazahl pro Region (0-1) Prozentualer Anteil pro Wort (0-100)
Barcode-Lesung Nein Ja (ocr.Configuration.ReadBarCodes = true)
hOCR-Export Nein Ja
Bereitstellungsgröße 300-500 MB ~80MB
Docker-Image-Größe ~1,5 GB (mit CUDA-Basis) ~400 MB
Kaltstartzeit 3-5 Sekunden (Modell laden) Unter 1 Sekunde
Plattformübergreifend Windows, Linux (teilweise) Windows, Linux, macOS, Docker, Azure, AWS
.NET -Kompatibilität .NET 6+ (Community-Wrapper) .NET Framework 4.6.2+, .NET 5/6/7/8/9
Kommerzielle Unterstützung Community-/ GitHub -Probleme Ja (Iron Software, mit SLA)
Lizenz Apache 2.0 (kostenlos) Unbefristet ($999 Lite / 1.499 USD Pro / 2.999 USD Enterprise)

Schnellstart: Migration von PaddleOCR (.NET) zu IronOCR

Schritt 1: Ersetzen von NuGet-Paketen

Entfernen Sie alle fünf PaddleOCR-bezogenen Pakete:

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

Falls die GPU-Laufzeitumgebung installiert war, entfernen Sie diese ebenfalls:

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

Installieren Sie IronOCR von der NuGet Paketseite :

dotnet add package IronOcr

Schritt 2: Namespaces aktualisieren

Ersetzen Sie alle Importe der Namespaces PaddleOCR und 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

Schritt 3: Lizenz initialisieren

Fügen Sie die Lizenzinitialisierung einmal beim Anwendungsstart hinzu, bevor eine IronTesseract-Instanz erstellt wird:

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

Auf der IronOCR -Lizenzseite ist ein kostenloser Testschlüssel erhältlich. Die Testversion erzeugt Ausgaben mit Wasserzeichen und ermöglicht das Testen aller Funktionen vor dem Kauf.

Beispiele für die Code-Migration

Eliminierung der lokalen Modellpfadkonfiguration

Projekte, die PaddleOCR-Modelldateien vorab herunterladen, um Baidu-Serververbindungen zur Laufzeit zu vermeiden, müssen drei separate Verzeichnispfade konfigurieren. Diese Konfiguration muss immer dann aktualisiert werden, wenn sich die Wrapper-Version ändert.

PaddleOCR-Ansatz:

// 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

IronOCR Ansatz:

//Neinmodel 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);
//Neinmodel 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

'Neinmodel 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

Der models/-Verzeichnisbaum, die drei FromDirectory()-Aufrufe und das Versionssynchronisierungsproblem verschwinden. Die IronOCR Engine ist beim Wiederherstellungszeitpunkt im NuGet Paket enthalten und erfordert keine Pfadauflösung zur Laufzeit. Siehe den IronTesseract-Einrichtungsleitfaden für Initialisierungsoptionen einschließlich der Platzierung des Lizenzschlüssels in appsettings.json.

Konsolidierung der zweistufigen Erkennungs- und Identifizierungspipeline

Die Dreh- und Orientierungspipeline von PaddleOCR wird über Eigenschaften in PaddleOcrAll konfiguriert. Das Replizieren dieses Verhaltens in IronOCR verwendet die OcrInput-Vorverarbeitungsmethoden, die dieselben Dokumentprobleme mit einer einfacheren Aufrufoberfläche behandeln.

PaddleOCR-Ansatz:

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

IronOCR Ansatz:

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

Die Deskew()-Methode von IronOCR behandelt die Dreherkennung als Teil der Vorverarbeitungspipeline. Die Lines-Sammlung des Ergebnisses wird in Lesereihenfolge vom Tesseract-Layout-Engine geliefert, was das manuelle Sortierungsmuster überflüssig macht. Der Leitfaden zur Bildausrichtungskorrektur dokumentiert die gesamte Bandbreite der Rotations- und Entzerrungsoptionen.

Entfernung der GPU- und CPU-Geräteauswahl

PaddleOCR-Anwendungen, die GPU-Inferenz ausführen, tragen die größte Migrationsoberfläche: das GPU-Runtime-NuGet-Paket, die CUDA/cuDNN-Umgebungsvoraussetzungen und der PaddleDevice.Gpu()-Konfigurationsaufruf. All dies wird während der Migration entfernt.

PaddleOCR-Ansatz:

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

IronOCR Ansatz:

Der Ansatz von IronOCR ist identisch mit dem oben genannten Beispiel – IronTesseract behandelt dieses Szenario mit dem gleichen API-Aufruf. Es sind weder GPU-Pakete noch CUDA-Voraussetzungen oder eine Geräteauswahl erforderlich. Ersetzen Sie new PaddleOcrAll(models, PaddleDevice.Gpu(deviceId: 0)) durch new IronTesseract() und entfernen Sie alle GPU-bezogenen Konfigurationen.

IronOCR liefert 150-300 ms pro Bild auf der CPU – schneller als PaddleOCR auf der CPU (300-500 ms) und ausreichend für die Mehrheit der Web-API- und Dokumenten-Pipeline-Workloads ohne GPU-Infrastruktur. Für Szenarien mit hohem Durchsatz umfasst der Leitfaden zur Geschwindigkeitsoptimierung Konfigurationsoptionen wie Thread-Management und die Optimierung des Seitensegmentierungsmodus.

Extraktion strukturierter Dokumentdaten

PaddleOCR gibt ein flaches Array von PaddleOcrResultRegion-Objekten zurück, die räumlich, nicht leseflussorientiert geordnet sind. Das Extrahieren der Absatz- oder Zeilenstruktur erfordert eine manuelle Gruppierungslogik basierend auf der Nähe der Begrenzungsrahmen.IronOCR liefert einen hierarchischen Ergebnisbaum mit garantierter Lesereihenfolge.

PaddleOCR-Ansatz:

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

//Neinparagraph 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);

//Neinparagraph 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)

        ' Neinparagraph 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

IronOCR Ansatz:

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

Die manuelle Annäherung an die Zeilengruppierung – das Runden der Y-Koordinaten auf eine Pixel-Bucket-Größe – wird durch die in die Tesseract-Layout-Engine integrierte Absatzsegmentierung ersetzt. Die Koordinaten des Begrenzungsrahmens sind auf jeder Ebene der Hierarchie über paragraph.X, paragraph.Y, paragraph.Width und paragraph.Height verfügbar. Eine vollständige Beschreibung des Ergebnisbaums finden Sie im Leitfaden zu strukturierten Ergebnissen und im Tutorial zum Lesen von Texten aus Bildern .

durchsuchbare PDF-Generierung

PaddleOCR erzeugt keine PDF-Ausgabe. Das Erzeugen eines durchsuchbaren PDFs aus den PaddleOCR-Ergebnissen erfordert eine separate PDF-Bibliothek, manuelles Koordinaten-Mapping von region.Rect auf PDF-Seiteneinheiten und das Einfügen einer unsichtbaren Textebene.IronOCR generiert direkt aus dem OCR-Ergebnis ein durchsuchbares PDF.

PaddleOCR-Ansatz:

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

//Neinbuilt-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);

//Neinbuilt-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)

        ' 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
        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

IronOCR Ansatz:

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

Das Problem der Koordinatenzuordnung – die Umwandlung von OpenCV-Pixelkoordinaten in den PDF-Punktraum bei der korrekten DPI – existiert in IronOCR nicht. Der durchsuchbare PDF-Leitfaden behandelt die Ausgabe von mehrseitigen Dokumenten, passwortgeschützte PDFs und Einstellungen zur Ausgabequalität. Für Teams, die gescannte Archive digitalisieren oder Pipelines zur Umwandlung von Faxen in durchsuchbare PDFs erstellen, ersetzt dieser einzelne Methodenaufruf ein ansonsten umfangreiches Integrationsprojekt.

Stapelverarbeitung von TIFF-Bildern mit mehreren Einzelbildern

Mehrseitige TIFF-Dateien treten häufig in Dokumentenscanning-Workflows auf. PaddleOCR hat keine direkte Unterstützung für TIFF-Multiframes — jeder Frame muss einzeln mit einer externen Bildbibliothek extrahiert und als separates Mat geladen werden.IronOCR verarbeitet TIFF-Dateien mit mehreren Einzelbildern nativ.

PaddleOCR-Ansatz:

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

IronOCR Ansatz:

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

Die Frame-Extraktionsschleife, die System.Drawing-Abhängigkeit, das Erstellen temporärer Dateien und die Aufräumlogik werden entfernt.IronOCR lädt alle Frames mit einem einzigen LoadImageFrames()-Aufruf und zeigt jeden Frame als Page im Ergebnis an. Der Leitfaden zur Eingabe von TIFF- und GIF-Dateien behandelt Optionen zum Laden mehrerer Einzelbilder, selektive Einzelbildbereiche und Speicherüberlegungen für große TIFF-Archive.

PaddleOCR (.NET) API-zu-IronOCR-Mapping-Referenz

PaddleOCR (Sdcb) IronOCR Notizen
Sdcb.PaddleOCR IronOcr Namensraum
Sdcb.PaddleOCR.Models.Online Nicht anwendbar Kein Modellakquisitions-Namespace erforderlich
Sdcb.PaddleInference Nicht anwendbar Kein Backend-Namespace für Inferenz erforderlich
FullOcrModel Nicht anwendbar Kein Äquivalent – ​​Modelle sind gebündelt
OnlineFullModels.ChineseV4.DownloadAsync() dotnet add package IronOcr.Languages.ChineseSimplified Die Modellakquise wurde durch NuGet ersetzt.
LocalDetectionModel.FromDirectory(path) Nicht anwendbar Keine Modellpfadverwaltung
LocalClassificationModel.FromDirectory(path) Nicht anwendbar Keine Modellpfadverwaltung
LocalRecognitionModel.FromDirectory(path) Nicht anwendbar Keine Modellpfadverwaltung
new PaddleOcrAll(models) new IronTesseract() Engine-Instanziierung
new PaddleOcrAll(models, PaddleDevice.Gpu(0)) Nicht anwendbar Die GPU-Geräteauswahl wurde vollständig entfernt.
PaddleDevice.Cpu() Nicht anwendbar CPU ist der einzige Modus; keine Auswahl erforderlich
ocr.AllowRotateDetection = true input.Deskew() Rotationskorrektur
ocr.Enable180Classification = true Automatisch Eine Umkehrerkennung ist integriert.
Cv2.ImRead(path) input.LoadImage(path) Bildladen – kein OpenCV erforderlich
ocr.Run(mat) ocr.Read(input) OCR ausführen
result.Text result.Text Vollständiger Dokumenttext
result.Regions result.Pages[0].Lines oder .Words Strukturierte Textbereiche
region.Text word.Text / line.Text Textinhalt einer Region
region.Score (float 0-1) word.Confidence (int 0-100) Konfidenzwert – Skala variiert
region.Rect.Center.X word.X Horizontale Position
region.Rect.Center.Y word.Y Vertikale Position
region.Rect.Size.Width word.Width Breite des Begrenzungsrahmens
region.Rect.Size.Height word.Height Höhe des Begrenzungsrahmens
Nicht anwendbar input.LoadPdf(path) Native PDF-Eingabe (kein PaddleOCR-Äquivalent)
Nicht anwendbar input.LoadImageFrames(path) Mehrbild-TIFF (kein PaddleOCR-Äquivalent)
Nicht anwendbar result.SaveAsSearchablePdf(path) Durchsuchbare PDF-Ausgabe (kein PaddleOCR-Äquivalent)

Gängige Migrationsprobleme und Lösungen

Problem 1: Diskrepanz zwischen Konfidenzskala und Skala

PaddleOCR: Die Region-Vertrauenswürdigkeit ist ein float von 0,0 bis 1,0. Ein gebräuchlicher Schwellenwert ist region.Score >= 0.8, um minderwertige Erkennungen zu filtern.

Lösung: Die IronOCR-Vertrauenswürdigkeit ist ein int-Prozentsatz von 0 bis 100. Multiplizieren Sie den PaddleOCR-Schwellenwert mit 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

Die Vertrauenswürdigkeit auf Dokumentebene ist als result.Confidence verfügbar, um die Qualität schnell zu prüfen. Der Leitfaden zu den Konfidenzwerten umfasst Schwellenwerte pro Wort und auf Dokumentebene.

Problem 2: Annahmen zur Lesereihenfolge

PaddleOCR: result.Regions ist in Erkennungsreihenfolge, nicht in Lesereihenfolge geordnet. Jeder Code, der result.Text konsumiert und eine von oben nach unten, von links nach rechts Ausgabe erwartet, beruht auf dem manuellen Sortierungsmuster, das in allen PaddleOCR-Beispielen verwendet wird.

Lösung: Die result.Text von IronOCR ist bereits in Lesereihenfolge. Die manuelle Sortierung entfernen. Für Fälle, in denen die Sortierung verwendet wurde, um eine zeilenweise Ausgabe zu erstellen, verwenden Sie direkt result.Pages[0].Lines:

// 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

Ausgabe 3: OpenCV Mat-Konvertierungscode

PaddleOCR: Einige Codebasen enthalten Hilfsmethoden, die Bilder aus Streams oder Byte-Arrays laden, indem sie zuerst in eine temporäre Datei schreiben und dann Cv2.ImRead() aufrufen. Diese Muster existieren, weil Cv2.ImRead() nur Dateipfade akzeptiert.

Lösung: Die OcrInput von IronOCR akzeptiert Streams und Byte-Arrays direkt. Löschen Sie die temporäre Zwischendatei:

// 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

Der Leitfaden zur Stream-Eingabe behandelt das Laden von Streams aus HTTP-Antworten, Datenbank-Blobs und Speicherstreams.

Problem 4: Entfernung des asynchronen Initialisierungsmusters

PaddleOCR: Die Initialisierung der Engine erfolgt asynchron, da der Modell-Download Netzwerk-E/A beinhaltet. Dies erzwingt Asynchronität in der gesamten Aufrufkette, was in synchronen Kontexten wie Konstruktoren oder nicht-asynchronen Ereignisbehandlern problematisch sein kann.

Lösung: Die Initialisierung von IronOCR erfolgt synchron. new IronTesseract() führt keine I/O-Operationen aus. Entfernen Sie die await und den async-Modifikator aus jeder Methode, deren einzige asynchrone Operation der Modelldownload war:

// 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 bietet auch native asynchrone Unterstützung über ocr.ReadAsync(input), wenn in einem asynchronen Kontext wirklich eine nicht-blockierende Ausführung benötigt wird.

Problem 5: Bereinigung des Docker-Build-Schritts

PaddleOCR: Die Dockerdatei enthält apt-get install libopencv-dev, eine COPY models/ /app/models/-Anweisung und oft einen Modell-Vor-Download-RUN-Schritt. Das Basisbild ist häufig das NVIDIA-CUDA-Bild für GPU-Bereitstellungen.

Lösung: Entfernen Sie alle PaddleOCR-spezifischen Dockerfile-Anweisungen. Das IronOCR Docker-Image benötigt kein spezielles Basis-Image und keinen Modellkopierschritt:

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

Das resultierende Image reduziert sich von ca. 1,5 GB auf ca. 400 MB. Der Docker-Bereitstellungsleitfaden behandelt die Anforderungen an Linux-Bibliotheken und Multi-Architektur-Builds.

Ausgabe 6: CI/CD-Modellcache-Invalidierung

PaddleOCR: CI/CD-Pipelines, die den NuGet Wiederherstellungsschritt zwischenspeichern, müssen das Zwischenspeichern der Modelldateien separat verwalten. Ein häufiges Muster ist das Zwischenspeichern eines models/-Ordners zwischen den Läufen. Bei einem Update der Wrapper-Version ändert sich der Cache-Schlüssel, und die Modelle müssen von den Baidu-Servern erneut heruntergeladen werden, was die Pipeline um 30 bis 60 Sekunden verlängert.

Lösung:IronOCR verfügt über kein Modell-Cache-Verzeichnis. Es wird lediglich der Standard NuGet -Paketcache benötigt. Kein separater Cache-Schritt, keine Cache-Invalidierung bei Wrapper-Aktualisierungen, kein Download von Drittanbieterservern während der 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')}}
# 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

PaddleOCR (.NET) Migrations-Checkliste

Vor der Migration

Prüfen Sie den Quellcode, um alle Verwendungen von PaddleOCR zu identifizieren, bevor Sie Änderungen vornehmen:

# 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

Erstellen Sie eine Bestandsaufnahme der Modellverzeichnisse und notieren Sie die Gesamtgröße. Identifizieren Sie, welche Sprachmodelle verwendet werden (Chinesisch, Englisch, Japanisch, usw.), um festzustellen, welche IronOcr.Languages.*-Pakete hinzugefügt werden sollen. Beachten Sie, ob eine GPU-Konfiguration vorhanden ist – diese Dateien bieten den größten Optimierungsbedarf.

Code-Migration

  1. Entfernen Sie Sdcb.PaddleOCR, Sdcb.PaddleOCR.Models.Online, Sdcb.PaddleInference.runtime.*, OpenCvSharp4 und OpenCvSharp4.runtime.* aus der .csproj-Datei
  2. Fügen Sie IronOcr zur .csproj-Datei hinzu
  3. Fügen Sie IronOcr.Languages.*-Pakete für jede nicht-englische Sprache hinzu, die zuvor als PaddleOCR-Modell heruntergeladen wurde
  4. Ersetzen Sie alle using Sdcb.PaddleOCR*- und using OpenCvSharp-Direktiven mit using IronOcr
  5. Fügen Sie IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"; beim Anwendungsstart hinzu
  6. Ersetzen Sie FullOcrModel models = await OnlineFullModels.*.DownloadAsync() durch nichts — die Zeile vollständig entfernen
  7. Ersetzen Sie new PaddleOcrAll(models) durch new IronTesseract()
  8. Ersetzen Sie new PaddleOcrAll(models, PaddleDevice.Gpu(deviceId: 0)) durch new IronTesseract()
  9. Ersetzen Sie Mat mat = Cv2.ImRead(path) durch var input = new OcrInput(); input.LoadImage(path);
  10. Ersetzen Sie ocr.Run(mat) durch ocr.Read(input)
  11. Ersetzen Sie den Zugriff auf result.Regions durch result.Pages[0].Lines oder result.Pages[0].Words
  12. Ersetzen Sie region.Score >= threshold durch word.Confidence >= threshold * 100
  13. Ersetzen Sie region.Rect.Center.X / .Center.Y durch word.X / word.Y
  14. Manuelle Sortierlogik entfernen – die IronOCR Ausgabe ist bereits in Lesereihenfolge.
  15. Entfernen Sie das models/-Verzeichnis und alle Modelldateien aus dem Repository und den Bereitstellungsskripten

Nach der Migration

  • Verifizieren Sie, dass dotnet build erfolgreich ist, ohne Verweise auf Sdcb.*, OpenCvSharp oder PaddleInference in der Build-Ausgabe
  • Führen Sie die OCR-Texterkennung auf demselben repräsentativen Dokumentensatz durch, der zur Validierung der PaddleOCR-Ausgabe verwendet wurde, und vergleichen Sie die Textgenauigkeit.
  • Sicherstellen, dass die Konfidenzwerte an allen Filterpunkten als ganze Zahlen 0-100 (und nicht als Gleitkommazahlen 0-1) gelesen werden.
  • Überprüfen Sie die Lesereihenfolge ohne manuelle Sortierung – insbesondere bei mehrspaltigen Dokumenten und Rechnungslayouts.
  • Testen Sie, dass der Docker-Image-Build ohne das CUDA-Basisbild oder apt-get install libopencv-dev abgeschlossen wird
  • Bitte prüfen Sie, ob die Docker-Image-Größe unter 500 MB liegt.
  • Führen Sie die CI/CD-Pipeline vollständig aus und überprüfen Sie, ob während des Builds keine externen Downloads erfolgen.
  • Test der isolierten Bereitstellung: Überprüfen Sie, ob die Anwendung startet und Dokumente verarbeitet, ohne dass ausgehende Netzwerkverbindungen vorhanden sind.
  • Überprüfen Sie bei allen TIFF-Eingaben mit mehreren Einzelbildern, ob alle Einzelbilder verarbeitet wurden und die Anzahl der Einzelbilder mit der Quelldatei übereinstimmt.
  • Verifizieren Sie für alle PDF-Eingaben, dass input.LoadPdf() die gleiche Seitenanzahl und denselben Textinhalt wie die vorherige auf PdfiumViewer basierende Konvertierung erzeugt

Wichtigste Vorteile der Migration zu IronOCR

Bereitstellungsartefakte schrumpfen um 80 Prozent. Der PaddleOCR-Bereitstellungsaufwand — paddle_inference.dll, OpenCV-DLLs und drei Modellverzeichnisse — fügt jedem Bereitstellungsziel 300-500 MB hinzu. Nach der Migration ist die IronOCR Installation ungefähr 80 MB groß. Die Größe der Docker-Images sinkt von ca. 1,5 GB auf ca. 400 MB. Der Containerstart erfolgt schneller, die Speicherkosten sind niedriger und Deployment-Pipelines, die zuvor 500 MB an Artefakten übertragen haben, übertragen jetzt 80 MB.

Der Kaltstart verkürzt sich von Sekunden auf Millisekunden. PaddleOCR lädt beim ersten Inferenzvorgang drei neuronale Netzwerkmodelldateien von der Festplatte und fügt eine Pause von 3-5 Sekunden ein, bevor der erste Aufruf zurückkehrt. Bei serverlosen Funktionen, Autoscaling-Szenarien oder in jedem Kontext, in dem neue Instanzen bei Bedarf gestartet werden, wird dieser Kaltstart immer wieder bezahlt. Die Engine von IronOCR ist integriert und initialisiert sich in weniger als einer Sekunde. Das einfache OCR-Beispiel veranschaulicht das Initialisierungsmuster.

Die Sprachabdeckung wird ohne Infrastrukturänderungen von 14 auf 125 erweitert. PaddleOCR unterstützt 14 Sprachen. Das Hinzufügen einer der 111 von IronOCR unterstützten Sprachen über die Grenzen von PaddleOCR hinaus erfordert lediglich das Hinzufügen eines einzigen NuGet Pakets pro Sprache – kein Modell-Download, keine Verzeichnisverwaltung, keine Versionssynchronisierung. Teams, deren Dokumentenvolumen sich auf neue Märkte ausdehnt, müssen weder eine Neuentwicklung noch ein neues Infrastrukturprojekt in Angriff nehmen, um die OCR-Unterstützung für Polnisch, Vietnamesisch, Griechisch oder Hebräisch hinzuzufügen. Der vollständige Sprachkatalog zeigt alle über 125 verfügbaren Pakete.

Die durchsuchbare PDF-Ausgabe benötigt eine Zeile. PaddleOCR gibt Textbereiche zurück. Um diese Regionen in eine durchsuchbare PDF-Ebene umzuwandeln, ist eine separate PDF-Bibliothek, eine Pixel-zu-Punkt-Koordinatenkonvertierung und unsichtbarer Texteinfügungscode erforderlich, der einen permanenten Wartungsaufwand bedeutet. Nach der Migration ersetzt result.SaveAsSearchablePdf("output.pdf") dieses gesamte Subsystem. Workflows für die Archivierung gescannter Dokumente, Fax-zu-PDF-Pipelines und Dokumentenmanagement-Integrationen profitieren alle direkt. Die durchsuchbare PDF-Anleitung und der Blogbeitrag zur PDF-Datenextraktion decken alle Ausgabeoptionen ab.

Keine externen Netzwerkverbindungen in irgendeiner Phase. PaddleOCR verbindet sich mit Baidus bj.bcebos.com-Speicher für Modelldownloads. In Umgebungen, in denen ausgehende Verbindungen eingeschränkt sind – Regierungsnetzwerke, Air-Gap-Systeme, Infrastrukturen von Finanzdienstleistungen – erfordert diese Verbindung entweder eine Firewall-Ausnahme oder einen Pre-Download-Workflow, der die CI/CD-Komplexität erhöht.IronOCR stellt zur Laufzeit keine externen Verbindungen her. Modelle werden als Teil von dotnet restore von NuGet wiederhergestellt und sind in der Bereitstellungsausgabe enthalten. Der AWS-Bereitstellungsleitfaden und der Azure-Bereitstellungsleitfaden beschreiben die cloudspezifische Konfiguration für Umgebungen mit Netzwerkbeschränkungen.

Ein kommerzieller Support-Kontakt für die gesamte OCR-Stack. PaddleOCR-Probleme betreffen den Sdcb.PaddleOCR-Wrapper (Community-GitHub), das PaddlePaddle-Framework (Baidu), OpenCvSharp (Community) und CUDA/cuDNN (NVIDIA). Jede Ebene verfügt über einen separaten Supportkanal, ohne Garantie auf Reaktionszeiten.IronOCR ist ein Einzelprodukt von Iron Software mit kommerziellem E-Mail-Support und priorisierten Reaktionsstufen. Im IronOCR Dokumentationsportal sind die gesamte API-Dokumentation, Anleitungen und Ressourcen zur Fehlerbehebung an einem Ort zusammengefasst.

Hinweis:PDFium, PaddleOCR, PDFSharp, Tesseract und iText sind registrierte Warenzeichen ihrer jeweiligen Inhaber. Diese Website steht in keiner Verbindung zu, wird nicht unterstützt oder gesponsert von Baidu, Chromium Project, Google, PaddlePaddle, empira Software GmbH oder iText Group. Alle Produktnamen, Logos und Marken sind Eigentum ihrer jeweiligen Inhaber. Vergleiche dienen nur zu Informationszwecken und spiegeln öffentlich zugängliche Informationen zum Zeitpunkt des Schreibens wider.

Häufig gestellte Fragen

Warum sollte ich von PaddleOCR zu IronOCR migrieren?

Zu den häufigsten Gründen gehören die Beseitigung der Komplexität der COM-Interoperabilität, die Ablösung der dateibasierten Lizenzverwaltung, die Vermeidung der seitenweisen Abrechnung, die Ermöglichung der Docker-/Container-Bereitstellung und die Einführung eines NuGet-nativen Workflows, der sich in die Standard-.NET-Werkzeuge integriert.

Was sind die wichtigsten Code-Änderungen bei der Migration von PaddleOCR zu IronOCR?

Ersetzen Sie die PaddleOCR-Initialisierungssequenzen durch IronTesseract-Instanziierung, entfernen Sie das COM-Lebenszyklusmanagement (explizite Create/Load/Close-Muster) und aktualisieren Sie die Namen der Ergebniseigenschaften. Das Ergebnis sind deutlich weniger Boilerplate-Zeilen.

Wie installiere ich IronOCR, um die Migration zu beginnen?

Führen Sie 'Install-Package IronOcr' in der Paketmanager-Konsole oder 'dotnet add package IronOcr' in der CLI aus. Sprachpakete sind separate Pakete: 'dotnet add package IronOcr.Languages.French' für Französisch, zum Beispiel.

Kann IronOCR die OCR-Genauigkeit von PaddleOCR für Standardgeschäftsdokumente erreichen?

IronOCR erzielt eine hohe Genauigkeit bei Standardgeschäftsinhalten wie Rechnungen, Verträgen, Quittungen und getippten Formularen. Bildvorverarbeitungsfilter (Schräglagenkorrektur, Rauschunterdrückung, Kontrastverbesserung) verbessern die Erkennungsgenauigkeit bei verschlechterten Eingaben weiter.

Wie geht IronOCR mit den Sprachdaten um, die PaddleOCR separat installiert?

Die Sprachdaten in IronOCR werden als NuGet-Pakete verteilt. mit 'dotnet add package IronOcr.Languages.German' wird die deutsche Unterstützung installiert. Es sind keine manuellen Dateiplatzierungen oder Verzeichnispfade erforderlich.

Erfordert die Migration von PaddleOCR zu IronOCR Änderungen an der Bereitstellungsinfrastruktur?

IronOCR erfordert weniger Änderungen an der Infrastruktur als PaddleOCR. Es gibt keine SDK-Binärpfade, keine Platzierung von Lizenzdateien oder Lizenzserverkonfigurationen. Das NuGet-Paket enthält die komplette OCR-Engine, und der Lizenzschlüssel ist ein String, der im Anwendungscode festgelegt wird.

Wie konfiguriere ich die IronOCR-Lizenzierung nach der Migration?

Weisen Sie IronOcr.License.LicenseKey = "YOUR-KEY" im Startup-Code der Anwendung zu. In Docker oder Kubernetes speichern Sie den Schlüssel als Umgebungsvariable und lesen ihn beim Starten aus. Verwenden Sie License.IsValidLicense zur Validierung, bevor Sie den Datenverkehr akzeptieren.

Kann IronOCR PDFs auf dieselbe Weise verarbeiten wie PaddleOCR?

Ja, IronOCR liest sowohl native als auch gescannte PDFs. Instanziieren Sie IronTesseract, rufen Sie ocr.Read(input) auf, wobei input ein PDF-Pfad oder OcrPdfInput ist, und iterieren Sie die OcrResult-Seiten. Es ist keine separate PDF-Rendering-Pipeline erforderlich.

Wie handhabt IronOCR das Threading bei der Verarbeitung großer Datenmengen?

IronTesseract kann sicher pro Thread instanziiert werden. Sie können eine Instanz pro Thread in einem Parallel.ForEach- oder Task-Pool aufsetzen, OCR gleichzeitig ausführen und jede Instanz nach Abschluss entsorgen. Es ist kein globaler Zustand oder Sperren erforderlich.

Welche Ausgabeformate unterstützt IronOCR nach der Textextraktion?

IronOCR liefert strukturierte Ergebnisse mit Text, Wortkoordinaten, Konfidenzwerten und Seitenstruktur. Zu den Exportoptionen gehören reiner Text, durchsuchbare PDF-Dateien und strukturierte Ergebnisobjekte für die nachgeschaltete Verarbeitung.

Ist die Preisgestaltung von IronOCR bei der Skalierung von Arbeitslasten berechenbarer als die von PaddleOCR?

IronOCR verwendet eine pauschale, unbefristete Lizenzierung ohne Seiten- oder Volumengebühren. Egal, ob Sie 10.000 oder 10 Millionen Seiten verarbeiten, die Lizenzkosten bleiben konstant. Optionen für Volumen- und Teamlizenzen finden Sie auf der IronOCR-Preisseite.

Was passiert mit meinen bestehenden Tests, nachdem ich von PaddleOCR zu IronOCR migriert habe?

Tests, die extrahierte Textinhalte überprüfen, sollten auch nach der Migration bestehen. Tests, die API-Aufrufmuster oder den Lebenszyklus von COM-Objekten validieren, müssen aktualisiert werden, um das einfachere Initialisierungs- und Ergebnismodell von IronOCR widerzuspiegeln.

Kannaopat Udonpant
Software Ingenieur
Bevor er Software-Ingenieur wurde, absolvierte Kannapat ein PhD in Umweltressourcen an der Hokkaido University in Japan. Während seines Studiums wurde Kannapat auch Mitglied des Vehicle Robotics Laboratory, das Teil der Fakultät für Bioproduktionstechnik ist. Im Jahr 2022 nutzte er seine C#-Kenntnisse, um dem Engineering-Team von Iron Software ...
Weiterlesen

Iron-Support-Team

Wir sind 24 Stunden am Tag, 5 Tage die Woche online.
Chat
E-Mail
Rufen Sie mich an