Tạo mã vạch PDF417 chỉ cần bốn dòng Python. Đọc lại mã từ ảnh điện thoại, bản quét 200 DPI, hoặc thẻ lên máy bay đã qua một ngày trong túi của ai đó là nơi công việc thực sự bắt đầu, và cũng là nơi hầu hết các tích hợp PDF417 thực sự thất bại. Trong bài viết này, bạn sẽ học cách đọc mã vạch PDF417 bằng Python khi hình ảnh nguồn không hoàn hảo. Nếu bạn đang tìm kiếm phần tạo mã, hướng dẫn trước đây về cách tạo mã vạch PDF417 bằng Python bao gồm việc tạo các ký hiệu PDF417 cơ bản và tùy chỉnh, bao gồm kiểm soát hàng và cột, và hướng dẫn đọc mã vạch Python đề cập đến việc quét đa mục đích trên các loại mã vạch. Những gì tiếp theo ở đây sẽ đi sâu và chi tiết vào việc nhận dạng PDF417.
Mỗi đoạn mã dưới đây đã được chạy trên Aspose.BarCode for Python via .NET 26.7 trên Linux với Python 3.12. Thời gian và kết quả đọc/thiếu được đo lường, không ước tính, và script tạo ra chúng nằm ở cuối để bạn có thể chạy lại trên các hình ảnh của mình.
Điều gì thực sự làm gián đoạn nhận dạng PDF417
PDF417 là một ký hiệu xếp chồng: các hàng của các codeword, mỗi codeword được tạo thành từ bốn thanh và bốn khoảng trống trải dài 17 mô-đun. Cấu trúc đó mang lại khả năng sửa lỗi Reed‑Solomon, vì vậy một góc bị rách hoặc một vết cà phê thường có thể phục hồi. Điều không thể phục hồi được là mất lưới mô-đun.
Ba điều phá hủy lưới, theo thứ tự xấp xỉ tần suất xuất hiện trong môi trường sản xuất:
- Chiều rộng mô-đun hiệu quả dưới hai pixel. Đây là lỗi chi phối. Nó xảy ra do thu nhỏ, do khoảng cách máy ảnh, và do mờ, khiến mực của một mô-đun lan sang các mô-đun lân cận. Một mã vạch được tạo ở ba pixel mỗi mô-đun rồi bị mờ về mặt chức năng giống như mã vạch ở một pixel mỗi mô-đun.
- Góc nhìn và xoay. Một mã vạch được chụp ở góc độ sẽ có các hàng không còn song song với các đường quét. Bộ phát hiện xử lý được điều này, nhưng nó tốn một lượt phát hiện mà cài đặt nhanh nhất sẽ bỏ qua.
- Sụp độ tương phản. Giấy nhiệt đã phai màu, màn hình được chụp dưới ánh chói, hoặc bản quét với độ sáng cố định. Ít nghiêm trọng hơn so với vẻ ngoài, như các số dưới đây cho thấy.
Hệ quả thực tế là các cài đặt nhận dạng là một cơ chế khôi phục, không phải là sự thay thế cho chất lượng chụp. Chúng giúp bạn lấy lại dải trung bình của chất lượng hình ảnh. Chúng không giúp bạn lấy lại phần thấp nhất.
Cài đặt Trình đọc PDF417 Python
Cài đặt thư viện từ PyPI:
pip install aspose-barcode-for-python-via-net
API nhận dạng nằm trong aspose.barcode.barcoderecognition. Hai lớp quan trọng cho bài viết này: BarCodeReader, lớp chịu trách nhiệm phát hiện và giải mã, và QualitySettings, lớp kiểm soát mức độ nỗ lực của trình đọc.
Đọc mã vạch PDF417 trong Python
Đọc tối thiểu khả thi là hai đối số và một vòng lặp:
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)

Đọc mã vạch PDF417 trong Python.
Kết quả trên hình ảnh sạch:
Code text: PASSENGER|KHAN/M|SEAT14C|LHE-DXB
Symbology: Pdf417
Reading quality: 100.0
Tham số thứ hai không phải là tùy chọn trong thực tế. Bỏ qua nó và BarCodeReader sẽ quay lại DecodeType.ALL_SUPPORTED_TYPES, cái sẽ thực hiện phát hiện hơn sáu mươi loại mã vạch trên mọi vùng ứng cử trong hình ảnh. Trong một quy trình chỉ xử lý PDF417, điều này hoàn toàn lãng phí, và nó mở ra khả năng một kết quả dương tính giả của mã vạch tuyến tính trong cấu trúc hàng PDF417. Đặt tên loại.
Nếu đầu vào của bạn đến dưới dạng byte từ một tải lên thay vì một tệp trên đĩa, hãy truyền một luồng và đặt thời gian chờ để một hình ảnh bất thường không thể làm treo 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()]
So sánh cài đặt chất lượng nhận dạng PDF417 trong Python
QualitySettings cung cấp bốn cài đặt trước đáng biết. Gán một trong số chúng cho trình đọc chỉ cần một dòng duy nhất.
reader = rec.BarCodeReader("scan.png", rec.DecodeType.PDF417)
reader.quality_settings = rec.QualitySettings.high_quality
| Cài đặt trước | Dành cho | Chi phí |
|---|---|---|
high_performance | Hình ảnh sạch, được tạo bởi máy | Nhanh nhất, bỏ qua các lần phục hồi |
normal_quality | Mặc định. Quét và xuất thường | Cân bằng |
high_quality | Ảnh chụp bằng máy ảnh, bản quét giảm chất lượng | Vừa phải |
max_quality | Thử lại trên các hình ảnh đã thất bại | Chậm nhất nhiều lần |
Để tìm hiểu ý nghĩa của những mô tả đó trong thực tế, tôi đã tạo một PDF417 với ba pixel mỗi mô-đun, làm giảm chất lượng theo sáu cách bằng Pillow, và chạy mọi cài đặt trước đối với mọi biến thể. Trung vị của ba lần chạy:
| Hình nguồn | high_performance | normal_quality | high_quality | max_quality |
|---|---|---|---|---|
| Sạch | đọc, 35 ms | đọc, 50 ms | đọc, 45 ms | đọc, 106 ms |
| Xoay 12°, mờ | bỏ lỡ, 15 ms | đọc, 74 ms | đọc, 67 ms | đọc, 157 ms |
| Nhiễu Gaussian (σ 40) | đọc, 31 ms | đọc, 49 ms | đọc, 52 ms | đọc, 123 ms |
| Nửa độ phân giải | đọc, 22 ms | đọc, 37 ms | đọc, 35 ms | đọc, 86 ms |
| Độ tương phản thấp | đọc, 24 ms | đọc, 38 ms | đọc, 43 ms | đọc, 112 ms |
| Mờ nặng (σ 2.2) | bỏ lỡ, 5 ms | bỏ lỡ, 25 ms | bỏ lỡ, 85 ms | bỏ lỡ, 180 ms |
Bốn điều rút ra từ bảng này, và chúng hữu ích hơn các số riêng lẻ:
- Tiếng ồn và độ tương phản thấp không phải là vấn đề như mọi người nghĩ. Reed-Solomon cộng với bộ phát hiện đã hấp thụ tiếng ồn Gaussian mạnh và giảm độ tương phản 82% trên preset nhanh nhất. Ngừng tinh chỉnh cho những thứ này.
- Xoay cộng với mờ là trường hợp phân biệt các preset. Nó cũng là hồ sơ chính xác của việc chụp bằng điện thoại cầm tay, vì vậy
high_performancelà mặc định sai cho bất kỳ quy trình nguồn từ di động nào. max_qualitytốn ba lần thời gian củanormal_qualityvà không đọc thêm gì. Nó xứng đáng có vị trí là đường đi thử lần thứ hai, không phải mặc định.- Khi lưới mô-đun biến mất, không có preset nào có thể khôi phục lại. Hàng mờ mạnh là một lỗi trên toàn bộ, và
max_qualityđã tiêu tốn 180 ms để chứng minh điều đó. Đó là vấn đề chụp ảnh với giải pháp chụp: nhiều pixel hơn, tiêu điểm tốt hơn,x_dimensionlớn hơn tại thời điểm tạo.
Điều chỉnh QualitySettings để Đọc Mã vạch PDF417 mờ trong Python
Một preset là một tập hợp các thuộc tính riêng lẻ, và bạn có thể bắt đầu từ một preset và ghi đè một thuộc tính. Đây là nơi mà những lợi ích thực sự xuất hiện cho một lỗi đã biết, có thể lặp lại.
Hình ảnh đã quay và làm mờ ở trên là một minh họa tốt. Dưới high_performance nó bị thiếu. Kích hoạt deconvolution trên cùng preset đó và nó sẽ hiển thị:
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)

Tinh chỉnh QualitySettings để đọc mã vạch PDF417 mờ trong Python.
Được đo: bỏ lỡ trong 12 ms mà không có ghi đè, đọc trong 54 ms có ghi đè. Một thuộc tính đã làm thay đổi kết quả, và kết quả vẫn nhanh hơn so với thiết lập sẵn max_quality.
Các thuộc tính đáng biết:
| Thuộc tính | Giá trị | Khi nào nên sử dụng |
|---|---|---|
deconvolution | FAST, NORMAL, SLOW | Hiệu ứng mờ chuyển động và ảnh không lấy nét |
barcode_quality | HIGH, NORMAL, LOW | Các khuyết điểm in, phai nhiệt, hiện tượng fax |
x_dimension | AUTO, SMALL, NORMAL, LARGE, USE_MINIMAL_X_DIMENSION | Mã vạch dày đặc, hoặc kích thước mô-đun cố định đã biết |
minimal_x_dimension | float | Kết hợp với USE_MINIMAL_X_DIMENSION để đặt mức tối thiểu |
complex_background | AUTO, DISABLED, ENABLED | Mã vạch được in trên hình ảnh nghệ thuật hoặc mẫu có họa tiết |
inverse_image | AUTO, DISABLED, ENABLED | Mã vạch trắng trên nền đen, chụp màn hình |
allow_incorrect_barcodes | bool | Chỉ dùng cho chẩn đoán, không bao giờ dùng trong sản xuất |
Cái cuối cùng này đáng để đưa ra một cảnh báo. allow_incorrect_barcodes trả về các ký hiệu không vượt qua kiểm tra checksum. Nó là công cụ gỡ lỗi giúp trả lời “bộ phát hiện có thực sự tìm thấy gì ở đây không?” Việc đưa nó vào sản phẩm có nghĩa là phát hành các chuỗi đã giải mã sai thay vì không có, điều này tệ hơn rất nhiều so với việc bỏ lỡ.
Một chiến lược phân lớp hoạt động tốt trong môi trường sản xuất: thử normal_quality trước, và khi không thành công, thử lại một lần với high_quality cộng deconvolution = SLOW. Bạn chỉ trả phí cho đường đi tốn kém đối với những hình ảnh cần nó.
Xác thực kết quả giải mã PDF417 trong Python
Một chuỗi đã giải mã không tự động là một chuỗi đúng. Ba trường trên BarCodeResult giúp:
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)]
Ghép lại một Macro PDF417 bị chia thành nhiều hình ảnh
Macro PDF417 chia một thông điệp logic thành nhiều ký hiệu, điều này xuất hiện trong các bản kê vận chuyển và tài liệu đa trang. Siêu dữ liệu đoạn vẫn tồn tại qua vòng quay, vì vậy việc lắp lại là quyết định được.
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")

Trang 1.

Trang 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
Lưu ý rằng
macro_pdf_417_file_idlà một số nguyên, không phải chuỗi, ở cả hai phía tạo và nhận dạng. Cùng một đối tượng cũng sẽ hiển thịmacro_pdf_417_file_name,macro_pdf_417_sender,macro_pdf_417_addressee,macro_pdf_417_time_stampvàmacro_pdf_417_checksumkhi bộ mã hoá đã điền chúng.
Đánh giá nhận dạng PDF417 trên hình ảnh của riêng bạn
Lựa chọn preset nên là một phép đo, không phải một ước đoán. Hướng công cụ này tới một thư mục chứa các bản ghi đại diện từ quy trình thực tế của bạn và nó sẽ cho bạn biết preset nào xứng đáng với chi phí của nó:
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
Chạy nó một lần với năm mươi bản ghi thực và cuộc tranh luận đã được thiết lập sẽ kết thúc.
Hướng dẫn thực tiễn
- Giới hạn
DecodeTypethànhPDF417trừ khi bạn thực sự mong đợi các ký hiệu hỗn hợp. Sử dụngMACRO_PDF417,COMPACT_PDF417hoặcMICRO_PDF417khi bạn biết biến thể. - Cắt ảnh trước khi giải mã. Việc truyền một bản quét A4 đầy đủ khi mã vạch chỉ chiếm 5 % sẽ lãng phí thời gian phát hiện và tạo ra nhiều kết quả dương tính giả.
- Giữ các tệp trung gian không mất dữ liệu. PNG hoặc TIFF. JPEG với chất lượng thấp gây hiện tượng ringing ngay tại các cạnh thanh mã mà bộ giải mã cần.
- Phân cấp các lần thử lại thay vì luôn dùng cài đặt chậm nhất.
- Sửa việc tạo mã trước khi tinh chỉnh nhận dạng. Nếu bạn kiểm soát bộ mã hoá, tăng
x_dimensionkhông tốn chi phí và giải quyết nhiều lỗi hơn bất kỳ cài đặt đọc nào. Bài viết bài viết về tạo PDF417 đề cập đến các tham số này. - Đặt
timeoutcho bất kỳ trình đọc nào xử lý hình ảnh do người dùng cung cấp.
Nhận giấy phép miễn phí
Bản dựng đánh giá sẽ chèn watermark vào văn bản đã giải mã cho các loại mã vạch ngoại trừ Code 39, điều này sẽ gây cản trở cho bất kỳ thử nghiệm vòng lặp nào bạn thực hiện. Một giấy phép tạm thời miễn phí sẽ loại bỏ điều đó trong quá trình đánh giá.
Tài Nguyên Bổ Sung Miễn Phí
- Các tùy chọn chất lượng đọc mã vạch và cài đặt trước
- Các trường hợp đọc mã vạch đặc biệt
- Tham chiếu API
- Công cụ mã vạch trực tuyến miễn phí
Kết luận
Đọc mã vạch PDF417 trong Python là một thao tác hai dòng trên hình ảnh sạch và là một vấn đề kỹ thuật trên các hình ảnh thực tế. Các đo lường ở trên chỉ ra một cách tiếp cận đơn giản: đặt tên cho DecodeType của bạn, mặc định là normal_quality, thử lại một lần với high_quality và bật deconvolution, và xác thực mọi kết quả trước khi thực hiện. Lưu các preset tốn kém cho đường dẫn thử lại, và khi một lớp hình ảnh toàn bộ không thành công ở mọi cài đặt, hãy sửa cách chụp thay vì bộ đọc. Mọi câu hỏi đều được chào đón trên diễn đàn hỗ trợ miễn phí.
Câu hỏi thường gặp
Tại sao cùng một mã vạch PDF417 có thể đọc được trong một hình ảnh mà lại không đọc được trong hình ảnh khác?
Việc nhận dạng phụ thuộc vào số pixel mà mỗi mô-đun chiếm sau khi chụp. Độ mờ, giảm kích thước và nén JPEG đều làm giảm chiều rộng mô-đun thực tế, và khi một mô-đun giảm xuống dưới khoảng hai pixel sạch, không có preset nào có thể khôi phục lại.Tôi nên sử dụng preset nhận dạng nào cho PDF417?
Bắt đầu vớinormal_quality, đây là mặc định. Chuyển sanghigh_qualitycho các ảnh chụp bằng máy ảnh và quét, và chỉ dùngmax_qualitycho các lần thử lại vì nó chậm hơn nhiều lần mà không đọc được nhiều hơn đáng kể.Việc giới hạn DecodeType chỉ cho PDF417 thực sự làm cho việc đọc nhanh hơn không?
Có. Mặc định làDecodeType.ALL_SUPPORTED_TYPES, chạy bộ phát hiện cho mọi ký hiệu được hỗ trợ. Đặt rõ PDF417 loại bỏ công việc đó và cũng loại bỏ khả năng phát hiện sai từ ký hiệu khác.Aspose.BarCode có thể đọc một tin nhắn Macro PDF417 được chia thành nhiều hình ảnh không?
Có. Đọc từng đoạn bằngDecodeType.MACRO_PDF417và sử dụngmacro_pdf_417_file_id,macro_pdf_417_segment_id, vàmacro_pdf_417_segments_counttrên kết quả mở rộng để lắp ráp lại dữ liệu theo thứ tự.Làm sao tôi biết kết quả giải mã có thể tin cậy không?
Kiểm trareading_qualityvàconfidencetrênBarCodeResult, và sử dụng hình tứ giácregionđể xác nhận mã vạch được tìm thấy ở vị trí bạn mong đợi trong ảnh.Nó có thể đọc PDF417 từ ảnh giấy phép lái xe hoặc thẻ lên máy bay không?
Có thể, với điều kiện ảnh được chụp nét và mã vạch không bị cắt. Cắt vùng mã vạch trước khi đọc, và ưu tiên PNG hơn JPEG cho các tệp trung gian.
