最近项目中用到二维码图片识别,在python下二维码识别,目前主要有三个模块:zbar 、zbarlight、zxing。
1、三个模块的用法:
#-*-coding=utf-8-*- import os import logging import zbar from PIL import Image import zxing import random import zbarlight logger=logging.getLogger(__name__) if not logger.handlers :logging.basicConfig(level=logging.INFO) DEBUG= (logging.getLevelName(logger.getEffectiveLevel())=='DEBUG') def ocr_qrcode_zbar(filename): img=Image.open(filename) width, height = img.size raw = img.tobytes() scanner = zbar.ImageScanner() scanner.parse_config('enable') #把图像装换成数据 zarimage = zbar.Image(width, height, 'Y800', raw) #扫描器进行扫描 scanner.scan(zarimage) data = '' for symbol in zarimage: # 对结果进行一些有用的处理 data += symbol.data if data: logger.debug(u'识别二维码:%s,内容: %s' %(filename ,data)) else: logger.error(u'识别zbar二维码出错:%s' %(filename)) img.save('%s-zbar.jpg' %filename) return data def ocr_qrcode_zbarlight(filename): img=Image.open(filename) width, height = img.size raw = img.tobytes() #把图像装换成数据 data = zbarlight.qr_code_scanner(raw, width, height) if data: logger.debug(u'识别二维码:%s,内容: %s' %(filename ,data)) else: logger.error(u'识别zbarlight二维码出错:%s' %(filename)) img.save('%s-zbar.jpg' %filename) return data def ocr_qrcode_zxing(filename): #在当前目录生成临时文件,规避java的路径问题 img= Image.open(filename) ran= int(random.random()*100000) img.save('%s%s.jpg' %(os.path.basename(filename).split('.')[0],ran)) zx = zxing.BarCodeReader() data ='' zxdata = zx.decode('%s%s.jpg' %(os.path.basename(filename).split('.')[0],ran)) #删除临时文件 os.remove('%s%s.jpg' %(os.path.basename(filename).split('.')[0],ran)) if zxdata: logger.debug(u'zxing识别二维码:%s,内容: %s' %(filename ,zxdata.data)) data = zxdata.data else: logger.error(u'识别zxing二维码出错:%s' %(filename)) img.save('%s-zxing.jpg' %filename) return data if __name__ == '__main__': filename =r'D:python 0025328.jpg' #zbar二维码识别 ltext = ocr_qrcode_zbar(filename) logger.info( u'[%s]Zbar二维码识别:[%s]!!!' %(filename,ltext)) print ltext #zbarlight二维码识别 ltext = ocr_qrcode_zbarlight(filename) logger.info( u'[%s]Zxing二维码识别:[%s]!!!' %(filename,ltext)) print ltext #zxing二维码识别 ltext = ocr_qrcode_zxing(filename) logger.info( u'[%s]Zxing二维码识别:[%s]!!!' %(filename,ltext)) print ltext
2、使用对比
1、zbar和zbarlight内核一致,都是基于zbar的dll编译加载的。
2、zbarlight使用比zbar更简单,不过是在zbar的基础又做了一点点封装而已。
3、zxing是基于java的zxing核心的python分支,其原理是调用javaw 加载zxing的core.jar包,再获取输出结果。
zxing的调试是一个大坑,网上的资料都存在这样那样的信息过时问题,加上zxing对java的依赖问题更多,这篇博客 http://www.cnblogs.com/oucsheep/p/6269813.html 相对来说比较清晰,但是估计初学者看起来会比较累。
3、总结:
1、项目的图片来源于是纸质文件的扫描件(qrcode),实际情况相对复杂,存在打印偏移,与其他文字重叠、图片变形、色带缺墨导致图片残缺等多种可能性。虽然经过一系列的图片处理,但目前来看三个包在容错性都不算太好。
2、但是,但是…… 微信中的“扫一扫”,却可以做到正常识别,应该是微信的二维码识别是有自己的独到算法,遗憾微信没有开放接口,也没有查到相关资料。
3、支付宝的"扫一扫",识别率略次于微信,但是也比开源的几个包要强的多。
4、网上有一些付费api,识别率也一般,怀疑也是基于zxing和zbar的二次封装。
5、三流无名厂家的二维码扫描头硬件,直接扫描该纸质文件,识别率基本可以做到90%以上,当然这不排除是扫描转换时产生的信息丢失这个重要因素。
综上,以识别能力排序,硬件>微信>支付宝>zxing>zbarlight(zbar)。
软件算法以微信最高,但比起硬件还是有差距,期待高手破解或者剥离微信的算法,也欢迎商用api开发者进行交流(可以付费),联系QQ 16906913 ,谢谢。
以上……