C#'da Çok Çerçeveli GIF'leri ve TIFF'leri Okuma
Bu kılavuz, .NET geliştiricilerini PaddleSharp OCR'den (Sdcb.PaddleOCR) IronOCR'ye tam bir geçişte yönlendirir. Çıkarım oturum yönetiminin yerini almayı, OpenCV ön işleme bağımlılığını ortadan kaldırmayı, CPU, GPU, ve OpenVINO için arka uç seçim mantığını kaldırmayı ve tablo tanıma iş akışlarını taşımayı kapsar. Her bölüm, genel OCR karşılaştırmalarında görünmeyen PaddleSharp'a özgü desenlerden alınan öncesi ve sonrası kod örnekleri sağlar.
Neden PaddleSharp OCR'dan Geçiş Yapmalı
PaddleSharp, uygulama katmanında bir derin öğrenme çıkarım hattı sunar. Bu mimari, PaddlePaddle model performansına erişim sağlar ancak uygulamanızın, aksi takdirde altyapının ilgileneceği konuları yönetmesini gerektirir. Aşağıdaki sorun noktaları, çoğu .NET ekibini alternatif aramaya yönlendiren etkenlerdir.
Çıkarım Arka Plan Yapılandırması Uygulama Kodudur. PaddleSharp'ta CPU, GPU ve OpenVINO arka plan seçenekleri arasında seçim yapmak, PaddleConfig nesnelerinin oluşturulmasını ve yapılandırılmasını, dağıtım hedefi için doğru yerel çalışma zamanı NuGet paketini seçmeyi ve çalıştırma zamanında mevcut donanıma göre başlangıç kodunuzu koşullu olarak dallandırmayı gerektirir. Bu mantık kütüphanede değil, uygulamanızda yer alır ve hedef ortam değiştiğinde bozulur.
OpenCV, Görüntü Girdisi İçin Gereken Bir Bağımlılıktır. PaddleSharp bir dosya yolu veya akışı doğrudan kabul edemez. Her görüntü, OCR motoruna ulaşmadan önce OpenCV'nin Cv2.ImRead() içinden geçer. Bu, bağımlılık grafiğinize OpenCvSharp4 ve platforma özgü OpenCvSharp4.runtime.* paketini zorunlu kılar. Diğerini güncellemeden bir platform çalışma zamanını güncellemek, ortamlar arasında çoğaltması zor çalışma zamanı başarısızlıklarına neden olur.
Çıkarım Oturumu Ömrü Açık Tasarım Gerektirir. PaddleOcrAll, oluşturma zamanında diskten üç model ikili dosyası yükler. Maliyeti — yüzlerce milisaniye olarak ölçülebilir — nesnenin talep başına oluşturulamayacağı anlamına gelir. Takımlar bir yaşam döngüsü stratejisi tasarlamalıdır: singleton, havuzlu veya kapsamlı. ASP.NET Core içinde, bu tipik olarak dikkatli iplik güvenliği analizi ile kayıtlı bir hizmet anlamına gelir, çünkü PaddleOcrAll temel yerel durumu paylaşır.
Table Tanıma Ayrı Model İndirmeleri Gerektirir. PaddleSharp'ta yapılandırılmamış belge çıkarımı, standart üç aşamalı tespit/sınıflandırma/tanıma hattına ek olarak özel bir tablo tanıma modeline ihtiyaç duyar. Bu model indirilmesi, sürümü yapılması ve yapılandırılması gereken dördüncü dosyadır. Birleşik bir API yüzeyi yoktur — tablo tanıma, kendi sonuç türüne sahip ayrı bir kod yolunu kullanır.
Aranabilir PDF Çıktısı Yoktur. PaddleSharp metin dizeleri üretir. Aranabilir PDF dosyalarını yazamaz. Taralı belgeleri metin aranabilir PDF'ler olarak arşivlemesi gereken ekipler, ayrı bir PDF kütüphanesi entegre etmeli, o ek bağımlılığı yönetmeli ve bir dönüştürme katmanı yazmalıdır. Çıktı biçimi boşluğu tamamdır: hOCR yok, yapılandırılmış aranabilir PDF yok, metin katmanı bindirme yok.
Yukarı Akış Bağımlılık Zinciri .NET Topluluğuna Ait Değildir. PaddleSharp, Baidu'nun PaddlePaddle çıkarım çerçevesini sarmallar. PaddleOCR sürümleri arasında model formatı değişiklikleri geçmişte .NET bağlayıcı katmanını bozdu. Çoğu sorun takibi, belgeler ve sürüm tartışmaları Çince'de yapılmaktadır. .NET ekibi için Mandarin konuşmacıları olmayan yukarı akış projelerini izleyen ekipler için, kırıcı değişiklikler uyarı olmadan gelir.
Temel Sorun
PaddleSharp'ta bir arka ucu seçmek ve başlatmaya başlamak, OCR mantığında değil, altyapıda yer alması gereken yapılandırma kodu gerektirir:
// PaddleSharp: Backend selection sprawls into application startup
// Simplified — see Sdcb.PaddleInference documentation for full API
using Sdcb.PaddleInference;
using Sdcb.PaddleOCR;
// CPU-only deployment
var config = PaddleConfig.FromModelDir("models/det");
config.SetCpuMathLibraryNumThreads(4);
// GPU deployment — different package, different init path
// var config = PaddleConfig.FromModelDir("models/det");
// config.EnableGpu(500, 0); // memoryMB, deviceId
// OpenVINO deployment — third conditional branch
// config.EnableMkldnn();
// Application code now owns the hardware topology decision
// PaddleSharp: Backend selection sprawls into application startup
// Simplified — see Sdcb.PaddleInference documentation for full API
using Sdcb.PaddleInference;
using Sdcb.PaddleOCR;
// CPU-only deployment
var config = PaddleConfig.FromModelDir("models/det");
config.SetCpuMathLibraryNumThreads(4);
// GPU deployment — different package, different init path
// var config = PaddleConfig.FromModelDir("models/det");
// config.EnableGpu(500, 0); // memoryMB, deviceId
// OpenVINO deployment — third conditional branch
// config.EnableMkldnn();
// Application code now owns the hardware topology decision
Imports Sdcb.PaddleInference
Imports Sdcb.PaddleOCR
' PaddleSharp: Backend selection sprawls into application startup
' Simplified — see Sdcb.PaddleInference documentation for full API
' CPU-only deployment
Dim config = PaddleConfig.FromModelDir("models/det")
config.SetCpuMathLibraryNumThreads(4)
' GPU deployment — different package, different init path
' Dim config = PaddleConfig.FromModelDir("models/det")
' config.EnableGpu(500, 0) ' memoryMB, deviceId
' OpenVINO deployment — third conditional branch
' config.EnableMkldnn()
' Application code now owns the hardware topology decision
// IronOCR:Hayırbackend selection.Hayırconfig objects. Zero hardware decisions.
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var result = new IronTesseract().Read("document.jpg");
Console.WriteLine(result.Text);
// Runs on CPU, Linux, Docker, or ARM without a code change
// IronOCR:Hayırbackend selection.Hayırconfig objects. Zero hardware decisions.
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var result = new IronTesseract().Read("document.jpg");
Console.WriteLine(result.Text);
// Runs on CPU, Linux, Docker, or ARM without a code change
Imports IronOcr
' IronOCR:Hayırbackend selection.Hayırconfig objects. Zero hardware decisions.
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim result = New IronTesseract().Read("document.jpg")
Console.WriteLine(result.Text)
' Runs on CPU, Linux, Docker, or ARM without a code change
IronOCR vs PaddleSharp OCR: Özellik Karşılaştırması
İşte geçiş sırasında en önemli olan boyutlar boyunca doğrudan bir yetenek karşılaştırması:
| Özellik | PaddleSharp OCR | IronOCR |
|---|---|---|
| NuGet paketleri gerekli | 3–4 minimum | 1 |
| Görüntü giriş yöntemi | OpenCV Cv2.ImRead() |
Doğrudan yol, akış veya byte dizisi |
| PDF girişi (yerel) | Hayır | Evet |
| Şifre korumalı PDF | Hayır | Evet |
| Çok sayfalı TIFF | OpenCV aracılığıyla | Yerel |
| Aranabilir PDF çıktısı | Hayır | Evet (result.SaveAsSearchablePdf()) |
| hOCR içeri aktarma | Hayır | Evet |
| Arka uç seçimi (CPU/GPU/OpenVINO) | Manuel PaddleConfig |
Otomatik |
| Ön işleme hattı | Manuel OpenCV işlemleri | Yerleşik (Deskew, DeNoise, Contrast, vb.) |
| Çıkarım oturumu yaşam süresi yönetimi | Manuel (pahalı yapılandırma) | Hafif IronTesseract |
| Tablo tanıma modeli | Ayrı indirme ve kod yolu | input.LoadImage() + yapılandırılmış sonuç |
| Desteklenen diller | ~10–20 | 125+ |
| Dil kurulumu | Model dosyası indirme | NuGet paketi |
| Çoklu dil aynı anda | Sınırlı | Evet (OcrLanguage.French + OcrLanguage.German) |
| Bölge bazlı OCR | Dahili yok | CropRectangle |
| OCR sırasında barkod okuma | Hayır | Evet (ocr.Configuration.ReadBarCodes = true) |
| Güven skoru | Bölge başına | Kelime başı, satır başı, sayfa başı |
| Yapılandırılmış çıktı hiyerarşisi | Düz bölgeler listesi | Sayfalar → Paragraflar → Satırlar → Kelimeler → Karakterler |
| Çapraz platform dağıtımı | Karmaşık (platform çalışma zamanı paketleri) | Tek NuGet, tüm platformlar |
| Docker dağıtımı | Birden çok katman, çalışma zamanı paketleri | Tek katman |
| Ticari destek | GitHub sorunları (öncelikle Çince) | E-posta desteği |
| Lisans modeli | Apache 2.0 | Süresiz ($999 Lite, $1,499 Pro, $2,999 Enterprise) |
Hızlı Başlangıç: PaddleSharp OCR'dan IronOCR Geçişi
Adım 1: NuGet Paketini Değiştirin
PaddleSharp ve onun OpenCV bağımlılığını kaldırın:
dotnet remove package Sdcb.PaddleOCR
dotnet remove package Sdcb.PaddleInference
dotnet remove package OpenCvSharp4
dotnet remove package OpenCvSharp4.runtime.win
dotnet remove package Sdcb.PaddleOCR
dotnet remove package Sdcb.PaddleInference
dotnet remove package OpenCvSharp4
dotnet remove package OpenCvSharp4.runtime.win
NuGet kullanarak IronOCR'u yükleyin:
dotnet add package IronOcr
Adım 2: Ad Alanlarını Güncelleyin
PaddleSharp ad alanlarını tek IronOCR ad alanı ile değiştirin:
// Before (PaddleSharp)
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models;
using Sdcb.PaddleInference;
using OpenCvSharp;
// After (IronOCR)
using IronOcr;
// Before (PaddleSharp)
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models;
using Sdcb.PaddleInference;
using OpenCvSharp;
// After (IronOCR)
using IronOcr;
Imports IronOcr
Adım 3: Lisansa İzin Verin
Uygulama başlangıcında bir kez lisans başlatımı ekleyin — Program.cs, Startup.cs veya kompozisyon kökünüzde:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"
Kod Göç Örnekleri
Çıkarım Oturum Süresi Değiştirme
PaddleSharp'ın PaddleOcrAll'ı, üç model ikili dosyasını oluşturma sırasında eşzamanlı olarak yüklemesi nedeniyle inşa edilmesi pahalıdır. Üretim uygulamaları, onu uzun ömürlü bir nesne olarak ele almalıdır, bu da belirli bir bağımlılık enjeksiyon modeli oluşturur. Atma zinciri de dikkat gerektirir çünkü altta yatan yerel kaynaklar doğru sırayla serbest bırakılmalıdır.
PaddleSharp OCR Yaklaşımı:
// Simplified — see Sdcb.PaddleOCR documentation for full API
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models;
using OpenCvSharp;
using Microsoft.Extensions.DependencyInjection;
// Expensive: loads 3 model files from disk on construction (~300–800ms)
public class PaddleOcrEngine : IDisposable
{
private readonly PaddleOcrAll _ocr;
private bool _disposed;
public PaddleOcrEngine()
{
var detModel = LocalFullModels.ChineseV3.DetectionModel;
var clsModel = LocalFullModels.ChineseV3.ClassifierModel;
var recModel = LocalFullModels.ChineseV3.RecognitionModel;
// Must be singleton — cannot afford per-request construction
_ocr = new PaddleOcrAll(detModel, clsModel, recModel);
}
public string Read(string imagePath)
{
using var mat = Cv2.ImRead(imagePath); // OpenCV required even for a file path
var result = _ocr.Run(mat);
return string.Join(" ", result.Regions.Select(r => r.Text));
}
public void Dispose()
{
if (!_disposed)
{
_ocr?.Dispose();
_disposed = true;
}
}
}
// Startup.cs — forced singleton because of construction cost
services.AddSingleton<PaddleOcrEngine>();
// Simplified — see Sdcb.PaddleOCR documentation for full API
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models;
using OpenCvSharp;
using Microsoft.Extensions.DependencyInjection;
// Expensive: loads 3 model files from disk on construction (~300–800ms)
public class PaddleOcrEngine : IDisposable
{
private readonly PaddleOcrAll _ocr;
private bool _disposed;
public PaddleOcrEngine()
{
var detModel = LocalFullModels.ChineseV3.DetectionModel;
var clsModel = LocalFullModels.ChineseV3.ClassifierModel;
var recModel = LocalFullModels.ChineseV3.RecognitionModel;
// Must be singleton — cannot afford per-request construction
_ocr = new PaddleOcrAll(detModel, clsModel, recModel);
}
public string Read(string imagePath)
{
using var mat = Cv2.ImRead(imagePath); // OpenCV required even for a file path
var result = _ocr.Run(mat);
return string.Join(" ", result.Regions.Select(r => r.Text));
}
public void Dispose()
{
if (!_disposed)
{
_ocr?.Dispose();
_disposed = true;
}
}
}
// Startup.cs — forced singleton because of construction cost
services.AddSingleton<PaddleOcrEngine>();
Imports Sdcb.PaddleOCR
Imports Sdcb.PaddleOCR.Models
Imports OpenCvSharp
Imports Microsoft.Extensions.DependencyInjection
' Expensive: loads 3 model files from disk on construction (~300–800ms)
Public Class PaddleOcrEngine
Implements IDisposable
Private ReadOnly _ocr As PaddleOcrAll
Private _disposed As Boolean
Public Sub New()
Dim detModel = LocalFullModels.ChineseV3.DetectionModel
Dim clsModel = LocalFullModels.ChineseV3.ClassifierModel
Dim recModel = LocalFullModels.ChineseV3.RecognitionModel
' Must be singleton — cannot afford per-request construction
_ocr = New PaddleOcrAll(detModel, clsModel, recModel)
End Sub
Public Function Read(imagePath As String) As String
Using mat = Cv2.ImRead(imagePath) ' OpenCV required even for a file path
Dim result = _ocr.Run(mat)
Return String.Join(" ", result.Regions.Select(Function(r) r.Text))
End Using
End Function
Public Sub Dispose() Implements IDisposable.Dispose
If Not _disposed Then
_ocr?.Dispose()
_disposed = True
End If
End Sub
End Class
' Startup.vb — forced singleton because of construction cost
services.AddSingleton(Of PaddleOcrEngine)()
IronOCR Yaklaşımı:
using IronOcr;
using Microsoft.Extensions.DependencyInjection;
// IronTesseract has lightweight initialization — no model loading on construction
public class OcrEngine
{
public string Read(string imagePath)
{
return new IronTesseract().Read(imagePath).Text;
}
}
// Flexible registration — singleton, scoped, or transient all work
services.AddTransient<OcrEngine>();
// Or skip the wrapper entirely and inject IronTesseract directly
services.AddTransient<IronTesseract>();
using IronOcr;
using Microsoft.Extensions.DependencyInjection;
// IronTesseract has lightweight initialization — no model loading on construction
public class OcrEngine
{
public string Read(string imagePath)
{
return new IronTesseract().Read(imagePath).Text;
}
}
// Flexible registration — singleton, scoped, or transient all work
services.AddTransient<OcrEngine>();
// Or skip the wrapper entirely and inject IronTesseract directly
services.AddTransient<IronTesseract>();
Imports IronOcr
Imports Microsoft.Extensions.DependencyInjection
' IronTesseract has lightweight initialization — no model loading on construction
Public Class OcrEngine
Public Function Read(imagePath As String) As String
Return New IronTesseract().Read(imagePath).Text
End Function
End Class
' Flexible registration — singleton, scoped, or transient all work
services.AddTransient(Of OcrEngine)()
' Or skip the wrapper entirely and inject IronTesseract directly
services.AddTransient(Of IronTesseract)()
Zorunlu tekil durumdan esnek yaşam süresine geçiş önemlidir. PaddleSharp'un yapı maliyeti hizmet yaşam süresi kararınızı kilitler; IronOCR, uygulamanızın iş parçacığı ve istek izolasyonu gereksinimlerine dayalı olarak seçmenize izin verir. IronTesseract kurulum rehberi, yapılandırma seçeneklerini kapsar, örnek düzeyinde uygulanır.
OpenCV Ön İşleme Hattı Göçü
Düşük kaliteli taramalar yapan PaddleSharp ekipleri genellikle OCR motorunu çağırmadan önce bir OpenCV ön işleme hattı oluşturur. Bu hat, OpenCV'nin API yüzeyinin — herhangi bir OCR ön işleme görevinden gereksizce daha büyük — bilgisine ihtiyaç duyar. Yaygın işlemler — eğim düzeltme, gürültü giderme, kontrast uzatma — birden fazla Mat işlemi ve yerel bellek sızıntılarını önlemek için using bloklarıyla dikkatli bellek yönetimi gerektirir.
PaddleSharp OCR Yaklaşımı:
// Simplified — see OpenCvSharp documentation for full API
using OpenCvSharp;
using Sdcb.PaddleOCR;
public string ReadWithPreprocessing(string imagePath, PaddleOcrAll ocr)
{
using var original = Cv2.ImRead(imagePath);
// Step 1: Grayscale conversion
using var gray = new Mat();
Cv2.CvtColor(original, gray, ColorConversionCodes.BGR2GRAY);
// Step 2: Denoise (Gaussian blur to reduce noise)
using var denoised = new Mat();
Cv2.GaussianBlur(gray, denoised, new Size(3, 3), 0);
// Step 3: Adaptive threshold for binarization
using var binary = new Mat();
Cv2.AdaptiveThreshold(denoised, binary, 255,
AdaptiveThresholdTypes.GaussianC, ThresholdTypes.Binary, 11, 2);
// Step 4: Deskew — requires custom rotation detection logic (not shown)
// Several dozen lines of custom Mat operations
var result = ocr.Run(binary);
return string.Join(" ", result.Regions.Select(r => r.Text));
// Each Mat must be disposed; missing a using block leaks native memory
}
// Simplified — see OpenCvSharp documentation for full API
using OpenCvSharp;
using Sdcb.PaddleOCR;
public string ReadWithPreprocessing(string imagePath, PaddleOcrAll ocr)
{
using var original = Cv2.ImRead(imagePath);
// Step 1: Grayscale conversion
using var gray = new Mat();
Cv2.CvtColor(original, gray, ColorConversionCodes.BGR2GRAY);
// Step 2: Denoise (Gaussian blur to reduce noise)
using var denoised = new Mat();
Cv2.GaussianBlur(gray, denoised, new Size(3, 3), 0);
// Step 3: Adaptive threshold for binarization
using var binary = new Mat();
Cv2.AdaptiveThreshold(denoised, binary, 255,
AdaptiveThresholdTypes.GaussianC, ThresholdTypes.Binary, 11, 2);
// Step 4: Deskew — requires custom rotation detection logic (not shown)
// Several dozen lines of custom Mat operations
var result = ocr.Run(binary);
return string.Join(" ", result.Regions.Select(r => r.Text));
// Each Mat must be disposed; missing a using block leaks native memory
}
Imports OpenCvSharp
Imports Sdcb.PaddleOCR
Public Function ReadWithPreprocessing(imagePath As String, ocr As PaddleOcrAll) As String
Using original As Mat = Cv2.ImRead(imagePath)
' Step 1: Grayscale conversion
Using gray As New Mat()
Cv2.CvtColor(original, gray, ColorConversionCodes.BGR2GRAY)
' Step 2: Denoise (Gaussian blur to reduce noise)
Using denoised As New Mat()
Cv2.GaussianBlur(gray, denoised, New Size(3, 3), 0)
' Step 3: Adaptive threshold for binarization
Using binary As New Mat()
Cv2.AdaptiveThreshold(denoised, binary, 255, AdaptiveThresholdTypes.GaussianC, ThresholdTypes.Binary, 11, 2)
' Step 4: Deskew — requires custom rotation detection logic (not shown)
' Several dozen lines of custom Mat operations
Dim result = ocr.Run(binary)
Return String.Join(" ", result.Regions.Select(Function(r) r.Text))
End Using
End Using
End Using
End Using
End Function
IronOCR Yaklaşımı:
using IronOcr;
public string ReadWithPreprocessing(string imagePath)
{
using var input = new OcrInput();
input.LoadImage(imagePath);
// Named operations replace OpenCV knowledge requirements
input.Deskew();
input.DeNoise();
input.Contrast();
input.Binarize();
var result = new IronTesseract().Read(input);
return result.Text;
// OcrInput implements IDisposable; using block handles cleanup
}
using IronOcr;
public string ReadWithPreprocessing(string imagePath)
{
using var input = new OcrInput();
input.LoadImage(imagePath);
// Named operations replace OpenCV knowledge requirements
input.Deskew();
input.DeNoise();
input.Contrast();
input.Binarize();
var result = new IronTesseract().Read(input);
return result.Text;
// OcrInput implements IDisposable; using block handles cleanup
}
Imports IronOcr
Public Function ReadWithPreprocessing(imagePath As String) As String
Using input As New OcrInput()
input.LoadImage(imagePath)
' Named operations replace OpenCV knowledge requirements
input.Deskew()
input.DeNoise()
input.Contrast()
input.Binarize()
Dim result = New IronTesseract().Read(input)
Return result.Text
' OcrInput implements IDisposable; using block handles cleanup
End Using
End Function
Hiçbir Mat atama yok. Uyumlu eşik parametrelerinin bilgisi yok. Özel kenar kenarı döndürme matematiği yok. Aynı ön işleme hattı, 30–50 satır OpenCV kodu gerektiren, dört yöntem çağrısı haline gelir. görüntü kalite düzeltme rehberi, her mevcut filtreyi belgelemektedir, öncesi ve sonrası örneklerle. Yoğun arka plan gürültüsüne sahip belgeler için, input.DeepCleanBackgroundNoise() herhangi bir ek parametre olmadan DeNoise()'dan daha ileri gider.
Ön işleme gereksinimleri standart olmayan ekipler için, filtre sihirbazı, kodu taahhüt etmeden önce belirli belge türleriniz üzerinde filtre kombinasyonlarını değerlendirmek için etkileşimli bir araç sağlar.
Arka Uç Seçimi Kaldırma
PaddleSharp, çıkarım arka ucunu bir uygulama düzeyi kaygısı olarak sunar. Yalnızca CPU bulut VM'sinde çalışması gereken bir dağıtım, bir GPU iş istasyonu veya bir Intel OpenVINO uyumlu kenar aygıtını hedefleyen beklentilerden farklı başlatma kodu kullanır. Bu şartlı mantık genellikle uygulama başlangıç kodu, ortam değişkeni kontrolü veya özellik bayraklarında sona erer — metin okuma ile hiçbir ilgisi olmayan altyapı çalışması.
PaddleSharp OCR Yaklaşımı:
// Simplified — see Sdcb.PaddleInference documentation for full API
using Sdcb.PaddleInference;
using Sdcb.PaddleOCR;
public PaddleOcrAll CreateOcrEngine(string backendMode)
{
// Each backend requires a different NuGet runtime package installed
switch (backendMode)
{
case "gpu":
// Requires: Sdcb.PaddleInference.runtime.win64.cuda
// Requires: CUDA toolkit + cuDNN installed on host
var gpuConfig = PaddleConfig.FromModelDir("models/");
gpuConfig.EnableGpu(500, deviceId: 0); // Simplified
break;
case "openvino":
// Requires: Sdcb.PaddleInference.runtime.win64.mkl
var oviConfig = PaddleConfig.FromModelDir("models/");
oviConfig.EnableMkldnn(); // Simplified
break;
default:
// CPU-only — still requires platform-specific runtime package
var cpuConfig = PaddleConfig.FromModelDir("models/");
cpuConfig.SetCpuMathLibraryNumThreads(Environment.ProcessorCount);
break;
}
// Backend-specific config passed to model constructors — Simplified
var detModel = LocalFullModels.ChineseV3.DetectionModel;
var clsModel = LocalFullModels.ChineseV3.ClassifierModel;
var recModel = LocalFullModels.ChineseV3.RecognitionModel;
return new PaddleOcrAll(detModel, clsModel, recModel);
}
// Simplified — see Sdcb.PaddleInference documentation for full API
using Sdcb.PaddleInference;
using Sdcb.PaddleOCR;
public PaddleOcrAll CreateOcrEngine(string backendMode)
{
// Each backend requires a different NuGet runtime package installed
switch (backendMode)
{
case "gpu":
// Requires: Sdcb.PaddleInference.runtime.win64.cuda
// Requires: CUDA toolkit + cuDNN installed on host
var gpuConfig = PaddleConfig.FromModelDir("models/");
gpuConfig.EnableGpu(500, deviceId: 0); // Simplified
break;
case "openvino":
// Requires: Sdcb.PaddleInference.runtime.win64.mkl
var oviConfig = PaddleConfig.FromModelDir("models/");
oviConfig.EnableMkldnn(); // Simplified
break;
default:
// CPU-only — still requires platform-specific runtime package
var cpuConfig = PaddleConfig.FromModelDir("models/");
cpuConfig.SetCpuMathLibraryNumThreads(Environment.ProcessorCount);
break;
}
// Backend-specific config passed to model constructors — Simplified
var detModel = LocalFullModels.ChineseV3.DetectionModel;
var clsModel = LocalFullModels.ChineseV3.ClassifierModel;
var recModel = LocalFullModels.ChineseV3.RecognitionModel;
return new PaddleOcrAll(detModel, clsModel, recModel);
}
Imports Sdcb.PaddleInference
Imports Sdcb.PaddleOCR
Public Function CreateOcrEngine(ByVal backendMode As String) As PaddleOcrAll
' Each backend requires a different NuGet runtime package installed
Select Case backendMode
Case "gpu"
' Requires: Sdcb.PaddleInference.runtime.win64.cuda
' Requires: CUDA toolkit + cuDNN installed on host
Dim gpuConfig As PaddleConfig = PaddleConfig.FromModelDir("models/")
gpuConfig.EnableGpu(500, deviceId:=0) ' Simplified
Case "openvino"
' Requires: Sdcb.PaddleInference.runtime.win64.mkl
Dim oviConfig As PaddleConfig = PaddleConfig.FromModelDir("models/")
oviConfig.EnableMkldnn() ' Simplified
Case Else
' CPU-only — still requires platform-specific runtime package
Dim cpuConfig As PaddleConfig = PaddleConfig.FromModelDir("models/")
cpuConfig.SetCpuMathLibraryNumThreads(Environment.ProcessorCount)
End Select
' Backend-specific config passed to model constructors — Simplified
Dim detModel = LocalFullModels.ChineseV3.DetectionModel
Dim clsModel = LocalFullModels.ChineseV3.ClassifierModel
Dim recModel = LocalFullModels.ChineseV3.RecognitionModel
Return New PaddleOcrAll(detModel, clsModel, recModel)
End Function
IronOCR Yaklaşımı:
using IronOcr;
//Hayırbackend selection.Hayırswitch statement.Hayırenvironment variable check.
// The same code runs on CPU-only VMs, GPU workstations, and ARM devices.
public IronTesseract CreateOcrEngine()
{
return new IronTesseract();
}
// Parallel processing across CPU cores — no GPU configuration required
public IEnumerable<string> ReadBatch(IEnumerable<string> imagePaths)
{
var results = new System.Collections.Concurrent.ConcurrentBag<string>();
Parallel.ForEach(imagePaths, path =>
{
var result = new IronTesseract().Read(path);
results.Add(result.Text);
});
return results;
}
using IronOcr;
//Hayırbackend selection.Hayırswitch statement.Hayırenvironment variable check.
// The same code runs on CPU-only VMs, GPU workstations, and ARM devices.
public IronTesseract CreateOcrEngine()
{
return new IronTesseract();
}
// Parallel processing across CPU cores — no GPU configuration required
public IEnumerable<string> ReadBatch(IEnumerable<string> imagePaths)
{
var results = new System.Collections.Concurrent.ConcurrentBag<string>();
Parallel.ForEach(imagePaths, path =>
{
var result = new IronTesseract().Read(path);
results.Add(result.Text);
});
return results;
}
Imports IronOcr
Imports System.Collections.Concurrent
Imports System.Threading.Tasks
Public Class OcrProcessor
' The same code runs on CPU-only VMs, GPU workstations, and ARM devices.
Public Function CreateOcrEngine() As IronTesseract
Return New IronTesseract()
End Function
' Parallel processing across CPU cores — no GPU configuration required
Public Function ReadBatch(imagePaths As IEnumerable(Of String)) As IEnumerable(Of String)
Dim results As New ConcurrentBag(Of String)()
Parallel.ForEach(imagePaths, Sub(path)
Dim result = New IronTesseract().Read(path)
results.Add(result.Text)
End Sub)
Return results
End Function
End Class
Buradaki Parallel.ForEach deseni baştan iplik güvenlidir. Her IronTesseract örneği, paylaşılan yerel durum olmadan bağımsızdır. PaddleSharp dağıtımı arka uç şartlılarını yönetirken zaman harcayan ekipler için, bu basitleştirme aynı zamanda dağıtım güvenilirliğini de artırır — aynı yapı eseri, donanım algılama kodu olmadan her yerde çalışır. hız optimizasyon rehberi, verimlilik duyarlı senaryolar için yapılandırma seçeneklerini kapsar.
Tablo Tanıma Göçü
PaddleSharp'ta tablo çıkartımı, standart tanıma, sınıflandırma, tanıma setinin ötesinde dördüncü bir model dosyası olan özel bir tablo tanıma modeline ihtiyaç duyar. Tablo modeli ayrı bir API çağrısı kullanır ve kendi sonuç yapısını döndürür. Fatura, form veya elektronik tablonun işleme hatları oluşturan ekipler, iki paralel başlatma yolu ve iki sonuç-parselleme stratejisini sürdürmelidir.
PaddleSharp OCR Yaklaşımı:
// Simplified — see Sdcb.PaddleOCR documentation for full API
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models;
using OpenCvSharp;
public class TableRecognitionService
{
// Standard OCR engine — 3 models
private readonly PaddleOcrAll _textOcr;
// Table engine — 4th model, separate initialization
// private readonly PaddleOcrTable _tableOcr; // Simplified
public TableRecognitionService()
{
var detModel = LocalFullModels.ChineseV3.DetectionModel;
var clsModel = LocalFullModels.ChineseV3.ClassifierModel;
var recModel = LocalFullModels.ChineseV3.RecognitionModel;
_textOcr = new PaddleOcrAll(detModel, clsModel, recModel);
// Table model: separate download, separate version tracking
// var tableModel = LocalFullModels.TableEnV2.Model; // Simplified
// _tableOcr = new PaddleOcrTable(tableModel); // Simplified
}
public void ProcessDocument(string imagePath)
{
using var image = Cv2.ImRead(imagePath);
// Text extraction path
var textResult = _textOcr.Run(image);
var text = string.Join(" ", textResult.Regions.Select(r => r.Text));
// Table extraction path — different API, different result structure
// var tableResult = _tableOcr.Run(image); // Simplified
// foreach (var cell in tableResult.Cells) { ... } // Simplified
}
}
// Simplified — see Sdcb.PaddleOCR documentation for full API
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models;
using OpenCvSharp;
public class TableRecognitionService
{
// Standard OCR engine — 3 models
private readonly PaddleOcrAll _textOcr;
// Table engine — 4th model, separate initialization
// private readonly PaddleOcrTable _tableOcr; // Simplified
public TableRecognitionService()
{
var detModel = LocalFullModels.ChineseV3.DetectionModel;
var clsModel = LocalFullModels.ChineseV3.ClassifierModel;
var recModel = LocalFullModels.ChineseV3.RecognitionModel;
_textOcr = new PaddleOcrAll(detModel, clsModel, recModel);
// Table model: separate download, separate version tracking
// var tableModel = LocalFullModels.TableEnV2.Model; // Simplified
// _tableOcr = new PaddleOcrTable(tableModel); // Simplified
}
public void ProcessDocument(string imagePath)
{
using var image = Cv2.ImRead(imagePath);
// Text extraction path
var textResult = _textOcr.Run(image);
var text = string.Join(" ", textResult.Regions.Select(r => r.Text));
// Table extraction path — different API, different result structure
// var tableResult = _tableOcr.Run(image); // Simplified
// foreach (var cell in tableResult.Cells) { ... } // Simplified
}
}
Imports Sdcb.PaddleOCR
Imports Sdcb.PaddleOCR.Models
Imports OpenCvSharp
Public Class TableRecognitionService
' Standard OCR engine — 3 models
Private ReadOnly _textOcr As PaddleOcrAll
' Table engine — 4th model, separate initialization
' Private ReadOnly _tableOcr As PaddleOcrTable ' Simplified
Public Sub New()
Dim detModel = LocalFullModels.ChineseV3.DetectionModel
Dim clsModel = LocalFullModels.ChineseV3.ClassifierModel
Dim recModel = LocalFullModels.ChineseV3.RecognitionModel
_textOcr = New PaddleOcrAll(detModel, clsModel, recModel)
' Table model: separate download, separate version tracking
' Dim tableModel = LocalFullModels.TableEnV2.Model ' Simplified
' _tableOcr = New PaddleOcrTable(tableModel) ' Simplified
End Sub
Public Sub ProcessDocument(imagePath As String)
Using image = Cv2.ImRead(imagePath)
' Text extraction path
Dim textResult = _textOcr.Run(image)
Dim text = String.Join(" ", textResult.Regions.Select(Function(r) r.Text))
' Table extraction path — different API, different result structure
' Dim tableResult = _tableOcr.Run(image) ' Simplified
' For Each cell In tableResult.Cells ' Simplified
' ...
' Next
End Using
End Sub
End Class
IronOCR Yaklaşımı:
using IronOcr;
public class TableRecognitionService
{
// One engine handles both text and table regions
public void ProcessDocument(string imagePath)
{
var ocr = new IronTesseract();
var result = ocr.Read(imagePath);
// Structured hierarchy: pages → paragraphs → lines → words
foreach (var page in result.Pages)
{
foreach (var paragraph in page.Paragraphs)
{
Console.WriteLine($"Block at ({paragraph.X},{paragraph.Y}): {paragraph.Text}");
}
}
Console.WriteLine($"Full document text: {result.Text}");
}
}
using IronOcr;
public class TableRecognitionService
{
// One engine handles both text and table regions
public void ProcessDocument(string imagePath)
{
var ocr = new IronTesseract();
var result = ocr.Read(imagePath);
// Structured hierarchy: pages → paragraphs → lines → words
foreach (var page in result.Pages)
{
foreach (var paragraph in page.Paragraphs)
{
Console.WriteLine($"Block at ({paragraph.X},{paragraph.Y}): {paragraph.Text}");
}
}
Console.WriteLine($"Full document text: {result.Text}");
}
}
Imports IronOcr
Public Class TableRecognitionService
' One engine handles both text and table regions
Public Sub ProcessDocument(imagePath As String)
Dim ocr As New IronTesseract()
Dim result = ocr.Read(imagePath)
' Structured hierarchy: pages → paragraphs → lines → words
For Each page In result.Pages
For Each paragraph In page.Paragraphs
Console.WriteLine($"Block at ({paragraph.X},{paragraph.Y}): {paragraph.Text}")
Next
Next
Console.WriteLine($"Full document text: {result.Text}")
End Sub
End Class
Tablo yapısının kendisi satır ve sütun olarak çıkarılması gereken belgeler için; IronOCR, özel bir tablo çıkarım yeteneği sunar:
using IronOcr;
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("invoice-with-table.jpg");
var result = ocr.Read(input);
// Access structured page layout for table region extraction
foreach (var page in result.Pages)
{
foreach (var line in page.Lines)
{
// Lines within a table region preserve spatial ordering
Console.WriteLine($"Row text: {line.Text} | Y position: {line.Y}");
foreach (var word in line.Words)
{
Console.WriteLine($" Cell: '{word.Text}' at X={word.X}");
}
}
}
using IronOcr;
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("invoice-with-table.jpg");
var result = ocr.Read(input);
// Access structured page layout for table region extraction
foreach (var page in result.Pages)
{
foreach (var line in page.Lines)
{
// Lines within a table region preserve spatial ordering
Console.WriteLine($"Row text: {line.Text} | Y position: {line.Y}");
foreach (var word in line.Words)
{
Console.WriteLine($" Cell: '{word.Text}' at X={word.X}");
}
}
}
Imports IronOcr
Dim ocr As New IronTesseract()
Using input As New OcrInput()
input.LoadImage("invoice-with-table.jpg")
Dim result = ocr.Read(input)
' Access structured page layout for table region extraction
For Each page In result.Pages
For Each line In page.Lines
' Lines within a table region preserve spatial ordering
Console.WriteLine($"Row text: {line.Text} | Y position: {line.Y}")
For Each word In line.Words
Console.WriteLine($" Cell: '{word.Text}' at X={word.X}")
Next
Next
Next
End Using
Bir model indirme ortadan kaldırıldı. Bir başlatma yolu ortadan kaldırıldı. IronOCR'deki yapılandırılmış sonuç hiyerarşisi — kelime düzeyindeki X/Y koordinatlarıyla — ayrı bir tanıma modeline gerek kalmadan tablo satırlarını ve sütunlarını yeniden oluşturmaya yönelik gereken pozisyonel verileri sağlar. tablo okuma rehberi ve sonuç okuma rehberi, tam yapılandırılmış çıktı API'sini kapsar.
Taratılmış Belgelerden Aranabilir PDF Çıktısı
PaddleSharp metin dizeleri üretir ve başka bir şey yok. Taranmış PDF'leri metin aranabilir yapmak için bir belge arşivi oluşturmak, ayrı bir PDF kütüphanesi entegre etmeyi, bir metin katmanı üzerine yazmayı ve iki kütüphaneyi uyum içinde yönetmeyi gerektirir. O kısıtlamayı kabul etmiş ekipler genellikle bu göç tetikleyicisidir — iki kütüphaneli entegrasyonun harcanan çabası, OCR sağlayıcılarını değiştirme çabalarını aşar.
PaddleSharp OCR Yaklaşımı:
// Simplified — PaddleSharp has no PDF output. Requires a separate PDF library.
// Example of what teams typically build:
// using Sdcb.PaddleOCR;
// using SomePdfLibrary; // Third dependency to produce searchable PDF
public void ArchiveScannedDocument(string imagePath, string outputPdfPath)
{
// Step 1: OCR via PaddleSharp — produces text only
// var text = _ocr.Run(Cv2.ImRead(imagePath));
// Step 2: Build a PDF with text overlay using a separate PDF library
// Requires: text positions mapped to PDF coordinate space
// Requires: image embedded as background
// Requires: invisible text layer positioned over image
// ~50–100 lines of PDF construction code
throw new NotImplementedException("Requires a separate PDF library");
}
// Simplified — PaddleSharp has no PDF output. Requires a separate PDF library.
// Example of what teams typically build:
// using Sdcb.PaddleOCR;
// using SomePdfLibrary; // Third dependency to produce searchable PDF
public void ArchiveScannedDocument(string imagePath, string outputPdfPath)
{
// Step 1: OCR via PaddleSharp — produces text only
// var text = _ocr.Run(Cv2.ImRead(imagePath));
// Step 2: Build a PDF with text overlay using a separate PDF library
// Requires: text positions mapped to PDF coordinate space
// Requires: image embedded as background
// Requires: invisible text layer positioned over image
// ~50–100 lines of PDF construction code
throw new NotImplementedException("Requires a separate PDF library");
}
Public Sub ArchiveScannedDocument(imagePath As String, outputPdfPath As String)
' Step 1: OCR via PaddleSharp — produces text only
' Dim text = _ocr.Run(Cv2.ImRead(imagePath))
' Step 2: Build a PDF with text overlay using a separate PDF library
' Requires: text positions mapped to PDF coordinate space
' Requires: image embedded as background
' Requires: invisible text layer positioned over image
' ~50–100 lines of PDF construction code
Throw New NotImplementedException("Requires a separate PDF library")
End Sub
IronOCR Yaklaşımı:
using IronOcr;
public void ArchiveScannedDocument(string imagePath, string outputPdfPath)
{
using var input = new OcrInput();
input.LoadImage(imagePath);
input.Deskew(); // Straighten scan before archiving
input.DeNoise(); // Clean up scan artifacts
var ocr = new IronTesseract();
var result = ocr.Read(input);
// One call: OCR + searchable PDF with text layer + image background
result.SaveAsSearchablePdf(outputPdfPath);
}
// Multi-page document — same pattern
public void ArchiveMultiPageDocument(string[] imageFiles, string outputPdfPath)
{
using var input = new OcrInput();
foreach (var file in imageFiles)
input.LoadImage(file);
var result = new IronTesseract().Read(input);
result.SaveAsSearchablePdf(outputPdfPath);
}
using IronOcr;
public void ArchiveScannedDocument(string imagePath, string outputPdfPath)
{
using var input = new OcrInput();
input.LoadImage(imagePath);
input.Deskew(); // Straighten scan before archiving
input.DeNoise(); // Clean up scan artifacts
var ocr = new IronTesseract();
var result = ocr.Read(input);
// One call: OCR + searchable PDF with text layer + image background
result.SaveAsSearchablePdf(outputPdfPath);
}
// Multi-page document — same pattern
public void ArchiveMultiPageDocument(string[] imageFiles, string outputPdfPath)
{
using var input = new OcrInput();
foreach (var file in imageFiles)
input.LoadImage(file);
var result = new IronTesseract().Read(input);
result.SaveAsSearchablePdf(outputPdfPath);
}
Imports IronOcr
Public Sub ArchiveScannedDocument(imagePath As String, outputPdfPath As String)
Using input As New OcrInput()
input.LoadImage(imagePath)
input.Deskew() ' Straighten scan before archiving
input.DeNoise() ' Clean up scan artifacts
Dim ocr As New IronTesseract()
Dim result = ocr.Read(input)
' One call: OCR + searchable PDF with text layer + image background
result.SaveAsSearchablePdf(outputPdfPath)
End Using
End Sub
' Multi-page document — same pattern
Public Sub ArchiveMultiPageDocument(imageFiles As String(), outputPdfPath As String)
Using input As New OcrInput()
For Each file In imageFiles
input.LoadImage(file)
Next
Dim result = New IronTesseract().Read(input)
result.SaveAsSearchablePdf(outputPdfPath)
End Using
End Sub
PDF kütüphanesi yok. Koordinat haritalama yok. Metin katmanı konumlandırma yok. IronOCR'deki aranabilir PDF çıktı formatı, orijinal görüntü üzerine görünmez bir metin katmanı yerleştirir, taralı belgeye görsel olarak sadık olan ve tamamen metin aranabilir bir dosya üretir. aranabilir PDF nasıl yapılır, sayfa seçimi, kalite seçenekleri ve meta veri kontrolünü kapsar.
PaddleSharp OCR API'den IronOCR Haritalama Referansı
| PaddleSharp OCR | IronOCR |
|---|---|
Sdcb.PaddleOCR (namespace) |
IronOcr (namespace) |
Sdcb.PaddleInference (namespace) |
Gerek yok — otomatik yapılandırılmış |
PaddleOcrAll |
IronTesseract |
new PaddleOcrAll(det, cls, rec) |
new IronTesseract() |
LocalFullModels.ChineseV3.DetectionModel |
Eşdeğer yok — model seçimi yok |
LocalFullModels.ChineseV3.ClassifierModel |
Eşdeğer yok — model seçimi yok |
LocalFullModels.ChineseV3.RecognitionModel |
Eşdeğer yok — model seçimi yok |
PaddleConfig.FromModelDir() |
Eşdeğer yok — yapılandırma nesnesi yok |
config.EnableGpu(memMB, deviceId) |
Eşdeğer yok — arka uç otomatik |
config.EnableMkldnn() |
Eşdeğer yok — arka uç otomatik |
config.SetCpuMathLibraryNumThreads(n) |
Eşdeğer yok — içsel olarak yönetiliyor |
Cv2.ImRead(path) (OpenCV yükleme) |
input.LoadImage(path) |
ocr.Run(mat) |
ocr.Read(input) veya ocr.Read("file.jpg") |
result.Regions |
result.Pages[0].Words veya result.Pages[0].Lines |
region.Text |
word.Text, line.Text, paragraph.Text |
region.Rect.Center.X/.Y |
word.X, word.Y |
region.Score (confidence) |
word.Confidence, result.Confidence |
| Model düzeyinde dil değişimi | ocr.Language = OcrLanguage.French |
| Tablo modeli (ayrı indirme) | Yerleşik yapılandırılmış sonuç hiyerarşisi |
Cv2.CvtColor(..., GRAY) |
input.Binarize() veya input.Contrast() |
Cv2.GaussianBlur(...) |
input.DeNoise() |
| Aranabilir PDF çıktısı yok | result.SaveAsSearchablePdf("output.pdf") |
Yaygın Göç Sorunları ve Çözümleri
1. Sorun: OpenCV Bağımlılığı Yüklenemiyor
PaddleSharp OCR: OpenCvSharp4.runtime.win ve benzeri platforma özgü çalışma zamanı paketleri yönetilmeyen yerel DLL'ler kurar. Bu DLL'ler bazı barındırma senaryolarında - özellikle IIS uygulama havuzu geri dönüşümünde - doğru temizliği engelleyebilir ve yanlış platform çalışma zamanı paketi oluşturma zamanında başvurulursa derleme yükleme hatalarına neden olabilir. Bunları kaldırmak, hem NuGet paketini kaldırmayı hem de çıktı dizinindeki önbelleğe alınmış yerel ikili dosyaları temizlemeyi gerektirir.
Çözüm: OpenCvSharp4 ve OpenCvSharp4.runtime.* paketlerini kaldırdıktan sonra, yeniden derlemeden önce yapı çıktısı dizinini temizleyin:
dotnet remove package OpenCvSharp4
dotnet remove package OpenCvSharp4.runtime.win
dotnet clean
dotnet build
dotnet remove package OpenCvSharp4
dotnet remove package OpenCvSharp4.runtime.win
dotnet clean
dotnet build
IronOCR, yerel bağımlılıklarını dahili olarak paketler ve yönetilmeyen yaşam döngüsünü yönetir. Platforma özgü çalışma zamanı paketi seçimi gerekmez. IronTesseract kurulum rehberi, IronOCR'un otomatik olarak ele aldığı platform gereksinimlerini belgeliyor.
2. Sorun: Taşıma Sonrası Diskte Bırakılan Model Dosyaları
PaddleSharp OCR: PaddleSharp tarafından indirilen model dosyaları (algılama, sınıflandırma, tanıma ve herhangi bir tablo modeli), tipik olarak uygulamaya göre ilgili bir models/ dizininde veya yapılandırılmış bir yolda saklanır. Bu dosyalar, NuGet paketi kaldırıldığında kaldırılmaz. Bir Docker imajında gereksiz katman boyutu eklerler. Bir dağıtım hattında, eski yollardaki bayat model dosyaları, herhangi bir kalıntı başlatma kodu bunlara başvurursa başlatma hatalarına neden olabilir.
Çözüm: Taşımanın bir parçası olarak model dizinlerini açıkça kaldırın. Başlatma yapılandırmasını herhangi bir yol referansı için inceleyin:
# Locate model directory references in application code
grep -r "LocalFullModels\|ModelPath\|models/" --include="*.cs" .
grep -r "DetectionModel\|RecognitionModel\|ClassifierModel" --include="*.cs" .
# Locate model directory references in application code
grep -r "LocalFullModels\|ModelPath\|models/" --include="*.cs" .
grep -r "DetectionModel\|RecognitionModel\|ClassifierModel" --include="*.cs" .
Model referansları kaldırıldıktan ve IronOCR başlatıldıktan sonra, model dizinini depodan ve Docker yapı bağlamından silin.
3. Sorun: Singleton Yaşam Süresi Varsayımı Taşıma Sonrası Bozuluyor
PaddleSharp OCR: PaddleOcrAll, oluşturma maliyeti talep başına oluşturulmayı pratik olmayan hale getirdiği için singleton olarak kaydedildi. IronOCR'u aynı tek başına kayıt altına alan taşıma kodu, gereksiz durum paylaşımını istekler arasında tanıtır. IronTesseract eşzamanlı olarak kullanıldığında iplik güvenliğe sahip olmasına rağmen, tek bir örneği paylaşmak gerekli değildir - her örnek bağımsızdır.
Çözüm: Singleton kaydının performans dışında bir amaca hizmet edip etmediğini değerlendirin. Çoğu ASP.NET Core uygulaması için geçici kayıt,IronOCR ile daha temiz bir seçenektir:
// PaddleSharp — forced singleton due to construction cost
services.AddSingleton<PaddleOcrAll>(sp =>
{
var det = LocalFullModels.ChineseV3.DetectionModel; // Simplified
var cls = LocalFullModels.ChineseV3.ClassifierModel; // Simplified
var rec = LocalFullModels.ChineseV3.RecognitionModel; // Simplified
return new PaddleOcrAll(det, cls, rec);
});
//IronOCR— transient works; no expensive construction
services.AddTransient<IronTesseract>();
// PaddleSharp — forced singleton due to construction cost
services.AddSingleton<PaddleOcrAll>(sp =>
{
var det = LocalFullModels.ChineseV3.DetectionModel; // Simplified
var cls = LocalFullModels.ChineseV3.ClassifierModel; // Simplified
var rec = LocalFullModels.ChineseV3.RecognitionModel; // Simplified
return new PaddleOcrAll(det, cls, rec);
});
//IronOCR— transient works; no expensive construction
services.AddTransient<IronTesseract>();
Imports Microsoft.Extensions.DependencyInjection
' PaddleSharp — forced singleton due to construction cost
services.AddSingleton(Of PaddleOcrAll)(Function(sp)
Dim det = LocalFullModels.ChineseV3.DetectionModel ' Simplified
Dim cls = LocalFullModels.ChineseV3.ClassifierModel ' Simplified
Dim rec = LocalFullModels.ChineseV3.RecognitionModel ' Simplified
Return New PaddleOcrAll(det, cls, rec)
End Function)
' IronOCR— transient works; no expensive construction
services.AddTransient(Of IronTesseract)()
Yüksek verimli toplu senaryolarda, explicit örnek yeniden kullanımı istediğinizde, tek başına veya havuzlanmış bir model yine de çalışır — ancak bu bir performans tercihidir, doğruluk gereksinimi değil.
4. Sorun: Sonuç Bölgesi Sıralaması Artık Gerekli Değil
PaddleSharp OCR: result.Regions, algılama sırası ızgarada sağlanan okuma sırasıyla eşleşmeyen algılanmış metin bölgelerini döndürür. Takımlar genellikle bölge metni birleştirmeden önce .Rect.Center.Y ve ardından .Rect.Center.X ile sıralama uygular - bu desen neredeyse her PaddleSharp metin çıkartma uygulamasında görünmektedir. Bu desenin harfi harfine IronOCR'a taşınması gereksiz kod üretir.
Çözüm: IronOCR, sonuçları varsayılan olarak okuma sırasına göre döndürür. Sıralamayı kaldırın:
// PaddleSharp — manual reading-order sort required
var text = string.Join("\n", result.Regions
.OrderBy(r => r.Rect.Center.Y)
.ThenBy(r => r.Rect.Center.X)
.Select(r => r.Text));
//IronOCR— result.Text is already in reading order; no sort needed
var text = result.Text;
// For word-level access with position, use the structured hierarchy directly
foreach (var word in result.Pages[0].Words)
{
Console.WriteLine($"{word.Text} at ({word.X},{word.Y})");
}
// PaddleSharp — manual reading-order sort required
var text = string.Join("\n", result.Regions
.OrderBy(r => r.Rect.Center.Y)
.ThenBy(r => r.Rect.Center.X)
.Select(r => r.Text));
//IronOCR— result.Text is already in reading order; no sort needed
var text = result.Text;
// For word-level access with position, use the structured hierarchy directly
foreach (var word in result.Pages[0].Words)
{
Console.WriteLine($"{word.Text} at ({word.X},{word.Y})");
}
Imports System
Imports System.Linq
' PaddleSharp — manual reading-order sort required
Dim text = String.Join(vbLf, result.Regions _
.OrderBy(Function(r) r.Rect.Center.Y) _
.ThenBy(Function(r) r.Rect.Center.X) _
.Select(Function(r) r.Text))
' IronOCR— result.Text is already in reading order; no sort needed
text = result.Text
' For word-level access with position, use the structured hierarchy directly
For Each word In result.Pages(0).Words
Console.WriteLine($"{word.Text} at ({word.X},{word.Y})")
Next
5. Sorun: Arka Uç Koşullu Paketler Geri Yüklemeyi Bozuyor
PaddleSharp OCR: Bazı PaddleSharp kurulumları, hedef ortama bağlı olarak farklı Sdcb.PaddleInference.runtime.* paketlerine koşullu olarak referans verir (GPU için CUDA, OpenVINO için MKL, yalnızca CPU). Bu bazen .csproj koşulları veya dağıtım hedefi başına ayrı proje dosyaları olarak görünür. Ortaya çıkan derleme matrisi, yanlış paket seti geri yüklendiğinde CI boru hatlarını bozar.
Çözüm: PaddleSharp paketlerini kaldırdıktan sonra, platform veya OpenCV koşullu .csproj bloklarını başvuran PackageReference dosyasını denetleyin ve tamamen kaldırın:
grep -n "Sdcb\|OpenCvSharp\|PaddleInference" *.csproj
grep -n "Sdcb\|OpenCvSharp\|PaddleInference" *.csproj
IronOCR, platform koşulları olmadan tek bir IronOcr paket referansı kullanır. Aynı paket, Windows, Linux ve macOS'ta doğru bir şekilde geri yüklenir.
6. Sorun: Tablo Sonuç Yapısının Doğrudan Bir Eşdeğeri Yok
PaddleSharp OCR: PaddleOcrTable, her tanınan hücre için satır ve sütun indeksleri içeren hücre tabanlı bir yapı döndürür. Bu yapıyı tüketen kod genellikle (row, column) tarafından indekslenen iki boyutlu bir dizi oluşturur. IronOCR, aynı hücre-indeks yapıyı sağlamaz — bir hücre ızgarasını yeniden yapılandırmak için uzaysal gruplama gerektiren kelime ve satır koordinatları sağlar.
Çözüm:IronOCR kelime koordinatlarından tablo yapısını satırlar için Y-konumu gruplaması ve sütunlar için X-konumu sıralaması kullanarak yeniden yapılandırın. Tablo okuma nasıl yapılır, yaygın tablo formatları için uzaysal gruplama yaklaşımı sağlar. Saha pozisyonları bilinen yapılandırılmış faturalar için, bölge tabanlı OCR ile CropRectangle, tam sayfa tablo çıkartmasından daha temiz bir modeldir:
using IronOcr;
// Target specific table cells by region instead of full-page table detection
var totalAmountRegion = new CropRectangle(400, 600, 200, 30); // x, y, width, height
using var input = new OcrInput();
input.LoadImage("invoice.jpg", totalAmountRegion);
var result = new IronTesseract().Read(input);
Console.WriteLine($"Total: {result.Text}");
using IronOcr;
// Target specific table cells by region instead of full-page table detection
var totalAmountRegion = new CropRectangle(400, 600, 200, 30); // x, y, width, height
using var input = new OcrInput();
input.LoadImage("invoice.jpg", totalAmountRegion);
var result = new IronTesseract().Read(input);
Console.WriteLine($"Total: {result.Text}");
Imports IronOcr
' Target specific table cells by region instead of full-page table detection
Dim totalAmountRegion As New CropRectangle(400, 600, 200, 30) ' x, y, width, height
Using input As New OcrInput()
input.LoadImage("invoice.jpg", totalAmountRegion)
Dim result = New IronTesseract().Read(input)
Console.WriteLine($"Total: {result.Text}")
End Using
PaddleSharp OCR Taşıma Kontrol Listesi
Öncesi-Geçiş
Paketleri çıkarmadan önce kod tabanındaki tüm PaddleSharp referanslarını denetleyin:
# Find all PaddleSharp and PaddleInference usages
grep -rn "Sdcb\.PaddleOCR\|Sdcb\.PaddleInference" --include="*.cs" .
# Find OpenCV usages that will need replacement
grep -rn "OpenCvSharp\|Cv2\.\|using var.*Mat\b" --include="*.cs" .
# Find model path references and configuration
grep -rn "LocalFullModels\|ModelDir\|DetectionModel\|RecognitionModel\|ClassifierModel" --include="*.cs" .
# Find backend selection logic
grep -rn "EnableGpu\|EnableMkldnn\|PaddleConfig\|SetCpuMath" --include="*.cs" .
# Find table recognition usages
grep -rn "PaddleOcrTable\|TableModel\|table.*ocr\|ocr.*table" --include="*.cs" .
# Find result region access patterns that need updating
grep -rn "\.Regions\b\|Rect\.Center\|region\.Text" --include="*.cs" .
# Find all PaddleSharp and PaddleInference usages
grep -rn "Sdcb\.PaddleOCR\|Sdcb\.PaddleInference" --include="*.cs" .
# Find OpenCV usages that will need replacement
grep -rn "OpenCvSharp\|Cv2\.\|using var.*Mat\b" --include="*.cs" .
# Find model path references and configuration
grep -rn "LocalFullModels\|ModelDir\|DetectionModel\|RecognitionModel\|ClassifierModel" --include="*.cs" .
# Find backend selection logic
grep -rn "EnableGpu\|EnableMkldnn\|PaddleConfig\|SetCpuMath" --include="*.cs" .
# Find table recognition usages
grep -rn "PaddleOcrTable\|TableModel\|table.*ocr\|ocr.*table" --include="*.cs" .
# Find result region access patterns that need updating
grep -rn "\.Regions\b\|Rect\.Center\|region\.Text" --include="*.cs" .
Diskteki model dosyalarının envanterini çıkarın ve yollarını not edin. Tüm dağıtım hedeflerini ve herhangi birinin GPU veya OpenVINO özel NuGet koşulları içerip içermediğini .csproj içinde envanterleyin. PaddleSharp oluşturma maliyeti nedeniyle tek başına kayıtlı herhangi bir hizmeti not edin.
Kod Geçişi
- Her proje dosyasından tüm
Sdcb.PaddleOCR,Sdcb.PaddleInference,OpenCvSharp4veOpenCvSharp4.runtime.*NuGet paketlerini kaldırın. IronOcrNuGet paketini yükleyin.- Gereken diller için dil NuGet paketlerini yükleyin (örneğin,
IronOcr.Languages.ChineseSimplified). - Uygulama başlangıcına
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";ekleyin. - Tüm
using Sdcb.PaddleOCR,using Sdcb.PaddleInferenceveusing OpenCvSharpifadeleriniusing IronOcrile değiştirin. PaddleOcrAlloluşturma ve model yüklemeyinew IronTesseract()ile değiştirin.- Tüm
PaddleConfigarka plan seçim bloklarını (CPU, GPU, OpenVINO koşulları) silin. Cv2.ImRead(path)çağrılarınıinput.LoadImage(path)ile,OcrInputkullanarak değiştirin.- OpenCV ön işleme işlemlerini (
CvtColor,GaussianBlur,Thresholdvb.)OcrInputfiltre yöntemleri (Deskew(),DeNoise(),Contrast(),Binarize()) ile değiştirin. ocr.Run(mat)çağrılarınıocr.Read(input)ile değiştirin.result.Regionssayımınıresult.Pages,result.Pages[n].Linesveyaresult.Pages[n].Wordsile değiştirin..OrderBy(r => r.Rect.Center.Y).ThenBy(r => r.Rect.Center.X)sıralama zincirlerini kaldırın — okuma sırası otomatik.- Bölge tabanlı hedefleme veya koordinat tabanlı kelime gruplaması ile
PaddleOcrTablebaşlatma ve sonuç ayrıştırmasını değiştirin. - Aranabilir bir PDF arşivi gerektiğinde her yerde
result.SaveAsSearchablePdf(path)ekleyin. - Hizmet yaşam süresi kayıtlarını yeniden değerlendirin: PaddleSharp oluşturma maliyeti nedeniyle yönlendirilen tekil kayıtlar genellikle geçici veya kapsamlı hale gelebilir.
- Diskten model dosyalarını silin ve Docker yapı bağlamlarından model dizinlerini kaldırın.
- Platforma özgü Paddle veya OpenCV kurulum paketleri için herhangi bir
.csprojkoşulluPackageReferencebloklarını kaldırın.
Geçiş Sonrası
- Metin çıkarma çıktısının, boru hattındaki her belge türünden temsil edici 20-30 dokümanda PaddleSharp çıktısıyla eşleştiğini veya aştığını doğrulayın.
- Uygulama başlangıç günlüklerinde
OpenCvSharpile ilgili monte yükleme istisnalarının olmadığını doğrulayın. - Windows, Linux, Docker'da her hedef platformda dağıtımı test edin ve aynı yapı eseri kullanarak — platforma özgü paket seçimi gerektiği konusunda emin olun.
- Önceden manuel sonuç sıralaması gerektiren belgelerin
result.Textile doğru sıralı metin ürettiğini doğrulayın. - Adobe Acrobat Reader veya tercih ettiğiniz bir PDF görüntüleyicisinde aranabilir PDF çıktı dosyalarının metin aramaya uygun olduğunu doğrulayın.
- Talep başına oluşturulan
IronTesseractörneklerinin, talep başınaPaddleOcrAllinşasına kıyasla bellek basıncı üretmediğini doğrulamak için uygulamayı yük altında çalıştırın. - Dil paketlerinin NuGet paketleri olarak yüklendiğini ve CI'de herhangi bir ek dosya yayım adımı olmaksızın doğru bir şekilde geri yüklendiğini doğrulayın.
- Beklenen satır/sütun yapısına karşı her tablo ayıklama senaryosunu test edin ve bölgeye dayalı veya koordinat gruplama yaklaşımı uygulayın.
- Başlangıç yolundan
PaddleOcrAllsingleton oluşturmayı ortadan kaldırdıktan sonra uygulama başlangıç süresinin azaldığını doğrulayın.
IronOCR'a Geçişin Ana Faydaları
Bir Paket, Dört Paketli Yığını Değiştirir. Geçişten sonra, OCR bağımlılık yükü tek bir IronOcr NuGet referansıdır. Dört paketli yığın - Sdcb.PaddleOCR, Sdcb.PaddleInference, OpenCvSharp4 ve platforma özgü bir çalışma zamanı - proje dosyasında bir giriş olur. Bağımlılık denetimleri, lisans taramaları ve güvenlik açığı izleme şimdi dört yerine bir yüzeyi kapsar.
Dağıtım Eserleri Tanıtımdan Ortamlara Kadar Tutarlıdır. Arka uç seçimi koşulları — CPU vs. GPU vs. OpenVINO — ortadan kalktı. Aynı yapı eseri geliştirici dizüstü bilgisayarına, CI runner'a, Linux konteynerine ve bulut VM'ye ortamdan bağımsız paket seçimi veya başlatım dalı olmadan dağıtılır. Docker görüntüleri küçülür çünkü COPY model dosyaları yoktur ve yüklemek için platform çalışma zamanı paketleri yoktur.
Belge Arşiv Hattı Artık İkinci Bir Kütüphane Gerektirmez. result.SaveAsSearchablePdf(), çoğu PaddleSharp takımının aranabilir arşivler üretmek için eklediği PDF kütüphane bağımlılığını ortadan kaldırır. OCR geçişi ve aranabilir PDF yazımı tek bir API çağrısıdır. Günde binlerce taranmış belge işleyen takımlar için, bu basitleştirme kütüphane versiyonu çakışmalarının tüm bir sınıfını ortadan kaldırır. aranabilir PDF'ler blog üretim ölçeğindeki dikkate almakla ilgili.
Hizmet Ömrü Kararları, Kütüphane Kısıtlamalarını Değil, Uygulama Gereksinimlerini Yansıtır. IronTesseract hafif bir yapıya sahiptir. PaddleSharp'un pahalı model yükleme nedeniyle yönlendirilen zorunlu tekil model artık gereksiz. Hizmetler, ASP.NET Core'da isteğe göre kapsamlı olabilir, eşzamanlı kullanıcılar arasında daha temiz bir izolasyon yaratır ve paylaşılan durum iş parçacığı endişelerini ortadan kaldırır. Dağıtım seçenekleri hakkında daha fazla bilgi için ASP.NET OCR kullanım durumu sayfasını izleyin.
Dil Genişletme Bir Araştırma Projesi Değildir, Bir Paket Kurulumudur. 125+ dil kataloğu, Avrupa, Asya, Orta Doğu ve özel scriptleri NuGet paketleri olarak kapsar. Çince olarak başlayan bir hat boyunca Fransızca, Almanca, Arapça veya Japonca eklemek dotnet add package IronOcr.Languages.French ve bir yapılandırma satırıdır. Model dosya kaynağı yoktur, yukarı akış kullanılabilirlik araştırması yoktur, manuel dosya konuşlandırması yoktur.
Ön İşleme OCR API'sinin Bir Parçasıdır. PaddleSharp ön işleme gerektiren OpenCV bilgisiyken - filtre çekirdeklerini anlama, Mat imhasını yönetme, uyarlanabilir eşik parametrelerini seçme - OCR çalışması için artık önkoşul değildir. OcrInput, mantıklı varsayılanlarla adlandırılmış işlemler sağlar. OpenCV uzmanı olmayan ancak OpenCV ön işleme kodunu koruyan takımlar bu kodu herhangi bir yerine geçmeden silebilir. ön işleme özellikleri sayfası her mevcut filtreyi ve her birini ne zaman uygulayacağınızı listeleyen belgeyi içerir.
Sıkça Sorulan Sorular
PaddleSharp OCR'dan IronOCR'ye neden geçmeliyim?
Yaygın geçiş nedenleri arasında COM ara bağlamının karmaşıklığını ortadan kaldırmak, dosya tabanlı lisans yönetimini değiştirmek, sayfa başına fatura düzenlemekten kaçınmak, Docker/kapsayıcı dağıtımını etkinleştirmek ve standart .NET araçlarıyla entegre olan bir NuGet doğal iş akışı benimsemek yer almaktadır.
PaddleSharp OCR'dan IronOCR'ye geçişteki ana kod değişiklikleri nelerdir?
PaddleSharp başlangıç dizilerini IronTesseract örneği ile değiştirin, COM yaşam döngüsü yönetimini (açık Create/Load/Close desenleri) kaldırın ve sonuç özellik adlarını güncelleyin. Sonuç, önemli ölçüde daha az boilerplate satırıdır.
Geçişi başlatmak için IronOCR'u nasıl kurarım?
Paket Yöneticisi Konsolunda 'Install-Package IronOcr' veya CLI'da 'dotnet add package IronOcr' çalıştırın. Dil paketleri ayrı paketlerdir: Örneğin, Fransızca için 'dotnet add package IronOcr.Languages.French'.
IronOCR, PaddleSharp OCR'nın standart iş belgeleri için OCR doğruluğunu karşılıyor mu?
IronOCR, faturalar, sözleşmeler, makbuzlar ve yazılı formlar dahil olmak üzere standart işletme içerikleri için yüksek doğruluğa ulaşır. Görüntü ön işleme filtreleri (dengelemeyi düzeltme, gürültü kaldırma, kontrast artırma) bozulmuş girdiler üzerindeki tanımayı daha da iyileştirir.
IronOCR, PaddleSharp OCR'nın ayrı kurduğu dil verilerini nasıl yönetiyor?
IronOCR'daki dil verileri, NuGet paketleri olarak dağıtılır. 'dotnet add package IronOcr.Languages.German' komutuyla Almanca desteği yüklenir. Herhangi bir manuel dosya yerleştirme veya dizin yolu gerekmez.
PaddleSharp OCR'dan IronOCR'ye geçiş, dağıtım altyapısında değişiklik gerektiriyor mu?
IronOCR, PaddleSharp OCR'dan daha az altyapı değişikliği gerektirir. SDK ikili yolları, lisans dosyası yerleşimleri veya lisans sunucu yapılandırmaları yoktur. NuGet paketi, tam OCR motorunu içerir ve lisans anahtarı uygulama kodunda belirlenmiş bir dizgedir.
Geçişten sonra IronOCR lisanslamasını nasıl yapılandırırım?
Uygulama başlangıç kodunda IronOcr.License.LicenseKey = "SİZİN-ANAHTARINIZ" atayın. Docker veya Kubernetes'te, anahtarı bir ortam değişkeni olarak saklayın ve başlangıçta okuyun. Trafiği kabul etmeden önce doğrulamak için License.IsValidLicense kullanın.
IronOCR, PDF'leri PaddleSharp gibi işleyebilir mi?
Evet. IronOCR hem yerel hem de taranmış PDF'leri okur. Bir PDF yolu veya OcrPdfInput olan girdiye ocr.Read(input) çağrısı yapmak için IronTesseract örneği çağırın ve OcrResult sayfalarını yineleyin. Ayrı bir PDF işleme hattı gerekmez.
IronOCR, yüksek hacim işleme sırasında iş parçacığı nasıl ele alır?
IronTesseract, iş parçacığı başına örnek olacak şekilde güvenlidir. Paralel.ForEach veya Görev havuzunda her iş parçacığı için bir örnek oluşturun, OCR'u eşzamanlı olarak çalıştırın ve her örneği iş tamamlandığında bırakın. Küresel durum veya kilitleme gerekmez.
IronOCR metin çıktıktan sonra hangi çıktıları destekler?
IronOCR, metin, kelime koordinatları, güven skorları ve sayfa yapısını içeren yapılandırılmış sonuçlar döndürür. Dışa aktarma seçenekleri düz metin, aranabilir PDF ve aşağı akış işlemesi için yapılandırılmış sonuç nesneleri içerir.
IronOCR'ın fiyatlandırması, ölçeklendirme iş yükleri için PaddleSharp OCR'dan daha öngörülebilir mi?
IronOCR, sayfa başına veya hacim ücretlendirmesi olmadan düz oranlı sürekli lisanslama kullanır. 10.000 veya 10 milyon sayfa işleseniz de lisans maliyeti sabit kalır. Hacim ve ekip lisanslama seçenekleri IronOCR fiyatlandırma sayfasındadır.
PaddleSharp OCR'dan IronOCR'ye geçtikten sonra mevcut testlerime ne olacak?
Çıkarılmış metin içeriğini doğrulayan testler, geçişten sonra çalışmaya devam etmelidir. API çağrı şablonlarını veya COM nesne yaşam döngüsünü doğrulayan testler, IronOCR'un daha basit başlatma ve sonuç modelini yansıtacak şekilde güncellenmelidir.

