树莓派二维码识别
最近一直忙于科研,好久没有更新博客了。今天更新一篇关于使用树莓派进行二维码识别的文章,是笔者树莓派项目开发的第四篇博客,希望能够给大家带来一丝的帮助。
现在二维码活跃在我们身边的大街小巷,基本上每天都会和二维码打交道,共享单车啊,移动支付等。那么如何实现二维码的识别呢,其实我们仔细观察二维码的特征的话,可能会看出一些特征,每一个QR码,都有三个定位块。识别二维码时会先找到定位块,然后开始读取二维码的的编码信息,然后遵循一定的规则对二维码的编码信息进行解码(翻译),解码出的内容就是我们想要的内容了,可以跳转网站,查看文字信息等。二维码识别的原理基于以上的过程,当然现在也有很多开源的二维码识别工具,如zbar和zxing。
1、开发环境搭建
硬件:树莓派3B plus 和 usb摄像头
软件: python2.7版本、二维码识别开源工具ZBar和opencv(opencv的安装可参考我的博客)
zbar 官网 http://zbar.sourceforge.net/
ZBar是一个开源软件套件,用于从各种来源读取条形码,例如视频流,图像文件和原始强度传感器。 它支持许多流行的符号(条形码类型),包括EAN-13 / UPC-A,UPC-E,EAN-8,
Code 128,Code 39,Interleaved 2 of 5和QR Code。灵活的分层实现方便了任何应用程序的条形码扫描和解码,可轻松地将条形码扫描小部件集成到您的Qt,GTK +或PyGTK GUI应用程序中,具备python,C++等多种语言API接口。广泛应用于零售、自动文档处理、库存跟踪、移动应用等领域。ZBar的特性如下:
- 跨平台 – Linux / Unix,Windows,iPhone®,嵌入式
- 高速 – 从视频流中实时扫描
- 内存占用少
- 小代码大小 – 核心扫描器和EAN解码器代表1K行的C代码
- 没有浮点运算
- 适用于使用廉价处理器/硬件的嵌入式应用
- 模块化组件可以一起使用或单独使用
zbar 安装
方案一
命令行安装:sudo apt-get install python-zbar
直接安装,识别英文一点问题都没有,识别中文不支持。
测试安装成功,进入python 环境: import zbar
方案二
源码安装,可识别中文
1、wget命令用来从指定的URL下载zbar源码,命令如下:
wget http://downloads.sourceforge.net/project/zbar/zbar/0.10/zbar-0.10.tar.gz
下载不成功的话,先用电脑下载zbar-0.10.tar.gz,上传到树莓派的pi目录下
2、解压zbar的源文件,解压至pi目录下的zbar-0.10文件夹
tar -zvxf zbar-0.10.tar.gz
3、zbar是基于C语言开发的,安装编译时需要编译器,安装python-gtk和libqt4-dev
sudo apt-get install python-gtk2-dev
4、安装libqt4-dev
sudo apt-get install libqt4-dev
5、进入zbar-0.10文件夹,运行configure 命令如下,此步运行成功生成makefile
./configure --without-imagemagick -disable-video -without-qt -without-gtk -without-x
6、 编译makefile : make
7、 make安装: sudo make install
8、 测试进入python环境:import zbar
注意:第5步安装时要进入/home/pi/zbar-0.10目录,第6、7步安装时可能会出现错误,但是并不影响使用。
zbar 中文支持修改
ZBar是日本人写的,若要识别带有中文文字的二维码,需要在安装的时候加个小插曲,需要修改一下ZBar源文件里面的函数:修改源文件下zbar-0.10/zbar/qrcode/qrdectxt.c
终端使用nano或者vim编辑器修改zbar-0.10/zbar/qrcode/qrdectxt.c
函数,以下该步骤需要在下载完源码后进行,修改完成后再进行编译和安装。
1、打开qrdectxt.c
,采用nano编辑器
2、找到默认编码的函数,修改编码,将 ISO8859-1,换成 GB18030 将SJIS,换成GB2312
3、找到默认编码定义的list,修改解码编码顺序
4、编译源码,安装ZBar
按照以上的步骤安装基本不会出现问题,如果出现问题仔细检查是否缺少相应的依赖安装即可。
2、二维码识别实践
ZBar可以直接对输入的图像提取二维码、扫码和解码,下面是笔者根据zbar的帮助文档改写的一个快速实现二维码识别的Demo,可实现对实施视频流中的二维码或者一维条码的识别,当二维码或者一维码的排放位置相对摄像头比较正时识别效果较好。
#-*- coding: UTF-8 -*-
# Simple QR code recognition
# @author: zdl
# import the necessary packages
#import simple_barcode_detection
import cv2
import numpy as np
import zbar
from PIL import Image
# create a reader
scanner = zbar.ImageScanner()
# configure the reader
scanner.parse_config('enable')
font=cv2.FONT_HERSHEY_SIMPLEX
camera=cv2.VideoCapture(0)
while(True):
# Capture frame-by-frame
grabbed, frame = camera.read()
if not grabbed:
break
pil= Image.fromarray(frame).convert('L') # 转成灰度图像
width, height = pil.size
raw = pil.tobytes()
zarimage = zbar.Image(width, height, 'Y800', raw)
scanner.scan(zarimage)
for symbol in zarimage:
# do something useful with results
if not symbol.count:
print 'decoded', symbol.type, 'symbol', '"%s"' % symbol.data
cv2.putText(frame,symbol.data,(20,100),font,1,(0,255,0),4)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
但是为提高扫码和解码的效率,我们先使用图像处理算法实现对二维码的定位并提取二维码的图像,将该部分的图像送入ZBar的扫码器中。如何实现对二维码的定位呢,方法如下:
- 基于梯度算子,水平垂直交叉定位
- 角点检测,仿射变换法,可校正倾斜的二维码
- 轮廓法,寻找最小外接矩形。
- 轮廓层析结构法,寻找二维码的三个定位点,可校正二维码。
我们采用第三种方法实现静态二维码的提取,实现二维码的识别。具体实现的步骤如下:
- 输入图像进行灰度化,滤波
- 图像进行Otsu自适应二值化。
- 二值化的图像进行图像形态学操作,实现细小连通区域的闭合。
- 图像位运算进行反色,这时二维码区域为白色。
- 寻找反色图像中的轮廓,二维码区域为轮廓中面积最大的那个,实现对二维码区域 的定位。
- 将定位的二维码图像取出,输入至zbar进行扫码和解码。
源代码如下:
# -*- coding: UTF-8 -*-
# Simple QR code detection
# @author: zdl
# ZBar+python2.7.13
import cv2
import numpy as np
import zbar
# 基于轮廓定位QR位置
def find_code(img):
# 高斯滤波
blur = cv2.GaussianBlur(img,(5,5),0)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值化
ret,th = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# 形态学操作
mask=cv2.erode(th,None,iterations=4)
mask=cv2.dilate(mask,None,iterations=4)
# 图像反色
cv2.bitwise_not(mask, mask)
# 寻找轮廓
_,contours,hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 寻找QR码的位置
if len(contours)>0:
cnt = max(contours, key=cv2.contourArea)
x,y,w,h = cv2.boundingRect(cnt)
img = cv2.rectangle(img,(x-15,y-15),(x+w+15,y+h+15),(0,255,0),3)
img_ROI = img[y-15:y+h+15, x-15:x+w+15]
else:
img_ROI = img
return img_ROI
# main函数
if __name__ == '__main__':
# 读入图片
img = cv2.imread('introduce.jpg', 1)
# 定位QR码的位置
img_ROI = find_code(img)
# 初始化scanner
scanner = zbar.ImageScanner()
scanner.parse_config('enable')
font = cv2.FONT_HERSHEY_SIMPLEX # openCV 字体
img_ROI_gray = cv2.cvtColor(img_ROI, cv2.COLOR_BGR2GRAY)
# 扫码
width, height = img_ROI_gray.shape # 获取图片大小
raw = img_ROI_gray.tobytes() # 图像矩阵数据转为字节数据
zarimage = zbar.Image(width, height, 'Y800', raw) # 设置参数
scanner.scan(zarimage) # 扫码
# 解码
for symbol in zarimage:
# do something useful with results
if not symbol.count:
print 'decoded', symbol.type, 'symbol', '"%s"' % symbol.data
else:
print 'no'
#cv2.putText(img,symbol.data,(20,100),font,1,(0,255,0),4) # 打印字符在图片上
# DisPlay
cv2.imshow('img_ROI', img_ROI_gray)
cv2.imshow('image', img)
cv2.waitKey(0)
运行效果:
基于本文,我们已经实现了二维码的识别,那么结合树莓派语音合成和树莓派控制方面的知识,是不是可以做点好玩的事情呢。
今天的文章树莓派python实现二维码识别——ZBar分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:http://bianchenghao.cn/9031.html