PDFで一定の量を取り戻し、ページ上の位置を取り戻す方法
この記事では、PyMuPDF を使用して、指定された四角形内の繰り返し金額テキストを見つける方法を示します。単語オクテットの最初の 5 フィールドを解析し、候補の数を検証することで、フラグメント スプライシングにおける誤った判断を回避できます。メモリレベルの Python の例、境界処理戦略、および受け入れテーブルを提供し、OmniDoc ドキュメント翻訳ワークフローと接続するための実践的な提案を提供します。
・矩形判定は候補枠が完全に含まれる必要があります。クエリ フレームが狭すぎる場合、サイド量がゼロヒットになる可能性があります。
- この例は合成サンプルの回帰チェックのみであり、実際の請求の正確性を表すものではありません。運用環境では、アサーションの代わりに明示的なブランチを使用する必要があります。
- 候補が 1 つだけあるということは、ビジネス上の意味が決定されることを意味するものではなく、量のセマンティクスをラベルや手動レビューと組み合わせる必要があります。
How to locate duplicate amounts?一文の結論
レイアウトが決まったら、まず既知の領域を限定してからテキストを確認し、候補の数は呼び出し者の判断に任せます。正規表現を積み上げ続けるよりも解釈が容易で、サイレントミスが発生する可能性が低くなります。
| あなたの状況 | 推奨される実践方法 | 理由 |
|---|---|---|
| 同じ金額がページ上に何度も現れます | 検索する前に、ビジネス分野がある長方形のエリアに限定してください | 全文検索ではどのフィールドがビジネスか判別できません |
| クエリエリア内には複数の候補者がいます | すべての候補を返す、タグを組み合わせるか手動の曖昧さ回避 | 手続きがビジネスの意思決定を決めるべきではありません |
| クエリエリア内でヒットはありません | 原因にマークし、元のページを確認してください。ゼロを埋めないでください。 | 誤った部分、分割された量、テキストレイヤーの欠落などは、ヒットゼロにつながることがあります |
| フレームの位置がずれているように見えます | 回転、トリミング、レンダリングのスケーリング用のトランジションチェーンを明確に定義してください | 表示座標と抽出座標を混ぜると、ずれが生じる可能性があります |
同じ金額が一つの声明に
1,200.00では明細書が2回表示されます:買掛金欄と説明文の2回です。 全文検索で見つかることはできますが、どの分野がビジネス分野かを判断する助けにはなりません。
フォームのレイアウトが固定されている場合は、通常、正規表現を調整し続けるよりも、最初に既知の領域を制限してからテキストを検索する方が解釈が容易です。重要なのは、「ボックスを 1 つだけ見つける」ことではなく、ゼロ ヒットと複数ヒットの両方を明確な結果として扱い、プログラムに不正な選択をさせないことです。
テキストだけでなく、単語の位置を残してください
PyMuPDF's `page.get_text("words")` returns a word record with position, the common field is (x0, y0, x1, y1, text, block_no, line_no, word_no).次の例では、最初の 5 つのフィールドのみを取得し、最後の 3 つの数値は、当面は地域フィルタリングに関与しません。
ここでの「単語」は抽出者によって与えられた断片であり、言語的な意味での単語と必ずしも等しいわけではなく、量が常に完全な断片であることも保証されません。 1,200.00 は逆アセンブルされているか、隣接するタグがある可能性があります。この記事では、完全な断片の正確な一致のみを扱います。私は、審査の条件を満たさない記録を一見合法的な量に静かにつなぎ合わせるよりも、むしろ引き渡したいと考えています。
同じ金額の2つの作文ページで確認してください
メモリ内に新しい PDF ページを作成し、垂直座標 120 と 420 の近くに同じ量をそれぞれ配置します。 The query area only covers the amount above.
テキストの挿入ポイントは、テキスト ボックスの左上隅ではなく、ベースラインの位置です。実際のボックスの高さと幅はフォントとフォント サイズの影響を受けるため、座標を固定値にハードコードすることはできません。
正しい出力は以下の2つの条件を満たす必要があります。
- クエリ領域には候補が 1 つだけあり、候補四角形が完全に領域に含まれています。
- クエリ範囲をページ全体に拡張した後、2 つの候補が取得されるため、曖昧性分岐に入る必要があります。
最後に、ページにない文字列のヒットがないかどうかを確認します。これは、単にルックアップの成功を示すというよりも、実際のインターフェイスで必要なコントラクトに近いものです。
実行可能なコード: 候補の数を呼び出し元に渡します
依存関係は pymupdf です。テスト環境でバージョンをインストールしてロックしてください。次のコードは、ネットワークにアクセスしたり、ファイルを書き込んだり、元の顧客ドキュメントを変更したりしません。 It constructs only a demonstration PDF.
import pymupdf
def locate(page, target, query):
query = pymupdf.Rect(query)
candidates = []
for word in page.get_text("words"):
x0, y0, x1, y1, text = word[:5]
box = pymupdf.Rect(x0, y0, x1, y1)
if text == target and query.contains(box):
candidates.append(tuple(box))
return candidates
def decide(candidates):
if len(candidates) == 0:
return "missing"
if len(candidates) > 1:
return "ambiguous"
return "unique"
with pymupdf.open() as doc:
page = doc.new_page(width=595, height=842)
page.insert_text((80, 120), "1,200.00", fontsize=11)
page.insert_text((80, 420), "1,200.00", fontsize=11)
query = pymupdf.Rect(72, 100, 300, 150)
local = locate(page, "1,200.00", query)
assert decide(local) == "unique"
assert query.contains(pymupdf.Rect(local[0]))
assert decide(locate(page, "1,200.00", page.rect)) == "ambiguous"
assert decide(locate(page, "999.99", query)) == "missing"
print("unique / ambiguous / missing cases passed")
contains では、領域の端に触れるだけではなく、完全に含める必要があります。クエリ ボックスが狭すぎると、サイド金額がゼロヒットになる可能性があります。これは、クエリ ボックスをページ全体に自動的に広げる理由にはなりません。範囲を調整する方法を決定する前に、領域を測定するときに使用される座標系を確認する必要があります。
ビジネスで中心点が入ることを許可する場合は、追加のルールを作成し、境界の重複について追加のテストを行う必要があります。同じ関数内の判定の意味を密かに変更しないでください。
最適化モードではアサーションが削除される可能性があるため、運用ロジックは例外をインターセプトするために assert だけに依存すべきではありません。この例のアサーションは回帰チェックに使用されます。実際にタスクキューにアクセスする場合は、クリアな条件分岐やビジネスステートを使用する必要があります。
三つの結果、三つの対処法
クエリ結果は通常 3 つのカテゴリに分類され、それぞれに異なる処理アクションが必要になります。
- ヒットは 1 つだけ: 領域内に完全に一致するフラグメントは 1 つだけあり、ページ番号、元のテキスト、四角形、およびルールのバージョンが保存されます。
- ゼロヒット: 領域が間違っているか、量が分割されているか、テキストレイヤーが欠落している可能性があります。原因候補にマークを付け、元のページを確認し、ゼロを追加しないでください。
- 複数のヒット: 同じ領域に重複した金額があるか、テンプレートが変更されている場合は、すべての候補を返し、ラベルを結合するか、手動で曖昧さを解消します。
他の 2 つの状況も個別に処理する必要があります。
- 枠はあるが値が間違っている:テキストレイヤー自体が間違っているか、マッチング対象が間違っている可能性があります。元のページに戻って、座標が値を承認していないことを確認してください。
- フレームの見た目のオフセット: 表示座標と抽出座標が混在する可能性があり、回転、トリミング、レンダリング スケーリングの変換チェーンが明確である必要があります。
📊 コアの比較
| クエリ方法 | 判断基準 | 注意が必要です |
|---|---|---|
| 完全包含(使用例) | 候補の四角形が完全にクエリ領域内に収まります | クエリ ボックスが狭すぎる場合、その辺の金額のヒットがゼロになる可能性があります。 |
| 中心点が落ちる(別のルールを書く必要がある) | 候補中心点は領域内にあります | 境界の重複には個別のテストが必要 |
| 全ページクエリ | すべての候補者を検索 | ほとんどの結果は曖昧で、ラベル付けや手動でのさらなる判断が必要です |
これは万能量抽出器ではありません
このコードは通貨や数千の区切り文字、十進法の解析を行わず、「当座繰り返し」や「前期残高」といった意味論も認めていません。 候補者が一人だけだからといって、そのビジネスが正しい意味であるとは限りません。
スキャンしたコピーは、まずテキストと場所が明かっている必要があります。 テキストレイヤーがあるが内容が誤っているページは、コピー可能だからといって許可できません。
この記事は回転していない作文ページを使用しています。 実際のページが回転する際は、まずクエリボックスが表示画面から来るのか座標抽出しているのかを指定し、必要な場合にのみ変換してください。出典に関係なく行列で掛け算しないでください。
ソースページを保存する際は、0から0のインデックスと人物向けページ番号を区別し、隣接ページを確認する際に証拠が存在しないと誤解しないようにしましょう。
🎯 どの方法があなたに合いますか?
固定レイアウトフォームからデータを抽出する必要がある場合
まず、ビジネスフィールドの場所を制限し、その金額を調べてページ番号、長方形、ルールバージョンを保存します。
複数の候補者に出会ったら
最初の選択肢を直接選ばず、すべての候補者を返却し、タグや手動判断でビジネスフィールドを決めましょう。
ページがよくゼロヒットになるなら
まず、面積座標、量、テキスト層が存在するかを確認し、その後スコープを調整するか他の抽出ルートに切り替えるかを決めます。
もし文書翻訳をやりたいなら
量、日付、数量などの重要な詳細が手動審査に含まれ、技術検査と手動審査の明確な分業が行われます。
重要な数字は翻訳審査に任せてください
文書翻訳は文の流暢さだけでなく、量、日付、数量といった重要な項目も考慮すべきです。OmniDoc(製品エントリー)は複数の文書翻訳ポータルを提供しており、公式ウェブサイトで紹介されているバイリンガル比較はレビューの入り口として機能します。 コーディネートポジショニングスクリプトは、元の証拠を保存し、問題箇所の特定に役立ちます。
まずはアップロード許可を得た脱感作サンプルを使って評価することをお勧めします。 平行移動が長くなるにつれて、内容の位置が合理的に変化する可能性があり、「新旧座標がまったく同じである」というのは正しい翻訳の厳密条件とは考えるべきではありません。
より価値のあるチェックは、金額が保持されているか、通貨が明確に定義されているか、対応するラベルが依然として同じビジネスの意味を示しているかなどです。
❓ よくある質問(FAQ)
1. なぜ最初の一服を受け入れないのですか?
全文検索では金額が表示される場所しか分からず、どの部分がビジネスフィールドかは特定できません。 最初の一撃を直接受けるのは正しいように見えるかもしれませんが、出典が間違っている可能性もあります。
2. クエリボックスは端に触れるだけで、完全な包含が必要なのはなぜですか?
この例では、不完全セグメントを有効なヒットとして扱わないために、完全に含まれる判定手法を用いています。 クエリボックスが狭すぎてヒットがゼロの場合は、自動的にページ全体を広げるのではなく、まず座標系と範囲を確認してください。
3. クエリ結果がゼロになったらどうすればいいですか?
候補原因にマークし、元のページを確認してください。ゼロを追加しないでください。 誤ったリージョン、分割された量、テキストレイヤーの欠落はすべてヒットゼロにつながることがあります。
4. このコードは実際の紙幣に直接使えますか?
直接使うことはできません。 この例は通貨、千単位の区切り、ビジネスの意味論を扱っておらず、この記事の合成サンプルは実際の紙幣の正確性テストを表していません。
📝 概要
量を決定する際は、まず範囲を定義し、その後、候補者の全数を判断に委ねます。ゼロヒットも複数ヒットも明確なハンドリングアクションが必要です。 まず、アンキシミングサンプルを使ってルールを検証し、その後徐々に実際の文書を統合します。


