Migrating from Google Cloud Vision OCR to IronOCR
.NET開発者がPaddleSharp OCR (Sdcb.PaddleOCR)からIronOCRへの完全な移行を進めるためのガイドです。 これには、推論セッション管理の置き換え、OpenCVの前処理への依存関係の排除、CPU、GPU、およびOpenVINO向けのバックエンド選択ロジックの削除、ならびにテーブル認識ワークフローの移行が含まれます。 各セクションでは、一般的なOCR比較には見られない、PaddleSharp特有のパターンから抽出した"翻訳前"と"翻訳後"のコードを掲載しています。
PaddleSharp OCRからの移行理由
PaddleSharpは、アプリケーション層でディープラーニングの推論パイプラインを提供します。 このアーキテクチャにより、PaddlePaddleモデルのパフォーマンスを活用できますが、通常はインフラストラクチャの課題となる部分をアプリケーション側で管理する必要があります。 以下の課題が、多くの .NET チームに代替手段を探すきっかけとなっています。
推論バックエンドの設定はアプリケーションコードです。 PaddleSharpでのCPU、GPU、OpenVINOバックエンドの選択には、PaddleConfigオブジェクトの構築と設定、デプロイメント対象の適切なネイティブランタイムNuGetパッケージの選択、および実行時に利用可能なハードウェアに基づいて初期化コードを条件分岐させることが必要です。このロジックはライブラリではなくアプリケーションに存在し、ターゲット環境が変わるとブレークします。
**画像入力には OpenCV が必須の依存関係となります。**PaddleSharp はファイルパスやストリームを直接受け入れることはできません。 すべての画像はOCRエンジンに到達する前にOpenCVのOpenCvSharp4.runtime.*パッケージが含まれます。 一方のプラットフォームのランタイムのみを更新すると、環境間で再現が困難なランタイムエラーが発生します。
推論セッションのライフタイムは明示的な設計が必要です。 PaddleOcrAllは構築時にディスクから3つのモデルバイナリをロードします。このコストは数百ミリ秒単位で測定可能で、オブジェクトがリクエストごとにインスタンス化できないことを意味します。チームはライフサイクル戦略(シングルトン、プール、またはスコープ)を設計する必要があります。 ASP.NET Coreでは、通常PaddleOcrAllが基盤となるネイティブ状態を共有するため、スレッドセーフティの慎重な分析を伴う登録済みサービスを意味します。
**表の認識には別途モデルのダウンロードが必要です。**PaddleSharpでの構造化ドキュメントの抽出には、標準的な3段階の検出/分類/認識パイプラインに加え、専用の表認識モデルが必要です。そのモデルは、ダウンロード、バージョン管理、設定を行う必要がある4つ目のファイルとなります。 統一されたAPIインターフェースは存在しません。テーブル認識は、独自の結果型を持つ別のコードパスを使用します。
**検索可能なPDF出力は行われません。**PaddleSharpはテキスト文字列を生成します。 検索可能なPDFファイルを作成することはできません。 スキャンした文書をテキスト検索可能なPDFとしてアーカイブする必要があるチームは、別途PDFライブラリを統合し、その追加の依存関係を管理し、変換レイヤーを実装する必要があります。 出力形式のギャップは完全に解消されています:hOCRなし、構造化された検索可能なPDFなし、テキストレイヤーのオーバーレイなし。
**上流の依存関係チェーンは、.NETコミュニティが所有するものではありません。**PaddleSharpは、Baiduの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) |
| 信頼度スコア | 地域別 | 単語単位、行単位、ページ単位 |
| 構造化された出力階層 | フラットな地域リスト | ページ → 段落 → 行 → WORD → 文字 |
| クロスプラットフォーム展開 | 複雑(プラットフォームランタイムパッケージ) | 単一のNuGetパッケージ、全プラットフォーム対応 |
| Dockerデプロイメント | 複数のレイヤー、ランタイムパッケージ | 単層 |
| 商用サポート | GitHubのイシュー(主に中国語) | メールサポート |
| ライセンスモデル | アパッチ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: 名前空間の更新
PaddleSharp ネームスペースを単一の IronOCR ネームスペースに置き換えてください:
// Before (PaddleSharp)
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models;
using Sdcb.PaddleInference;
using OpenCvSharp;
// After (IronOCR)
using IronOcr;
ステップ 3: ライセンスの初期化
アプリケーションの起動時に一度、Startup.cs、またはコンポジションルートでライセンスの初期化を追加してください。
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"コード移行の例
推論セッションのライフサイクル置換
PaddleSharpのPaddleOcrAllは、インスタンス化時に3つのモデルバイナリを同期的にロードするため、構築が高価です。 本番環境のアプリケーションでは、これを長寿命オブジェクトとして扱う必要があり、これが特定の依存性注入パターンを導きます。 また、基盤となるネイティブリソースを正しい順序で解放する必要があるため、破棄処理の順序にも注意が必要です。
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の割り当てなし。 適応しきい値パラメータに関する知識は不要です。 独自の傾き補正計算は行わないでください。 OpenCVのコードで30~50行必要だった前処理パイプラインが、4つのメソッド呼び出しで済むようになります。 画像品質補正ガイドでは、利用可能なすべてのフィルターについて、適用前後の例を交えて解説しています。 重い背景ノイズがある文書に対して、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でのテーブル抽出には、専用のテーブル認識モデルが必要です。これは、標準的な検出、分類、認識のセットに加えて、4つ目のモデルファイルとなります。 このテーブルモデルは個別のAPI呼び出しを使用し、独自の結果構造を返します。 請求書、フォーム、またはスプレッドシートの処理パイプラインを構築するチームは、2つの並列初期化パスと2つの結果解析戦略を維持します。
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}");
}
}
}
モデル1つのダウンロードが削除されました。 初期化パスが1つ削除されました。 IronOCRの構造化された結果階層(単語レベルのX/Y座標を含む)は、個別の認識モデルを使用せずに表の行と列を再構築するために必要な位置情報を提供します。 "テーブル読み取りガイド"および"読み取り結果ガイド"では、構造化出力APIの全範囲を網羅しています。
スキャンした文書からの検索可能なPDF出力
PaddleSharpはテキスト文字列のみを生成し、それ以外は何も生成しません。 スキャンしたPDFをテキスト検索可能にするドキュメントアーカイブを構築するには、別のPDFライブラリを統合し、テキストオーバーレイ層を実装し、2つのライブラリを連携させて管理する必要があります。 この制約を受け入れたチームは、それが移行のきっかけになることが多いと気づきます。つまり、2つのライブラリを統合する労力が、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 OCRAPI から IronOCR へのマッピングリファレンス
| PaddleSharp OCR | IronOCR |
|---|---|
Sdcb.PaddleOCR (namespace) | IronOcr (namespace) |
Sdcb.PaddleInference (namespace) | 不要 — 自動設定済み |
PaddleOcrAll | IronTesseract |
new PaddleOcrAll(det, cls, rec) | new IronTesseract() |
LocalFullModels.ChineseV3.DetectionModel | 同等のものがない — モデル選択なし |
LocalFullModels.ChineseV3.ClassifierModel | 同等のものがない — モデル選択なし |
LocalFullModels.ChineseV3.RecognitionModel | 同等のものがない — モデル選択なし |
PaddleConfig.FromModelDir() | 対応する項目なし — config オブジェクトなし |
config.EnableGpu(memMB, deviceId) | 対応する項目なし — バックエンドは自動処理されます |
config.EnableMkldnn() | 対応する項目なし — バックエンドは自動処理されます |
config.SetCpuMathLibraryNumThreads(n) | 対応する項目なし — 内部管理 |
Cv2.ImRead(path) (OpenCV load) | 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 (confidence) | 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: PaddleSharpによってダウンロードされたモデルファイル(検出、分類、認識、その他のテーブルモデル)は通常、アプリケーションに対して相対的な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: PaddleOcrAllは構築コストがリクエストごとのインスタンス化を不可能にしたため、シングルトンとして登録されました。 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セットアップは、ターゲット環境に基づいて異なるSdcb.PaddleInference.runtime.*パッケージを条件付きで参照します(GPU用のCUDA、OpenVINO用のMKL、CPU専用)。 これは.csproj条件として表示されることもあれば、デプロイメントターゲットごとに異なるプロジェクトファイルとして表示されることもあります。 結果として生成されたビルドマトリックスは、誤ったパッケージセットが復元された場合にCIパイプラインを中断させます。
ソリューション: PaddleSharpパッケージを削除した後、任意のPackageReferenceブロックを監査し、それらを完全に削除してください。
grep -n "Sdcb\|OpenCvSharp\|PaddleInference" *.csproj
IronOCRはプラットフォーム条件なしで単一のIronOcrパッケージ参照を使用します。 このパッケージは、Windows、Linux、macOSのいずれでも正しく復元されます。
課題 6: 表の結果構造に直接対応する表現がない
PaddleSharp OCR: PaddleOcrTableは、認識されたセルごとに行と列のインデックスを持つセルベースの構造を返します。 この構造を使用するコードは通常、(row, column)をインデックスとする2次元配列を構築します。 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" .
ディスク上のモデルファイルを一覧表示し、そのパスを記録してください。 すべてのデプロイメントターゲットと、.csprojにGPUまたはOpenVINO固有のNuGet条件があるかどうかを確認してください。 PaddleSharpの構築コストによりシングルトンとして登録されているサービスがある場合は、その点に留意してください。
コードの移行
- すべてのプロジェクトファイルからすべての
OpenCvSharp4.runtime.*NuGetパッケージを削除してください。 IronOcrNuGetパッケージをインストールします。- 必要な言語の言語NuGetパッケージをインストールします(例:
IronOcr.Languages.ChineseSimplified)。 - アプリケーションの起動時に
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";を追加してください。 - すべての
using IronOcrで置き換えてください。 new IronTesseract()で置き換えてください。- すべての
PaddleConfigバックエンド選択ブロック(CPU、GPU、OpenVINO条件)を削除してください。 input.LoadImage(path)に置き換えてください。- OpenCVの前処理操作(
Binarize())で置き換えてください。 ocr.Read(input)で置き換えてください。result.Pages[n].Wordsで置き換えてください。.OrderBy(r => r.Rect.Center.Y).ThenBy(r => r.Rect.Center.X)ソートチェーンを削除してください — 読み取り順は自動です。OcrInput領域ベースのターゲティングまたは座標ベースの単語グルーピングで置き換えてください。- 検索可能なPDFアーカイブが必要な場所に
result.SaveAsSearchablePdf(path)を追加してください。 - サービスのライフタイム登録を見直す:PaddleSharpのコンストラクタコストによって駆動されるシングルトン登録は、通常、一時的またはスコープ限定のものに変更可能です。
- ディスクからモデルファイルを削除し、Dockerビルドコンテキストからモデルディレクトリを削除します。
- プラットフォーム固有のPaddleまたはOpenCVランタイムパッケージ用の
PackageReferenceブロックを削除してください。
移行後
- パイプライン内の各ドキュメントタイプから抽出した代表的なサンプル(20~30件)について、テキスト抽出の出力が PaddleSharp の出力と同等か、それ以上であることを確認してください。
- アプリケーションの起動ログに
OpenCvSharp関連のアセンブリロード例外がないことを確認してください。 - 同一のビルド成果物を使用して、各ターゲットプラットフォーム(Windows、Linux、Docker)でのデプロイをテストしてください。プラットフォーム固有のパッケージ選択は不要である必要があります。
- 以前に手動の結果ソートが必要だった文書が
result.Textを介して正しく順序付けされたテキストを生成することを確認してください。 - 検索可能なPDF出力ファイルが、Adobe Acrobat Readerまたは任意のPDFビューアでテキスト検索可能であることを確認してください。
- アプリケーションを負荷状態で実行して、リクエストごとに作成された
PaddleOcrAll構築に匹敵するメモリ圧力を生じないことを確認してください。 - NuGet パッケージとしてインストールされた言語パックが、追加のファイル展開手順なしに CI 環境で正しく復元されることを確認してください。
- 領域ベースまたは座標グループ化のアプローチを用いて、期待される行/列構造に対してあらゆるテーブル抽出シナリオをテストしてください。
- 起動パスから
PaddleOcrAllシングルトン構築を削除した後、アプリケーションの起動時間が短縮されることを確認してください。
IronOCRへの移行の主なメリット
1つのパッケージが4つのパッケージスタックを置き換えます。 移行後、OCR依存関係フットプリントは単一のIronOcr NuGetリファレンスになります。 4つのパッケージスタック — OpenCvSharp4、およびプラットフォーム固有のランタイム — はプロジェクトファイルで1つのエントリになります。依存関係の監査、ライセンススキャン、および脆弱性の監視は、4つの表面ではなく1つの表面に集中します。
**デプロイメントアーティファクトは環境を問わず統一されています。**バックエンドの選択条件(CPU、GPU、OpenVINOの比較)はなくなりました。 単一のビルド成果物により、環境固有のパッケージ選択や初期化の分岐を行うことなく、開発者のノートPC、CIランナー、Linuxコンテナ、およびクラウドVMへのデプロイが可能です。 モデルファイルをCOPYする必要がなく、プラットフォームランタイムパッケージをインストールする必要がないため、Dockerイメージが縮小されます。
文書アーカイブパイプラインではもはや2番目のライブラリは必要ありません。 result.SaveAsSearchablePdf()は、以前PaddleSharpのチームが検索可能なアーカイブを生成するために追加していたPDFライブラリの依存関係を排除します。 OCR処理と検索可能なPDFへの書き込みは、1回のAPI呼び出しで実行されます。 1日に数千件のスキャン文書を処理するチームにとって、この簡素化により、ライブラリ間のバージョン競合という問題が一掃されます。 検索可能なPDFに関するブログ記事では、本番環境での運用に関する考慮事項について解説しています。
サービスライフタイムの決定がアプリケーションの要件を反映し、ライブラリの制約ではありません。 IronTesseractは軽量な構築です。 PaddleSharpの高コストなモデル読み込みによって引き起こされていた強制シングルトンパターンは、もはや必要ありません。 .NET Core では、リクエストごとにサービスのスコープを定義できるため、同時接続ユーザー間の分離が明確になり、共有状態によるスレッド関連の懸念が解消されます。 デプロイメントのオプションの詳細については、ASP.NET OCR のユースケースページをご覧ください。
言語の拡張は、研究プロジェクトではなく、パッケージのインストールです。125以上の言語カタログは、ヨーロッパ、アジア、中東の言語や特殊な文字体系をNuGetパッケージとして網羅しています。 中国語のみで始まったパイプラインにフランス語、ドイツ語、アラビア語、日本語を追加することはdotnet add package IronOcr.Languages.Frenchであり、設定項目は1行です。モデルファイルの調達は不要で、上流での利用可能性の調査も不要で、手動のファイルデプロイも必要ありません。
前処理はOCR APIの一部です。 PaddleSharpによる前処理が要求していたOpenCVの知識 — フィルタカーネルの理解、Matの廃棄管理、適応的しきい値パラメータの選択 — はOCR作業の前提条件ではなくなりました。 OcrInputは、適切なデフォルト値を持つ命名された操作を提供します。 OpenCVの専門家ではないものの、OpenCVの前処理コードを保守していたチームは、そのコードを置き換えることなく削除することができます。 前処理機能のページには、利用可能なすべてのフィルターと、それぞれを適用すべきタイミングに関するドキュメントが記載されています。
