Generowanie kodu kreskowego PDF417 zajmuje cztery linie Pythona. Odczytanie go z zdjęcia telefonu, skanu 200 DPI lub karty pokładowej, która spędziła dzień w czyjejś kieszeni, to miejsce, w którym zaczyna się prawdziwa praca i gdzie większość integracji PDF417 faktycznie zawodzi. W tym artykule dowiesz się, jak odczytywać kody kreskowe PDF417 w Pythonie, gdy obraz źródłowy jest niedoskonały. Jeśli zamiast tego interesuje Cię generowanie, wcześniejszy przewodnik, jak generować PDF417 barcodes using Python opisuje tworzenie podstawowych i niestandardowych symboli PDF417, w tym kontrolę wierszy i kolumn, a Python barcode reader guide obejmuje skanowanie ogólnego przeznaczenia w różnych symbologiach. To, co następuje, jest wąskie i głębokie w rozpoznawaniu PDF417.
Każdy fragment kodu poniżej został uruchomiony na Aspose.BarCode for Python via .NET 26.7 w systemie Linux z Pythonem 3.12. Czasy oraz wyniki odczytu/pominięcia są mierzone, a nie szacowane, a skrypt, który je wygenerował, znajduje się na końcu, abyś mógł ponownie uruchomić go na własnych obrazach.
Co tak naprawdę psuje rozpoznawanie PDF417
PDF417 jest symbologią warstwową: wiersze kodów słów, każdy kod słowa zbudowany z czterech pasków i czterech spacji obejmujących 17 modułów. Ta struktura zawiera korekcję błędów Reed‑Solomon, więc rozerwany róg lub plama po kawie zazwyczaj da się przetrwać. Nie da się natomiast przetrwać utraty samej siatki modułów.
Trzy rzeczy niszczą siatkę, w przybliżonej kolejności, jak często pojawiają się w produkcji:
- Efektywna szerokość modułu spadająca poniżej dwóch pikseli. To jest dominująca awaria. Dzieje się to przez zmniejszanie skali, odległość kamery oraz rozmycie, które rozprzestrzenia tusz jednego modułu na sąsiednie. Kod kreskowy wygenerowany przy trzech pikselach na moduł, a następnie rozmyty, jest funkcjonalnie kodem kreskowym przy jednym pikselu na moduł.
- Perspektywa i rotacja. Kod kreskowy sfotografowany pod kątem ma wiersze, które nie są już równoległe do linii skanowania. Detektor radzi sobie z tym, ale wymaga dodatkowego przebiegu wykrywania, który naj szybszy preset pomija.
- Utrata kontrastu. Papier termiczny, który wyblakł, ekran sfotografowany w odblasku lub skan z ustawioną jasnością. Mniej fatalne niż się wydaje, co pokazują poniższe liczby.
Praktycznym konsekwencją jest to, że ustawienia rozpoznawania są mechanizmem odzyskiwania, a nie zamiennikiem jakości przechwytywania. Przywracają one środkowy zakres jakości obrazu. Nie przywracają one dolnego zakresu.
Skonfiguruj czytnik PDF417 w Pythonie
Zainstaluj bibliotekę z PyPI:
pip install aspose-barcode-for-python-via-net
API rozpoznawania znajduje się w aspose.barcode.barcoderecognition. Dwie klasy mają znaczenie w tym artykule: BarCodeReader, która steruje wykrywaniem i dekodowaniem, oraz QualitySettings, która kontroluje, jak bardzo czytnik się stara.
Odczyt kodu kreskowego PDF417 w Pythonie
Minimalny wykonalny odczyt to dwa argumenty i pętla:
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)

Odczytaj kod kreskowy PDF417 w Pythonie.
Wynik na czystym obrazie:
Code text: PASSENGER|KHAN/M|SEAT14C|LHE-DXB
Symbology: Pdf417
Reading quality: 100.0
Drugi argument w praktyce nie jest opcjonalny. Pomiń go, a BarCodeReader domyślnie użyje DecodeType.ALL_SUPPORTED_TYPES, co powoduje wykrywanie ponad sześćdziesięciu symbologii w każdym potencjalnym regionie obrazu. W pipeline dedykowanym wyłącznie PDF417 jest to czyste marnotrawstwo i otwiera drzwi do fałszywego alarmu symbologii liniowej wewnątrz struktury wiersza PDF417. Podaj typ.
Jeśli Twoje dane wejściowe przychodzą jako bajty z przesyłania, a nie jako plik na dysku, przekaż strumień i ustaw limit czasu, aby patologiczny obraz nie mógł zablokować worker:a
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()]
Porównaj ustawienia jakości rozpoznawania PDF417 w Pythonie
QualitySettings zawiera cztery przydatne presety. Przypisanie jednego do czytnika wymaga jednego wiersza:
reader = rec.BarCodeReader("scan.png", rec.DecodeType.PDF417)
reader.quality_settings = rec.QualitySettings.high_quality
| Ustawienie | Przeznaczone dla | Koszt |
|---|---|---|
high_performance | Czyste, generowane maszynowo obrazy | Najszybszy, pomija przebiegi odzyskiwania |
normal_quality | Domyślne. Regularne skany i eksporty | Zrównoważony |
high_quality | Zdjęcia z aparatu, zdegradowane skany | Umiarkowany |
max_quality | Ponowna próba na obrazach, które już nie powiodły się | Najwolniejszy z dużym marginesem |
Aby dowiedzieć się, co te opisy oznaczają w praktyce, wygenerowałem PDF417 przy trzech pikselach na moduł, zdegradowałem go na sześć sposobów przy użyciu Pillow i uruchomiłem każdy preset przeciwko każdej wariancie. Mediana z trzech uruchomień:
| Obraz źródłowy | high_performance | normal_quality | high_quality | max_quality |
|---|---|---|---|---|
| Czysty | odczyt, 35 ms | odczyt, 50 ms | odczyt, 45 ms | odczyt, 106 ms |
| Obrócony o 12°, rozmyty | pudło, 15 ms | odczyt, 74 ms | odczyt, 67 ms | odczyt, 157 ms |
| Szum gaussowski (σ 40) | odczyt, 31 ms | odczyt, 49 ms | odczyt, 52 ms | odczyt, 123 ms |
| Połowa rozdzielczości | odczyt, 22 ms | odczyt, 37 ms | odczyt, 35 ms | odczyt, 86 ms |
| Niski kontrast | odczyt, 24 ms | odczyt, 38 ms | odczyt, 43 ms | odczyt, 112 ms |
| Silne rozmycie (σ 2.2) | pudło, 5 ms | pudło, 25 ms | pudło, 85 ms | pudło, 180 ms |
Z tej tabeli wypadają cztery rzeczy, które są bardziej przydatne niż poszczególne liczby:
- Szum i niski kontrast nie są problemem, za który ludzie uważają, że jest. Reed-Solomon plus detektor wchłonęły silny szum Gaussa i 82 % redukcję kontrastu w najszybszym ustawieniu. Przestań dostrajać pod te warunki.
- Rotacja plus rozmycie to przypadek, który rozdziela ustawienia. To także dokładny profil przechwytywania z ręcznego telefonu, dlatego
high_performancejest niewłaściwym domyślnym wyborem dla dowolnego potoku pochodzącego z urządzeń mobilnych. max_qualitykosztuje trzykrotnie więcej czasu niżnormal_qualityi nie odczytuje nic dodatkowego. Zasługuje na miejsce jako ścieżka drugiego podejścia, a nie jako domyślna.- Gdy siatka modułów zniknie, żadne ustawienie jej nie przywróci. Ciężki wiersz rozmycia jest porażką we wszystkich przypadkach, a
max_qualityspędził 180 ms, aby to udowodnić. To problem przechwytywania z rozwiązaniem przechwytywania: więcej pikseli, lepsze ustawienie ostrości, większyx_dimensionw czasie generacji.
Dostosuj QualitySettings, aby odczytać rozmyte kody kreskowe PDF417 w Pythonie
Preset to zestaw indywidualnych właściwości, a możesz rozpocząć od presetu i nadpisać jedną z nich. To właśnie tutaj znajdują się prawdziwe korzyści w przypadku znanego, powtarzalnego defektu.
Obrócony i rozmyty obraz powyżej jest dobrą demonstracją. W sekcji high_performance brakuje. Włącz dekonwolucję na tym samym ustawieniu i otrzymasz:
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)

Dostosuj QualitySettings, aby odczytywać rozmyte kody kreskowe PDF417 w Pythonie.
Zmierzono: miss w 12 ms bez nadpisania, odczyt w 54 ms z nim. Jedna właściwość odwróciła wynik, a rezultat nadal był szybszy niż preset max_quality.
Właściwości, które warto znać:
| Właściwość | Wartości | Kiedy używać |
|---|---|---|
deconvolution | FAST, NORMAL, SLOW | Rozmycie ruchu i zdjęcia poza ostrością |
barcode_quality | HIGH, NORMAL, LOW | Wady druku, blaknięcie termiczne, artefakty faksu |
x_dimension | AUTO, SMALL, NORMAL, LARGE, USE_MINIMAL_X_DIMENSION | Gęste kody kreskowe lub stały znany rozmiar modułu |
minimal_x_dimension | float | Połącz z USE_MINIMAL_X_DIMENSION, aby ustawić minimalną wartość |
complex_background | AUTO, DISABLED, ENABLED | Kod kreskowy drukowany na grafice lub wzorzystym formularzu |
inverse_image | AUTO, DISABLED, ENABLED | Kody kreskowe białe na czarnym tle, zrzuty ekranu |
allow_incorrect_barcodes | bool | Tylko diagnostyka, nigdy w produkcji |
Ten ostatni zasługuje na ostrzeżenie. allow_incorrect_barcodes zwraca symbole, które nie przeszły weryfikacji sumy kontrolnej. Jest to pomocnicze narzędzie debugowania służące do odpowiedzi na pytanie „czy detektor w ogóle coś tutaj znalazł?”. Udostępnienie go oznacza wysyłanie zdekodowanych ciągów, które są nieprawidłowe zamiast nieobecnych, co jest zdecydowanie gorsze niż pominięcie.
Strategia warstwowania, która dobrze sprawdza się w produkcji: najpierw wypróbuj normal_quality, a w przypadku niepowodzenia spróbuj ponownie raz z high_quality plus deconvolution = SLOW. Płacisz wysoką cenę tylko za obrazy, które tego potrzebują.
Walidacja wyników dekodowania PDF417 w Pythonie
Zdekodowany ciąg nie jest automatycznie poprawnym ciągiem. Trzy pola w BarCodeResult pomagają:
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)]
Ponowne złożenie makro PDF417 podzielonego na obrazy
Macro PDF417 dzieli jedną logiczną wiadomość na kilka symboli, co pojawia się w listach przewozowych i dokumentach wielostronicowych. Metadane segmentu przetrwają podróż w obie strony, więc ponowne składanie jest deterministyczne:
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")

Strona 1.

Strona 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
Należy zauważyć, że
macro_pdf_417_file_idjest liczbą całkowitą, a nie ciągiem znaków, zarówno po stronie generowania, jak i rozpoznawania. Ten sam obiekt udostępnia równieżmacro_pdf_417_file_name,macro_pdf_417_sender,macro_pdf_417_addressee,macro_pdf_417_time_stamporazmacro_pdf_417_checksum, gdy enkoder je wypełnił.
Benchmark rozpoznawania PDF417 na własnych obrazach
Wybór presetu powinien być pomiarem, a nie zgadywaniem. Skieruj go na folder z reprezentatywnymi przechwyceniami z Twojego rzeczywistego potoku, a powie Ci, który preset jest wart swojej ceny:
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
Uruchom to raz na pięćdziesięciu rzeczywistych przechwyceniach, a wstępna debata się kończy.
Praktyczne wytyczne
- Ogranicz
DecodeTypedoPDF417, chyba że naprawdę spodziewasz się mieszanych symbologii. UżyjMACRO_PDF417,COMPACT_PDF417lubMICRO_PDF417, gdy znasz wariant. - Przytnij przed dekodowaniem. Przesyłanie pełnego skanu A4, gdy kod kreskowy zajmuje tylko 5 % powierzchni, marnuje czas wykrywania i zwiększa liczbę fałszywych trafień.
- Zachowuj pliki pośrednie bezstratnie. PNG lub TIFF. JPEG przy niskich ustawieniach jakości wprowadza artefakty dokładnie na krawędziach pasków, które potrzebuje dekoder.
- Warstwuj ponowne próby, zamiast domyślnie używać najwolniejszego ustawienia.
- Napraw generowanie przed dostrajaniem rozpoznawania. Jeśli kontrolujesz enkoder, zwiększenie
x_dimensionnie kosztuje nic i rozwiązuje więcej pominięć niż jakiekolwiek ustawienie czytnika. Artykuł o generowaniu PDF417 opisuje te parametry. - Ustaw
timeoutw każdym czytniku, który przetwarza obrazy dostarczone przez użytkownika.
Uzyskaj darmową licencję
Wersja ewaluacyjna nakłada znak wodny na zdekodowany tekst dla symbologii innych niż Code 39, co może zakłócić wszelkie testy typu round‑trip, które przeprowadzasz. Darmowa tymczasowa licencja usuwa to w wersji ewaluacyjnej.
Darmowe dodatkowe zasoby
- Opcje jakości odczytu kodów kreskowych i zestawy ustawień
- Specjalne przypadki odczytu kodów kreskowych
- Referencja API
- Darmowe narzędzia online do kodów kreskowych
Wnioski
Odczytywanie kodów kreskowych PDF417 w Pythonie to dwuliniowa operacja na czystych obrazach i problem inżynierski na rzeczywistych. Powyższe pomiary wskazują prostą zasadę: nazwij swój DecodeType, domyślnie użyj normal_quality, spróbuj ponownie raz z włączonym high_quality i dekonwolucją, oraz zweryfikuj każdy wynik przed podjęciem działania. Zachowaj kosztowne presety na ścieżkę ponownego próbowania, a gdy cała klasa obrazów nie przechodzi żadnego ustawienia, napraw sposób przechwytywania zamiast czytnika. Pytania są mile widziane na bezpłatnym forum wsparcia.
Najczęściej zadawane pytania
Dlaczego ten sam kod kreskowy PDF417 jest odczytywany na jednym obrazie, a w innym nie?
Rozpoznawanie zależy od liczby pikseli, które każdy moduł zajmuje po przechwyceniu. Rozmycie, zmniejszanie rozdzielczości i kompresja JPEG wszystkie zmniejszają efektywną szerokość modułu, a gdy moduł spadnie poniżej około dwóch czystych pikseli, żadne ustawienie nie przywróci go.Jakie ustawienie rozpoznawania powinienem używać dla PDF417?
Zacznij odnormal_quality, które jest domyślne. Przejdź dohigh_qualityprzy przechwytywaniu z kamery i skanach, amax_qualityzarezerwuj na dodatkowe próby, ponieważ jest kilka razy wolniejsze, nie przynosząc znacząco lepszych wyników.Czy ograniczenie DecodeType do PDF417 naprawdę przyspiesza odczyt?
Tak. Domyślnie jestDecodeType.ALL_SUPPORTED_TYPES, co uruchamia detektor dla każdej obsługiwanej symbologii. Jawne określenie PDF417 usuwa to dodatkowe obciążenie i eliminuje ryzyko fałszywego wykrycia innej symbologii.Czy Aspose.BarCode może odczytać wiadomość Macro PDF417 podzieloną na kilka obrazów?
Tak. Odczytaj każdy segment przy użyciuDecodeType.MACRO_PDF417i skorzystaj zmacro_pdf_417_file_id,macro_pdf_417_segment_idorazmacro_pdf_417_segments_countw rozszerzonym wyniku, aby ponownie złożyć ładunek w odpowiedniej kolejności.Jak mogę sprawdzić, czy odczytany wynik jest wiarygodny?
Sprawdźreading_qualityiconfidencew obiekcieBarCodeResult, a także użyj czworokątaregion, aby potwierdzić, że kod kreskowy został znaleziony w oczekiwanym miejscu na obrazie.Czy można odczytać PDF417 ze zdjęcia prawa jazdy lub karty pokładowej?
Tak, pod warunkiem że zdjęcie jest ostre i kod kreskowy nie jest obcięty. Przed odczytem przytnij obszar kodu kreskowego i preferuj format PNG zamiast JPEG dla plików pośrednich.
