安装pyzbar,通过pyzbar中的decode函数读取图片中的二维码/条形码信息。
首先看一下decode读取的信息长啥样。
import cv2 as cv
import numpy as np
from pyzbar.pyzbar import decode
img = cv.imread('Qrcode1.jpg')
code = decode(img)
print(code)
[Decoded(data=b’111111’, type=‘QRCODE’, rect=Rect(left=93, top=195, width=82, height=81), polygon=[Point(x=93, y=195), Point(x=93, y=276), Point(x=175, y=276), Point(x=175, y=195)])]
data中就是二维码中所包含的信息,rect和polygon体现了二维码边界框的所在位置和大小,前者是矩形的表示方式,后者是多边形的表示方式。
接下来识别一个含有多个二维码的图片,通过循环可以把每一个二维码的每一部分的信息单独输出。
for barcode in code:
print(barcode.data)
print(barcode.rect)
print(barcode.polygon)
myData = barcode.data.decode('utf-8')
print(myData)
下面是其中前两组的输出。
b’987654’
Rect(left=124, top=352, width=210, height=210)
[Point(x=124, y=352), Point(x=124, y=562), Point(x=334, y=562), Point(x=334, y=352)]
987654
b’111116’
Rect(left=621, top=354, width=210, height=210)
[Point(x=621, y=354), Point(x=621, y=564), Point(x=831, y=564), Point(x=831, y=354)]
111116
通过这些信息可以在图像上框出二维码并输出对应的信息(在测试时发现如果一张图中的二维码相离比较远,可能就不能全部识别出来,不知道是什么原因)。在这里再创建一个text文件作为授权名单,其中包括111111、111112、111113、111114、111115,通过对比所识别信息和文件中的信息,来判断所识别信息是否已授权。
import cv2 as cv
import numpy as np
from pyzbar.pyzbar import decode
with open('myDataFile.text') as f:
myDataList = f.read().splitlines() #读取被授权名单
print(myDataList)
img = cv.imread('QrCode.jpg')
code = decode(img)
for barcode in code:
myData = barcode.data.decode('utf-8')
print(myData)
if myData in myDataList: # 根据名单判断是否授权,同时切换输出的文本和边界框颜色
myOutput = 'Authorized'
myColor = (0, 255, 0)
print('Authorized')
else:
myOutput = 'Un-Authorized'
myColor = (0, 0, 255)
print('Un-Authorized')
# 用多边形画出二维码的边界框。因为当画面出现旋转时,矩形可能无法画出相应的区域 #
pts = np.array([barcode.polygon], np.int32)
print(pts)
pts = pts.reshape((-1, 1, 2))
print(pts)
cv.polylines(img, [pts], True, myColor, 5)
pts2 = barcode.rect #使用矩形左上方的点作为文本初始点
cv.putText(img,myData+myOutput, (pts2[0], pts2[1]-25), cv.FONT_HERSHEY_SIMPLEX, 0.9, myColor, 2)
cv.imshow('Result',img)
cv.waitKey(0)
最后通过电脑摄像头来捕捉二维码并输出,大致思路相同,只是需要设置下摄像头。
import cv2 as cv
import numpy as np
from pyzbar.pyzbar import decode
# 读取摄像头捕捉到的二维码
cap = cv.VideoCapture(0) #从我的笔记本摄像头读取视频(只有一个,编号为0)
cap.set(3,640) #3表示设置视频流的帧的宽度
cap.set(4,480) #4表示设置视频流的帧的高度
with open('myDataFile.text') as f:
myDataList = f.read().splitlines() #读取被授权名单
print(myDataList)
while True:
success,img = cap.read()
for barcode in decode(img):
print(barcode.data)
myData = barcode.data.decode('utf-8')
print(myData)
if myData in myDataList:
myOutput = 'Authorized'
myColor = (0,255,0)
print('Authorized')
else:
myOutput = 'Un-Authorized'
myColor = (0, 0, 255)
print('Un-Authorized')
pts = np.array([barcode.polygon],np.int32)
print(pts)
pts = pts.reshape((-1,1,2))
print(pts)
cv.polylines(img,[pts],True,myColor,5)
pts2 = barcode.rect
cv.putText(img,myData+myOutput,(pts2[0],pts2[1]-25),cv.FONT_HERSHEY_SIMPLEX,0.9,myColor,2)
cv.imshow('Result',img)
cv.waitKey(1)
遗憾的是本次实验中测试条形码的效果并不是很好。截图的效果是多次尝试中比较好的结果,其他的识别结果多边形大多是不规则的,不知是因为手持导致的不稳定还是国内外的条形码差别,又或是其他原因…