二维码
🗓 2022年11月05日 📁 文章归类: 0x25_CV
版权声明:本文作者是郭飞。转载随意,标明原文链接即可。
原文链接:https://www.guofei.site/2022/11/05/qr.html
种类
根据公开协议,二维码有这些:
- 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 的基本原理-识别
- 定位
- 检测3个定位图案(Finder Pattern)的位置
- 检测对齐图案(Alignment pattern),以对抗畸变
- 检查定时图案(Timing pattern),辅助网格采样
- 几何校正
- 解决投影变形(如斜拍、小角度弯曲),采用透视变换把拍摄到的二维码”拉正”
- 图像分割与采样
- 按码元格(Module)网格提取每个小黑/白块的颜色,转换为比特流。
- 二值化处理
- 各种阈值算法(OTSU、局部阈值),提高在光照变化下的鲁棒性。
- 掩模还原
- 去除编码时的掩码,还原真实数据比特流。
- 纠错与译码
- 解码比特流,利用RS算法纠正一定范围内的损坏;
- 转成原始数据输出(文本、链接、文件等)。
生成二维码
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)
- 对拍照之类的都能准确定位边框
- 某些系统产出的二维码无法提取信息(但边框检测还是可以准确定位)
您的支持将鼓励我继续创作!
