杰瑞科技汇

Python OpenCV如何高效识别二维码?

Of course! Using Python and OpenCV to read QR codes is a common and powerful task. While OpenCV has built-in QR code detection capabilities, the most robust and widely used method is to use the pyzbar library, which is a wrapper for the excellent ZBar library.

Python OpenCV如何高效识别二维码?-图1
(图片来源网络,侵删)

Here's a complete guide covering three scenarios:

  1. Reading QR codes from an image file.
  2. Reading QR codes from your webcam in real-time.
  3. Detecting QR codes in a live video stream and drawing a bounding box around them.

Prerequisites: Installation

First, you need to install the necessary libraries. opencv-python is for image/video processing, and pyzbar is for the QR code decoding.

pip install opencv-python
pip install pyzbar

Important Note for Linux Users: pyzbar relies on the zbar library. You need to install its system dependencies first.

  • For Ubuntu/Debian:
    sudo apt-get update
    sudo apt-get install libzbar0
  • For Fedora/CentOS:
    sudo dnf install zbar

Method 1: Reading QR Codes from an Image File

This is the simplest case. We'll load an image, find all QR codes in it, and print their data.

Python OpenCV如何高效识别二维码?-图2
(图片来源网络,侵删)

Code

import cv2
from pyzbar.pyzbar import decode
# 1. Load the image
image_path = 'qrcode.png'  # Replace with your image path
image = cv2.imread(image_path)
if image is None:
    print(f"Error: Could not read image from {image_path}")
    exit()
# 2. Decode the QR codes
# The decode function returns a list of Decoded objects
decoded_objects = decode(image)
# 3. Process the decoded data
print(f"Found {len(decoded_objects)} QR code(s).")
for obj in decoded_objects:
    # Get the data and type
    qr_data = obj.data.decode('utf-8')
    qr_type = obj.type
    print(f"Type: {qr_type}")
    print(f"Data: {qr_data}")
    # Get the bounding box coordinates
    # obj.rect is a Rect object with (x, y, w, h)
    (x, y, w, h) = obj.rect
    # Draw a rectangle around the QR code
    cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 3)
    # Put the text above the rectangle
    text_y = y - 10 if y - 10 > 10 else y + h + 20
    cv2.putText(image, qr_data, (x, text_y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
# 4. Display the result
cv2.imshow('QR Code Detection', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Explanation

  1. cv2.imread(): Loads the image from the specified file path.
  2. decode(image): This is the core function from pyzbar. It scans the image and returns a list of all detected barcodes/QR codes.
  3. Looping through decoded_objects: Each object in the list represents one detected code.
    • obj.data: The raw data of the code (bytes). We decode it to a UTF-8 string.
    • obj.type: The type of barcode (e.g., 'QRCODE', 'CODE128', 'EAN13').
    • obj.rect: The coordinates of the bounding box around the code.
  4. Drawing: We use OpenCV's drawing functions (rectangle, putText) to visually mark the detected QR code and display its data on the image.
  5. cv2.imshow(): Displays the final image with the annotations.

Method 2: Reading QR Codes from a Webcam (Real-Time)

This method continuously captures frames from your webcam, decodes any QR codes found in each frame, and prints the data to the console.

Code

import cv2
from pyzbar.pyzbar import decode
# Initialize the webcam
# 0 is usually the default webcam
cap = cv2.VideoCapture(0)
if not cap.isOpened():
    print("Error: Could not open webcam.")
    exit()
print("Starting QR code scanner. Press 'q' to quit.")
while True:
    # Read a frame from the webcam
    success, frame = cap.read()
    if not success:
        print("Error: Failed to capture frame.")
        break
    # Decode QR codes in the current frame
    decoded_objects = decode(frame)
    for obj in decoded_objects:
        qr_data = obj.data.decode('utf-8')
        print(f"QR Code Data: {qr_data}")
        # Optional: Draw bounding box and text on the frame
        (x, y, w, h) = obj.rect
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 3)
        cv2.putText(frame, qr_data, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
    # Display the frame
    cv2.imshow('Live QR Code Scanner', frame)
    # Exit the loop if 'q' is pressed
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
# Release resources
cap.release()
cv2.destroyAllWindows()

Explanation

  1. cv2.VideoCapture(0): Initializes the video capture object using the default webcam.
  2. while True loop: This creates a real-time video stream.
  3. cap.read(): Captures one frame from the webcam. success is a boolean indicating if the frame was captured correctly.
  4. Decoding and Drawing: The logic is identical to the image method, but it's applied to every frame of the video stream.
  5. cv2.waitKey(1): This is crucial for real-time applications. It waits for 1 millisecond for a key press. This prevents the window from freezing and allows the loop to continue.
  6. ord('q'): Checks if the 'q' key was pressed to break the loop and stop the scanner.
  7. cap.release() and cv2.destroyAllWindows(): Properly closes the video stream and all OpenCV windows.

Method 3: Advanced - Live Stream with Bounding Box and Data

This is an enhanced version of Method 2. It draws a bounding box around the QR code and also displays the decoded data on the screen, making it more user-friendly.

Code

import cv2
from pyzbar.pyzbar import decode
# Initialize the webcam
cap = cv2.VideoCapture(0)
# Check if the webcam is opened correctly
if not cap.isOpened():
    print("Error: Could not open webcam.")
    exit()
print("Starting QR code scanner. Press 'q' to quit.")
while True:
    success, frame = cap.read()
    if not success:
        break
    # Convert the frame to grayscale for potentially faster decoding
    # (though pyzbar handles color well, this can be an optimization)
    # gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    # decoded_objects = decode(gray_frame)
    decoded_objects = decode(frame)
    for obj in decoded_objects:
        # Get data and coordinates
        qr_data = obj.data.decode('utf-8')
        (x, y, w, h) = obj.rect
        # Draw a green rectangle around the QR code
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 3)
        # Prepare the text to be displayed
        text = f"Data: {qr_data}"
        # Get the width and height of the text to position the background
        (text_width, text_height), baseline = cv2.getTextSize(text, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1)
        # Draw a filled rectangle behind the text for better readability
        cv2.rectangle(frame, (x, y - text_height - baseline), (x + text_width, y), (0, 255, 0), -1)
        # Put the text on the frame
        cv2.putText(frame, text, (x, y - baseline), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1)
    # Display the resulting frame
    cv2.imshow('QR Code Scanner with Data', frame)
    # Break the loop on 'q' key press
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
# Release everything
cap.release()
cv2.destroyAllWindows()

Explanation

The main difference here is how the text is rendered.

  1. cv2.getTextSize(): This function calculates
Python OpenCV如何高效识别二维码?-图3
(图片来源网络,侵删)
分享:
扫描分享到社交APP
上一篇
下一篇