Gerar um código de barras PDF417 leva quatro linhas de Python. Ler um de volta a partir de uma foto de telefone, uma digitalização de 200 DPI ou um cartão de embarque que passou um dia no bolso de alguém é onde o trabalho real começa, e é onde a maioria das integrações PDF417 realmente falha. Neste artigo, você aprenderá como ler códigos de barras PDF417 em Python quando a imagem de origem está imperfeita. Se você está procurando a parte de geração, o tutorial anterior sobre como gerar códigos de barras PDF417 usando Python cobre a criação de símbolos PDF417 básicos e personalizados, incluindo controle de linhas e colunas, e o guia do leitor de código de barras Python aborda a digitalização de uso geral em várias simbologias. O que segue aqui é mais específico e aprofundado no reconhecimento de PDF417.
Cada trecho abaixo foi executado com Aspose.BarCode for Python via .NET 26.7 no Linux com Python 3.12. Os tempos e os resultados de leitura/erro foram medidos, não estimados, e o script que os gerou está no final para que você possa executá‑lo em suas próprias imagens.
O que realmente quebra o reconhecimento PDF417
PDF417 é uma simbologia empilhada: linhas de palavras‑código, cada palavra‑código construída a partir de quatro barras e quatro espaços que abrangem 17 módulos. Essa estrutura incorpora correção de erros Reed‑Solomon, de modo que um canto rasgado ou uma mancha de café geralmente são sobrevivíveis. O que não é sobrevivível é perder a própria grade de módulos.
Três coisas destroem a grade, em ordem aproximada de frequência com que aparecem na produção:
- Largura efetiva do módulo abaixo de dois pixels. Esta é a falha dominante. Ela ocorre por redução de escala, por distância da câmera e por desfoque, que espalha a tinta de um módulo para os vizinhos. Um código de barras gerado com três pixels por módulo e depois desfocado funciona como um código de barras com um pixel por módulo.
- Perspectiva e rotação. Um código de barras fotografado em ângulo tem linhas que não são mais linhas de varredura paralelas. O detector lida com isso, mas isso custa uma passagem de detecção que a configuração mais rápida pula.
- Colapso de contraste. Papel térmico que desbotou, uma tela fotografada sob reflexo ou uma digitalização com o brilho fixado. Menos fatal do que parece, como os números abaixo mostram.
A consequência prática é que as configurações de reconhecimento são um mecanismo de recuperação, não um substituto para a qualidade de captura. Elas devolvem a faixa média da qualidade da imagem. Elas não devolvem a faixa inferior.
Configurar o Leitor PDF417 em Python
Instale a biblioteca do PyPI:
pip install aspose-barcode-for-python-via-net
A API de reconhecimento está em aspose.barcode.barcoderecognition. Duas classes são importantes para este artigo: BarCodeReader, que conduz a detecção e decodificação, e QualitySettings, que controla o quão esforçado o leitor tenta.
Ler um código de barras PDF417 em Python
A leitura mínima viável consiste em dois argumentos e um loop:
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)

Ler um código de barras PDF417 em Python.
Saída em uma imagem limpa:
Code text: PASSENGER|KHAN/M|SEAT14C|LHE-DXB
Symbology: Pdf417
Reading quality: 100.0
O segundo argumento não é opcional na prática. Deixe‑o de fora e BarCodeReader volta para DecodeType.ALL_SUPPORTED_TYPES, que executa a detecção de mais de sessenta simbologias contra cada região candidata na imagem. Em um pipeline somente PDF417 isso é puro desperdício, e abre a porta para um falso positivo de simbologia linear dentro da estrutura de linhas do PDF417. Nomeie o tipo.
Se sua entrada chegar como bytes de um upload em vez de um arquivo no disco, passe um stream e defina um tempo limite para que uma imagem patológica não possa travar um worker:
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()]
Comparar Configurações de Qualidade de Reconhecimento PDF417 em Python
QualitySettings oferece quatro predefinições que vale a pena conhecer. Atribuir uma ao leitor é uma única linha:
reader = rec.BarCodeReader("scan.png", rec.DecodeType.PDF417)
reader.quality_settings = rec.QualitySettings.high_quality
| Preset | Destinado a | Custo |
|---|---|---|
high_performance | Imagens limpas, geradas por máquina | Mais rápido, pula as passagens de recuperação |
normal_quality | Padrão. Digitalizações e exportações regulares | Equilibrado |
high_quality | Capturas de câmera, digitalizações degradadas | Moderado |
max_quality | Passagem de tentativa em imagens que já falharam | Mais lento por uma grande margem |
Para descobrir o que essas descrições significam na prática, eu gerei um PDF417 com três pixels por módulo, degradei‑o de seis maneiras com o Pillow e executei cada preset contra cada variante. Mediana de três execuções:
| Imagem de origem | high_performance | normal_quality | high_quality | max_quality |
|---|---|---|---|---|
| Limpa | lido, 35 ms | lido, 50 ms | lido, 45 ms | lido, 106 ms |
| Rotacionada 12°, borrada | não encontrado, 15 ms | lido, 74 ms | lido, 67 ms | lido, 157 ms |
| Ruído gaussiano (σ 40) | lido, 31 ms | lido, 49 ms | lido, 52 ms | lido, 123 ms |
| Meia resolução | lido, 22 ms | lido, 37 ms | lido, 35 ms | lido, 86 ms |
| Baixo contraste | lido, 24 ms | lido, 38 ms | lido, 43 ms | lido, 112 ms |
| Desfoque intenso (σ 2.2) | não encontrado, 5 ms | não encontrado, 25 ms | não encontrado, 85 ms | não encontrado, 180 ms |
Quatro coisas surgem desta tabela, e elas são mais úteis do que os números individuais:
- Ruído e baixo contraste não são o problema que as pessoas pensam. Reed-Solomon mais o detector absorveram ruído gaussiano pesado e uma redução de contraste de 82% na predefinição mais rápida. Pare de ajustar para isso.
- Rotação mais desfoque é o caso que separa as predefinições. Também é o perfil exato de uma captura com telefone manual, razão pela qual
high_performanceé a configuração padrão errada para qualquer pipeline de origem móvel. max_qualitycusta três vezes o tempo denormal_qualitye não lê nada extra. Ganha seu lugar como caminho de segunda tentativa, não como padrão.- Uma vez que a grade do módulo desaparece, nenhuma predefinição a recupera. A linha de desfoque pesado é um erro geral, e
max_qualitygastou 180 ms provando isso. Isso é um problema de captura com uma correção de captura: mais pixels, melhor foco, maiorx_dimensionno momento da geração.
Ajuste QualitySettings para Ler Códigos de Barras PDF417 Embaçados em Python
Um preset é um conjunto de propriedades individuais, e você pode começar a partir de um preset e substituir uma. É aqui que os ganhos reais se encontram para um defeito conhecido e repetível.
A imagem girada e borrada acima é uma boa demonstração. Em high_performance ela falha. Ative a deconvolução sobre o mesmo preset e ele exibe:
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)

Ajuste QualitySettings para ler códigos de barras PDF417 desfocados em Python.
Medido: falha em 12 ms sem a substituição, leitura em 54 ms com ela. Uma propriedade mudou o resultado, e o resultado ainda voltou mais rápido do que o preset max_quality teria.
As propriedades que vale a pena conhecer:
| Propriedade | Valores | Quando utilizá-lo |
|---|---|---|
deconvolution | FAST, NORMAL, SLOW | Desfoque de movimento e capturas fora de foco |
barcode_quality | HIGH, NORMAL, LOW | Defeitos de impressão, desbotamento térmico, artefatos de fax |
x_dimension | AUTO, SMALL, NORMAL, LARGE, USE_MINIMAL_X_DIMENSION | Códigos de barras densos ou um tamanho de módulo fixo conhecido |
minimal_x_dimension | float | Combine com USE_MINIMAL_X_DIMENSION para definir um limite mínimo |
complex_background | AUTO, DISABLED, ENABLED | Código de barras impresso sobre arte ou um formulário padronizado |
inverse_image | AUTO, DISABLED, ENABLED | Códigos de barras branco sobre preto, capturas de tela |
allow_incorrect_barcodes | bool | Somente para diagnóstico, nunca em produção |
Esse último merece um aviso. allow_incorrect_barcodes retorna símbolos que falharam a validação de checksum. É uma ajuda de depuração para responder “o detector chegou a encontrar algo aqui?” Enviá‑lo significa enviar strings decodificadas que estão erradas em vez de ausentes, o que é estritamente pior que um erro.
Uma estratégia de tiering que funciona bem em produção: tente normal_quality primeiro, e em caso de falha tente novamente uma vez com high_quality mais deconvolution = SLOW. Você paga o caminho caro apenas para as imagens que precisam dele.
Validar Resultados de Decodificação PDF417 em Python
Uma string decodificada não é automaticamente uma string correta. Três campos em BarCodeResult ajudam:
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)]
Reunir um Macro PDF417 Dividido em Imagens
Macro PDF417 divide uma mensagem lógica em vários símbolos, o que aparece em manifestos de embarque e documentos de várias páginas. Os metadados do segmento sobrevivem à viagem de ida e volta, portanto a remontagem é determinística:
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")

Página 1.

Página 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
Observe que
macro_pdf_417_file_idé um inteiro, não uma string, tanto no lado de geração quanto no de reconhecimento. O mesmo objeto também expõemacro_pdf_417_file_name,macro_pdf_417_sender,macro_pdf_417_addressee,macro_pdf_417_time_stampemacro_pdf_417_checksumquando o codificador os preencheu.
Benchmark de Reconhecimento PDF417 em Suas Próprias Imagens
A escolha do preset deve ser uma medida, não um palpite. Aponte isso para uma pasta de capturas representativas do seu pipeline real e ele dirá qual preset justifica seu custo:
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
Execute‑o uma vez contra cinquenta capturas reais e o debate pré‑definido termina.
Diretrizes Práticas
- Restrinja
DecodeTypeaPDF417a menos que você realmente espere simbologias mistas. UseMACRO_PDF417,COMPACT_PDF417ouMICRO_PDF417quando souber a variante. - Corte antes de decodificar. Passar uma digitalização completa de A4 quando o código de barras ocupa apenas 5 % dela desperdiça tempo de detecção e adiciona superfícies de falsos positivos.
- Mantenha arquivos intermediários sem perdas. PNG ou TIFF. O ringing do JPEG em configurações de baixa qualidade ataca exatamente as bordas das barras que o decodificador precisa.
- Estruture suas tentativas em vez de usar o preset mais lento por padrão.
- Corrija a geração antes de ajustar o reconhecimento. Se você controla o codificador, aumentar
x_dimensionnão custa nada e resolve mais falhas do que qualquer configuração de leitor. O artigo de geração PDF417 cobre esses parâmetros. - Defina
timeoutem qualquer leitor que manipule imagens fornecidas pelo usuário.
Obtenha uma Licença Gratuita
A compilação de avaliação adiciona marcas d’água ao texto decodificado para simbologias diferentes de Code 39, o que interferirá em qualquer teste de ida e volta que você fizer. Uma licença temporária gratuita remove isso na avaliação.
Recursos Adicionais Gratuitos
- Opções de Qualidade de Leitura de Código de Barras e Predefinições
- Casos Especiais de Leitura de Código de Barras
- Referência da API
- Ferramentas Gratuitas de Código de Barras Online
Conclusão
Ler códigos de barras PDF417 em Python é uma operação de duas linhas em imagens limpas e um problema de engenharia em imagens reais. As medições acima apontam para uma postura simples: nomeie seu DecodeType, use normal_quality como padrão, tente novamente uma vez com high_quality e deconvolução habilitada, e valide cada resultado antes de agir sobre ele. Salve as predefinições caras para o caminho de tentativa e, quando uma classe inteira de imagens falhar em todas as configurações, corrija a captura em vez do leitor. Perguntas são bem‑vindas no forum de suporte gratuito.
FAQs
Por que o mesmo código de barras PDF417 é lido em uma imagem e falha em outra?
O reconhecimento depende de quantos pixels cada módulo ocupa após a captura. Desfoque, redução de escala e compressão JPEG reduzem a largura efetiva do módulo e, quando um módulo cai abaixo de aproximadamente dois pixels limpos, nenhum preset o recuperará.Qual preset de reconhecimento devo usar para PDF417?
Comece comnormal_quality, que é o padrão. Passe parahigh_qualitypara capturas e digitalizações com câmera e reservemax_qualitypara tentativas de repetição, pois é várias vezes mais lento sem ler muito mais.Restringir DecodeType para PDF417 realmente torna a leitura mais rápida?
Sim. O padrão éDecodeType.ALL_SUPPORTED_TYPES, que executa o detector para todas as simbologias suportadas. Nomear PDF417 explicitamente remove esse trabalho e também elimina a chance de um falso positivo de outra simbologia.Pode o Aspose.BarCode ler uma mensagem Macro PDF417 dividida em várias imagens?
Sim. Leia cada segmento comDecodeType.MACRO_PDF417e usemacro_pdf_417_file_id,macro_pdf_417_segment_idemacro_pdf_417_segments_countno resultado estendido para remontar a carga útil na ordem correta.Como saber se um resultado decodificado pode ser confiável?
Verifiquereading_qualityeconfidencenoBarCodeResulte use o quadriláteroregionpara confirmar que o código de barras foi encontrado onde você esperava na imagem.Ele pode ler PDF417 a partir de uma foto de carteira de motorista ou cartão de embarque?
Pode, desde que a captura esteja em foco e o código de barras não esteja cortado. Recorte para a região do código de barras antes da leitura e prefira PNG em vez de JPEG para arquivos intermediários.
