首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Recognize QR codes by pyzbar

Recognize QR codes by pyzbar

原创
作者头像
Swing Dunn
发布2025-10-23 16:38:42
发布2025-10-23 16:38:42
1380
举报
文章被收录于专栏:Some studies in imgsSome studies in imgs

Here we explains how to use pyzbar to recognize QR codes.

1.First, the image needs to be read and converted into a grayscale image.

To make it simpler, directly extract the approximate area where the QR code is located from the image.

代码语言:txt
复制
                ori_img = cv2.imread(file_path, cv2.IMREAD_ANYCOLOR)  # 目标图像
                if len(ori_img.shape) == 3 and ori_img.shape[2] == 3:
                    gray_img = cv2.cvtColor(ori_img, cv2.COLOR_BGR2GRAY)
                elif len(ori_img.shape) == 2:
                    gray_img = ori_img.copy()
                else:
                    print('error: bad image')
                    return   
                ori_bar_area = ori_img[bar_range[1]:bar_range[3], bar_range[0]:bar_range[2]]
                bar_area = gray_img[bar_range[1]:bar_range[3], bar_range[0]:bar_range[2]]
QR Code area
QR Code area

2.Adjust the size of the image, recognize it at different scales;reduce image noise and interference through preprocessing, and improve the image quality of the QR code area may help increase the accuracy of recognition.

代码语言:txt
复制
                lt_sacle = [1.0, 1.25, 1.5, 2.0, 2.25, 2.5, 3.0]
                for scale_factor in lt_sacle:
                    resized_image = cv2.resize(bar_area, None, fx=scale_factor, fy=scale_factor, interpolation=cv2.INTER_LINEAR)
                    
                    blurred_image = cv2.GaussianBlur(resized_image, (7, 7), 0)
                   #blurred_image = cv2.medianBlur(blurred_image, 5)
                    #g_threshold, binary = cv2.threshold(resized_image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
                    qrcode_content = recognize_QRcode(blurred_image)

3.Identify the content of the QR code using pyzbar

代码语言:txt
复制
def recognize_QRcode(img):
    # 使用 pyzbar 解码二维码
    decoded_objects = decode(img)

    # 遍历解码结果
    for obj in decoded_objects:
        points = obj.polygon
        if len(points) > 4:
            hull = cv2.convexHull(np.array([point for point in points], dtype=np.float32))
            points = hull

        for j in range(len(points)):
            cv2.line(img, tuple(points[j]), tuple(points[(j + 1) % len(points)]), (0, 255, 0), 3)
    if(len(decoded_objects) > 0):
        return obj.data.decode('utf-8')
    else:
        return None

4.Visualization of the decoding results:

代码语言:txt
复制
 qrcode_content = recognize_QRcode(blurred_image)
                    if qrcode_content:
                        print("二维码缩放率:", scale_factor)
                        print('二维码内容: ', qrcode_content)
                        x, y = (10,140)
                        cv2.putText(ori_bar_area,qrcode_content, (x, y), cv2.FONT_HERSHEY_SIMPLEX,0.6,  (0, 0, 255), 1)
                        find = True
                        show_image(ori_bar_area)
                        break
                    else:
                        show_image(blurred_image)

result
result

5.Since the images of these QR codes in my group are rather blurry and of poor quality, there will also be cases where they cannot be recognized.

Like this:

No result
No result

6.Recognition accuracy rate

For nearly a thousand identical poor quality QR code identifications, the accuracy rates are as follows:

accuracy rate
accuracy rate

When the QR code is clear enough, pyzbar will be a reliable tool.

Source code:

代码语言:txt
复制

import cv2
import os
from pyzbar.pyzbar import decode
import numpy as np

# 读取目标图像和模板图像
def show_image(img):
    cv2.namedWindow("1",cv2.WINDOW_AUTOSIZE )
    cv2.imshow("1",img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

def recognize_QRcode(img):
    # 使用 pyzbar 解码二维码
    decoded_objects = decode(img)

    # 遍历解码结果
    for obj in decoded_objects:
        points = obj.polygon
        if len(points) > 4:
            hull = cv2.convexHull(np.array([point for point in points], dtype=np.float32))
            points = hull

        for j in range(len(points)):
            cv2.line(img, tuple(points[j]), tuple(points[(j + 1) % len(points)]), (0, 255, 0), 3)
    if(len(decoded_objects) > 0):
        return obj.data.decode('utf-8')
    else:
        return None
  

def main():
    folder_path = './imgs8'
    #模板定位点信息
    bar_range = (1377, 152, 1536, 293)
    paper_num = 0
    error_paper_num = 0

    # 递归遍历文件夹
    for root, dirs, files in os.walk(folder_path): 
        for filename in files:
            if filename.lower().endswith('.jpg'):
                paper_num += 1

                file_path = os.path.join(root, filename)
                ori_img = cv2.imread(file_path, cv2.IMREAD_ANYCOLOR)  # 目标图像
                if len(ori_img.shape) == 3 and ori_img.shape[2] == 3:
                    gray_img = cv2.cvtColor(ori_img, cv2.COLOR_BGR2GRAY)
                elif len(ori_img.shape) == 2:
                    gray_img = ori_img.copy()
                else:
                    print('error: bad image')
                    return   

                ori_bar_area = ori_img[bar_range[1]:bar_range[3], bar_range[0]:bar_range[2]]
                bar_area = gray_img[bar_range[1]:bar_range[3], bar_range[0]:bar_range[2]]
                #show_image(bar_area)

                find = False
                lt_sacle = [1.0, 1.25, 1.5, 2.0, 2.25, 2.5, 3.0]
                for scale_factor in lt_sacle:
                    resized_image = cv2.resize(bar_area, None, fx=scale_factor, fy=scale_factor, interpolation=cv2.INTER_LINEAR)
                    
                    blurred_image = cv2.GaussianBlur(resized_image, (7, 7), 0)
                    blurred_image = cv2.medianBlur(blurred_image, 5)
                    g_threshold, binary = cv2.threshold(resized_image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
                    qrcode_content = recognize_QRcode(blurred_image)
                    if qrcode_content:
                        print("二维码缩放率:", scale_factor)
                        print('二维码内容: ', qrcode_content)
                        x, y = (10,140)
                        cv2.putText(ori_bar_area,qrcode_content, (x, y), cv2.FONT_HERSHEY_SIMPLEX,0.6,  (0, 0, 255), 1)
                        find = True
                        #show_image(ori_bar_area)
                        break
                if not find : 
                    error_paper_num += 1
                    pass
                    #show_image(blurred_image)
              
                
                print('识别总份数: ', paper_num)
                print('未识别到二维码份数: ', error_paper_num)
                print('二维码识别率: ', str(1 - error_paper_num / paper_num))
                print()     


if __name__ == '__main__':
    main()

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Source code:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档