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
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
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
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
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
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"
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
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
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
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
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
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
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
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
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
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
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
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)
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)
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
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
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')}}
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" .
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
- Entfernen Sie
Sdcb.PaddleOCR,Sdcb.PaddleOCR.Models.Online,Sdcb.PaddleInference.runtime.*,OpenCvSharp4undOpenCvSharp4.runtime.*aus der.csproj-Datei - Fügen Sie
IronOcrzur.csproj-Datei hinzu - Fügen Sie
IronOcr.Languages.*-Pakete für jede nicht-englische Sprache hinzu, die zuvor als PaddleOCR-Modell heruntergeladen wurde - Ersetzen Sie alle
using Sdcb.PaddleOCR*- undusing OpenCvSharp-Direktiven mitusing IronOcr - Fügen Sie
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";beim Anwendungsstart hinzu - Ersetzen Sie
FullOcrModel models = await OnlineFullModels.*.DownloadAsync()durch nichts — die Zeile vollständig entfernen - Ersetzen Sie
new PaddleOcrAll(models)durchnew IronTesseract() - Ersetzen Sie
new PaddleOcrAll(models, PaddleDevice.Gpu(deviceId: 0))durchnew IronTesseract() - Ersetzen Sie
Mat mat = Cv2.ImRead(path)durchvar input = new OcrInput(); input.LoadImage(path); - Ersetzen Sie
ocr.Run(mat)durchocr.Read(input) - Ersetzen Sie den Zugriff auf
result.Regionsdurchresult.Pages[0].Linesoderresult.Pages[0].Words - Ersetzen Sie
region.Score >= thresholddurchword.Confidence >= threshold * 100 - Ersetzen Sie
region.Rect.Center.X / .Center.Ydurchword.X / word.Y - Manuelle Sortierlogik entfernen – die IronOCR Ausgabe ist bereits in Lesereihenfolge.
- Entfernen Sie das
models/-Verzeichnis und alle Modelldateien aus dem Repository und den Bereitstellungsskripten
Nach der Migration
- Verifizieren Sie, dass
dotnet builderfolgreich ist, ohne Verweise aufSdcb.*,OpenCvSharpoderPaddleInferencein 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-devabgeschlossen 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.
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.

