简单搜索后发现有两种Python三方库可以实现扫码功能:zxing和pyzbar,以下是示例代码:
import zxing
def qrcode_zxing(image_path):
zxreader = zxing.BarCodeReader()
zxdata = zxreader.decode(image_path)
return zxdata.parsed
zxing是基于Java zxing库的python封装,使用比较简单,识别率不错,但功能比较有限只能识别图片中一个二维码,而且性能较差识别耗时较长。
import pyzbar.pyzbar as pyzbar
from PIL import Image, ImageEnhance
def zbar_parser(image_path):
img = Image.open(image_path)
#以下图片处理过程可以不做
#img = ImageEnhance.Brightness(img).enhance(2.0)#增加亮度
#img = ImageEnhance.Sharpness(img).enhance(17.0)#锐利化
#img = ImageEnhance.Contrast(img).enhance(4.0)#增加对比度
#img = img.convert('L')#灰度化
qrcodes = pyzbar.decode(img)
for qrcode in qrcodes:
qrcodeData = qrcode.data.decode("utf-8")
print(qrcodeData)
pyzbar是基于zbar库的python封装,使用起来略微复杂,能识别多个二维码性能也不错,但识别率堪忧,有些图片不做预处理的话多个二维码一个也识别不出,即使做预处理也可能只识别出部分,所以似乎也不是最好的选择。
继续搜索发现微信曾经把二维码扫码功能贡献给了OpenCV社区,需要安装opencv-contrib-python(>=4.5.1),简单的示例代码如下:
import cv2
print('cv2.__version__:', cv2.__version__)
detector = cv2.wechat_qrcode_WeChatQRCode()
img = cv2.imread(image_path)
res, points = detector.detectAndDecode(img)
print('res: ', res)
测试一下发现性能识别率都挺好,但只能识别图片中的一个二维码,想要识别多个二维码还需要以下高阶用法:
import cv2
depro = './config/detect.prototxt'
decaf = './config/detect.caffemodel'
srpro = './config/sr.prototxt'
srcaf = './config/sr.caffemodel'
detector = cv2.wechat_qrcode_WeChatQRCode(depro, decaf, srpro, srcaf)
img = cv2.imread(image_path)
#img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #转为灰度图片,可以不做
qrcodes, points = detector.detectAndDecode(img)
print('qrcodes: ', qrcodes)
其中config目录中由微信提供的模型文件下载地址:GitHub - WeChatCV/opencv_3rdparty: OpenCV - 3rdparty
测试结果比较理想,同样图片不做预处理的情况下识别率高于pyzbar,但偶尔也会发生图片中多个二维码只能识别部分的问题,同样的图片交给微信客户端识别测试结果一致,看来想要更完整准确的识别结果就需要对图片进行一些针对性的预处理了。
至此,使用Python识别图片中多个二维码的解决方案可以基本确定为OpenCV中的微信扫码功能。