Python实现扫码工具

Python实现扫码工具

一.步骤

1.生成二维码,二维码解析 2.调用摄像头 3.识别二维码。

opencv是英特尔的计算机视觉处理模块,而pyzbar则是用于解析二维码的模块。

二、环境

环境包括python环境和模块。我的环境如下:

模块安装很简单,我们直接用pip安装,先安装opencv模块:

pip install opencv-python-4.4.0.44
pip install pyzbar
pip install numpy
pip install qrcode
pip install MyQR
pip install zxing
pip install pillow

三.生成二维码

# 导包
# 方法1 MyQR二维码加背景图片(公司logo)
from MyQR import myqr
# 方法2 qrcode 二维码
import qrcode

# 主要用到以下几个参数
# words:文本,可以是一个链接,或者你想说的话(不支持中文,很不友好)
# picture:你用到的图片,作为背景,不然只是一个光秃秃的二维码
# colorsize:True,表示生成彩图
# save_name:表示生成的二维码的名字

# 解析1
import zxing

# 解析2
import numpy as np
from PIL import Image
from pyzbar import pyzbar

class UserQR():
    def __init__(self):
        self.bgimg = "view.png"
        self.url="http://127.0.0.1:5000/users/opendoor"

    def qr(self,opencode,userid):
        myqr.run(words=self.url+"?opencode="+str(opencode)+"&userid="+str(userid),
                 picture=self.bgimg,
                 colorized=True,
                 save_name="UserQRimg/"+str(userid)+".png")

    def myqr(self,opencode,userid):
        # 调用QRCode,可以接收以下参数
        """
        version: 二维码的格子大小,可以是1到40。值越大,格子越大,一般不超过10,选择3比较合适
        error_correction: 二维码错误容许率,默认为qrcode.constants.ERROR_CORRECT_M,容许小于 15% 的错误率
                 此外还有qrcode.constants.ERROR_CORRECT_L: 容许小于 7% 的错误率
                 qrcode.constants.ROR_CORRECT_H: 容许小于 30% 的错误率
        box_size: 二维码每个小格子包含的像素数量
        border: 二维码到图片边框的小格子数,默认值为 4
        """
        qr = qrcode.QRCode()  # 事实上里面的参数我们可以都不指定,默认会选择一个比较合适的参数
        # 调用add_data,指定url或者数据。
        qr.add_data(self.url+"?opencode="+str(opencode)+"&userid="+str(userid))
        # 生成二维码图像,颜色为蓝色,背景色为粉色
        img = qr.make_image(fill_color='blue', back_color='pink')
        # 显示图像,这个会打开一个临时文件
        img.show()
        # 此外,我们还可以保存到硬盘上
        img.save("img/"+str(userid)+".png")

        # 事实上,这个img实际上是通过PIL模块得到的,可以理解为里面Image对象
        # 如果你熟悉PIL模块的话,那么你应该知道可以将里面Image对象保存成图片对应的字节流
        from io import BytesIO

        buf = BytesIO()
        img.save(buf)  # 将字节保存到buf里面
        with open("img/"+str(userid)+".png", "wb") as f:
            f.write(buf.getvalue())  # 和直接保存为1.png是一样的

    # 解析1
    def decode_QR(self):
        reader = zxing.BarCodeReader()
        barcode = reader.decode('UserQRimg/1.png')
        # 解析二维码图片
        return barcode.parsed  # 是可以解析出来的

    # 解析2
    def decode_QR1(self):
        # 读取文件,转成数组
        im = np.array(Image.open("UserQRimg/1.png"))
        print(pyzbar.decode(im))
        # 返回的信息还是很多的
        """
        [
           Decoded(data=b'http://www.bilibili.com',
               type='QRCODE',
               rect=Rect(left=35, top=35, width=263, height=264),
               polygon=[Point(x=35, y=35), Point(x=35, y=297), Point(x=297, y=299), Point(x=298, y=35)])
        ]
        """
        # 返回拿到的内容
        return pyzbar.decode(im)[0].data.decode("utf-8")

my = UserQR()
# my.qr("123456",1)

四、识别二维码

有了pyzbar模块后,我们识别二维码的工作就非常简单了,首先需要准备一张二维码。有了二维码后就可以开始解析了,具体步骤如下:

1.读取二维码图片2.解析二维码中的数据3.在解析出的数据中提取data信息

实现代码如下:

import cv2
from pyzbar import pyzbar
# 1、读取二维码图片
qrcode = cv2.imread('qrcode.jpg')
# 2、解析二维码中的数据
data = pyzbar.decode(qrcode)
print(data)
# 3、在数据中解析出二维码的data信息
text = data[0].data.decode('utf-8')
print(text)

这样我们就能拿到二维码中包含的信息了。为了方便后续使用,可以将上面的代码写成一个函数:

def scan_qrcode(img_path):
    qrcode = cv2.imread(img_path)
    data = pyzbar.decode(qrcode)
    return data[0].data.decode('utf-8')

接下来我们再看看如何调用摄像头。

四、调用摄像头

在opencv中提供了一个VideoCapture类用于读取视频,同样可以用来调用摄像头。调用摄像头的步骤如下:

1.调用摄像头2.循环3.在循环内读取一帧画面4.显示当前读取的画面5.等待键盘输入6.判断是否按退出键q7.按了退出键则退出,没按则继续循环

使用 cv2.VideoCapture

  • filename – 文件路径;
  • device – 视频设备id ,若只有一个摄像头可以填 0,表示打开默认摄像头;

使用 VideoCapture 对象的 read 方法按帧读取视频,ret, frame 是 read 方法的两个返回值 ,其中 ret 是布尔值,如果能正确读取帧,则返回 True;如果文件读取到结尾,它的返回值就为 False。frame 就是每一帧的图像,是一个三维矩阵。

具体代码如下:

import cv2
# 调用摄像头(0,笔记本默认摄像头)
cap = cv2.VideoCapture(0)
while True:
    # 读取一帧画面,fram:三维矩阵
    ret, frame = cap.read()
    # 显示当前帧
    cv2.imshow('scan qrcode', frame)
    # 等待键盘输入
    key = cv2.waitKey(10)
    # 当按下q键时关闭摄像头
    if key == ord('q'):
        break
# 销毁所有窗口
cv2.destroyAllWindows()

你们可以自己尝试运行一下上面的代码,效果就像是打开了自己的前置摄像头。

现在调用了摄像头,我们可以把两部分的代码结合起来。

五、实现扫码工具

我们扫码工具的主体部分是调用摄像头的操作,我们需要对读取到的每一帧画面进行解析,当解析出结果后输出并退出。具体代码如下:

import cv2
from pyzbar import pyzbar

def scan_qrcode(qrcode):
    data = pyzbar.decode(qrcode)
    return data[0].data.decode('utf-8')

cap = cv2.VideoCapture(0)
while True:
    ret, frame = cap.read()
    cv2.imshow('scan qrcode', frame)

    # 解析二维码
    text = None
    try:
        text = scan_qrcode(frame)
    except Exception as e:
        pass
    if text:
        print(text)
        break

    key = cv2.waitKey(10)
    if key == ord('q'):
        break
cv2.destroyAllWindows()

上面我们把scan_qrcode函数修改了一下,从原来的传入图片路径到直接传入图片对象。因为通过VideoCapture对象获取的图片帧和通过cv2.imread获取的图片是同一数据类型。

上面关键步骤在解析二维码的操作。首先定义一个text,因为解析过程中如果没有二维码会出现异常,所以用try-except语句处理。如何通过if判断text的内容,只有当我们真正解析到了数据,程序才会输出结果,并退出程序。

关闭视频文件

vc.release()

到这里,我们就实现了扫码工具。

你可能感兴趣的:(flask,python,视觉检测,图像处理)