Створення штрих‑коду PDF417 займає всього чотири рядки коду на Python. Читання його з фотографії телефону, сканування 200 DPI або посадкового талону, який провів день у чиїйсь кишені, — це те, де починається справжня робота, і саме тут більшість інтеграцій PDF417 зазнають невдачі. У цій статті ви дізнаєтеся, як зчитувати штрих‑коди PDF417 у Python, коли вихідне зображення є недосконалим. Якщо вас цікавить саме створення, раніше наведений посібник щодо генерації штрих‑кодів PDF417 за допомогою Python охоплює створення базових та кастомних символів PDF417, включаючи керування рядками та стовпцями, а посібник з читання штрих‑кодів у Python розглядає універсальне сканування різних символьних систем. Далі йде вузьке і глибоке занурення у розпізнавання PDF417.
Кожен фрагмент нижче був запущений проти Aspose.BarCode for Python via .NET 26.7 на Linux з Python 3.12. Час виконання та результати зчитування/пропуску виміряні, а не оцінені, і скрипт, який їх створив, знаходиться в кінці, щоб ви могли повторно запустити його на своїх зображеннях.
Що насправді порушує розпізнавання PDF417
PDF417 — це складена символьна система: ряди кодових слів, кожне кодове слово складається з чотирьох смуг і чотирьох пробілів, що охоплюють 17 модулів. Така структура містить корекцію помилок Рід‑Соломона, тому порвана кутка або пляма від кави зазвичай можуть бути відновлені. Те, що не підлягає відновленню, — це втрата самої сітки модулів.
Три речі знищують сітку, у приблизному порядку, як часто вони з’являються в продакшені:
- Ефективна ширина модуля, що падає нижче двох пікселів. Це домінуюча помилка. Вона виникає через зменшення масштабу, через відстань камери та через розмиття, яке розповсюджує чорнило одного модуля на його сусідів. Штрих‑код, згенерований при трьох пікселях на модуль і потім розмитий, функціонально є штрих‑кодом при одному пікселі на модуль.
- Перспектива та обертання. Штрих‑код, сфотографований під кутом, має рядки, які більше не паралельні скануючим лініям. Детектор справляється з цим, але це вимагає проходу детекції, який пропускає найшвидший пресет.
- Колапс контрасту. Термопапір, який потемнів, екран, сфотографований під відблиском, або сканування з зафіксованою яскравістю. Менш фатально, ніж здається, як показують наведені нижче цифри.
Практичний наслідок полягає в тому, що налаштування розпізнавання є механізмом відновлення, а не заміною якості захоплення. Вони відновлюють середню смугу якості зображення. Вони не відновлюють нижню.
Налаштування читача PDF417 на Python
Встановіть бібліотеку з PyPI:
pip install aspose-barcode-for-python-via-net
API розпізнавання знаходиться в aspose.barcode.barcoderecognition. Два класи мають значення для цієї статті: BarCodeReader, який здійснює виявлення та декодування, і QualitySettings, який контролює, наскільки наполегливо працює читач.
Читання штрих‑коду PDF417 у Python
Мінімально життєздатне читання — це два аргументи та цикл:
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)

Зчитування штрих‑коду PDF417 у Python.
Вивід на чистому зображенні:
Code text: PASSENGER|KHAN/M|SEAT14C|LHE-DXB
Symbology: Pdf417
Reading quality: 100.0
Другий аргумент на практиці не є необов’язковим. Якщо його опустити, BarCodeReader повернеться до DecodeType.ALL_SUPPORTED_TYPES, що виконує виявлення більш ніж шістдесяти симболій у кожному кандидатному регіоні зображення. У конвеєрі, що працює лише з 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()]
Порівняння налаштувань якості розпізнавання PDF417 у Python
QualitySettings постачається з чотирма пресетами, про які варто знати. Призначення одного з них читачу — це один рядок:
reader = rec.BarCodeReader("scan.png", rec.DecodeType.PDF417)
reader.quality_settings = rec.QualitySettings.high_quality
| Пресет | Призначено для | Вартість |
|---|---|---|
high_performance | Чисті, створені машиною зображення | Найшвидший, пропускає проходи відновлення |
normal_quality | За замовчуванням. Регулярні сканування та експорти | Збалансовано |
high_quality | Знімки з камери, погіршені сканування | Помірно |
max_quality | Повторний прохід для зображень, які вже не вдалося обробити | Найповільніший з великою різницею |
Щоб з’ясувати, що означають ці описи на практиці, я згенерував PDF417 з трьома пікселями на модуль, погіршив його шістьма способами за допомогою Pillow і запустив кожен пресет проти кожного варіанту. Медіана трьох запусків:
| Вихідне зображення | high_performance | normal_quality | high_quality | max_quality |
|---|---|---|---|---|
| Чисте | прочитано, 35 мс | прочитано, 50 мс | прочитано, 45 мс | прочитано, 106 мс |
| Повернено на 12°, розмито | пропуск, 15 мс | прочитано, 74 мс | прочитано, 67 мс | прочитано, 157 мс |
| Гаусове шум (σ 40) | прочитано, 31 мс | прочитано, 49 мс | прочитано, 52 мс | прочитано, 123 мс |
| Половина роздільної здатності | прочитано, 22 мс | прочитано, 37 мс | прочитано, 35 мс | прочитано, 86 мс |
| Низький контраст | прочитано, 24 мс | прочитано, 38 мс | прочитано, 43 мс | прочитано, 112 мс |
| Сильне розмиття (σ 2.2) | пропуск, 5 мс | пропуск, 25 мс | пропуск, 85 мс | пропуск, 180 мс |
З цієї таблиці випливають чотири речі, і вони корисніші, ніж окремі числа:
- Шум і низька контрастність не є тією проблемою, яку люди вважають. Reed‑Solomon плюс детектор поглинули сильний гаусівський шум і зниження контрастності на 82 % у найшвидшому пресеті. Припиніть налаштовувати це.
- Поворот плюс розмиття — це випадок, який розділяє пресети. Це також точний профіль зйомки зручним телефоном, через що
high_performanceє неправильним значенням за замовчуванням для будь‑якого конвеєра, що походить з мобільного пристрою. max_qualityвимагає втричі більше часу, ніжnormal_quality, і не дає додаткових результатів. Він заслуговує на роль другого варіанту, а не за замовчуванням.- Як тільки сітка модуля зникає, жоден пресет її не відновлює. Рядок з сильним розмиттям — це провал у всіх випадках, і
max_qualityвитратив 180 мс, доводячи це. Це проблема захоплення, яку можна виправити: більше пікселів, краща фокусування, більшийx_dimensionпід час генерації.
Налаштуйте QualitySettings для зчитування розмитих PDF417 штрих-кодів у Python
Пресет — це набір окремих властивостей, і ви можете почати з пресету та перевизначити одну з них. Саме тут знаходяться реальні переваги для відомого, повторюваного дефекту.
Повернуте‑і‑розмите зображення вище є хорошою демонстрацією. У розділі 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)

Налаштуйте QualitySettings для читання розмитих штрих-кодів PDF417 у Python.
Виміряно: пропуск за 12 мс без перевизначення, читання за 54 мс з ним. Одна властивість змінила результат, і все ж результат був швидшим, ніж передвстановлення max_quality.
Властивості, які варто знати:
| Property | Values | Коли його використовувати |
|---|---|---|
deconvolution | FAST, NORMAL, SLOW | Розмиття руху та знімки з розфокусуванням |
barcode_quality | HIGH, NORMAL, LOW | Дефекти друку, термічне згасання, артефакти факсу |
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. Ви сплачуєте за дорогий шлях лише для зображень, які його потребують.
Перевірка результатів декодування PDF417 у Python
Декодований рядок не обов’язково є правильним рядком. Три поля в BarCodeResult допомагають:
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 розбиває одне логічне повідомлення на кілька символів, що відображається у транспортних накладних та багатосторінкових документах. Метадані сегмента переживають круговий прохід, тому повторна збірка детермінована:
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
Запустіть його один раз проти п’ятидесяти реальних захоплень, і попередня дискусія закінчиться.
Практичні рекомендації
- Обмежте
DecodeTypeдоPDF417, якщо ви не очікуєте змішаних символьних наборів. ВикористовуйтеMACRO_PDF417,COMPACT_PDF417абоMICRO_PDF417, коли знаєте варіант. - Обрізайте перед декодуванням. Передача повного сканування A4, коли штрих‑код займає лише 5 % площі, витрачає час на виявлення і додає хибнопозитивну поверхню.
- Зберігайте проміжні файли без втрат. PNG або TIFF. JPEG з низькою якістю створює артефакти, які саме уражають краї штрих‑коду, необхідні декодеру.
- Розподіляйте спроби по рівнях замість використання найповільнішого пресету за замовчуванням.
- Виправте генерацію перед налаштуванням розпізнавання. Якщо ви контролюєте енкодер, збільшення
x_dimensionнічого не коштує і вирішує більше пропусків, ніж будь‑яке налаштування читача. У статті про генерацію PDF417 розглядаються ці параметри. - Встановіть
timeoutдля будь‑якого читача, який працює з зображеннями, наданими користувачем.
Отримати безкоштовну ліцензію
Оцінювальна збірка додає водяний знак до розкритого тексту для символогій, відмінних від Code 39, що може заважати будь‑якому тестуванню у режимі «круговий прохід». Безкоштовна тимчасова ліцензія безкоштовна тимчасова ліцензія усуває це під час оцінки.
Безкоштовні додаткові ресурси
- Параметри якості зчитування штрих-кодів та пресети
- Особливі випадки зчитування штрих-кодів
- Документація API
- Безкоштовні онлайн інструменти для штрих-кодів
Висновок
Читання штрих‑кодів PDF417 у Python — це двохрядкова операція на чистих зображеннях і інженерна проблема на реальних. Наведені вище вимірювання вказують на просту стратегію: назвіть ваш DecodeType, за замовчуванням використовуйте normal_quality, спробуйте ще раз з high_quality і увімкненою деконволюцією, і перевіряйте кожен результат перед тим, як діяти. Збережіть дорогі пресети для шляху повторної спроби, і коли цілий клас зображень не проходить жодне налаштування, виправляйте захоплення замість читача. Питання вітаються у безкоштовному форумі підтримки.
Питання та відповіді
Чому той самий штрих-код PDF417 читається на одному зображенні, а на іншому — ні?
Розпізнавання залежить від того, скільки пікселів займає кожен модуль після захоплення. Розмиття, зменшення розміру та JPEG‑компресія зменшують ефективну ширину модуля, і коли модуль стає менше приблизно двох чистих пікселів, жоден пресет його не відновить.Який пресет розпізнавання слід використовувати для 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у розширеному результаті, щоб зібрати корисне навантаження у правильному порядку.Як визначити, чи можна довіряти розкодуваному результату?
Перевіртеreading_qualityтаconfidenceуBarCodeResultі використайте чотирикутникregion, щоб підтвердити, що штрих-код був знайдений у очікуваному місці на зображенні.Чи може він зчитувати PDF417 з фотографії водійського посвідчення або посадкового талону?
Так, за умови, що зображення чітке і штрих-код не обрізаний. Обріжте область штрих-коду перед читанням і віддавайте перевагу PNG замість JPEG для проміжних файлів.
