How to Decode Barcodes and Industrial 2D Codes with Python
Building a code generator is only half the battle. In this walkthrough, we will build a high-performance scanning system capable of identifying and decoding multiple barcodes and 2D codes (QR, Data Matrix, etc.) from both static images and real-time video streams.
1. The Power Couple: OpenCV and PyZbarβ
To read barcodes effectively, we use OpenCV for image manipulation and PyZbar for the heavy lifting of decoding.
- OpenCV: Handles the "eyes" of our application-opening the camera, converting colors, and drawing feedback on the screen [4.2].
- PyZbar: A Python wrapper for the ZBar library, which is a world-class engine for scanning barcodes across many formats [4.1].
π» Installationβ
On most systems, you will need to install the C-library for ZBar before the Python wrapper:
- Windows: Automatically included with the pip package.
- macOS:
brew install zbar - Linux:
sudo apt-get install libzbar0
Then, install the Python libraries:
pip install opencv-python pyzbar
2. The Scanning Pipelineβ
A robust scanner doesn't just "look" at an image; it processes it. The pipeline looks like this:
- Pre-processing: Convert to grayscale and apply a slight blur to reduce noise [4.3].
- Decoding: PyZbar scans the processed image for known patterns.
- Localization: We extract the coordinates of the code to draw a bounding box.
- Parsing: The raw bytes are converted into a readable string.
3. Static Image Scanner (Code Walkthrough)β
This script will take a single image file and print every barcode it finds inside it.
import cv2
from pyzbar import pyzbar
def scan_image(image_path):
# 1. Load the image
image = cv2.imread(image_path)
# 2. Pre-process: Convert to grayscale
# This makes the black-and-white patterns easier to distinguish
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 3. Decode all barcodes in the image
barcodes = pyzbar.decode(gray)
for obj in barcodes:
# Extract the data as a string
data = obj.data.decode("utf-8")
type = obj.type
# 4. Localization: Get coordinates for a bounding box
(x, y, w, h) = obj.rect
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
print(f"Found {type} Code: {data}")
# Show the result with the bounding box
cv2.imshow("Scanner Result", image)
cv2.waitKey(0)
# scan_image("my_labels.png")
4. Real-Time Webcam Scannerβ
For industrial or retail apps, you need a live feed. This script initializes your webcam and decodes data at 30+ frames per second.
import cv2
from pyzbar import pyzbar
def live_scanner():
# Initialize the camera (0 is usually the default webcam)
cap = cv2.VideoCapture(0)
print("Scanner started. Press 'q' to quit.")
while True:
ret, frame = cap.read()
if not ret:
break
# Optional: Pre-processing for speed
# gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Detect and decode
decoded_objects = pyzbar.decode(frame)
for obj in decoded_objects:
# Draw green box around detected code
points = obj.polygon
if len(points) > 4:
hull = cv2.convexHull(np.array([point for point in points], dtype=np.float32))
hull = list(map(tuple, np.squeeze(hull)))
else:
hull = points
# Draw the lines
n = len(hull)
for j in range(0, n):
cv2.line(frame, hull[j], hull[(j + 1) % n], (0, 255, 0), 3)
# Overlay the decoded text
data = obj.data.decode("utf-8")
cv2.putText(frame, data, (obj.rect.x, obj.rect.y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
print(f"Scanned: {data}")
cv2.imshow("Live Scanner", frame)
# Stop if 'q' is pressed
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
# live_scanner()
5. Multi-Format Handlingβ
One of the best features of pyzbar is that it handles multiple formats simultaneously. You don't need a separate "QR Scanner" and "EAN-13 Scanner." A single pyzbar.decode() call will return:
- Standard Barcodes: EAN-13, UPC-A, Code 128, Code 39.
- 2D Codes: QR Codes.
Note on Data Matrix/PDF417: While
pyzbaris excellent for standard barcodes and QR codes, for specialized industrial codes like Data Matrix, you might need thepylibdmtxlibrary.
π Sources & Further Readingβ
- [4.1] PyZbar Documentation: NaturalHistoryMuseum/pyzbar - Primary source for the decoder logic.
- [4.2] OpenCV Official Documentation: Drawing Functions - For localization visualization.
- [4.3] LearnOpenCV: Barcode and QR Code Scanner - Detailed breakdown of the pre-processing math.
- [4.5] PyImageSearch: Real-time Barcode Scanning - Source for the frame-by-frame loop optimization.
