一起学习二维码(三)二维码解码

小白最近需要做一个和二维码相关的项目,因此近期小白会陆陆续续的为大家带来一些和二维码相关的分享。

上一篇推送中,小白成功的安装了能够解码QR二维码的开源库zbar,并且利用测试程序检测了安装的正确性,但是由于解码二维码只是项目中的一小部分,因此在实际的项目中我们必须自己编写程序,这样才能更好的将解码的功能结合主程序中(虽然也可以在ROS下通过话题的方式来实现解码节点,但是这样也仍然需要自己写一个解码节点)。

于是小白便开始了自己写程序解码二维码之路。

小白采用的方式是OpenCV+Zbar的方式实现二维码的解码,通过OpenCV加载图片,之后在进行解码工作。我们之前已经验证过zbar库成功安装,因此我们只需要在写程序的时候引用上就可以了。经常在Ubuntu环境下编程的小伙伴可能都比较了解,我们首先需要写一个CMakeList.txt文件,将我们引用的OpenCV库包含在程序里。

于是按照常规的方式来写CMakeList文件,同时也参考了网上的一些程序,网上找到的N多版本,都如下所示:

project(qrtest)
find_package( OpenCV 2.4.9 REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
add_executable(qrtest main.cpp)
target_link_libraries( qrtest ${OpenCV_LIBS} )

好吧,既然大家都这么写,我也就试试看吧,然后写了如下的解码程序:

#include <iostream>
#include <zbar.h>
#include <cv.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
using namespace zbar;
int main(int argc, char **argv) {
   //Mat image= imread("qrcode.bmp");
   Mat image = imread("fz.png");
   if ( image.data == nullptr ) //数据不存在,可能是文件不存在
   {
       cerr<<"文件不存在."<<endl;
       return 0;
   }                                                                                                                              = zbar_image_scanner_create();
   ImageScanner scanner;
   scanner.set_config(zbar::ZBAR_NONE,zbar::ZBAR_CFG_ENABLE,1);
   Mat imageGray;
   cvtColor(image,imageGray,CV_RGB2GRAY);
   int width = imageGray.cols;
   int height = imageGray.rows;
   uchar *raw = (uchar *)imageGray.data;
   zbar::Image imageZbar(width, height, "Y800", raw, width * height);
   scanner.scan(imageZbar);
   zbar::Image::SymbolIterator symbol = imageZbar.symbol_begin();
   if(imageZbar.symbol_begin()==imageZbar.symbol_end())
   {
     cout<<"查询条码失败,请检查图片"<<endl;
     return 0;
   }
   for(;symbol!=imageZbar.symbol_end();++symbol)
   {
     cout<<"类型"<<endl<<symbol->get_type_name()<<endl<<endl;
     cout<<"内容"<<endl<<symbol->get_data()<<endl<<endl;
   }  
   cv::waitKey(0);
   imageZbar.set_data(NULL,0);
   std::cout << "Hello, world!" << std::endl;
   return 0;
}

之后编译,出现了错误!!!,错误内容如下:

错误提示是说基本的函数不能使用,例如:

zbar_image_scanner_t *scanner =zbar_image_scanner_create();

提示说函数zbar_image_scanner_create()没有定义,秉着我遇到的问题也会有别人遇到的想法,开始了漫长的搜索之路。最后小白决定,还是借个梯子吧,于是谷歌了一下,哈哈,还真有人遇到了(这说明手边有个梯子是多么的幸福)。

问题的原因是libzbar.a没有包含在程序中。恩,只要在CMakeList里面链接该文件就可以了,于是抱着试试看的心态,战战兢兢的将下面一行代码加入进去:

target_link_libraries( qrtest/usr/lib/libzbar.a )

程序通了,大功告成。

特别说明,由于我的文件zbar是默认安装的,所以libzbar.a文件在/usr/lib/下,这个需要根据不同的情况进行更改。

最后小白测试一下程序,可以正确的解读自己之前生成的代码。读取的图片和结果都放在下面:

小白和师兄不小心出镜了,但是还是盖上吧,嘿嘿!!!

最后一行的hello,world属于乱入,可以忽略不计

这个程序只是实现了简单的二维码读取功能,如果图片再复杂一些,还是会出现无法读取的问题,关于这些问题的解决方法,小白会在后续的更新中陆续与小伙伴们分享。

(0)

相关推荐