Jdnie Nie Jiadong's Blog

Zbar二维码识别

本来想自己开发一个识别二维码的程序,无非是图像预处理,仿射变换,二值化,协议解析等等。然而网上有现成的开源库,也就不必重复造轮子了。

源码路径:https://github.com/ZBar/ZBar

为何是ZBar?C语言,速度快。ZXing主要是java接口,C也是在java之上封装的。


编译X86的库

./configure --prefix=$PWD/x86 --disable-pthread --disable-video --disable-assert --with-pic --without-xshm --without-xv --without-jpeg --without-imagemagick --without-gtk --without-python --without-qt
make;make install
g++ -o test test.cpp -I./include ./lib/libzbar.a -lrt

在x64环境下编译测试程序时不需要-lrt。

编译嵌入式平台的库

./configure --prefix=$PWD/arm --disable-pthread --disable-video --disable-assert --with-pic --without-xshm --without-xv --without-jpeg --without-imagemagick --without-gtk --without-python --without-qt --host=arm-hisiv300-linux

尝试过配置CC/CXX=arm-hisiv300-linux-gcc/g++,–host=arm,–host=arm-hisiv300-linux- 等。


编译问题

In file included from /usr/include/stdio.h:936:0,
                 from zbar/debug.h:60,
                 from zbar/scanner.c:34:
/usr/include/x86_64-linux-gnu/bits/stdio2.h:139:1: error: expected identifier or ‘(’ before ‘{’ token

解决方法一:把Debug.h中的相关代码注释掉。

解决方法二:configure时—disable-assert。

中文乱码

我没有遇到,测试过带中文信息的二维码,能正常识别,输出的string中,中文字符的编码方式是UTF-8,或许后期的测试会遇到。

网上有说将zbar/qrcode/qrdextxt.c中的

latin1_cd=iconv_open(“UTF-8”,”ISO8859-1”);修改为

latin1_cd=iconv_open(“UTF-8”,”GBK”);


代码中的坑

错误代码一

ImageScanner scanner;        
scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);
Image imageZbar(width, height, "Y800", gray, width*height);

scanner.scan(imageZbar); //扫描条码      
Image::SymbolIterator symbol = imageZbar.symbol_begin();
for(;symbol != imageZbar.symbol_end();++symbol)      
{
    std::string data = symbol->get_data();
    printf("type : %s \n", symbol->get_type_name().c_str());
    printf("data : %s \n", data.c_str());
}

printf("scan again!\n");
scanner.scan(imageZbar); //扫描条码
symbol = imageZbar.symbol_begin();
for(;symbol != imageZbar.symbol_end();++symbol)      
{
    std::string data = symbol->get_data();
    printf("type : %s \n", symbol->get_type_name().c_str());
    printf("data : %s \n", data.c_str());
}

这样会出现coredump!问题不在scanner,也不在imageZbar,而在symbol。

错误代码二

ImageScanner scanner;        
scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);
Image imageZbar(width, height, "Y800", gray, width*height);

scanner.scan(imageZbar); //扫描条码      
Image::SymbolIterator symbol;
for(symbol = imageZbar.symbol_begin();symbol != imageZbar.symbol_end();++symbol)
{
    std::string data = symbol->get_data();
    printf("type : %s \n", symbol->get_type_name().c_str());
    printf("data : %s \n", data.c_str());
}

这样也会出问题的,看清楚Image::SymbolIterator怎么用了么?深坑不谢。

正确用法

Image::SymbolIterator symbol = imageZbar.symbol_begin();
for(;symbol != imageZbar.symbol_end();++symbol)

That’s all!嵌入式设备上二维码识别程序已运行成功。