如何在 C# 中讀取多 FramePage GIF 和 TIFF
本指南帶領.NET開發人員全面遷移從PaddleSharp OCR (Sdcb.PaddleOCR) 到 IronOCR。 它涵蓋替換推理會話管理,消除OpenCV預處理依賴,移除CPU、GPU和OpenVINO的後端選擇邏輯,以及遷移表格識別工作流程。 每個部分提供來自PaddleSharp特定模式的前後程式碼範例,這些模式不會出現在一般OCR比較中。
為什麼從PaddleSharp OCR遷移
PaddleSharp在應用層導出一個深度學習推理管道。 該架構讓您可以存取PaddlePaddle模型性能,但要求您的應用程式管理否則會是基礎設施的問題。 以下痛點驅使大多數.NET團隊尋找替代方案。
推理後端配置為應用程式程式碼。 在PaddleSharp中,選擇CPU、GPU和OpenVINO後端需要構建和配置PaddleConfig物件,選擇適合部署目標的本機運行時NuGet包,並根據運行時可用的硬體有條件地分支您的初始化程式碼。此邏輯存在於您的應用程式中,而不是在庫中,當目標環境變更時會中斷。
OpenCV是圖像輸入的必要依賴。 PaddleSharp不能直接接受文件路徑或流。 每個圖像在到達OCR引擎之前,必須通過OpenCV的OpenCvSharp4.runtime.*包進入您的依賴圖。 更新一個平台運行時而不更新另一個平台運行時會導致運行時失敗,而這些失敗在不同環境中很難重現。
推理會話生命週期需要顯式設計。 PaddleOcrAll在構建時從磁碟載入三個模型二進制文件。這種成本(以毫秒為單位計算)意味著該物件無法按需實例化。團隊必須設計一個生命週期策略: 單例、池化或範圍。 在ASP.NET Core中,這通常意味著註冊服務並仔細進行執行緒安全分析,因為PaddleOcrAll共享底層的本地狀態。
表格識別需要單獨的模型下載。 PaddleSharp中的結構化文件提取除了標準的三段檢測/分類/識別管道外,還需要專門的表格識別模型。該模型是下載、版本管理和配置的第四個文件。 沒有統一的API表面——表格識別使用具有自身結果型別的單獨程式碼路徑。
無可搜尋的PDF輸出。 PaddleSharp生成文字字串。 它無法生成可搜尋的PDF文件。 需要將掃描文件歸檔為文字可搜尋的PDF的團隊必須整合單獨的PDF庫,管理該附加依賴並編寫轉換層。 輸出格式差距是完全的:無hOCR,無結構化的可搜尋PDF,無文字層覆蓋。
上游依賴鏈不屬於.NET社群。 PaddleSharp封裝了百度的PaddlePaddle推理框架。 PaddleOCR版本之間的模型格式更改曾經破壞過.NET綁定層。大多數問題跟踪、文件和發佈討論都是用中文進行的。 對於沒有普通話使用者監控上游項目的.NET團隊,革命性變革會毫無預警地到來。
根本問題
在PaddleSharp中選擇和初始化後端需要應屬於基礎設施的配置程式碼,而不是OCR邏輯:
// 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
// IronOCR:不是backend selection.不是config 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與 PaddleSharp OCR: 功能對比
這裡是一個在遷移過程中最為重要的能力維度的直接比較:
| 功能 | PaddleSharp OCR | IronOCR |
|---|---|---|
| 需要 NuGet 套件 | 至少3–4 | 1 |
| 圖像輸入方法 | OpenCV Cv2.ImRead() | 直接路徑、流或字節陣列 |
| PDF輸入(本機) | 不是 | 是 |
| 受密碼保護的 PDF | 不是 | 是 |
| 多頁TIFF | 通過OpenCV | 本地 |
| 可搜尋的 PDF 輸出 | 不是 | 是 (result.SaveAsSearchablePdf()) |
| hOCR匯出 | 不是 | 是 |
| 後端選擇(CPU/GPU/OpenVINO) | 手動 PaddleConfig | 自動 |
| 預處理管道 | 手動OpenCV操作 | 內建 (Deskew, DeNoise, Contrast, 等) |
| 推理會話生命週期管理 | 手動(代價高的構建) | 輕量級 IronTesseract |
| 表格識別模型 | 獨立下載和程式碼路徑 | input.LoadImage() + 結構化結果 |
| 支持的語言 | ~10–20 | 125+ |
| 語言安裝 | 模型文件下載 | NuGet套件 |
| 同時多語言支持 | 有限 | 是 (OcrLanguage.French + OcrLanguage.German) |
| 基於區域的OCR | 無內建 | CropRectangle |
| OCR期間的條碼讀取 | 不是 | 是 (ocr.Configuration.ReadBarCodes = true) |
| 置信分數 | 每區域 | 每單詞,每行,每頁 |
| 結構化輸出層次 | 平坦的區域列表 | 頁 → 段落 → 行 → 單詞 → 字元 |
| 跨平台部署 | 複雜(平台運行時包) | 單一NuGet,所有平台 |
| Docker部署 | 多層,運行時包 | 單層 |
| 商業支持 | GitHub問題(主要是中文) | 電子郵件支援 |
| 授權模式 | Apache 2.0 | 永久 ($999 Lite, $1,499 Pro, $2,999 Enterprise) |
快速開始:PaddleSharp OCR到IronOCR遷移
步驟1:替換NuGet包
移除 PaddleSharp 及其 OpenCV 依賴項:
dotnet remove package Sdcb.PaddleOCR
dotnet remove package Sdcb.PaddleInference
dotnet remove package OpenCvSharp4
dotnet remove package OpenCvSharp4.runtime.win
從NuGet安裝IronOCR:
步驟2:更新命名空間
用單一的IronOCR命名空間替換 PaddleSharp 命名空間:
// Before (PaddleSharp)
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models;
using Sdcb.PaddleInference;
using OpenCvSharp;
// After (IronOCR)
using IronOcr;
步驟3:初始化許可證
在應用程式啟動時一次性新增許可初始化,可以在Program.cs, Startup.cs或您的組合根中進行:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"程式碼遷移範例
推理會話生命週期替代
PaddleSharp的PaddleOcrAll非常昂貴,因為在實例化時同步載入三個模型二進制文件。 生產應用必須將其視為長壽命物件,這驅動了一個具體的依賴注入模式。 釋放鏈也需要注意,因為必須按正確的順序釋放底層本地資源。
PaddleSharp OCR 方法:
// 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>();
IronOCR方法:
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>();
從強制單例轉變為靈活壽命是具有重要意義的。 PaddleSharp的構建成本鎖定了您的服務壽命決策; IronOCR讓您可以根據應用程式的執行緒處理和請求隔離需求進行選擇。 IronTesseract 設置指南 涵蓋了在實例級別應用的配置選項。
OpenCV 預處理管道遷移
PaddleSharp 團隊通常會在調用OCR引擎之前構建一個OpenCV預處理管道。該管道要求了解OpenCV的API表面,這遠遠大於任何OCR預處理任務實際需要的。 常見操作—矯正、去噪、對比度伸縮—需要多個using塊的小心記憶體管理,以防止本地記憶體洩漏。
PaddleSharp OCR 方法:
// 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
}
IronOCR方法:
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
}
無Mat分配。 無需了解自適應閾值參數。 無需自定義矯正旋轉數學。 同樣的預處理管道需要30–50行OpenCV程式碼,現在只需四次方法調用。 影像品質修正指南 記錄了每個可用的過濾器,並附有前後對比的例子。 對於背景噪音較重的文件,DeNoise(),無需其他參數。
對於預處理需求不標準的團隊,過濾器嚮導 提供了一個互動工具,用於在對特定文件型別進行測試之前評估各種過濾器組合。
後端選擇消除
PaddleSharp 將推理後端暴露為應用級關注點。 需要在僅CPU的雲VM上運行的部署使用的初始化程式碼與目標GPU工作站或Intel OpenVINO溢出的裝置不同。這種條件邏輯通常有最終應用程式啟動程式碼中的,而與從圖像中讀取文字無關的基礎設施工作無關。
PaddleSharp OCR 方法:
// 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);
}
IronOCR方法:
using IronOcr;
//不是backend selection.不是switch statement.不是environment 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;
}
Parallel.ForEach 模式本質上是執行緒安全的。 每個IronTesseract實例獨立,無共用本地狀態。 對於那些PaddleSharp部署花時間管理後端條件的團隊來說,這種簡化也改進了部署可靠性—相同的構建工件可以在不需要硬體檢測程式碼的情況下到處運行。 速度優化指南 涵蓋了針對吞吐量敏感場景的配置選項。
表格識別遷移
在PaddleSharp中,表格提取需要專用的表格識別模型—超出了標準檢測、分類和識別集的第四方面。 表格模型使用單獨的API調用並返回其自身的結果結構。 專門用於構建發票、表單或電子表格處理管道的團隊需要維護兩個平行的初始化路徑和兩個結果解析策略。
PaddleSharp OCR 方法:
// 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
}
}
IronOCR方法:
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}");
}
}
針對必需作為行和列提取的文件表結構,IronOCR提供專用的表提取功能:
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}");
}
}
}
消除了所需的一次模型下載。 消除了所需的一次初始化路徑。 IronOCR中的結構化結果層次結構具有單詞級X/Y坐標,提供了用於重建表行和列的位置資訊,而不需要單獨的識別模型。 表格讀取指南和讀取結果指南涵蓋了完整的結構化輸出API。
從掃描文件生成可搜尋的PDF輸出
PaddleSharp只生成文字串,沒有其他。 打造一個可以搜尋的PDF存檔需要整合單獨的PDF庫,編寫一個文字覆蓋層,並協同管理兩個庫。 接受該約束的團隊通常發現遷移是一個觸發因素-兩庫整合的努力超過了更換OCR提供者的努力。
PaddleSharp OCR 方法:
// 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");
}
IronOCR方法:
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);
}
無需PDF庫。 無需坐標映射。 無需文字層定。 IronOCR中的可搜尋PDF輸出格式將不可見的文字層嵌入到原始圖像上,生成的文件在視覺上忠於掃描文件且完全可搜尋。 可搜尋PDF的做法涵蓋了頁面選擇、質量選項和元資料控制。
PaddleSharp OCR API到IronOCR對應參考
| PaddleSharp OCR | IronOCR |
|---|---|
Sdcb.PaddleOCR(命名空間) | IronOcr(命名空間) |
Sdcb.PaddleInference(命名空間) | 不需要—自動配置 |
PaddleOcrAll | IronTesseract |
new PaddleOcrAll(det, cls, rec) | new IronTesseract() |
LocalFullModels.ChineseV3.DetectionModel | 沒有等價物—沒有模型選擇 |
LocalFullModels.ChineseV3.ClassifierModel | 沒有等價物—沒有模型選擇 |
LocalFullModels.ChineseV3.RecognitionModel | 沒有等價物—沒有模型選擇 |
PaddleConfig.FromModelDir() | 沒有等價物—沒有配置物件 |
config.EnableGpu(memMB, deviceId) | 沒有等價物—後端是自動的 |
config.EnableMkldnn() | 沒有等價物—後端是自動的 |
config.SetCpuMathLibraryNumThreads(n) | 沒有等價物—內部管理 |
Cv2.ImRead(path)(OpenCV載入) | input.LoadImage(path) |
ocr.Run(mat) | ocr.Read(input) 或 ocr.Read("file.jpg") |
result.Regions | result.Pages[0].Words 或 result.Pages[0].Lines |
region.Text | word.Text, line.Text, paragraph.Text |
region.Rect.Center.X/.Y | word.X, word.Y |
region.Score(信心) | word.Confidence, result.Confidence |
| 模型級語言切換 | ocr.Language = OcrLanguage.French |
| 表格模型(單獨下載) | 內建結構化結果層次結構 |
Cv2.CvtColor(..., GRAY) | input.Binarize() 或 input.Contrast() |
Cv2.GaussianBlur(...) | input.DeNoise() |
| 無可搜尋PDF輸出 | result.SaveAsSearchablePdf("output.pdf") |
常見的遷移問題与解決方案
問題1: OpenCV依賴無法解除安裝
PaddleSharp OCR:OpenCvSharp4.runtime.win和類似的特定平台運行時包安裝未托管的本地DLL。 這些DLL會阻止正確的清理阻止某些託管場景,例如IIS應用程式池回收並且在構建時引用錯誤的平台運行時包導致組件載入失敗。移除它們需要移除NuGet包和清除輸出目錄中的任何已快取本地二進制文件。
**解決方案:**在解除安裝OpenCvSharp4.runtime.*包後,清理構建輸出目錄並重新構建:
dotnet remove package OpenCvSharp4
dotnet remove package OpenCvSharp4.runtime.win
dotnet clean
dotnet build
IronOCR在內部打包了其本地依賴項,並處理未托管的生命週期。 不需要進行平台特定的運行時包選擇。 IronTesseract設置指南記錄了IronOCR自動處理的平台要求。
問題2: 遷移後磁碟上遺留的模型文件
**PaddleSharp OCR:**Padsharp下載的模型文件(檢測、分類、識別和任何表模型)通常儲存在靠近應用程式的models/目錄中或在配置路徑中。 當解除安裝NuGet包時,這些文件不會被刪除。 在Docker映像中,它們增加了不必要的層大小。在部署管道中,老路徑中的陳舊模型文件可能會導致啟動失敗。
**解決方案:**遷移時明確刪除模型目錄。 審核啟動配置以檢查任何路徑引用:
# Locate model directory references in application code
grep -r "LocalFullModels\|ModelPath\|models/" --include="*.cs" .
grep -r "DetectionModel\|RecognitionModel\|ClassifierModel" --include="*.cs" .
在移除模型參考並初始化IronOCR後,從倉庫和Docker構建上下文中刪除模型目錄。
問題3: 單例生命週期假設遷移後中斷
**PaddleSharp OCR:**註冊為單例因其構建成本使得按需實例化不切實際。 將IronOCR抬升到單例註冊中引入了不必要的跨請求狀態分享。 雖然IronTesseract在並發使用時是執行緒安全的,但不必共享單個實例—每個實例都是獨立的。
**解決方案:**評估實例的設計是否超過性能: 對於大多數ASP.NET Core應用,使用IronOCR選擇轉瞬即逝的註冊是更為整潔的選擇:
// 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>();
對於想要顯式實例重用的高吞吐量批量場景,單例或池化模式仍然可行—但這是一項性能選擇,而不是正確性要求。
問題4: 不再需要結果區域排序
PaddleSharp OCR:result.Regions按檢測順序返回檢測到的文字區域,這不一定與閱讀順序(從左到右,從上到下)相匹配。 團隊通常在連接區域文字之前按.Rect.Center.X進行排序—幾乎每個PaddleSharp文字提取實現中都出現的模式。 將此模式直接遷移到IronOCR會產生冗餘程式碼。
**解決方案:**IronOCR預設按閱讀順序返回結果。 刪除排序:
// 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})");
}
問題5: 後端配置包中斷恢復
**PaddleSharp OCR:**某些PaddleSharp設置根據目標環境(如GPU的CUDA、OpenVINO的MKL、僅限CPU)有條件地引用不同的Sdcb.PaddleInference.runtime.*包。 這有時顯現為.csproj條件或按部署目標分開的項目文件。 錯誤的包集回复會中斷CI管道。
**解決方案:**在移除PaddleSharp包後,審計PackageReference條件:
grep -n "Sdcb\|OpenCvSharp\|PaddleInference" *.csproj
IronOCR使用單個IronOcr包引用,無平台條件。 同一個包在Windows、Linux和macOS上都能正確恢復。
問題6: 表結果結構無直接等效
PaddleSharp OCR:PaddleOcrTable 返回基於單元格的結構,每個被識別的單元格有行和列索引。 消費此結構的程式碼通常構建 (row, column) 為索引的二維陣列。 IronOCR没有提供一個相同的單元格索引結構—它提供單詞和線條坐標,這需要進行空間分組以重構單元格網格。
**解決方案:**從IronOCR單詞坐標中使用Y位置分組構建表格,並排序X位置以形成列。 對於常見的表格格式,表閱讀方法提供了一種空間分組的方法。 對於具有已知字段位置的結構化發票,基於區域的OCR與CropRectangle直接模型相比是更乾淨的一種模式。
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}");
PaddleSharp OCR遷移清單
遷移前
掃瞄程式碼庫中用的所有 PaddleSharp 參考文獻,然後再移除包:
# 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" .
清點磁片中的模型文件並記下其路徑。 清點所有部署目標及是否有GPU或OpenVINO特定的NuGet扣押在.csproj中。 註記由於PaddleSharp構建成本而註冊為單例的任何服務。
程式碼遷移
- 從每個項目文件中移除所有
OpenCvSharp4.runtime.*NuGet包。 - 安裝
IronOcrNuGet包。 - 為所需語言安裝語言NuGet包(例如,
IronOcr.Languages.ChineseSimplified)。 - 將
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";新增到應用啟動。 - 將所有
using IronOcr。 - 用
PaddleOcrAll實例化和模型載入。 - 刪除所有
PaddleConfig後端選擇區塊(CPU、GPU、OpenVINO條件)。 - 使用
input.LoadImage(path)。 - 利用
Threshold等)。 - 以
ocr.Run(mat)呼叫。 - 用
result.Regions枚舉。 - 刪除
.OrderBy(r => r.Rect.Center.Y).ThenBy(r => r.Rect.Center.X)排序鏈-閱讀順序是自動的。 - 用
PaddleOcrTable初始化和結果解析。 - 在任何需要可搜尋PDF存檔的地方新增
result.SaveAsSearchablePdf(path)。 - 重新評估服務生命週期註冊:因PaddleSharp構建成本驅動的單例註冊通常可以成為過渡或範圍。
- 從磁片刪除模型文件,並從Docker構建上下文中移除模型目錄。
- 移除任何類似於
.csproj的平台特定 Paddle 或 OpenCV 運行時包的條件PackageReference區塊。
遷移後
- 驗證文字提取輸出是否匹配或超過代表性樣本的PaddleSharp輸出,從每個文件管道型別中取樣20–30個文件。
- 確認未發現與
OpenCvSharp相關的組件載入異常於應用啟動日誌中。 - 使用相同的構建工件測試每個目標平台上的部署(Windows、Linux、Docker)— 不應需要平台特定的包選擇。
- 驗證先前需要手動結果排序的文件使用
result.Text生產正確排序的文字。 - 確認可搜尋PDF輸出文件在Adobe Acrobat Reader或您選擇的PDF查看器中是文字可搜尋的。
- 在負載下運行應用,確認
PaddleOcrAll構建相當的記憶壓力。 - 驗證作為NuGet包安裝的語言包在CI中正確恢復,無需額外的文件部署步驟。
- 使用區域基於或坐標分組方法測試任何表格提取場景是否符合預期的行/列結構。
- 確認在消除
PaddleOcrAll單例構建後應用啟動時間有所減少。
遷移至IronOCR的主要好處
一個包取代四個包棧。 遷移後,OCR依賴包只需單一IronOcr NuGet引用。 四個包棧—OpenCvSharp4和一個平台專用運行時—成為項目文件中的一個條目。現在,同一個面板覆蓋依賴性審核、許可證掃描和漏洞檢測工作,而不是四重。
部署工件在不同環境中是統一的。 後端選擇條件—CPU對比GPU對比OpenVINO—已消失。 相同的構建工件部署到開發者筆記型電腦、CI執行器、Linux容器和雲VM,無需進行環境專享的包選擇或初始化分支。 因為沒有要COPY的模型文件,也沒有需要安裝的運行時平台包,所以Docker映像縮小了。
文件存檔管道不再需要第二個庫。 result.SaveAsSearchablePdf()消除了大多數PaddleSharp團隊使用的PDF庫依賴,以生成可以搜尋的存檔。 OCR遍及和可搜尋PDF寫入是單次API調用。 對於每天處理數千個掃描文件的團隊來說,這種簡化消除了一整類的庫間版本衝突。 可搜尋PDF部落格文章涵蓋了生產規模的考慮因素。
服務生命週期決策反映了應用程式需求,而不是庫限制。 IronTesseract建設輕量。 PaddleSharp昂貴的模型載入驅動的單一模式不再必要。 服務可以在ASP.NET Core中按每次請求來設置範圍,創造更乾淨的並發使用者隔離,消除共享狀態的執行緒關注。 有關更多部署選項,請參閱ASP.NET OCR使用案例頁面。
語言擴展是一個包安裝,而不是研究項目。 125+語言目錄 涵蓋歐洲、亞洲、中東和特殊字元集,作為NuGet包提供。 在最初僅支持中文的管道中新增法語、德語、阿拉伯語或日語是dotnet add package IronOcr.Languages.French和一行配置。無需模型文件攝取、上游研究、手動文件部署。
預處理是OCR API的一部分。 PaddleSharp預處理所需的OpenCV知識—理解過濾器內核、管理Mat釋放、選擇自適性閾值參數—不再是OCR工作的前提。 OcrInput提供具有合理預設值的命名操作。 不是OpenCV專家但不斷維持OpenCV預處理程式碼的團隊可以刪除這些程式碼而不替換它。 預處理功能頁面列出了每個可用過濾器,並附有何時應用每個過濾器的文件。
