使用 OpenCV QRCodeDetector 读取条形码

Reading a barcode using OpenCV QRCodeDetector

我正尝试在 Python3 上使用 OpenCV 创建带有 QR 码的图像并读回该代码。

这里是一些相关的代码:

def make_qr_code(self, data):
    qr = qrcode.QRCode(
        version=2,
        error_correction=qrcode.constants.ERROR_CORRECT_H,
        box_size=10,
        border=4,
    )

    qr.add_data(data)
    return numpy.array( qr.make_image().get_image())

# // DEBUG
img = numpy.ones([380, 380, 3]) * 255
index = self.make_qr_code('Hello Whosebug!')
img[:index.shape[0], :index.shape[1]][index] = [0, 0, 255]
frame = img
# // DEBUG

self.show_image_in_canvas(0, frame)
frame_mono = cv.cvtColor(numpy.uint8(frame), cv.COLOR_BGR2GRAY)
self.show_image_in_canvas(1, frame_mono) 

qr_detector = cv.QRCodeDetector()
data, bbox, rectifiedImage = qr_detector.detectAndDecode(frame_mono)
if len(data) > 0:
    print("Decoded Data : {}".format(data))
    self.show_image_in_canvas(2, rectifiedImage)
else:
    print("QR Code not detected")

(调用 show_image_in_canvas 只是为了在我的 GUI 中显示图像,这样我就可以看到发生了什么)。

在目测 frameframe_mono 时,我觉得没问题

但是,QR 码检测器 return 什么都没有(进入其他:"QR Code not detected")。

除了我刚刚生成的 QR 码,框架中几乎没有其他内容。我需要对 cv.QRCodeDetector 进行哪些配置,或者我需要对相框进行哪些额外的预处理才能使其找到二维码?

OP在这里;通过仔细查看生成的二维码并将其与其他来源进行比较,解决了这个问题。

问题不在检测上,而是在二维码的生成上。 显然,qrcode.QRCode returns 的数组在 的网格正方形中具有 False(或者可能是 0,我认为它是一个布尔值) 部分代码,以及 不是 .

的正方形中的 True (或非零)

所以当我这样做时 img[:index.shape[0], :index.shape[1]][index] = [0, 0, 255] 我实际上是在创建二维码的负面图像。

当我将index数组倒置后,二维码由左图变成右图,检测成功

此外,我决定切换到 ZBar 库,因为它在不太完美的情况下(例如从网络摄像头图像)检测这些代码要好得多。

import cv2
import sys

filename = sys.argv[1]
# Or you can take file directly like this:
#   filename = f'images/filename.jpg' where images is folder for files that you trying to read 

# read the QRCODE image
# in case if QR code is not black/white it is better to convert it into grayscale
# Zero means grayscale
img = cv2.imread(filename, 0)  
img_origin = cv2.imread(filename)

# initialize the cv2 QRCode detector
detector = cv2.QRCodeDetector()

# detect and decode
data, bbox, straight_qrcode = detector.detectAndDecode(img)

# if there is a QR code
if bbox is not None:
    print(f"QRCode data:\n{data}")
    # display the image with lines
    # length of bounding box
    # Cause bbox = [[[float, float]]], we need to convert fload into int and loop over the first element of array
    n_lines = len(bbox[
                      0])  
    bbox1 = bbox.astype(int)  # Float to Int conversion
    for i in range(n_lines):
        # draw all lines
        point1 = tuple(bbox1[0, [i][0]])
        point2 = tuple(bbox1[0, [(i + 1) % n_lines][0]])
        cv2.line(img_origin, point1, point2, color=(255, 0, 0), thickness=2)

    # display the result
    cv2.imshow("img", img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

else:
    print("QR code not detected")