PDF417 バーコードの生成は、Python の 4 行で行えます。電話の写真、200 DPI のスキャン、または誰かのポケットで一日過ごした搭乗券からそれを読み取ることが、本格的な作業の開始点であり、ほとんどの PDF417 統合が実際に失敗する場所です。この記事では、ソース画像が不完全な場合に Python で PDF417 バーコードを読み取る方法を学びます。生成側をお探しの場合は、以前の Python を使用した PDF417 バーコードの生成 に関するウォークスルーで、基本的およびカスタムの PDF417 シンボルの作成(行と列の制御を含む)について説明しています。また、Python バーコードリーダー ガイド では、さまざまなシンボルに対応した汎用スキャンについて解説しています。以下では、PDF417 認識に関して、より狭く深く掘り下げます。
以下のすべてのスニペットは、Linux 上で Python 3.12 を使用し、Aspose.BarCode for Python via .NET 26.7 に対して実行されました。タイミングと読み取り/ミス結果は測定されたものであり、推定ではありません。また、これらを生成したスクリプトは最後に掲載されているので、独自の画像で再実行できます。
実際にPDF417認識を壊すもの
PDF417 はスタック型シンボリティです。コードワードの行で構成され、各コードワードは 4 本のバーと 4 本のスペースで構成され、17 モジュールにまたがります。この構造は Reed‑Solomon エラー訂正を備えているため、角が破れたりコーヒーのシミがついたりしても通常は復元可能です。復元できないのは、モジュールグリッド自体が失われた場合です。
グリッドを破壊するものは3つあり、実運用で現れる頻度の大まかな順序は次の通りです:
- 有効モジュール幅が2ピクセル未満になる。これは支配的な失敗です。ダウンスケーリング、カメラ距離、そしてブラーによって起こります。ブラーは1つのモジュールのインクを隣接モジュールに広げます。モジュールあたり3ピクセルで生成されたバーコードをブラー処理すると、実質的にはモジュールあたり1ピクセルのバーコードになります。
- パースペクティブと回転。角度を付けて撮影されたバーコードは、行がもはや平行な走査線ではなくなります。検出器はこれに対応しますが、最速のプリセットがスキップする検出パスが必要になります。
- コントラスト崩壊。色あせた熱感紙、グレア下で撮影されたスクリーン、または明るさが固定されたスキャン。以下の数値が示すように、見たほど致命的ではありません。
実際の結果として、認識設定は回復メカニズムであり、キャプチャ品質の代替手段ではありません。画像品質の中間帯域を取り戻すことができますが、下位帯域は取り戻せません。
Python PDF417 リーダーのセットアップ
PyPI からライブラリをインストールします:
pip install aspose-barcode-for-python-via-net
認識 API は aspose.barcode.barcoderecognition にあります。この記事で重要な 2 つのクラスは、検出とデコードを実行する BarCodeReader と、リーダーの試行の厳しさを制御する QualitySettings です。
PythonでPDF417バーコードを読み取る
最小限の実装は2つの引数とループです:
from aspose.barcode import barcoderecognition as rec
reader = rec.BarCodeReader("clean.png", rec.DecodeType.PDF417)
for result in reader.read_bar_codes():
print("Code text:", result.code_text)
print("Symbology:", result.code_type_name)
print("Reading quality:", result.reading_quality)

PythonでPDF417バーコードを読み取る。
クリーンな画像の出力:
Code text: PASSENGER|KHAN/M|SEAT14C|LHE-DXB
Symbology: Pdf417
Reading quality: 100.0
実際には第2引数は省略できません。 省略すると BarCodeReader は DecodeType.ALL_SUPPORTED_TYPES にフォールバックし、画像内のすべての候補領域に対して60以上のシンボルを検出します。PDF417 のみのパイプラインではこれは全く無駄であり、PDF417 の行構造内で線形シンボルの誤検出が発生する可能性があります。タイプ名を指定してください。
入力がディスク上のファイルではなくアップロードからのバイトとして届く場合は、ストリームを渡し、タイムアウトを設定して、病的な画像がワーカーを停止させないようにします。
import io
from aspose.barcode import barcoderecognition as rec
def decode_pdf417(image_bytes, timeout_ms=2000):
reader = rec.BarCodeReader(io.BytesIO(image_bytes), rec.DecodeType.PDF417)
reader.timeout = timeout_ms
return [r.code_text for r in reader.read_bar_codes()]
PythonでPDF417認識品質設定を比較
QualitySettings は、知っておくべき4つのプリセットを提供します。リーダーに1つを割り当てるのは1行で済みます:
reader = rec.BarCodeReader("scan.png", rec.DecodeType.PDF417)
reader.quality_settings = rec.QualitySettings.high_quality
| プリセット | 用途 | コスト |
|---|---|---|
high_performance | クリーンで機械生成された画像 | 最速、リカバリーパスをスキップ |
normal_quality | デフォルト。通常のスキャンとエクスポート | バランスが取れた |
high_quality | カメラ撮影、劣化したスキャン | 中程度 |
max_quality | すでに失敗した画像に対する再試行パス | 圧倒的に遅い |
実際にそれらの説明が何を意味するかを確認するため、モジュールあたり 3 ピクセルの PDF417 を生成し、Pillow で 6 通りに劣化させ、すべてのプリセットをすべてのバリアントで実行しました。3 回の実行の中央値:
| ソース画像 | high_performance | normal_quality | high_quality | max_quality |
|---|---|---|---|---|
| クリーン | 読み取り, 35 ms | 読み取り, 50 ms | 読み取り, 45 ms | 読み取り, 106 ms |
| 12°回転、ぼかし | ミス, 15 ms | 読み取り, 74 ms | 読み取り, 67 ms | 読み取り, 157 ms |
| ガウスノイズ (σ 40) | 読み取り, 31 ms | 読み取り, 49 ms | 読み取り, 52 ms | 読み取り, 123 ms |
| 解像度半分 | 読み取り, 22 ms | 読み取り, 37 ms | 読み取り, 35 ms | 読み取り, 86 ms |
| 低コントラスト | 読み取り, 24 ms | 読み取り, 38 ms | 読み取り, 43 ms | 読み取り, 112 ms |
| 強いぼかし (σ 2.2) | ミス, 5 ms | ミス, 25 ms | ミス, 85 ms | ミス, 180 ms |
この表から得られる4つのことは、個々の数値よりも有用です。
ノイズと低コントラストは、人々が考えているほど問題ではありません。 Reed‑Solomon と検出器は、重いガウスノイズと最速プリセットでの 82% のコントラスト低下を吸収しました。これらの調整はやめてください。
回転とぼかしは、プリセットを分けるケースです。 これはハンドヘルドの電話撮影の正確なプロファイルでもあり、そのため
high_performanceはモバイル由来のパイプラインのデフォルトとして間違っています。max_qualityはnormal_qualityの 3 倍の時間がかかり、追加の読み取りはありません。 それはデフォルトではなく、二度目の試みのパスとして位置づけられます。モジュールグリッドが失われると、どのプリセットもそれを復元できません。 重いぼかしの行は全体的に失敗であり、
max_qualityはそれを証明するために 180 ms を費やしました。これはキャプチャの問題であり、キャプチャの修正策は次のとおりです:ピクセル数を増やす、フォーカスを改善する、生成時にx_dimensionを大きくする。
PythonでぼやけたPDF417バーコードを読み取るためにQualitySettingsを調整
プリセットは個々のプロパティのバンドルであり、プリセットから開始してそのうちの1つをオーバーライドすることができます。これが、既知で再現可能な欠陥に対して実際の効果が得られる場所です。
上の回転してぼやけた画像は良いデモンストレーションです。high_performance の下ではそれが欠けています。同じプリセットの上にデコンボリューションを有効にすると、次のように表示されます:
from aspose.barcode import barcoderecognition as rec
reader = rec.BarCodeReader("rotated.png", rec.DecodeType.PDF417)
quality = rec.QualitySettings.high_performance
quality.deconvolution = rec.DeconvolutionMode.NORMAL
reader.quality_settings = quality
for result in reader.read_bar_codes():
print(result.code_text)

Python でぼやけた PDF417 バーコードを読み取るために QualitySettings を調整する。
測定結果: オーバーライドなしでは12 msでミス、オーバーライドありでは54 msで読み取りました。1つのプロパティが結果を逆転させましたが、結果は max_quality プリセットよりも速く返ってきました。
知っておくべきプロパティ:
| プロパティ | 値 | 使用する場面 |
|---|---|---|
deconvolution | FAST, NORMAL, SLOW | モーションブラーやピントが合っていない撮影 |
barcode_quality | HIGH, NORMAL, LOW | 印刷欠陥、熱による退色、FAXのアーティファクト |
x_dimension | AUTO, SMALL, NORMAL, LARGE, USE_MINIMAL_X_DIMENSION | 密集したバーコード、または既知の固定モジュールサイズ |
minimal_x_dimension | float | USE_MINIMAL_X_DIMENSION と組み合わせて下限を設定 |
complex_background | AUTO, DISABLED, ENABLED | アートワークやパターン化されたフォーム上に印刷されたバーコード |
inverse_image | AUTO, DISABLED, ENABLED | 白黒反転のバーコード、スクリーンキャプチャ |
allow_incorrect_barcodes | bool | 診断目的のみ、実運用では使用しない |
最後のものは警告が必要です。allow_incorrect_barcodes はチェックサム検証に失敗したシンボルを返します。これは「検出器はここで何かを見つけたのか?」という質問に答えるためのデバッグ支援です。これを出荷すると、欠如しているのではなく間違ったデコード文字列が出荷されることになり、単なる見逃しよりもはるかに悪い結果になります。
本番環境でうまく機能する階層化戦略: まず normal_quality を試し、失敗した場合は high_quality と deconvolution = SLOW を使って一度だけ再試行します。高コストのパスは必要な画像に対してのみ支払います。
PythonでPDF417デコード結果を検証する
デコードされた文字列が自動的に正しい文字列になるわけではありません。BarCodeResult の 3 つのフィールドが役立ちます:
for result in reader.read_bar_codes():
print("Text:", result.code_text)
print("Reading quality:", result.reading_quality)
print("Confidence:", result.confidence)
print("Region:", [(p.x, p.y) for p in result.region.points])
Text: PASSENGER|KHAN/M|SEAT14C|LHE-DXB
Reading quality: 100.0
Confidence: 100
Region: [(7, 6), (261, 7), (261, 276), (7, 277)]
画像に分割されたマクロ PDF417 を再構成する
Macro PDF417 は、1 つの論理メッセージを複数のシンボルに分割します。これにより、出荷明細書や複数ページの文書に表示されます。セグメント メタデータは往復で保持されるため、再構築は決定的です:
from aspose.barcode import barcoderecognition as rec
segments = {}
total = None
for path in ["page1.png", "page2.png"]:
reader = rec.BarCodeReader(path, rec.DecodeType.MACRO_PDF417)
for result in reader.read_bar_codes():
meta = result.extended.pdf417
segments[meta.macro_pdf_417_segment_id] = result.code_text
total = meta.macro_pdf_417_segments_count
print(f"{path}: segment {meta.macro_pdf_417_segment_id + 1} of {total}, "
f"file id {meta.macro_pdf_417_file_id}")
if total and len(segments) == total:
payload = "".join(segments[i] for i in sorted(segments))
print("Reassembled:", payload)
else:
print("Incomplete: missing segments")

ページ 1.

ページ 2.
Output:
Data\pdf417\page1.png: segment 1 of 2, file id 42
Data\pdf417\page2.png: segment 2 of 2, file id 42
Reassembled: SEGMENT-A-DATASEGMENT-B-DATA
macro_pdf_417_file_idは生成側と認識側の両方で文字列ではなく整数であることに注意してください。エンコーダがそれらを設定した場合、同じオブジェクトはmacro_pdf_417_file_name、macro_pdf_417_sender、macro_pdf_417_addressee、macro_pdf_417_time_stamp、およびmacro_pdf_417_checksumも公開します。
自分の画像で PDF417 認識をベンチマーク
プリセットの選択は推測ではなく測定であるべきです。実際のパイプラインからの代表的なキャプチャが入ったフォルダーを指定すると、どのプリセットがコストに見合うかを教えてくれます:
import time, statistics, pathlib
from aspose.barcode import barcoderecognition as rec
PRESETS = ["high_performance", "normal_quality", "high_quality", "max_quality"]
def probe(path, preset, reps=3):
times, found = [], False
for _ in range(reps):
reader = rec.BarCodeReader(str(path), rec.DecodeType.PDF417)
reader.quality_settings = getattr(rec.QualitySettings, preset)
start = time.perf_counter()
results = list(reader.read_bar_codes())
times.append((time.perf_counter() - start) * 1000)
found = found or bool(results)
return found, statistics.median(times)
for image in sorted(pathlib.Path("samples").glob("*.png")):
row = []
for preset in PRESETS:
found, ms = probe(image, preset)
row.append(f"{preset}: {'read' if found else 'miss'} {ms:.0f}ms")
print(f"{image.name:28} " + " | ".join(row))
clean.png high_performance: read 32ms | normal_quality: read 48ms | high_quality: read 51ms | max_quality: read 130ms
faded_thermal.png high_performance: read 26ms | normal_quality: read 43ms | high_quality: read 46ms | max_quality: read 144ms
half_resolution.png high_performance: read 27ms | normal_quality: read 41ms | high_quality: read 41ms | max_quality: read 89ms
heavy_blur.png high_performance: miss 7ms | normal_quality: miss 24ms | high_quality: miss 69ms | max_quality: miss 180ms
noisy_scan.png high_performance: read 26ms | normal_quality: read 42ms | high_quality: read 47ms | max_quality: read 116ms
Page1.png high_performance: read 21ms | normal_quality: read 34ms | high_quality: read 38ms | max_quality: read 90ms
Page2.png high_performance: read 21ms | normal_quality: read 33ms | high_quality: read 38ms | max_quality: read 89ms
rotated.png high_performance: miss 16ms | normal_quality: read 43ms | high_quality: read 57ms | max_quality: read 147ms
実際のキャプチャを50件に対して一度実行すれば、プリセットの議論は終了します。
実用的なガイドライン
DecodeTypeをPDF417に制限 ただし、混在したシンボリズムが本当に必要な場合を除きます。バリアントが分かっている場合はMACRO_PDF417、COMPACT_PDF417、またはMICRO_PDF417を使用してください。- デコード前にトリミング。バーコードが全体の 5% しか占めていない A4 スキャン全体を渡すと、検出時間が無駄になり、誤検出が増えます。
- 中間ファイルはロスレスで保持。PNG または TIFF を使用してください。低品質設定の JPEG のリングは、デコーダが必要とするバーのエッジを直接攻撃します。
- リトライを段階的に設定 して、最も遅いプリセットをデフォルトにしないようにします。
- 認識の調整前に生成を修正。エンコーダを制御できる場合、
x_dimensionを上げてもコストはかからず、どのリーダー設定よりも多くのミスを解消します。 PDF417 generation article でこれらのパラメータを解説しています。 timeoutを設定 ユーザー提供画像に触れるすべてのリーダーで。
無料ライセンスを取得する
評価ビルドでは、Code 39 以外のシンボロジーに対してデコードされたテキストに透かしが入ります。これにより、実施するラウンドトリップテストが妨げられます。評価版では、無料の一時ライセンスでこれを解除できます。
無料の追加リソース
結論
Reading PDF417 バーコードを Python で読み取ることは、クリーンな画像では2行の操作で済み、実際の画像ではエンジニアリングの課題です。上記の測定結果はシンプルな姿勢を示しています:DecodeType を指定し、デフォルトは normal_quality、high_quality とデコンボリューションを有効にして一度リトライし、結果を使用する前にすべて検証します。高コストのプリセットはリトライパス用に保存し、すべての設定で画像のクラス全体が失敗する場合は、リーダーではなくキャプチャを修正してください。質問は無料サポートフォーラムで受け付けています。
よくある質問
同じ PDF417 バーコードがある画像では読み取れ、別の画像では失敗するのはなぜですか?
認識は、キャプチャ後に各モジュールが占めるピクセル数に依存します。ぼやけ、縮小、JPEG 圧縮はすべて実効モジュール幅を縮小させ、モジュールが約 2 ピクセル未満になると、どのプリセットでも復元できなくなります。PDF417 に使用すべき認識プリセットはどれですか?
デフォルトのnormal_qualityから開始します。カメラ撮影やスキャンの場合はhigh_qualityに切り替え、読み取り速度が数倍遅くなるものの、効果が大きくないmax_qualityは再試行時にのみ使用してください。DecodeType を PDF417 に限定すると実際に読み取りが速くなりますか?
はい。デフォルトはDecodeType.ALL_SUPPORTED_TYPESで、サポートされているすべてのシンボロジーに対して検出器が実行されます。PDF417 を明示的に指定することでその処理が省かれ、他のシンボロジーによる誤検出の可能性もなくなります。Aspose.BarCode は複数の画像に分割された Macro PDF417 メッセージを読み取れますか?
はい。各セグメントをDecodeType.MACRO_PDF417で読み取り、拡張結果のmacro_pdf_417_file_id、macro_pdf_417_segment_id、macro_pdf_417_segments_countを使用してペイロードを順番に再構成します。デコード結果が信頼できるかどうかはどう判断すればよいですか?
BarCodeResultのreading_qualityとconfidenceを確認し、regionの四角形でバーコードが画像内の期待位置に検出されたことを確認します。運転免許証や搭乗券の写真から PDF417 を読み取れますか?
可能です。ただし、撮影がフォーカスされており、バーコードが切り取られていないことが前提です。読み取り前にバーコード領域を切り抜き、途中のファイルは JPEG より PNG を使用することを推奨します。
