概要
本システムは、テキストデータの品質向上および構造化を目的とした自動処理ツールキットです。主な機能として、自然言語処理による誤り訂正、画像からの文字抽出(OCR)、そして表構造の解析が含まれます。CPU 環境での効率的な動作を重視し、各種モデルの最適化が行われています。
テキスト誤り訂正機能
文章の精度を高めるため、複数のアプローチを組み合わせています。具体的には、統計的语言モデル(N-gram)、深層学習モデル、およびルールベースの文法チェックを併用します。また、固有名や成語といった特殊な語彙に対する補正ロジックも実装されています。
画像文字認識(OCR)
画像内のテキスト検出および認識には、高性能なモデルを採用しています。推論速度を向上させるため、モデルは ONNX 形式に変換されており、CPU 環境でも一枚の画像あたり約 10 秒での処理を目指しています。認識前に画像プレプロセスを行うことで精度を確保しています。
実装例
以下のコードは、画像ファイルを読み込み、テキスト検出モデルと認識モデルを用いて結果を取得するプロセスを示しています。
public void executeTextExtraction() {
// 画像ファイルのパス設定
final String sourceFile = "data/input/sample_document.png";
Path filePath = Paths.get(sourceFile);
// 画像データの読み込み
var inputImage = ImageFactory.getInstance().fromFile(filePath);
// モデルパスの解決と初期化
String detModelPath = resolveResourcePath("models/detect.onnx");
String recModelPath = resolveResourcePath("models/recognize.onnx");
OpticalCharacterReader reader = new OpticalCharacterReader(
Paths.get(detModelPath),
Paths.get(recModelPath)
);
reader.initialize();
// 推論実行と時間計測
long startTime = System.currentTimeMillis();
var recognitionOutcome = reader.processImage(inputImage, 960);
long duration = System.currentTimeMillis() - startTime;
System.out.println("処理時間:" + (duration / 1000.0) + "秒");
// 結果の出力
for (var item : recognitionOutcome.getLeft()) {
System.out.println(item);
}
// 結果画像の保存とリソース解放
reader.exportVisualization(recognitionOutcome, "output.png", "data/output");
reader.releaseResources();
}
出力データ形式
認識結果は、テキスト内容とその座標情報のペアとして返されます。
座標:[800.0, 609.0, 877.0, 609.0, 877.0, 645.0, 800.0, 645.0], 文字列:8.23%
座標:[433.0, 607.0, 494.0, 607.0, 494.0, 649.0, 433.0, 649.0], 文字列:68.4
座標:[96.0, 610.0, 316.0, 611.0, 316.0, 641.0, 96.0, 640.0], 文字列:股东权益比率(%)
座標:[624.0, 605.0, 688.0, 605.0, 688.0, 650.0, 624.0, 650.0], 文字列:63.2
座標:[791.0, 570.0, 887.0, 570.0, 887.0, 600.0, 791.0, 600.0], 文字列:-39.64%
...
表構造認識機能
OpenCV を利用したルールベースの解析により、表のセル構造を特定します。境界線のある表、ない表、および部分的にある表の 3 パターンに対応しています。
実装例
表のタイプに応じて適切な解析クラスを呼び出します。
public void analyzeTableStructures() {
// 境界線ありの表
processTableType("data/input/bounded.png", TableGridAnalyzer::detectBoundedGrid);
// 境界線なしの表
processTableType("data/input/unbounded.jpg", TableGridAnalyzer::detectUnboundedGrid);
// 部分的境界線の表
processTableType("data/input/partial.jpg", TableGridAnalyzer::detectPartialGrid);
}
private void processTableType(String path, Function<Mat, Pair<List<List<List<Integer>>>, Mat>> analyzer) {
Mat sourceMatrix = imread(path);
System.out.println("画像サイズ:" + sourceMatrix.size().height() + "x" + sourceMatrix.size().width());
var analysisResult = analyzer.apply(sourceMatrix);
System.out.println(analysisResult.getLeft());
ImageUtils.imshow("Preview", analysisResult.getRight());
}
解析結果
各セルの座標情報がネストされたリスト構造で返されます。
[
[[58, 48, 247, 182], [309, 48, 247, 182], [560, 48, 247, 182], [], [], [1061, 48, 247, 182], [1312, 48, 247, 182], [811, 48, 246, 182], [], [], [], []],
[[58, 234, 247, 118], [309, 234, 247, 118], [560, 234, 247, 118], [], [811, 234, 246, 118], [], [1061, 234, 247, 118], [], [], [1312, 234, 247, 118], [], []],
[[58, 356, 247, 118], [], [309, 356, 247, 118], [560, 356, 247, 118], [], [811, 356, 246, 118], [], [], [1061, 356, 247, 118], [], [1312, 356, 247, 118], []],
...
]