二维码

种类

根据公开协议,二维码有这些:

  • QR Code
  • Micro QR Code
  • Data Matrix:特别适合在小面积上高密度存储信息,常见于制造业和医疗
    • 特点:左边和下边是实心组成的“L”型,右边和上边是黑白间隔的格子(时钟边)
  • PDF417:多用于物流和身份证
  • Aztec Code:主要用于运输领域
  • 等等

在线生成(几百种):https://barcode.tec-it.com/en/MobileSemaPhone

QR Code 的参数

  • Version:1到40,版本越高,二维码越大,存储数据越多
  • 容错等级
    • L:7%
    • M:15%
    • Q:25%
    • H:30%
  • 编码模式:
    • 数字 Numeric
    • 字母数字 Alphanumeric
    • 字节 Byte
    • 汉字 Kanji
    • 混合
  • 掩码模式:8种(0-7)用于避免二维码图案误读

QR Code 的基本原理-生成

  • 数据分段。对输入的数据(文本、数据、二进制)用合适的模式进行分段
  • 数据编码:例如转字节
  • Reed-Solomon 编码:用于纠错
  • 定位信息、信息潜入
  • 输出最终的图像

QR Code 的基本原理-识别

  1. 定位
    • 检测3个定位图案(Finder Pattern)的位置
    • 检测对齐图案(Alignment pattern),以对抗畸变
    • 检查定时图案(Timing pattern),辅助网格采样
  2. 几何校正
    • 解决投影变形(如斜拍、小角度弯曲),采用透视变换把拍摄到的二维码”拉正”
  3. 图像分割与采样
    • 按码元格(Module)网格提取每个小黑/白块的颜色,转换为比特流。
  4. 二值化处理
    • 各种阈值算法(OTSU、局部阈值),提高在光照变化下的鲁棒性。
  5. 掩模还原
    • 去除编码时的掩码,还原真实数据比特流。
  6. 纠错与译码
    • 解码比特流,利用RS算法纠正一定范围内的损坏;
    • 转成原始数据输出(文本、链接、文件等)。

caption: QR

caption: Micro QR

caption: pdf417

caption: data_matrix

生成二维码

https://github.com/lincolnloop/python-qrcode

#%% pip install qrcode
import qrcode

qr = qrcode.QRCode(
    version=1,
    error_correction=qrcode.constants.ERROR_CORRECT_L,
    box_size=10,
    border=4,
)
qr.add_data('https://www.guofei.site/')
qr.make(fit=True)

img = qr.make_image(fill_color="black", back_color="white")

img.save("qr.png")

# %% Micro QR
# pip install segno
import segno

segno.make('guofei.site/', micro=True). \
    save('micro_qr.png', scale=10)

# %% PDF417
# pip install pdf417gen
import pdf417gen

codes = pdf417gen.encode('https://www.guofei.site/')
img_pdf417 = pdf417gen.render_image(codes)  # PIL.Image对象
img_pdf417.save('pdf417.png')

datamatrix 可以用 rust 版:

  • https://github.com/jannschu/datamatrix-rs
  • 或者 https://github.com/rxing-core/rxing

读取二维码:opencv

# -*-coding:utf-8 -*-

import cv2 as cv
import numpy as np

src_image = cv.imread("./img.png")
qrcode = cv.QRCodeDetector()

# qr检测并解码
msg, points, straight_qrcode = qrcode.detectAndDecode(src_image)
# 绘制qr检测到的边框
cv.drawContours(src_image, [np.int32(points)], 0, (0, 0, 255), 2)
print("points", points)
# 打印解码结果
print("qrcode :", msg)
cv.imshow("result", src_image)
cv.waitKey(0)
  • 对拍照之类的都能准确定位边框
  • 某些系统产出的二维码无法提取信息(但边框检测还是可以准确定位)


您的支持将鼓励我继续创作!