二维码识别

任务一

在项目week1中建立python脚本实现二维码识别,要求打印出二维码文本,并输出二维码四个角像素坐标

函数格式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def decode_qr(img_path):
"""

输入:图片路径

输出:
{

'content': 二维码文本,

'points': [[x1,y1],...,[x4,y4]] # 四个角点像素坐标

}

"""

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import cv2  

def decode_qr(img_path):
# 读取图片
image = cv2.imread(img_path)
if image is None:
raise ValueError("无法读取图片,请检查路径是否正确")

# 创建 QRCodeDetector 对象
qr_detector = cv2.QRCodeDetector()

# 检测并解码二维码
content, points, _ = qr_detector.detectAndDecode(image)

if not content:
return None # 如果没有检测到二维码,返回 None

points = points[0].tolist()

# 返回结果
return {
'content': content,
'points': points
}

if __name__ == "__main__":
result = decode_qr("mission1/1,2,3,left.png")
if result:
print("二维码内容:", result['content'])
print("二维码角点:", result['points'])
else:
print("未检测到二维码")

代码思路

先使用imread()函数读取指定路径的图片数据,如果无法读取,返回错误提示;若正常读取,使用detectAndDecode()方法检测和解码二维码,将返回值分别赋值给content,和points变量,然后将points变量转化为pyhton自带的列表形式,最后返回内容(保存在content变量中)和角点坐标(保存在points变量中)。

基础知识

imread()函数

1
cv2.imread(filename, flags)

参数:

  1. filepath:读入读取图片的路径(绝对/相对)
  2. flags:标志位,可输入参数如下
    • cv2.IMREAD_COLOR:默认参数,读入一副彩色图片,忽略alpha通道,可用1作为实参替代
    • cv2.IMREAD_GRAYSCALE:读入灰度图片,可用0作为实参替代
    • cv2.IMREAD_UNCHANGED:顾名思义,读入完整图片,包括alpha通道,可用-1作为实参替代

alpha通道,又称A通道,是一个8位的灰度通道,该通道用256级灰度来记录图像中的透明度复信息,定义透明、不透明和半透明区域,其中黑表示全透明,白表示不透明,灰表示半透明

路径注意点

filename:要读取的图像的完整路径,注意文件名中不能有中文

比如当读取文件为中文名时,输入image = cv2.imread("示范.png")

报错无法找到can't open/read file: check file path/integrity

imread()的返回值

imread()函数返回的是一个numpy.ndarray类型的数据,一般是一个三维数组

imread读取图片的颜色顺序是B->G->R
所以image[:,:,1] image[:,:,2] image[:,:,3] 这3个数组中分别存放图片各像素点BGR的值

imshow()

使用imshow()函数时,必须将输入值补全,特别是显示窗口的名称,否则无法显示,比如输入以下代码:

1
2
3
import cv2
a1 = cv2.imread("mission1/1,2,3,left.png")
cv2.imshow(a1)

显示错误

加上窗口名称后

1
2
3
import cv2  
a1 = cv2.imread("mission1/1,2,3,left.png")
cv2.imshow("sample",a1)

正常运行,但界面一闪而过

图片显示后一闪而过的原因是缺少让程序暂停的等待操作。cv2.imshow函数只是负责显示图像窗口,但如果没有后续的等待指令,窗口会立即关闭。

增加语句cv2.waitKey(0)

1
2
3
4
import cv2  
a1 = cv2.imread("mission1/1,2,3,left.png")
cv2.imshow("sample",a1)
cv2.waitKey(0)

图片正常保持显示

代码解释

根据题目要求,函数decode_qr()的输入值img_path是二维码的路径

1
image = cv2.imread(img_path)

通过cv2.imread() 函数将img_path路径的图片文件加载为 NumPy 数组,数组中的每个元素分别表示像素值的BGR数值

1
2
if image is None:
raise ValueError("无法读取图片,请检查路径是否正确")

检查图片是否成功加载,当imread返回值为空(None)时,说明图片路径无效或文件损坏,抛出异常提示用户

1
qr_detector = cv2.QRCodeDetector()

cv2.QRCodeDetector()是 OpenCV 提供的用于检测和解码二维码的类,创建一个了一个 QR 码检测器实例qr_detector

1
content, points, _ = qr_detector.detectAndDecode(image)

利用创建的实例qr_detectordetectAndDecode()方法检测图片转化的数组image中的二维码并解码其内容。
detectAndDecode()方法会返回三个值:

  1. content:二维码包含的信息(字符串格式)。
  2. points:二维码的四个角点坐标(NumPy 数组)。
  3. _:二维码的二进制数据(未使用)。
1
2
if not content:
return None

当没有检测到二维码时,detectAndDecode()方法会返回的第一个值content为空字符串,函数返回 None。

1
points = points[0].tolist()

detectAndDecode() 方法返回的二维码在图像中的位置信息保存在points中,points[0]中包含多个点的坐标,形式如points[0] = [[x1, y1], [x2, y2], [x3, y3], [x4, y4]]
tolist()是NumPy数组的一个方法,用于将数组转换为Python原生的列表格式。
这一句也可以删去。

1
2
3
4
return {
'content': content,
'points': points
}

按要求返回值。

运行结果

第一张二维码

第二张二维码

opencv #二维码 #QR #二维码识别


二维码识别
https://pattianfang.github.io/2025/04/01/二维码识别/
作者
Pat Tian Fang
发布于
2025年4月1日
更新于
2025年5月3日
许可协议