ホーム 記事一覧 ブック DH週間トピックス 検索 このサイトについて
English

KotenOCR: 近代OCRの検出重複を解消する(NMS追加とクラスフィルタリング)

はじめに KotenOCRは、国立国会図書館(NDL)が公開したOCRモデルをiOS上で動作させ、くずし字や近代活字をオフラインで認識するアプリです。 近代OCRモード(NDLモード)では、NDLのDEIMv2-Sモデルでレイアウト検出を行い、PARSeQで文字認識を行います。しかし、iOS実装の検出結果が本家のndlocr-liteと比べて明らかに多く、テキストが重複して認識されるという問題がありました。 本記事では、原因の調査から修正までの過程を記録します。 症状:検出数が多すぎる テスト画像として、NDLデジタルコレクションから取得した「校異源氏物語」の序文ページを使いました。 本家ndlocr-liteでは17件の行検出(line_main、line_captionなど)が得られるのに対し、iOS実装では28件の検出が返り、OCR結果にも重複テキストや文字化けが混入していました。 検出数が多い原因は大きく3つありました。 原因1:NMS(Non-Maximum Suppression)が未実装だった DEIMv2モデルのONNX出力は、内部でNMSを完了した結果を返すと想定していました。しかし本家ndlocr-liteのコードを読むと、モデル推論後に追加のNMS(IoU閾値=0.2)を適用していることがわかりました。 つまり、モデル出力にはまだ重複する矩形が含まれており、後処理でそれを除去する必要があったのです。 修正:NMSの追加 DEIMDetector.swiftにNMS処理を追加しました。 // DEIMDetector.swift — postprocess() の末尾 // Sort by score descending let sorted = detections.sorted { $0.score > $1.score } // Apply NMS to remove overlapping detections let nmsResult = applyNMS(sorted, iouThreshold: iouThreshold) return Array(nmsResult.prefix(maxDetections)) NMS本体の実装は以下のとおりです。スコア降順にソートされた検出結果を走査し、既に採用した矩形とのIoUが閾値を超える場合は除外します。 // DEIMDetector.swift /// Apply Non-Maximum Suppression to remove overlapping detections. private func applyNMS(_ detections: [Detection], iouThreshold: Float) -> [Detection] { var kept: [Detection] = [] for det in detections { var shouldKeep = true for existing in kept { if computeIoU(det.box, existing.box) > iouThreshold { shouldKeep = false break } } if shouldKeep { kept.append(det) } } return kept } /// Compute Intersection over Union between two boxes [x1, y1, x2, y2]. private func computeIoU(_ a: [Int], _ b: [Int]) -> Float { let x1 = max(a[0], b[0]) let y1 = max(a[1], b[1]) let x2 = min(a[2], b[2]) let y2 = min(a[3], b[3]) let interW = max(0, x2 - x1) let interH = max(0, y2 - y1) let interArea = Float(interW * interH) let areaA = Float((a[2] - a[0]) * (a[3] - a[1])) let areaB = Float((b[2] - b[0]) * (b[3] - b[1])) let unionArea = areaA + areaB - interArea guard unionArea > 0 else { return 0 } return interArea / unionArea } 原因2:全クラスをOCRに送っていた DEIMv2モデルは17クラスのレイアウト要素を検出します。 ...

DH週間トピックス — 2026年3月第4週

DH週間トピックス — 2026年3月第4週

デジタル人文学(DH)関連の新規ツール開発・公開情報を週次でまとめています。 NDL OCR-Lite のモバイル対応・段組み認識対応 国立国会図書館が開発した古典籍OCRエンジン「NDL OCR-Lite」のWebアプリケーション版がモバイル対応および段組み認識機能に対応しました。iPhone、iPad、Android端末でカメラや写真ライブラリから画像を選択してOCR処理が可能になったとのことです。また、段組みレイアウトの認識にも対応し、複雑な文書構造の処理精度が向上したようです。 NDL OCR-Lite Web版 @blue0620の投稿およびGitHub更新情報より 軽量AIモデルQwen 3.5 9Bの数学問題解答性能 @blue0620による投稿で、軽量AIモデル「Qwen 3.5 9B」をローカルサーバで動作させたところ、東京大学の数学問題を解答できたとの報告がありました。軽量モデルでありながら高い性能を示しており、今後の自治体等での活用可能性が示唆されています。 @blue0620の投稿より 筑摩書房版芥川龍之介全集専用OCRスクリプト NDL OCR-Liteを活用した、筑摩書房版芥川龍之介全集の特殊なレイアウト(本文2段・脚注1段)に対応した専用OCRスクリプトが開発されました。本文と脚注を分離して作品ごとに整理する機能を持つとのことです。 @tolle_et_legeの投稿より 本記事は X投稿・GitHub更新・カレントアウェアネス・ポータルから自動収集した情報を基に生成しています。

Swift ConcurrencyでOCR認識処理を並列化し最大6.7倍高速化する

Swift ConcurrencyでOCR認識処理を並列化し最大6.7倍高速化する

OCRパイプラインの構造 iOSでONNX Runtimeを使ったOCRパイプラインは、大まかに以下の流れで動作します。 画像全体に対する文字領域検出(Detection) 検出された各領域に対する文字認識(Recognition) 読み順の推定と結合 この中で、検出は画像全体に対して1回だけ実行されます。一方、認識は検出された領域の数だけ繰り返されます。領域数が多い画像では、認識処理が全体の処理時間の大部分を占めることになります。 逐次処理の問題 認識処理を単純なforループで逐次実行すると、処理時間は領域数にほぼ比例します。 for det in detections { let rect = CGRect(x: max(0, det.box[0]), y: max(0, det.box[1]), width: max(1, det.box[2] - det.box[0]), height: max(1, det.box[3] - det.box[1])) if let cropped = image.cropping(to: rect) { _ = try recognizer.recognize(image: cropped) } } たとえば98領域が検出された画像の場合、1領域あたり約80msとすると合計で約8秒かかります。 withThrowingTaskGroupによる並列化 Swift ConcurrencyのwithThrowingTaskGroupを使うと、各領域の認識処理を並列に実行できます。 let results = try await withThrowingTaskGroup(of: (Int, String).self) { group in for i in 0..<detections.count { let box = detections[i].box let cropRect = CGRect( x: max(0, box[0]), y: max(0, box[1]), width: max(1, box[2] - box[0]), height: max(1, box[3] - box[1]) ) guard let cropped = image.cropping(to: cropRect) else { continue } group.addTask { let text = try recognizer.recognize(image: cropped) return (i, text) } } var texts: [(Int, String)] = [] for try await result in group { texts.append(result) } return texts } for (i, text) in results { recognized[i].text = text } 各タスクはインデックスとともに結果を返すため、完了順序に関係なく元の順序を保持できます。 ベンチマーク結果 iOSシミュレータ上で、逐次処理と並列処理の実行時間を比較しました。 古典籍(源氏物語、6642x4990px、21領域) 出典: 東京大学デジタルアーカイブ 源氏物語 方式 処理時間 逐次 4.55s 並列 3.24s 高速化率 1.4x 近代活字(NDLデジタルコレクション、6890x4706px、98領域) 出典: 国立国会図書館デジタルコレクション 方式 処理時間 逐次 7.59s 並列 1.13s 高速化率 6.7x 高速化率が異なる理由 21領域の場合と98領域の場合で高速化率に差が出ています。 ...

KotenOCR:くずし字をオフラインで認識するiOSアプリの開発と公開

KotenOCR:くずし字をオフラインで認識するiOSアプリの開発と公開

はじめに 古典籍に書かれたくずし字(変体仮名・草書体の漢字)を読むのは、専門家でも容易ではありません。近年はAI-OCRによって機械的な認識が可能になってきましたが、調査した限り、スマートフォンでオフライン利用できるツールは見当たりませんでした。 KotenOCRは、国立国会図書館(NDL)が公開した軽量くずし字OCRモデル「NDL古典籍OCR-Lite」をiOS上で動作させ、写真を撮るだけでくずし字を認識できるアプリです。 App Store(無料): https://apps.apple.com/jp/app/kotenocr/id6760045646 背景:既存ツールの状況 NDLが「NDL古典籍OCR-Lite」を公開したことで、くずし字OCRの敷居は下がりました。既存ツールを見渡すと以下のような状況でした。 ツール 形態 インターネット接続 NDL古典籍OCR-Lite デスクトップ / Web / CLI 不要(デスクトップ版) miwo(CODH) モバイルアプリ 必要 古文書カメラ(TOPPAN) モバイルアプリ 必要 モバイルアプリは存在するものの、いずれもクラウド通信が必要です。一方、NDL古典籍OCR-LiteはPC環境でしか動作しません。 そこで、NDL古典籍OCR-Liteのモデルをスマートフォンに載せて、オフラインで動くiOSアプリを作ることにしました。 KotenOCRの特徴 完全オフライン — すべての処理がデバイス上で完結。通信不要 iPhone / iPad対応 — iOS 16.0以上 無料 — App Storeから無料でダウンロード可能 スキャン履歴 — 認識結果を保存・管理 TXT / PDFエクスポート — 認識テキストをファイルとして出力 範囲トリミング — 認識する領域を指定可能 使い方 古典籍の写真を撮影する(またはライブラリから選択) AIがくずし字を自動認識 認識されたテキストをコピー・エクスポート OCRパイプライン 写真からテキストが認識されるまでの処理フローは以下の通りです。 写真 → トリミング → テキスト領域検出 → 文字認識 → 読み順決定 → 表示 テキスト領域検出: RTMDetモデルにより、画像内の文字領域を検出 文字認識: PARSeqモデルにより、検出領域内の文字を認識(7,141文字、NDLmojiの文字集合に対応) 読み順: 日本語の縦書き・右から左への読み順を考慮して並べ替え ...

Transkribus:AIによる手書き文字認識で歴史文書を読み解く

Transkribus:AIによる手書き文字認識で歴史文書を読み解く

TL;DR Transkribus は、AIベースの手書き文字認識(HTR: Handwritten Text Recognition)プラットフォームである。100以上の言語に対応し、印刷文字だけでなく手書き文字の認識が可能である。カスタムモデルの学習機能により、特定の筆跡や書体に最適化した認識精度の向上が図れる。歴史文書のテキスト化において、DH研究者にとって不可欠なツールとなっている。 Transkribusとは Transkribusは、オーストリアのインスブルック大学で開始されたプロジェクトに端を発し、現在はREAD-COOP SCE(欧州協同組合)によって運営されている。EU の Horizon 2020 プログラムなどの支援を受けて開発が進められてきた。 主な特徴は以下の通りである。 HTR(手書き文字認識):ディープラーニングベースの手書き文字認識エンジン 100以上の言語:ラテン文字、キリル文字、アラビア文字、ヘブライ文字など多様な文字体系に対応 カスタムモデル学習:自分のデータで認識モデルを学習させ、特定の文書に特化した高精度な認識が可能 レイアウト解析:ページ内のテキスト領域、行、段落を自動的に検出 協調作業:チームでの共同作業に対応し、大規模なテキスト化プロジェクトを効率的に進められる 主要機能 テキスト認識(HTR/OCR) Transkribusの中核機能である。事前学習済みの汎用モデルを使えば、すぐにテキスト認識を開始できる。公開されているモデルには、中世ラテン語写本、近世ドイツ語の亀甲文字(Kurrent)、英語の筆記体など、様々な時代・言語に対応したものがある。 カスタムモデルの学習 最も強力な機能の一つである。約50ページ分のGround Truth(正解テキスト付き画像)を用意すれば、特定の筆跡や書体に特化したモデルを学習できる。学習済みモデルは他のユーザーと共有することも可能である。 レイアウト解析 文書画像のレイアウトを自動的に解析し、テキスト領域(TextRegion)、行(TextLine)、ベースラインを検出する。複雑なレイアウト(多段組み、表、マージン書き込みなど)にも対応している。 Transkribus Lite ブラウザベースのインターフェースで、インストール不要で利用できる。基本的なHTR機能とレイアウト解析が利用可能であり、手軽に試したい場合に適している。 使い方 基本的なワークフロー アカウント作成:Transkribusでアカウントを作成する 文書のアップロード:画像ファイル(JPEG、PNG、TIFF)やPDFをアップロードする レイアウト解析:自動レイアウト解析を実行し、テキスト領域と行を検出する モデル選択:適切なHTRモデルを選択する(公開モデル一覧から検索可能) テキスト認識実行:選択したモデルでHTRを実行する 結果の確認・修正:認識結果を画像と照合しながら確認・修正する エクスポート:TEI-XML、PAGE XML、ALTO XML、プレーンテキストなどの形式でエクスポートする 料金体系 Transkribusは従量課金制を採用している。無料枠(月500クレジット)があり、小規模な利用であれば無料で始められる。大規模プロジェクトにはサブスクリプションプランが用意されている。 DH研究における活用例 歴史文書のテキスト化 アーカイブに眠る手書き文書をテキスト化し、全文検索可能なデジタルアーカイブを構築できる。例えば、江戸時代の古文書や明治期の手書き公文書のテキスト化に活用できる。 大規模コーパスの構築 カスタムモデルの学習と自動認識を組み合わせることで、数千ページ規模の文書を効率的にテキスト化し、テキストマイニングや言語学的分析のためのコーパスを構築できる。 比較文書学 同一テキストの異なる写本をそれぞれテキスト化し、テキストの異同を分析する比較文書学(Stemmatology)に活用できる。TEI-XML形式でのエクスポートにより、Critical Editionの作成にもつなげられる。 市民参加型プロジェクト Transkribusの協調作業機能を活用し、ボランティアによるクラウドソーシング型のテキスト化プロジェクトを運営できる。品質管理機能により、市民参加型でも高品質な成果を得られる。 他ツールとの比較 特徴 Transkribus Google Cloud Vision Tesseract OCR HTR(手書き) 高精度 基本的 非対応 カスタムモデル 可能 AutoML利用 学習可能 歴史文書対応 特化 汎用 汎用 レイアウト解析 高度 基本的 基本的 料金 従量課金 従量課金 無料(OSS) 出力形式 TEI/ALTO/PAGE JSON テキスト/hOCR まとめ Transkribusは、歴史文書のテキスト化において最も実績のあるプラットフォームである。AIベースのHTRエンジンとカスタムモデル学習機能により、様々な時代・言語の手書き文書に対応できる。DH研究において、テキスト化は多くの分析の出発点であり、Transkribusはその基盤を提供する重要なツールである。 ...

DH週間トピックス — 2026年3月第3週

DH週間トピックス — 2026年3月第3週

デジタル人文学(DH)関連の新規ツール開発・公開情報を週次でまとめています。 今週は該当するトピックはありませんでした。 本記事は X投稿・GitHub更新・カレントアウェアネス・ポータルから自動収集した情報を基に生成しています。

DH週間トピックス — 2026年3月第2週

DH週間トピックス — 2026年3月第2週

デジタル人文学(DH)関連の新規ツール開発・公開情報を週次でまとめています。 今週は該当するトピックはありませんでした。 本記事は X投稿・GitHub更新・カレントアウェアネス・ポータルから自動収集した情報を基に生成しています。

DH週間トピックス — 2026年3月第1週

DH週間トピックス — 2026年3月第1週

デジタル人文学(DH)関連の新規ツール開発・公開情報を週次でまとめています。 今週は該当するトピックはありませんでした。 本記事は X投稿・GitHub更新・カレントアウェアネス・ポータルから自動収集した情報を基に生成しています。

DH週間トピックス — 2026年2月第4週

DH週間トピックス — 2026年2月第4週

デジタル人文学(DH)関連の新規ツール開発・公開情報を週次でまとめています。 NDLOCR-Lite Web版の公開 国立国会図書館のAI-OCRツール「NDLOCR-Lite」のWebブラウザ版「NDLOCR-Lite Web」が公開されました。この新版では、ブラウザ上で手軽に画像やPDFのOCR処理を試すことができ、画像や認識テキストが外部に送信されることなく、ローカルで処理が完結するとのことです。 WebWorkerを使った並列処理化(最大8スレッド)により、1枚あたり数秒での認識が可能で、100ページ程度の文庫本であれば数分で処理が完了すると説明されています。また、AndroidのChromeでの動作確認がされており、モバイル環境での利用も可能なようです。 NDLOCR-Lite Web 開発者によると、読み順推定アルゴリズムに横書きテキストでの不具合が確認されており、修正作業が進められているとのことです。 @yuta1984の投稿およびGitHubリポジトリへの頻繁なコミットから確認されました。 本記事は X投稿・GitHub更新・カレントアウェアネス・ポータルから自動収集した情報を基に生成しています。

DH週間トピックス — 2026年2月第3週

DH週間トピックス — 2026年2月第3週

デジタル人文学(DH)関連の新規ツール開発・公開情報を週次でまとめています。 koten-layout-detector v1.0.0およびv1.1.0がリリース 古典文献のレイアウト検出を行うツール「koten-layout-detector」のバージョン1.0.0が2026年2月20日にリリースされ、同日中にv1.1.0へのアップデートも行われました。このツールは古典文献の画像から文字領域やレイアウト要素を自動検出する機能を提供するものと推測されます。 koten-layout-detectorリポジトリ @yuta1984のGitHub更新情報より。 本記事は X投稿・GitHub更新・カレントアウェアネス・ポータルから自動収集した情報を基に生成しています。

BDRC Tibetan OCR:チベット語OCRツールの紹介と実装事例

BDRC Tibetan OCR:チベット語OCRツールの紹介と実装事例

はじめに チベット語写本のデジタル化は、デジタル人文学における重要な課題の一つです。貴重な仏教経典や歴史文書が世界中の図書館に保管されていますが、その多くはまだテキストデータ化されていません。手作業での文字起こしには膨大な時間とコストがかかり、専門知識を持つ研究者も限られています。 本記事では、BDRC Tibetan OCR を紹介します。このツールは、Buddhist Digital Resource Center (BDRC) によって開発されたオープンソースのチベット語OCRシステムです。 また、チベット語写本カンギュール114点 をデジタル化するプロジェクトでの実装事例も紹介します。 BDRC Tibetan OCRとは BDRC Tibetan OCR は、チベット語の画像からテキストを自動抽出する無料のオープンソースツールです。 主要な特徴 1. デスクトップアプリケーション Windows、macOS(Intel/M1,M2)で動作するGUIアプリケーションです。 インストール方法: リリースページから各OS用のZIPファイルをダウンロード 解凍して実行ファイルを起動するだけ 2. 複数の出力形式 プレーンテキスト : 抽出されたUnicodeチベット文字 PageXML : 座標情報付きXML(Transkribusと互換) Wylie : ローマ字転写形式 3. 画像補正機能 歪み補正(Dewarping) : ページの湾曲を補正 回転補正 : 自動的にページの傾きを検出・補正 行検出 : 行分割機能 4. バッチ処理対応 複数の画像ファイルを一括処理 PDFファイルからの直接OCR IIIF(International Image Interoperability Framework)マニフェストからの自動取得・処理 4つの専門OCRモデル BDRC Tibetan OCRの特徴の一つは、書体や資料の種類に応じて最適化された4つの専門モデル を提供している点です。 1. ウチェン(Uchen)モデル - 現代印刷用 用途: 印刷された経典、現代の出版物 データセット: 440万サンプルの統一ウチェンモデル 特徴: チベット語で最も標準的な書体 適用例: コンピューターフォントで印刷されたテキスト、木版印刷 ウチェンは「正書体」を意味し、チベット語で最も標準的な書体です。現代の印刷物やデジタルフォントで使用されます。 ...

Azure OpenAI GPT-4 vs Document Intelligence: 日本語縦書きOCRの比較検証

Azure OpenAI GPT-4 vs Document Intelligence: 日本語縦書きOCRの比較検証

概要 Microsoft Azureが提供する2つのOCRサービス(Azure OpenAI GPT-4 VisionとAzure Document Intelligence)を使用して、日本語の縦書き原稿用紙のOCR処理を実施し、その結果を詳細に比較検証しました。 検証対象画像 画像ソース : Canvaテンプレート(400字詰め原稿用紙) URL : https://www.canva.com/ja_jp/templates/EAFbqUoH7P8/ 画像の特徴 : 20×20の400字詰め原稿用紙 縦書きレイアウト 薄いグリッド線(マス目) タイトル欄と本文欄の区別 正解データ(Ground Truth) 原稿のタイトル 佐藤ちあき 原稿用紙に書くテキストが入ります。作文や小論文を作ったり、小説を書いたりなどにご活用ください。 このテキストを使用する場合は、日本語の全角を使うことでマスにあった文字を打つことができます。手書きで使用したい場合は、このテキストを削除し、印刷してご使用ください。 1. Azure OpenAI GPT-4.1 による認識結果 認識されたテキスト 原稿のタイトル 佐藤 ちあき 原稿用紙に書くテキストが入ります。作文や小論文を作ったり、小説を書いたりなどにご活用ください。 このテキストを使用する場合は、日本語の全角を使うことでマスにあった文字を打つことができます。手書きで使用したい場合は、このテキストを削除し、印刷してご使用ください。 評価 GPT-4.1は縦書きの原稿用紙に対して以下の特徴を示しました: ✅ タイトルと著者名の順序を正しく認識 ✅ 本文の開始部分を正確に認識 ✅ 原稿用紙のマス目に関する記述を認識 ✅ 縦書きの読み順(右から左)を完璧に理解 ✅ 文章の連続性を保持 正解データとの差異 「佐藤ちあき」→「佐藤 ちあき」(全角スペースが追加) これは画像上でスペースがあるように見えるための合理的な解釈 その他のテキストは完全に一致 精度評価: 99% 2. Azure Document Intelligence による認識結果 認識された領域の可視化 評価 Document Intelligenceは以下の特徴を示しました: ✅ 文字認識能力 - 個々の文字は正確に認識(「佐藤」「ちあき」「原稿」等) ⚠️ 文章の断片化 - マス目ごとに独立した要素として処理され、連続性が失われる ❌ 縦書き読み順の課題 - 縦書きの右から左への流れを適切に処理できない ⚠️ 後処理が必要 - 座標情報を使った再構成により、ある程度の復元は可能 ✅ 座標情報の詳細取得 - 各文字の正確な位置情報は完璧に取得 精度評価: 文字認識精度は約80%、ただし縦書きレイアウトの理解に課題あり ...

LLMによる原稿用紙OCR性能比較:縦書き日本語の認識精度検証

LLMによる原稿用紙OCR性能比較:縦書き日本語の認識精度検証

はじめに 本記事では、実際の原稿用紙画像を用いて 主要LLMモデルのOCR性能を比較検証しました。多くのOCRベンチマークが印刷文書や横書きテキストを対象とする中、日本独自の縦書き原稿用紙という特殊なフォーマット での認識精度を評価することで、各モデルの日本語文書理解能力をより実践的に検証しています。 本検証の特徴 原稿用紙という日本固有のフォーマットを使用 :マス目に収められた文字、縦書きレイアウト、特有の余白構成など、複雑な要素を含む画像での検証 実用シーンを想定 :作文、小説、論文など、実際の執筆場面で使用される原稿用紙での性能評価 最新モデルの網羅的比較 :GPT-5、GPT-4.1、Gemini 2.5 Pro、Claude Opus 4.1、Claude Sonnet 4という最新モデルを同一条件で比較 検証概要 使用画像 画像ソース : Canvaテンプレート(400字詰め原稿用紙) URL : https://www.canva.com/ja_jp/templates/EAFbqUoH7P8/ 画像の特徴 : 20×20の400字詰め原稿用紙 縦書きレイアウト 薄いグリッド線(マス目) タイトル欄と本文欄の区別 検証条件 使用プロンプト : 「OCRして」(全モデル共通) パラメータ : 各モデルのデフォルト設定 実行時期 : 2025年9月 正解テキスト 原稿のタイトル 佐藤 ちあき 原稿用紙に書くテキストが入ります。作文や小論文を作ったり、小説を書いたりなどにご活用ください。 このテキストを使用する場合は、日本語の全角を使うことでマスにあった文字を打つことができます。手書きで使用したい場合は、このテキストを削除し、印刷してご使用ください。 評価方法 本記事の精度スコアは、文字認識の正確性、レイアウト理解、文章構造の保持などを総合的に評価した主観的なスコア です。実用的な観点から、各モデルの強みと課題を分かりやすく数値化しています。 OCR結果詳細 🥇 Gemini 2.5 Pro - 精度スコア: 98/100 原稿のタイトル 佐藤ちあき 原稿用紙に書くテキストが入ります。作文や小論文を作ったり、小説を書いたりなどにご活用ください。 このテキストを使用する場合は、日本語の全角を使うことでマスにあった文字を打つことができます。手書きで使用したい場合は、このテキストを削除し、印刷してご使用ください。 評価ポイント : ✅ 文字認識: ほぼ完璧 ⚠️ 著者名のスペース欠落 ✅ 段落構成: 適切な2段落構成 ✅ レイアウト保持: 優秀 🥈 GPT-5 - 精度スコア: 97/100 原稿のタイトル 佐藤 ちあき 原稿用紙に書くテキストが入ります。作文や小論文を作ったり、小説を書いたりなどにご活用ください。このテキストを使用する場合は、日本語の全角を使うことでマスにあった文字を打つことができます。手書きで使用したい場合は、このテキストを削除し、印刷してご使用ください。 評価ポイント : ...

PDFの透明テキスト抽出における順序保持の課題と解決策

PDFの透明テキスト抽出における順序保持の課題と解決策

はじめに PDFファイルから透明テキストレイヤーを抽出する際、「テキストの順序が元のPDFと異なってしまう」という問題に直面しました。本記事では、この問題の原因と、JavaScriptとPythonそれぞれでの解決策について解説します。誤っている点もあるかもしれませんが、参考になりましたら幸いです。 PDFの透明テキストとは PDFの透明テキストレイヤーは、PDFファイル内に埋め込まれた検索可能なテキスト情報です。OCR処理されたPDFや、デジタル生成されたPDFには、この透明テキストレイヤーが含まれており、以下のような機能を実現しています: テキスト検索 コピー&ペースト スクリーンリーダーによる読み上げ 機械翻訳 問題:テキストの順序が乱れる理由 PDFの内部構造 PDFファイルは、テキストを「コンテンツストリーム」という形式で保存しています。このストリームには、テキストとその位置情報が含まれていますが、必ずしも読む順序で格納されているわけではありません。 例:PDFコンテンツストリームの概念図 [位置: x=100, y=200, テキスト="見出し"] [位置: x=300, y=400, テキスト="脚注"] [位置: x=100, y=300, テキスト="本文"] 一般的な抽出方法の問題点 多くのPDF処理ライブラリは、以下のような手順でテキストを抽出します: コンテンツストリームからテキストと位置情報を取得 座標でソート (上から下、左から右) ソート結果を出力 この「座標でソート」する処理が、テキスト順序の乱れを引き起こす主な原因です。 具体的な問題例 縦書きと横書きの混在 :日本語文書でよく見られる 複数カラムレイアウト :新聞や雑誌形式 図表の挿入 :本文の流れを分断する要素 ヘッダー・フッター :ページをまたぐ要素 解決策:言語別アプローチ JavaScript (PDF.js) での解決策 PDF.jsは、Mozillaが開発したJavaScriptベースのPDFレンダリングライブラリです。 順序を保持する実装 // PDF.jsを使用した順序保持テキスト抽出 async function extractTextWithOrder(page) { // getTextContent()はコンテンツストリームの順序を維持 const textContent = await page.getTextContent(); // itemsは元の順序を保持した配列 const orderedText = textContent.items.map(item => { return { text: item.str, x: item.transform[4], y: item.transform[5], width: item.width, height: item.height }; }); // 配列の順序をそのまま使用(座標ソートしない) return orderedText; } ポイント getTextContent()メソッドは、PDFの内部構造に忠実な順序でテキストを返す 配列のインデックスが元の順序を表現 座標による再ソートを行わない Python (PyMuPDF) での解決策 PyMuPDF(fitz)は、MuPDFライブラリのPythonバインディングです。 ...

TEI ODDファイルのカスタマイゼーション:NDL古典籍OCRの事例

TEI ODDファイルのカスタマイゼーション:NDL古典籍OCRの事例

はじめに TEI (Text Encoding Initiative) は、人文学研究におけるテキストのデジタル化と共有のための国際標準です。本記事では、NDL古典籍OCR-Liteアプリケーションの出力形式に合わせてTEI ODDファイルをカスタマイズした過程を紹介します。 ODD (One Document Does it all) は、TEIスキーマをカスタマイズするための仕組みで、必要な要素と属性だけを含む独自のスキーマを定義できます。 背景:NDL古典籍OCR-Liteアプリケーションの開発 NDL古典籍OCR-Liteの出力結果をTEI/XMLで出力するアプリケーションを作成しています。このアプリケーションは、日本の古典籍をOCR処理し、その結果を標準的なTEI形式で出力することを目的としています。 出力されるTEI XMLには以下の情報を含めることにしました: テキスト情報 : OCRで認識した文字列 レイアウト情報 : 各行の座標情報(バウンディングボックス) 画像参照 : IIIF (International Image Interoperability Framework) 対応の画像URL メタデータ : 文書タイトル、処理情報など このアプリケーションで使用するスキーマをODDで記述してみました。以下、そのカスタマイゼーション過程を紹介します。 カスタマイゼーションのアプローチ 1. 初期アプローチ:標準モジュールの利用 最初は、TEIの標準モジュールを利用してODDを作成しました: schemaSpec ident="ndl_koten_ocr" start="TEI" prefix="tei_"> moduleRef key="tei"/> moduleRef key="header" include="teiHeader fileDesc titleStmt publicationStmt sourceDesc"/> moduleRef key="core" include="p title name resp respStmt lb pb graphic"/> moduleRef key="textstructure" include="TEI text body"/> moduleRef key="transcr" include="facsimile surface zone"/> schemaSpec> include属性の重要性 moduleRef要素のinclude属性は、モジュールから特定の要素のみを選択的に含める重要な機能です: ...

NDL古典籍OCR-lite Next.js版の開発

NDL古典籍OCR-lite Next.js版の開発

概要 @yuta1984 さんが「WebAssemblyを使用したNDL古典籍OCR-liteのWeb移植版」を開発されました。 https://github.com/yuta1984/ndlkotenocr-lite-web 今回は、上記のリポジトリを参考にさせていただき、Next.js版を作成しました。 https://nkol.vercel.app/ja/ 加えて、以下の点を追加しています。 IIIFマニフェストファイルの入力フォーム TEI/XMLファイルのダウンロード機能 出力フォーマットに関するODDファイルの作成 使い方 サンプルとして、九州大学附属図書館の源氏物語を利用させていただきます。 https://catalog.lib.kyushu-u.ac.jp/image/manifest/1/820/411193.json マニフェストファイルを入力し、「読み込む」ボタンを押すと、以下のように、画像の一覧が表示されます。 なお、内部的には、@iiif/parserを利用し、v2とv3、どちらのマニフェストファイルにも対応するようにしています。 その後、処理の実行ボタンを押すと、画像ごとにOCR結果のテキストが表示されます。 実行完了後、画面下部に結果のダウンロードボタンが表示されます。 ODDファイルの作成 TEI/XMLでのエクスポートにあたり、どのようなタグや形式が想定されているのか、という質問をいただくことがありました。 そこで、このフォーマットの共有にあたり、ODD(One Document Does it all)ファイルを作成しました。 このODDファイルの作成については、以下の記事も参考にしてください。 さらに、TEIGarageのAPIを利用し、RNGファイルやHTMLファイルを作成しています。この変換については、以下の記事を参考にしてください。 不完全な部分もありますが、このような方法を採ることで、TEIのエコシステムを活用しながら、スキーマを公開・共有することができそうです。 これまでに作成したツールと今後開発予定のツール これまでの開発 NDL古典籍OCR-liteについては、これまでにいくつかのツールを開発してきました。 まず、Gradio Appを作成しました。こちらは公式に提供されている「デスクトップアプリケーション」で代替可能なものでしたが、スマホやタブレットで撮影した画像に対してOCRをかけるといった用途では有用性があると考えられます。 次に、以下の記事で紹介したように、同じくGradioを用いたウェブアプリですが、IIIFマニフェストファイルを入力とし、TEI/XMLファイルを出力とするアプリを作成しました。IIIFとTEIを接続している点で有用性はありましたが、Hugging Faceの無料枠でアプリを公開しているため、多くの人が同時に使用できる環境ではないという課題がありました。 これらの課題に対して、@yuta1984 さんが作成されたウェブ版を参考に、IIIFとTEIの接続機能を維持しながら、ユーザの端末側でOCR処理を実行する環境を今回構築しました。これにより、複数人が同時に処理を実行できるようになりました。 今後の展望 人手でOCRをかける際には、公式のデスクトップアプリケーションを使用するか、@yuta1984 さんのウェブアプリ、あるいは今回開発したNext.js版のウェブアプリを使用することで、多くのニーズに対応できると考えています。 今後の取り組みとして、API等を介して大量の画像に対して一括でOCR処理を行う場合には、複数のサーバで並列にOCR処理を実行することで効率化を図ることができます。例えば、2000枚を超える画像から構成されるIIIFマニフェストファイルを対象とする際には、並列でOCR処理を行うことが、順次実行するよりも効果的です。 このような処理を実現するため、以下の記事で紹介しているように、Azure Container Appsを使用したスケーラブルなOCR処理システムの構築を進めています。 まだ不完全な点や考慮すべき点は多いものの、サーバレスな環境でOCRを提供することで、大規模な画像に対するOCR処理の実現を目指しています。 まとめ NDL古典籍OCR-liteの活用にあたり、参考になりましたら幸いです。

Azure Container AppsでNDL古典籍OCR Liteを用いたスケーラブルOCR処理システム

Azure Container AppsでNDL古典籍OCR Liteを用いたスケーラブルOCR処理システム

⚠️ 重要な利用上の注意 本記事で紹介するシステムは、外部サーバーに負荷をかける可能性があります。利用時は十分ご注意ください。 サーバー負荷 : 並列リクエストは対象サーバーに負荷を与えます DoS攻撃のリスク : 大量の同時アクセスはDoS攻撃と誤解される可能性があります 推奨アプローチ : 事前に画像をローカルにダウンロードし、OCR処理のみを並列実行することを推奨します 利用規約の確認 : 対象サーバーの利用規約を必ず確認し、必要に応じて事前許可を取得してください 適切なレート制限 : 実運用では慎重な並列数設定(5-10並列程度)を強く推奨します 責任ある利用 : サーバー管理者や他の利用者への配慮を忘れずに 本記事は技術的な実証実験の記録です。読者の皆様には責任を持った利用をお願いします。 はじめに 本記事では、国立国会図書館(NDL)が開発したNDL古典籍OCR Liteを活用し、Azure Container AppsでスケーラブルなOCR処理システムを構築した事例を紹介します。クラウドネイティブなアーキテクチャにより、従量課金とオートスケーリングを実現したシステムの設計と実装について解説します。 システム概要 アーキテクチャ IIIF画像 → Azure Container Apps → NDL古典籍OCR → TEI XML出力 ↓ オートスケーリング (0-30レプリカ) 主要コンポーネント OCRエンジン : NDL古典籍OCR Lite(日本古典籍特化) インフラ : Azure Container Apps(サーバーレスコンテナ) API設計 : REST API(画像URL → OCR結果) 出力形式 : TEI P5準拠XML スケーリング : 需要に応じた自動スケーリング NDL古典籍OCR Liteの特徴 日本古典籍に最適化されたOCR 縦書きレイアウト対応 : 古典籍特有の縦書き文書構造 読み順序最適化 : 右から左、上から下の日本語読み順 古典文字認識 : くずし字や変体仮名への対応 軽量実装 : Docker化によりクラウドデプロイ対応 Azure Container Appsの選択理由 サーバーレスコンテナの利点 # スケーリング設定例 scale: minReplicas: 0 # アイドル時: コスト0 maxReplicas: 30 # 需要時: 自動拡張 cooldownPeriod: 300 # 5分でスケールダウン コスト最適化 従量課金 : 使用した分のみ課金 0レプリカ : アイドル時は完全にコスト0 自動スケーリング : 需要に応じたリソース調整 システム実装 サーバーサイド実装 # Flask + NDL OCR統合 from flask import Flask, request, jsonify from flask_restx import Api, Resource from simple_ocr_service import OCRService app = Flask(__name__) api = Api(app, doc='/docs/') @api.route('/api/image') class ImageOCR(Resource): def get(self): image_url = request.args.get('image_url') # NDL OCRで画像処理 result = ocr_service.process_single_image(image_url) return result 読み順序アルゴリズム def sort_japanese_reading_order(lines): """日本古典籍の読み順序ソート""" return sorted(lines, key=lambda line: ( -line["bbox"][0], # x座標降順(右→左) line["bbox"][1] # y座標昇順(上→下) )) TEI XML出力 xml version="1.0" encoding="UTF-8"?> TEI xmlns="http://www.tei-c.org/ns/1.0"> teiHeader> fileDesc> titleStmt> title>桐壺title> titleStmt> respStmt> resp>Automated Transcriptionresp> name ref="https://github.com/ndl-lab/ndlkotenocr-lite"> NDL古典籍OCR Lite name> respStmt> fileDesc> teiHeader> facsimile> surface xml:id="surface-1"> zone xml:id="zone-1-1" ulx="3391" uly="1141" lrx="3727" lry="2924" cert="0.799"/> surface> facsimile> text> body> div type="transcription"> pb n="1" facs="#surface-1"/> lb n="1.1" corresp="#zone-1-1" cert="high"/> いづれの御時にか div> body> text> TEI> 処理結果事例 小規模テスト処理(桐壺) 対象 : 東京大学所蔵「桐壺」 ページ数 : 32ページ 処理時間 : 約30秒 成功率 : 100% 並列数 : 10並列 コスト : 約$0.05 パフォーマンス特性 処理時間 = 約1秒/ページ(並列処理時) コスト効率 = $1.5〜2.0/1000ページ スケーリング = 数秒で0→20レプリカ システムの技術的特徴 1. コールドスタート対応 async def process_with_retry(image_url, max_retries=3): """コールドスタート時の自動リトライ""" for attempt in range(max_retries + 1): try: if attempt > 0: wait_time = 2 ** (attempt - 1) await asyncio.sleep(wait_time) return await ocr_request(image_url) except (HTTPError, TimeoutError) as e: if attempt == max_retries: raise e 2. 設定の外部化 # 環境変数による設定 OCR_API_URL=https://your-ocr-service.azurecontainerapps.io DEFAULT_MAX_CONCURRENT=10 DEFAULT_CONFIDENCE_THRESHOLD=0.3 DEFAULT_OUTPUT_FORMAT=xml 3. Swagger UI統合 # API仕様の自動生成 api = Api(app, version='1.0', title='NDL古典籍OCR API', description='日本古典籍専用OCR処理API', doc='/docs/' ) デプロイメント Azure Container Appsデプロイ # コンテナアプリ作成 az containerapp create \ --name ocr-service \ --resource-group rg-ocr \ --environment container-env \ --image registry.azurecr.io/ocr-app:latest \ --target-port 80 \ --ingress external \ --min-replicas 0 \ --max-replicas 30 \ --cpu 2.0 \ --memory 4Gi Docker化 FROM python:3.11-slim # NDL OCRモデル配置 COPY model/ /app/model/ COPY config/ /app/config/ # アプリケーション設定 WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . EXPOSE 80 CMD ["gunicorn", "--bind", "0.0.0.0:80", "app:app"] 運用とモニタリング パフォーマンスメトリクス レスポンス時間 : 平均2-3秒/画像 スループット : 10-15画像/秒(20レプリカ時) 成功率 : 99%以上 コスト効率 : アイドル時$0、処理時のみ課金 ログ監視 # Container Appsログ確認 az containerapp logs show \ --name ocr-service \ --resource-group rg-ocr \ --follow 今後の展望 技術的改善点 画像キャッシュ : 重複処理の削減 バッチ処理 : 効率的な大量処理 GPU対応 : OCR処理の高速化 メトリクス強化 : 詳細な性能分析 応用可能性 デジタルアーカイブ : 図書館・博物館での活用 研究支援 : 人文学研究のデジタル化 教育分野 : 古典文献の教材化 文化保存 : 貴重資料のデジタル保存 まとめ NDL古典籍OCR LiteとAzure Container Appsを組み合わせることで、コスト効率とスケーラビリティを両立した古典籍OCRシステムを構築できました。サーバーレスアーキテクチャにより、従量課金と自動スケーリングを実現し、実用的なデジタルヒューマニティーズツールとして活用可能です。 ...

DToC: Dynamic Table of Contextsを試す

DToC: Dynamic Table of Contextsを試す

概要 DToC: Dynamic Table of Contextsを試す機会がありましたので、備忘録です。 https://www.leaf-vre.org/docs/features/dtoc 機械翻訳の結果は以下です。 セマンティックマークアップの威力と書籍のナビゲーション機能を融合させ、電子読書に革新をもたらします。従来の印刷書籍で長年親しまれてきた目次とキーワード索引という概観機能が、全文検索やタグベースのインデックス機能と動的に統合されることで、新たな読書体験を実現します。 最終的に、以下のような可視化を行うことができました。 https://dtoc.leaf-vre.org/view?document=https://dtoc-demo.vercel.app/P-III-b-1189/dtoc.json 対象データ 東洋文庫が所蔵するモリソンパンフレット「Marco Polo’s adventures : The greatest traveller the world has seen.」をサンプルデータとして利用しました。 https://www.toyo-bunko.org/open/show_detail_open.php?targetid=363479 https://www.toyo-bunko.org/morisonp2015/morisonpocr2016_showimg.php?tgfn=P-III-b-1189&tgfn2=01Geo01 背景 以下のワークショップに参加し、DToCの使用方法を教えてもらいました。 https://github.com/LEAF-VRE/dh2025_workshop 以下のチュートリアルも参考になりました。 https://www.leaf-vre.org/docs/training/tutorials/dtoc-tutorial mainとなるxmlを作成する まず、mainとなるxmlを作成します。以下のURLで確認できます。 https://dtoc-demo.vercel.app/P-III-b-1189/main.xml OCR Azure AI Document Intelligenceを用いてOCRを行いました。 https://azure.microsoft.com/en-us/products/ai-services/ai-document-intelligence 校正 & タグづけ OCR結果の校正と、人名や地名のタグ付与にあたり、「Google: Gemini 2.5 Pro」を使用しました。 https://deepmind.google/models/gemini/pro/ このように機械的な処理のため、誤りなどが含まれている可能性が高いですが、DToCで使用するためのTEI/XMLファイルを用意することができました。 index用のxmlを作成する 以下を参考にしました。 https://www.leaf-vre.org/docs/training/tutorials/dtoc-tutorial#step-2-create-an-index このindex作成にも「Google: Gemini 2.5 Pro」を使用し、先に作成したmain.xmlから機械的に作成しました。結果は以下です。 https://dtoc-demo.vercel.app/P-III-b-1189/index.xml JSONファイルを作成する DToCでロードするためのJSONファイルを作成します。この部分はGUIから行うことができました。最終的な結果は以下です。 https://dtoc-demo.vercel.app/P-III-b-1189/dtoc.json まず、以下にアクセスし、GitHubアカウントでログインします。 https://dtoc.leaf-vre.org/ 次に以下にアクセスします。 https://dtoc.leaf-vre.org/view そして、チュートリアル資料などを参考に、必要な項目を入力します。 Documentsには、前のプロセスで作成したXMLファイルのURLを入力します。 Corpus Partsでは、XMLファイルのどの部分を使用するか、を指定します。Curpus Partではmain.xmlのdivタグを、Curpus Indexではindex.xmlのdivタグをXPathで指定しました。 ...

NDL古典籍OCR-Liteを用いて、IIIFマニフェストファイルからTEI/XMLファイルを作成する

NDL古典籍OCR-Liteを用いて、IIIFマニフェストファイルからTEI/XMLファイルを作成する

概要 NDL古典籍OCR-Liteを用いて、IIIFマニフェストファイルからTEI/XMLファイルを作成するGradioアプリの紹介です。 以下のURLからアクセスできます。 https://nakamura196-ndlkotenocr-lite-iiif.hf.space/ 背景 以下の記事の続きです。 これまでは、2つのアプリを使用する必要がありましたが、今回の改修により、単独のGradioアプリで変換作業が完結するようにしました。 また画像のコマ数が多いマニフェストファイルを処理する場合、進捗がわかりにくいことや、処理結果をコピーできない、といった不具合があったので、これらを修正しています。 画面の例 以下のように、「ページ 111/129 を処理中… - 79.7%」といった進捗を表示するように修正しました。 実装にあたっては、Progressを使用しています。 https://www.gradio.app/docs/gradio/progress またOCR完了後は、TEI/XMLファイルをダウンロードするためのリンクが表示されるようにしました。 まとめ Hugging Faceの無料で利用可能なCPUの制約上、OCRに時間がかかることがありますが、参考になりましたら幸いです。

その2:NDL古典籍OCR-Liteを用いたアノテーション付きIIIFマニフェストファイルとTEI/XMLファイルの作成

その2:NDL古典籍OCR-Liteを用いたアノテーション付きIIIFマニフェストファイルとTEI/XMLファイルの作成

概要 以下の記事で、NDL古典籍OCR-Liteを用いたアノテーション付きIIIFマニフェストファイルとTEI/XMLファイルの作成について紹介しました。 上記について、説明が不十分な点が多かったため、改めて使い方を紹介いたします。 補足 今回の記事執筆に合わせて、以下の改修を加えました。 プロセス1: IIIFマニフェストファイルの作成 IIIF Presentation API v3に対応しました。 プロセス2: TEI/XMLファイルの作成 プロセス1との接続を考慮して、文字列を入力とするフォームを追加 使い方 プロセス1: IIIFマニフェストファイルの作成 以下にアクセスします。 https://nakamura196-ndlkotenocr-lite-iiif.hf.space/ 今回は、IIIF Presentation API v3でマニフェストファイルが公開されている「東北大学総合知デジタルアーカイブ」を対象とします。以下の「源氏物語湖月抄 本居宣長自筆付箋及書入」を対象とします。 https://touda.tohoku.ac.jp/portal/item/10010030012489 IIIFマニフェストファイルのURLは以下です。 https://touda.tohoku.ac.jp/collection/iiif/0/metadata/10010030012489/manifest.json 以下のように入力します。注意点として、「Image Width」を-1に設定してください。これにより、最大ピクセルの画像をダウンロードするようになります。(デフォルト値である1200ピクセルではエラーとなります。) 結果、OCRテキストをアノテーションとして持つIIIFマニフェストファイルのJSON文字列が画面右側に表示されます。以下の赤字で示すコピーボタンを押して、文字列をコピーしておきます。 プロセス2: TEI/XMLファイルの作成 以下にアクセスします。 https://iiif-tei-monorepo-web.vercel.app/ コピーしたJSON文字列を「Paste Manifest JSON」というフォームに貼り付け、Convert to TEI XMLボタンを押します。 結果、TEIに変換され、XMLファイルをダウンロードできます。 Oxygen XML EditorのAuthorモードで表示した例が以下です。 まとめ 使いにくい点も多いかと思いますが、OCRとIIIF・TEIの応用にあたり、参考になりましたら幸いです。