Migrating from GdPicture.NET to IronOCR
このガイドは、.NET開発者にSdcb.PaddleOCRパッケージファミリーからIronOCRへの完全な移行を案内します。 これは、完全な置き換えパスを網羅しています。つまり、複数のパッケージからなるPaddlePaddleスタックの削除、モデルファイル管理とGPU構成の排除、そしてOpenCVに依存する推論パイプラインを単一のNuGetインストールに置き換えることです。 各セクションは独立しており、比較記事を事前に読む必要はありません。
PaddleOCRから移行する理由
Sdcb.PaddleOCRラッパーは、PaddlePaddle for Pythonディープラーニングエコシステムと.NETの間のコミュニティによって維持される橋渡しです。 それは目的を果たすものの、モデルファイル、ネイティブ推論バイナリ、画像読み込み用のOpenCV、そしてオプションのCUDAインフラストラクチャなど、その橋梁全体の重量を背負うことになる。 ほとんど for .NET OCRワークロードにとって、それはプロジェクトでは決して必要とされなかったインフラストラクチャです。
1文字を読み取る前に3つのモデルディレクトリを経由します。PaddleOCRの推論パイプラインは、検出モデル、方向分類モデル、認識モデルという3つのニューラルネットワークを連結しています。 各ネットワークは、models/ディレクトリツリーを通じて提供されるかにかかわらず、開発者はモデルのバージョン管理を常に担います。 Sdcb.PaddleOCRが更新されると、以前のバージョンから先にダウンロードされたモデルを再ダウンロードする必要があるかもしれません。 IronOCRにはモデルファイルもモデルディレクトリもなく、バージョン同期の問題もありません。 エンジンはNuGetパッケージに同梱されています。
OpenCVはオプションではありません。 OpenCvSharpを迂回してPaddleOCR推論へファイルパスから移行する経路はありません。すべての画像は形式にかかわらずocr.Run(mat)が受け入れることができます。 これは、2つの追加のNuGetパッケージ(System.Drawing.Bitmapを直接受け入れます。 Mat仲介は存在しません。
GPU構成は数日かかる作業です。PaddleOCRが宣伝しているGPUパフォーマンスの数値(画像1枚あたり50~100msに対し、CPUでは300~500ms)は本当です。 そこを実現するには、特定のバージョンのNVIDIAドライバー、CUDA Toolkit 11.8(12.xではない)、正しいPATHの場所に配置されたcuDNN 8.6以降、および別のGPUランタイムNuGetパッケージが必要です。 Dockerでは、ベースイメージはnvidia-container-toolkitがインストールされている必要があります。 既存のGPUインフラストラクチャを持たないチームは、環境ごとにCUDA構成に2~8時間を費やしている。 IronOCRはCPU推論向けに設計されており、標準的なハードウェアで画像1枚あたり150~300ミリ秒の処理速度を実現し、GPUの設定は一切不要です。
デプロイメントアーティファクトは4-6倍の大きさです。 PaddleOCRのデプロイメント出力にはopencv_world*.dllファイル(合計約50MB)、およびモデルディレクトリ(約21MB)が含まれます。 Dockerイメージのサイズは約1.5GBです。 IronOCRのデプロイメントに必要な総容量は約80MBです。 Dockerイメージのサイズは約400MBです。 CI/CDでは、その違いがNuGet顕著になります。NuGetパッケージを復元するパイプラインの実行ごとに、Baiduからモデルをダウンロードするか、別途管理されているキャッシュレイヤーからモデルを取得する必要があります。
検索可能なPDF出力はありません。PaddleOCRは画像からテキスト領域を返しますが、認識したテキストを検索可能なレイヤーとしてPDFに埋め込む機能はありません。 PaddleOCRの出力から検索可能なPDFを作成するには、サードパーティ製のPDFライブラリ、ページごとのテキストレイヤーの挿入、および座標の再マッピングが必要です。 IronOCRは1行のコードで完全に検索可能なPDFを生成します:result.SaveAsSearchablePdf("output.pdf")。
基本的な問題
PaddleOCRでは、推論を開始する前に3つのモデルディレクトリを設定する必要があります。
// PaddleOCR: three model directories, all must exist and match the wrapper version
FullOcrModel models = new FullOcrModel(
LocalDetectionModel.FromDirectory("models/ch_PP-OCRv4_det_infer"), // ~5MB
LocalClassificationModel.FromDirectory("models/ch_ppocr_mobile_v2.0_cls_infer"), // ~2MB
LocalRecognitionModel.FromDirectory("models/ch_PP-OCRv4_rec_infer") // ~15MB
);
using PaddleOcrAll ocr = new PaddleOcrAll(models);
using Mat mat = Cv2.ImRead("document.png"); // OpenCvSharp required for every image
PaddleOcrResult result = ocr.Run(mat);
IronOCRにはモデルファイルもモデルディレクトリもOpenCVへの依存関係もありません。
// IronOCR: one package, zero model management
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("document.png");
var result = ocr.Read(input);
Console.WriteLine(result.Text);
IronOCRとPaddleOCR(.NET)の機能比較
以下の表は、移行計画において最も重要な要素を網羅しています。
| フィーチャー | パドルOCR(Sdcb) | IronOCR |
|---|---|---|
| 必要なNuGetパッケージ | 4-5 | 1 |
| モデルファイルが必要です | はい(3つのディレクトリ、約21MB) | いいえ(パッケージに同梱されています) |
| モデルのダウンロード元 | Baiduサーバー(bj.bcebos.com) | NuGet復元 (Iron Software) |
| OpenCVの依存関係 | 必須(OpenCvSharp4) | None |
| 画像入力 | 経由Mat mat = Cv2.ImRead() | ファイルパス、ストリーム、バイト配列を直接指定 |
| ネイティブPDF入力 | なし | はい(input.LoadPdf()) |
| 検索可能なPDF出力 | なし | はい(result.SaveAsSearchablePdf()) |
| マルチフレームTIFF入力 | フレームごとの手動ループ | input.LoadImageFrames() |
| GPUサポート | はい(CUDA 11.8 + cuDNNが必要) | CPU最適化済み(GPU不要) |
| 組み込みの前処理 | いいえ(ニューラルネットワークは歪みやノイズを処理します) | はい(傾き補正、ノイズ除去、コントラスト調整、二値化、シャープ化) |
| 対応言語 | 14 | 125+ |
| 言語のインストール方法 | 言語モデルごとにDownloadAsync() | dotnet add package IronOcr.Languages.* |
| 多言語同時通訳 | いいえ(言語ごとに異なるモデル) | はい(OcrLanguage.English + OcrLanguage.French) |
| 構造化された出力 | result.Regions(空間的、ソートされていない) | ページ、段落、行、単語、文字 |
| 信頼度スコア | 地域ごとの浮動小数点数(0~1) | 単語あたりの割合(0~100%) |
| バーコード読み取り | なし | はい(ocr.Configuration.ReadBarCodes = true) |
| hOCRエクスポート | なし | はい |
| 展開サイズ | 300~500MB | ~80MB |
| Dockerイメージのサイズ | 約1.5GB(CUDAベースを含む) | 約400MB |
| コールドスタート時間 | 3~5秒(モデル負荷時) | 1秒未満 |
| クロスプラットフォーム | Windows、Linux(一部対応) | Windows、Linux、macOS、Docker、Azure、AWS |
| .NET互換性 | .NET 6以降(コミュニティラッパー) | .NET Framework 4.6.2以降、 .NET 5/6/7/8/9 |
| 商用サポート | コミュニティ / GitHub の問題 | はい(Iron Software、SLA付き) |
| ライセンス | アパッチ2.0(無料) | 永続ライセンス($999 Lite / $1,499 Pro / $2,999 Enterprise) |
クイックスタート:PaddleOCR(.NET)からIronOCRへの移行
ステップ 1: NuGet パッケージを置き換える
PaddleOCR関連のパッケージを5つすべて削除してください。
dotnet remove package Sdcb.PaddleOCR
dotnet remove package Sdcb.PaddleOCR.Models.Online
dotnet remove package Sdcb.PaddleInference.runtime.win64.mkl
dotnet remove package OpenCvSharp4
dotnet remove package OpenCvSharp4.runtime.win
GPUランタイムがインストールされている場合は、それも削除してください。
dotnet remove package Sdcb.PaddleInference.runtime.win64.cuda118
NuGetパッケージページからIronOCRをインストールしてください。
ステップ 2: 名前空間の更新
PaddleOCRおよびOpenCvSharp名前空間のインポートをすべて置き換えます。
// Before (PaddleOCR)
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models;
using Sdcb.PaddleOCR.Models.Online;
using Sdcb.PaddleInference;
using OpenCvSharp;
// After (IronOCR)
using IronOcr;
ステップ 3: ライセンスの初期化
アプリケーションの起動時に一度、ライセンスの初期化を行ってください。IronTesseractインスタンスが作成される前に行う必要があります:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"IronOCRのライセンスページから無料トライアルキーを入手できます。 試用版では透かし入りの出力が得られ、購入前に全機能を試すことができます。
コード移行の例
ローカルモデルパス構成の削除
実行時に Baidu サーバーへの接続を回避するために PaddleOCR モデルファイルを事前にダウンロードするプロジェクトでは、3 つの別々のディレクトリ パスを設定する必要があります。 この設定は、ラッパーのバージョンが変更されるたびに更新する必要があります。
PaddleOCRのアプローチ:
// Local model configuration — developer owns the directory structure
// Each wrapper update may require re-downloading model files
string modelsRoot = Path.Combine(AppContext.BaseDirectory, "models");
FullOcrModel models = new FullOcrModel(
LocalDetectionModel.FromDirectory(
Path.Combine(modelsRoot, "ch_PP-OCRv4_det_infer")),
LocalClassificationModel.FromDirectory(
Path.Combine(modelsRoot, "ch_ppocr_mobile_v2.0_cls_infer")),
LocalRecognitionModel.FromDirectory(
Path.Combine(modelsRoot, "ch_PP-OCRv4_rec_infer"))
);
// Fails at runtime if any of the three directories is missing or stale
using PaddleOcrAll ocr = new PaddleOcrAll(models)
{
AllowRotateDetection = true,
Enable180Classification = true
};
using Mat mat = Cv2.ImRead("document.png");
PaddleOcrResult result = ocr.Run(mat);
Console.WriteLine(result.Text);
IronOCRのアプローチ:
// なし model directories, no path configuration, no version matching
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("document.png");
var result = ocr.Read(input);
Console.WriteLine(result.Text);
FromDirectory()呼び出し、およびバージョン同期の問題はすべて消えます。 IronOCRエンジンは復元時にNuGetパッケージ内にバンドルされるため、実行時のパス解決は不要です。 ライセンスキーの場所をappsettings.jsonに含む初期化オプションについては、IronTesseractセットアップガイドを参照してください。
2段階検出・認識パイプラインの統合
PaddleOCRの回転と方向パイプラインはPaddleOcrAllのプロパティを通じて構成されます。 IronOCRでこの動作を再現するにはOcrInput前処理メソッドを使用します。これは、同じドキュメントの問題をより簡単なコール表面で処理します。
PaddleOCRのアプローチ:
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models.Online;
using OpenCvSharp;
// Separate async initialization step — blocks startup for 3-5 seconds on cold run
FullOcrModel models = await OnlineFullModels.EnglishV4.DownloadAsync();
using PaddleOcrAll ocr = new PaddleOcrAll(models)
{
AllowRotateDetection = true, // Enables 0/90/180/270 degree rotation detection
Enable180Classification = true // Additional pass for upside-down text
};
// OpenCV Mat required — no direct file path support
using Mat mat = Cv2.ImRead("rotated-scan.png");
if (mat.Empty())
{
throw new FileNotFoundException("Image could not be loaded by OpenCvSharp");
}
// Three neural network passes: detection → classification → recognition
PaddleOcrResult result = ocr.Run(mat);
// Regions arrive in spatial order, not reading order
// Manual sort required for top-to-bottom, left-to-right output
var orderedRegions = result.Regions
.OrderBy(r => r.Rect.Center.Y)
.ThenBy(r => r.Rect.Center.X);
foreach (var region in orderedRegions)
{
Console.WriteLine($"{region.Text} (confidence: {region.Score:P1})");
}
IronOCRのアプローチ:
using IronOcr;
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("rotated-scan.png");
input.Deskew(); // Corrects rotation and skew automatically
var result = ocr.Read(input);
// Output is already in reading order — no sort needed
foreach (var page in result.Pages)
{
foreach (var line in page.Lines)
{
Console.WriteLine($"{line.Text} (confidence: {line.Confidence}%)");
}
}
IronOCRのLinesコレクションは、Tesseractのレイアウトエンジンによって読み取り順に提供されるため、手動ソートパターンを排除します。 画像方向補正ガイドには、回転と傾き補正に関するあらゆるオプションが記載されています。
GPUおよびCPUデバイスの選択解除
GPU推論を実行するPaddleOCRアプリケーションは、最も大きな移行面を持ちます:GPUランタイムNuGetパッケージ、CUDA/cuDNN環境の前提条件、およびPaddleDevice.Gpu()構成呼び出し。 これらはすべて移行時に削除されます。
PaddleOCRのアプローチ:
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models.Online;
using Sdcb.PaddleInference; // GPU configuration namespace
using OpenCvSharp;
// Prerequisites must exist on every deployment environment:
// - NVIDIA Driver 452.39+ (Windows) / 450.80.02+ (Linux)
// - CUDA Toolkit 11.8 (not 12.x — version must match exactly)
// - cuDNN 8.6.0+ placed in CUDA bin directory
// - dotnet add package Sdcb.PaddleInference.runtime.win64.cuda118
FullOcrModel models = await OnlineFullModels.ChineseV4.DownloadAsync();
// GPU device 0, 1000MB initial memory pool
// Throws native load exception if CUDA_PATH not set or cuDNN DLL missing
using PaddleOcrAll ocr = new PaddleOcrAll(models, PaddleDevice.Gpu(deviceId: 0))
{
AllowRotateDetection = true,
Enable180Classification = true
};
using Mat mat = Cv2.ImRead("scanned-batch.png");
PaddleOcrResult result = ocr.Run(mat);
Console.WriteLine($"Text regions: {result.Regions.Length}");
Console.WriteLine(result.Text);
IronOCRのアプローチ:
*IronOCRのアプローチは上記の例と同じです。IronTesseractは同じAPI呼び出しでこのシナリオを処理します。 GPUパッケージ、CUDAの前提条件、デバイスの選択は不要です。 new IronTesseract()に置き換え、すべてのGPU関連の構成を削除します。
IronOCRはCPU上で画像1枚あたり150~300msの処理速度を実現しており、CPU上のPaddleOCR(300~500ms)よりも高速で、GPUインフラストラクチャがなくても、ほとんどのWeb APIやドキュメントパイプラインのワークロードに十分対応できます。 高スループットのシナリオ向けには、速度最適化ガイドで、スレッド管理やページ分割モードの調整などの構成オプションについて説明しています。
構造化文書データ抽出
PaddleOCRは、PaddleOcrResultRegionオブジェクトのフラットな配列を返します。これは読み取りフローではなく、空間的に並べ替えられています。 段落レベルまたは行レベルの構造を抽出するには、境界ボックスの近接度に基づいた手動のグループ化ロジックが必要です。 IronOCRは、読み上げ順序が保証された階層的な結果ツリーを提供します。
PaddleOCRのアプローチ:
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models.Online;
using OpenCvSharp;
using System.Collections.Generic;
FullOcrModel models = await OnlineFullModels.EnglishV4.DownloadAsync();
using PaddleOcrAll ocr = new PaddleOcrAll(models);
using Mat mat = Cv2.ImRead("invoice.png");
PaddleOcrResult result = ocr.Run(mat);
// なし paragraph or line grouping — must implement manually
// Group regions into lines by proximity on the Y axis
var lineGroups = new Dictionary<int, List<PaddleOcrResultRegion>>();
foreach (var region in result.Regions)
{
// Round Y center to nearest 15 pixels to approximate line grouping
int lineKey = (int)(region.Rect.Center.Y / 15) * 15;
if (!lineGroups.ContainsKey(lineKey))
lineGroups[lineKey] = new List<PaddleOcrResultRegion>();
lineGroups[lineKey].Add(region);
}
// Sort lines top to bottom, then regions left to right within each line
foreach (var line in lineGroups.OrderBy(kv => kv.Key))
{
var lineText = string.Join(" ", line.Value
.OrderBy(r => r.Rect.Center.X)
.Select(r => r.Text));
Console.WriteLine(lineText);
}
IronOCRのアプローチ:
using IronOcr;
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("invoice.png");
var result = ocr.Read(input);
// Hierarchical structure: Pages → Paragraphs → Lines → Words → Characters
// All delivered in reading order by the layout engine
foreach (var page in result.Pages)
{
Console.WriteLine($"Page {page.PageNumber} — {page.Words.Count} words");
foreach (var paragraph in page.Paragraphs)
{
Console.WriteLine($" Paragraph at ({paragraph.X}, {paragraph.Y}):");
Console.WriteLine($" {paragraph.Text}");
}
}
手動で行をグループ化する近似処理(Y座標をピクセル単位のバケットサイズに丸める)は、Tesseractレイアウトエンジンに組み込まれている段落分割機能に置き換えられました。 定界ボックスの座標は、paragraph.Heightを通じて階層のすべてのレベルで利用可能です。 結果ツリーの全体像については、構造化結果ガイドと画像からのテキスト読み取りチュートリアルを参照してください。
検索可能なPDF生成
PaddleOCRはPDF出力を生成しません。 PaddleOCRの結果から検索可能なPDFを生成するには、別のPDFライブラリ、region.RectからPDFページ単位への手動の座標マッピング、および不可視テキストレイヤーの注入が必要です。 IronOCRは、OCRの結果から直接検索可能なPDFを生成します。
PaddleOCRのアプローチ:
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models.Online;
using OpenCvSharp;
// Requires additional package: PdfSharp, iTextSharp, or similar
// Manual coordinate remapping from OpenCV pixel space to PDF point space
FullOcrModel models = await OnlineFullModels.EnglishV4.DownloadAsync();
using PaddleOcrAll ocr = new PaddleOcrAll(models);
using Mat mat = Cv2.ImRead("scanned-page.png");
PaddleOcrResult paddleResult = ocr.Run(mat);
// なし built-in searchable PDF output — must build with external library
// region.Rect coordinates are in pixel space, PDF uses points (1 point = 1/72 inch)
// DPI conversion required for coordinate mapping
float dpiScale = 72.0f / 96.0f; // Assuming 96 DPI source image
// ... hundreds of lines of PDF construction code using external library ...
// This is permanent maintenance, not a one-time cost
Console.WriteLine("Searchable PDF output requires external PDF library and coordinate mapping.");
IronOCRのアプローチ:
using IronOcr;
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("scanned-page.png");
input.Deskew();
input.DeNoise();
var result = ocr.Read(input);
// Searchable PDF in one line — no external PDF library, no coordinate mapping
result.SaveAsSearchablePdf("searchable-output.pdf");
Console.WriteLine($"Searchable PDF created. Confidence: {result.Confidence}%");
IronOCRには、座標マッピングの問題(OpenCVのピクセル座標を正しいDPIのPDFポイント空間に変換すること)は存在しません。 検索可能なPDFガイドでは、複数ページ出力、パスワード保護付きPDF、出力品質設定について解説しています。 スキャンされたアーカイブをデジタル化するチームや、ファックスを検索可能なPDFに変換するパイプラインを構築するチームにとって、この単一のメソッド呼び出しは、そうでなければ大規模な統合プロジェクトとなるであろう作業を不要にします。
複数フレームTIFFバッチ処理
複数ページのTIFFファイルは、文書スキャンワークフローで頻繁に登場します。 PaddleOCRにはTIFFのマルチフレームの直接サポートがありません。各フレームは外部のイメージライブラリを使用して個別に抽出し、別個のMatとしてロードする必要があります。 IronOCRは、マルチフレームTIFFをネイティブに処理します。
PaddleOCRのアプローチ:
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models.Online;
using OpenCvSharp;
using System.Drawing; // For multi-frame TIFF extraction
using System.Drawing.Imaging;
using System.Text;
FullOcrModel models = await OnlineFullModels.EnglishV4.DownloadAsync();
using PaddleOcrAll ocr = new PaddleOcrAll(models);
var fullText = new StringBuilder();
// Must use System.Drawing to extract individual TIFF frames
// OpenCvSharp cannot enumerate TIFF frames directly
using var tiff = Image.FromFile("multipage-scan.tiff");
FrameDimension dimension = new FrameDimension(tiff.FrameDimensionsList[0]);
int frameCount = tiff.GetFrameCount(dimension);
for (int i = 0; i < frameCount; i++)
{
tiff.SelectActiveFrame(dimension, i);
// Save frame to temp file — OpenCvSharp needs a file path
string tempPath = Path.GetTempFileName() + ".png";
tiff.Save(tempPath, ImageFormat.Png);
try
{
using Mat mat = Cv2.ImRead(tempPath);
PaddleOcrResult result = ocr.Run(mat);
fullText.AppendLine($"=== Frame {i + 1} ===");
fullText.AppendLine(result.Text);
}
finally
{
File.Delete(tempPath); // Must clean up temp files
}
}
Console.WriteLine(fullText.ToString());
IronOCRのアプローチ:
using IronOcr;
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImageFrames("multipage-scan.tiff"); // All frames in one call
var result = ocr.Read(input);
foreach (var page in result.Pages)
{
Console.WriteLine($"=== Frame {page.PageNumber} ===");
Console.WriteLine(page.Text);
}
// Optionally save the entire multi-frame result as searchable PDF
result.SaveAsSearchablePdf("multipage-searchable.pdf");
フレーム抽出ループ、System.Drawing依存性、一時ファイル作成、およびクリーンアップロジックはすべて削除されます。 IronOCRは、単一のPageとして公開します。 TIFFおよびGIF入力ガイドでは、複数フレームの読み込みオプション、選択的なフレーム範囲、および大規模なTIFFアーカイブのメモリに関する考慮事項について説明します。
PaddleOCR (.NET) API からIronOCRへのマッピング リファレンス
| パドルOCR(Sdcb) | IronOCR | ノート |
|---|---|---|
Sdcb.PaddleOCR | IronOcr | 名前空間 |
Sdcb.PaddleOCR.Models.Online | 該当なし | モデル取得ネームスペースは不要です |
Sdcb.PaddleInference | 該当なし | 推論バックエンドの名前空間は不要です |
FullOcrModel | 該当なし | 同等のモデルはありません。モデルはバンドルされています。 |
OnlineFullModels.ChineseV4.DownloadAsync() | dotnet add package IronOcr.Languages.ChineseSimplified | モデル取得はNuGetに置き換えられました |
LocalDetectionModel.FromDirectory(path) | 該当なし | モデルパス管理なし |
LocalClassificationModel.FromDirectory(path) | 該当なし | モデルパス管理なし |
LocalRecognitionModel.FromDirectory(path) | 該当なし | モデルパス管理なし |
new PaddleOcrAll(models) | new IronTesseract() | エンジンのインスタンス化 |
new PaddleOcrAll(models, PaddleDevice.Gpu(0)) | 該当なし | GPUデバイスの選択が完全に削除されました |
PaddleDevice.Cpu() | 該当なし | CPUモードのみ。 選択不要 |
ocr.AllowRotateDetection = true | input.Deskew() | 回転補正 |
ocr.Enable180Classification = true | 自動翻訳 | 上下逆さま検出機能が組み込まれています |
Cv2.ImRead(path) | input.LoadImage(path) | 画像読み込み - OpenCVは不要 |
ocr.Run(mat) | ocr.Read(input) | OCRを実行する |
result.Text | result.Text | 文書全体のテキスト文字列 |
result.Regions | .Words | 構造化されたテキスト領域 |
region.Text | word.Text / line.Text | 地域のテキストコンテンツ |
region.Score(浮動小数点0-1) | word.Confidence(整数0-100) | 信頼度値 - スケールが異なる |
region.Rect.Center.X | word.X | 水平位置 |
region.Rect.Center.Y | word.Y | 垂直位置 |
region.Rect.Size.Width | word.Width | バウンディングボックスの幅 |
region.Rect.Size.Height | word.Height | バウンディングボックスの高さ |
| 該当なし | input.LoadPdf(path) | ネイティブPDF入力(PaddleOCRに相当する機能はありません) |
| 該当なし | input.LoadImageFrames(path) | マルチフレームTIFF(PaddleOCRに相当するものはありません) |
| 該当なし | result.SaveAsSearchablePdf(path) | 検索可能なPDF出力(PaddleOCRと同等の機能はありません) |
一般的な移行の問題と解決策
問題点1:信頼度尺度の不一致
PaddleOCR: リージョン自信度は0.0から1.0のregion.Score >= 0.8です。
ソリューション: IronOCRの自信度は0から100のintパーセントです。PaddleOCRのしきい値に100を掛けてください。
// PaddleOCR: filter at 0.8
var highConfidence = result.Regions.Where(r => r.Score >= 0.8);
// IronOCR equivalent: filter at 80
var highConfidence = result.Pages
.SelectMany(p => p.Words)
.Where(w => w.Confidence >= 80);
ドキュメントレベルの自信度は、迅速な品質ゲーティングのためにresult.Confidenceとして利用可能です。 信頼度スコアガイドでは、単語単位および文書単位の閾値について説明しています。
問題2:読書順序に関する前提
PaddleOCR: result.Regionsは検出順に並べられており、読み取り順ではありません。 読み取り順のトップからボトム、左から右出力を期待するresult.Textを消費するコードは、PaddleOCRの例全体で使用されている手動ソートパターンに頼っています。
ソリューション: IronOCRのresult.Textはすでに読み取り順にあります。 手動ソートを削除します。 行ごとの出力を構築するためにソートを使用していた場合は、result.Pages[0].Linesを直接使用してください。
// PaddleOCR: manual sort required for reading order
var lines = result.Regions
.OrderBy(r => r.Rect.Center.Y)
.ThenBy(r => r.Rect.Center.X)
.Select(r => r.Text);
// IronOCR: reading order is the default
var lines = result.Pages[0].Lines.Select(l => l.Text);
問題3:OpenCVのMat変換コード
PaddleOCR: 一部のコードベースには、ストリームやバイト配列から画像を読み込むヘルパーメソッドが含まれており、最初に一時ファイルに書き込んでからCv2.ImRead()を呼び出します。 これらのパターンが存在する理由は、Cv2.ImRead()がファイルパスのみを受け入れるためです。
ソリューション: IronOCRのOcrInputは、直接ストリームやバイト配列を受け入れます。 一時ファイル中間を削除します。
// PaddleOCR: stream → temp file → Mat → OCR
string tempPath = Path.GetTempFileName() + ".png";
using (var fs = File.Create(tempPath))
await imageStream.CopyToAsync(fs);
using Mat mat = Cv2.ImRead(tempPath);
PaddleOcrResult result = ocr.Run(mat);
File.Delete(tempPath);
// IronOCR: stream → OCR (no temp file)
using var input = new OcrInput();
input.LoadImage(imageStream);
var result = ocr.Read(input);
ストリーム入力ガイドでは、HTTPレスポンス、データベースBLOB、およびメモリストリームからのストリーム読み込みについて説明します。
問題4:非同期初期化パターンの削除
**PaddleOCR:**モデルのダウンロードにはネットワークI/Oが伴うため、エンジンの初期化は非同期で行われます。 これにより、呼び出しチェーン全体で非同期処理が強制されるため、コンストラクタや非同期ではないイベントハンドラなどの同期的なコンテキストでは問題が発生する可能性があります。
解決策: IronOCRの初期化は同期的に行われます。 new IronTesseract()はI/Oを実行しません。 モデルのダウンロードが唯一の非同期操作だったメソッドからasync修飾子を削除してください。
// PaddleOCR: async forced by model download
public async Task<string> ExtractTextAsync(string imagePath)
{
FullOcrModel models = await OnlineFullModels.EnglishV4.DownloadAsync();
using PaddleOcrAll ocr = new PaddleOcrAll(models);
using Mat mat = Cv2.ImRead(imagePath);
return ocr.Run(mat).Text;
}
// IronOCR: synchronous — no async required unless the caller needs it
public string ExtractText(string imagePath)
{
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage(imagePath);
return ocr.Read(input).Text;
}
IronOCRはまた、非同期コンテキストで真に必要なときには非ブロック実行を通してocr.ReadAsync(input)によるネイティブ非同期サポートを提供します。
問題5:Dockerビルドステップのクリーンアップ
PaddleOCR: DockerfileにはRUNステップが含まれています。ベースイメージはしばしばGPUデプロイメント用のNVIDIA CUDAイメージです。
解決策: PaddleOCR固有のDockerfile命令をすべて削除してください。 IronOCRのDockerイメージは、特別なベースイメージやモデルのコピー手順を必要としません。
# PaddleOCR Dockerfile (remove all of this)
FROM nvidia/cuda:11.8.0-cudnn8-runtime-ubuntu22.04
RUN apt-get update && apt-get install -y libopencv-dev libgdiplus
COPY models/ /app/models/
COPY . /app
# IronOCR Dockerfile (clean)
FROM mcr.microsoft.com/dotnet/aspnet:8.0
COPY . /app
WORKDIR /app
ENTRYPOINT ["dotnet", "YourApp.dll"]
結果として得られる画像のサイズは、約1.5GBから約400MBに縮小されます。 Dockerの導入ガイドでは、 Linuxライブラリの要件とマルチアーキテクチャビルドについて説明しています。
問題6:CI/CDモデルキャッシュの無効化
PaddleOCR: NuGet復元ステップをキャッシュするCI/CDパイプラインは、モデルファイルのキャッシュを個別に管理する必要があります。 共通のパターンは、実行間でmodels/フォルダをキャッシュすることです。 ラッパーのバージョンが更新されると、キャッシュキーが変更され、モデルをBaiduサーバーから再ダウンロードする必要があるため、処理に30~60秒追加されます。
解決策: IronOCRにはモデルキャッシュディレクトリがありません。 必要なキャッシュは、標準のNuGetパッケージキャッシュのみです。 個別のキャッシュ手順なし、ラッパー更新時のキャッシュ無効化なし、CI中にサードパーティサーバーからのダウンロードなし:
# Remove from CI/CD pipeline:
# - name: Cache PaddleOCR models
# uses: actions/cache@v3
# with:
# path: models/
# key: paddleocr-models-${{env.PADDLEOCR_VERSION}}
# IronOCR only needs standard NuGet caching:
- name: Cache NuGet packages
uses: actions/cache@v3
with:
path: ~/.nuget/packages
key: nuget-${{hashFiles('**/*.csproj')}}
PaddleOCR (.NET) 移行チェックリスト
移行前
変更を加える前に、コードベースを監査してPaddleOCRの使用箇所をすべて特定してください。
# Find all PaddleOCR namespace imports
grep -rn "using Sdcb.PaddleOCR" --include="*.cs" .
# Find all OpenCvSharp imports (added as PaddleOCR dependency)
grep -rn "using OpenCvSharp" --include="*.cs" .
# Find all Mat usage patterns
grep -rn "Cv2\.ImRead\|new Mat\|Mat mat" --include="*.cs" .
# Find all async model download calls
grep -rn "DownloadAsync\|OnlineFullModels\|LocalDetectionModel" --include="*.cs" .
# Find all GPU device configuration
grep -rn "PaddleDevice\|EnableUseGpu\|cuda" --include="*.cs" .
# Find all result region access patterns
grep -rn "result\.Regions\|region\.Score\|region\.Rect" --include="*.cs" .
# Locate model directory references in configuration files
grep -rn "PP-OCRv4\|cls_infer\|det_infer\|rec_infer" --include="*.cs" --include="*.json" --include="*.yaml" .
モデルのディレクトリを確保し、合計サイズを確認してください。どの言語モデルが使用中か(中国語、英語、日本語など)を特定して、追加するIronOcr.Languages.*パッケージを決定します。 GPU構成ファイルが存在するかどうかを確認してください。これらのファイルは、クリーンアップが必要な領域が最も大きいためです。
コードの移行
.csprojファイルから削除します。.csprojファイルに追加します。- これまでにPaddleOCRモデルとしてダウンロードされた英語以外の言語ごとに
IronOcr.Languages.*パッケージを追加します。 - すべての
using IronOcrで置き換えます。 - アプリケーション起動時に
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";を追加します。 FullOcrModel models = await OnlineFullModels.*.DownloadAsync()を何もないものに置き換えます—行を完全に削除します。new IronTesseract()で置き換えます。new IronTesseract()で置き換えます。Mat mat = Cv2.ImRead(path)をvar input = new OcrInput();で置き換えます。 input.LoadImage(path);`.ocr.Read(input)で置き換えます。result.Pages[0].Wordsで置き換えます。word.Confidence >= threshold * 100で置き換えます。word.X / word.Yで置き換えます。- 手動ソートロジックを削除する — IronOCRの出力は既に読み上げ順になっている
models/ディレクトリおよびすべてのモデルファイルをリポジトリおよびデプロイメントスクリプトから削除します。
移行後
- ビルド出力に
dotnet buildが成功することを検証します。 - PaddleOCRの出力検証に使用したのと同じ代表文書セットでOCRを実行し、テキストの精度を比較する。
- すべてのフィルタポイントで信頼度値が整数0~100(浮動小数点数0~1ではない)として読み取られていることを確認してください。
- 手動で並べ替えずに読み上げ順序が正しいことを確認する — 特に複数列レイアウトと請求書レイアウトをチェックする
- CUDAベースイメージや
apt-get install libopencv-devなしでDockerイメージのビルドが完了することをテストします。 - Dockerイメージのサイズが500MB未満であることを確認してください CI/CDパイプラインをエンドツーエンドで実行し、ビルド中に外部ダウンロードが発生しないことを確認します。
- エアギャップ展開のテスト:アプリケーションが起動し、外部ネットワーク接続なしでドキュメントを処理することを確認します。 複数フレームのTIFF入力の場合、すべてのフレームが処理され、フレーム数がソースファイルと一致していることを確認してください。
- すべてのPDF入力について、
input.LoadPdf()がPdfiumViewerベースの変換と同じページ数とテキスト内容を生成することを確認します。
IronOCRへの移行の主なメリット
デプロイメントアーティファクトが80%縮小します。 PaddleOCRのデプロイメントフットプリント—paddle_inference.dll、OpenCV DLL、および3つのモデルディレクトリ—は、すべてのデプロイメントターゲットに300-500MBを追加します。 移行後、 IronOCRのデプロイメントは約80MBになります。 Dockerイメージのサイズが約1.5GBから約400MBに縮小します。 コンテナの起動が高速化され、ストレージコストが削減されました。また、以前は500MBのアーティファクトを転送していたデプロイパイプラインが、現在は80MBの転送で済むようになりました。
**コールドスタート時間が数秒から数ミリ秒に短縮。**PaddleOCRは、最初の推論時にディスクから3つのニューラルネットワークモデルファイルを読み込むため、最初の呼び出しが返るまでに3~5秒の遅延が生じます。 サーバーレス関数、自動スケーリングのシナリオ、あるいはオンデマンドで新しいインスタンスが起動されるあらゆる状況において、そのコールドスタートのコストは繰り返し発生します。 IronOCRのエンジンはバンドルされており、1秒未満で初期化されます。 基本的なOCRの例では、初期化のパターンを示しています。
**インフラストラクチャの構築作業なしに、対応言語が14言語から125言語に拡大。**PaddleOCRは14言語に対応しています。 PaddleOCRの上限を超えてIronOCRがサポートする111言語のいずれかを追加する場合、言語ごとにNuGetパッケージを1つ追加するだけで済みます。モデルのダウンロード、ディレクトリ管理、バージョンの同期は一切不要です。 ドキュメントのボリュームが拡大し、新たな市場に進出するチームであっても、ポーランド語、ベトナム語、ギリシャ語、またはヘブライ語のOCRサポートを追加するために、ドキュメントの書き直しや新たなインフラストラクチャプロジェクトに取り組む必要はありません。 言語カタログの完全版には、利用可能な125以上のパックがすべて掲載されています。
**検索可能なPDF出力には1行が必要です。**PaddleOCRはテキスト領域を返します。 これらの領域を検索可能なPDFレイヤーに変換するには、別のPDFライブラリ、ピクセルからポイントへの座標変換、および恒久的なメンテナンスとなる不可視テキストの挿入コードが必要となります。 移行後、result.SaveAsSearchablePdf("output.pdf")がその全サブシステムを置き換えます。 スキャンされた文書のアーカイブワークフロー、FAXからPDFへの変換パイプライン、および文書管理システムとの連携など、これらすべてが直接的な恩恵を受けます。 検索可能なPDFの操作ガイドおよびPDFデータ抽出に関するブログ記事では、出力オプションの全容を網羅しています。
どの段階でも外部ネットワーク接続はありません。 PaddleOCRはモデルのダウンロードのためにBaiduのbj.bcebos.comストレージに接続します。 政府ネットワーク、エアギャップシステム、金融サービスインフラなど、外部への接続が制限されている環境では、その接続にはファイアウォールの例外設定、あるいはCI/CDの複雑さを増す事前ダウンロードワークフローのいずれかが必要となります。 IronOCRはランタイムで外部接続を行いません。モデルはNuGetからdotnet restoreの一部として復元され、デプロイメント出力に存在します。 AWS 導入ガイドおよび Azure 導入ガイドでは、ネットワーク制限のある環境におけるクラウド固有の設定について解説しています。
OCRスタック全体に対する1つの商業サポート連絡先。 PaddleOCRの問題はSdcb.PaddleOCRラッパー(コミュニティGitHub)、PaddlePaddleフレームワーク(Baidu)、OpenCvSharp(コミュニティ)、およびCUDA/cuDNN(NVIDIA)にわたります。 各レイヤーには異なるサポートチャネルが用意されていますが、応答時間は保証されません。IronOCRはIron Softwareの単一製品であり、商用メールサポートおよび優先対応レベルが提供されています。 IronOCRドキュメントハブでは、すべてのAPIドキュメント、ハウツーガイド、トラブルシューティングリソースを一か所にまとめています。
