Python OpenCV 二维码 reader

Python OpenCV QrCode reader

我想使用 opencv 和 Python 制作二维码 reader。我的硬件是 Raspberry Pi 4B 和 pi 相机。

在代码中,当我向相机显示二维码时,opencv 解码二维码。之后我想使用 requests.post 将此代码发送到 Node.js 服务器。那里一切都很好,但有一个问题。问题在于,只要相同的二维码停留在摄像头前,它就会不断发送 post 带有该二维码的请求。

在系统中,人们将通过手机phone读取二维码并根据二维码进入大楼。 Nodejs 向服务器发送无限请求,就像一个人发送二维码,只要它在屏幕上。

实际上系统应该是这样工作的,

用户将二维码保存在相机中。

使用requests.post,代码发送到服务器。

服务器 returns 否定或肯定响应。

答案出现在屏幕上。

在下一个用户到达之前不采取任何行动。

请给我你对这件事的看法。

如何在其他用户到达之前停止发送请求?

如何使用函数控制它?

test.py

basic_auth_url= "http://192.168.1.6:3000/test"


def qr_test(code):
    myObj={"code":code}
    response = requests.post(
            url=basic_auth_url,
            data=myObj
            )
            
    print(response.content)




cap = cv2.VideoCapture(0)

detector = cv2.QRCodeDetector()

while True:
    _, img = cap.read()
    data, bbox, _ = detector.detectAndDecode(img)
    
    if(bbox is not None):
        for i in range(len(bbox)):
            cv2.line(img, tuple(bbox[i][0]), tuple(bbox[(i+1) % len(bbox)][0]), color=(255,
                     0, 255), thickness=2)
        cv2.putText(img, data, (int(bbox[0][0][0]), int(bbox[0][0][1]) - 10), cv2.FONT_HERSHEY_SIMPLEX,
                    0.5, (0, 255, 0), 2)
        if data:
        
            code=data
            code1=str(code)
            code=code.split("|")

            code_1=code[1]
            code_1=code_1[0:10]
            qr_test(code_1)
    cv2.imshow("code detector", img)
    if(cv2.waitKey(1) == ord("q")):
        break
cap.release()
cv2.destroyAllWindows()

将全局变量 previous_qrcode 声明为 None 然后您将更新它为当前条形码的值,如果用户尝试使用类似于 previous_qrcode 的二维码值调用 qr_test() 函数该函数将不执行任何操作.

希望这会有所帮助

#!/usr/bin/python
# -*- coding: utf-8 -*-

# You can do this

basic_auth_url = 'http://192.168.1.6:3000/test'

previous_qrcode = None
def qr_test(code):
    if code != previous_qrcode:
        myObj = {'code': code}
        response = requests.post(url=basic_auth_url, data=myObj)
        print(response.content)
        previous_qrcode = code

正如我在评论中所写,您可以将最后一个 qrcode 保留在变量中并与新值进行比较。如果值相同则不要发送 request。如果新值不同,则发送 request 并保留新值以将其与下一个值进行比较。

Value last_qrcode 必须在函数外部才能成为全局值并在函数执行之间保持值。在函数内部你必须使用 global 来通知函数它必须给外部变量赋值

last_code = None   # default value at start

def qr_test(code):
    global last_code

    if code != last_code:
       myObj = {"code": code}
       response = requests.post(
                    url=basic_auth_url,
                    data=myObj
                 )
   
       result = response.content        
       last_code = code

       print(result)

您还可以将所有唯一值保留在某些 list/dictionary 中 - 作为缓存 - 从字典中获取它而不是发送 request。因为它会改变 ndictionary 中的值所以它不需要 global

last_code = None   # default value at start
all_codes = {}     # empty dict at start

def qr_test(code):
    global last_code

    if code != last_code:

       if code in all_codes:
           result = all_codes[code]
           print('already seen before')
       else:
           myObj = {"code": code}
           response = requests.post(
                    url=basic_auth_url,
                    data=myObj
                 )
           result = response.content        
           all_codes[code] result

       last_code = code              

       print(result)

您可以使用标准 functools.cache 作为缓存,但它需要以不同的方式写入它,并且它无法识别它是否是从缓存中获取的

import functools

last_code = None   # default value at start

@functools.cache
def check_code(code):
    myObj = {"code": code}
    response = requests.post(
                 url=basic_auth_url,
                 data=myObj
               )

    return response.content

def qr_test(code):
    global last_code

    if code != last_code:
       result = check_code(code)
       last_code = code              

       print(result)

使用 @functools.lru_cache(maxsize=10) 你可以在缓存中只保留 10 个最后的结果。