首先说明我的测试场景是“识别打印在纸上的二维码”,在扫描结果中寻找二维码并进行识别,而不是直接让摄像头对着二维码扫描。

zbar和zxing用的都是自己从github上clone的c++源码/接口编译出来的dll,都是默认参数

再说结论:测了大概几千张图片,两个库的准确率差不多(由于图片场景的多样性,确切的准确率数字也没有什么意义),但是zbar的速度要快很多,大概是zxing的4-5倍。其实两个库的准确率都不太如人意,稍微模糊一点就无法识别,甚至有一些不模糊的图像也识别不出。相比之下,微信的识别效果就逆天了,怎么折腾都能识别出来,让我很好奇。

后来自己尝试改进识别效果,先看了一下二维码的识别原理,太复杂了,无从下手。于是尝试对图像进行预处理改进,结果只是用了一个二值化加开运算就让识别效果得到了大幅提升,让我很奇怪这么简单的预处理为什么开发人员没有去做呢?然后又继续优化了一下,发现二值化的阈值对二维码的识别非常关键,badcase通常是因为阈值不合适导致的,于是牺牲了一下性能,在识别程序中多次尝试不同阈值,最终识别效果达到了比较令人满意的结果,准确率从90%左右上升到99.8%左右,绝大部分打印不清晰导致的badcase都得到了解决,代码如下:

  1. #include <iostream>
  2. #include <include\zbar.h>
  3. #include "opencv/cv.h"
  4. #include "opencv/highgui.h"
  5.  
  6. using namespace std;
  7. using namespace cv;
  8. using namespace zbar;
  9.  
  10. //zbar接口
  11. string ZbarDecoder(Mat img)
  12. {
  13. string result;
  14. ImageScanner scanner;
  15. const void *raw = (&img)->data;
  16. // configure the reader
  17. scanner.set_config(ZBAR_QRCODE, ZBAR_CFG_ENABLE, );
  18. // wrap image data
  19. Image image(img.cols, img.rows, "Y800", raw, img.cols * img.rows);
  20. // scan the image for barcodes
  21. int n = scanner.scan(image);
  22. // extract results
  23. result = image.symbol_begin()->get_data();
  24. image.set_data(NULL, );
  25. return result;
  26. }
  27.  
  28. //对二值图像进行识别,如果失败则开运算进行二次识别
  29. string GetQRInBinImg(Mat binImg)
  30. {
  31. string result = ZbarDecoder(binImg);
  32. if(result.empty())
  33. {
  34. Mat openImg;
  35. Mat element = getStructuringElement(MORPH_RECT, Size(, ));
  36. morphologyEx(binImg, openImg, MORPH_OPEN, element);
  37. result = ZbarDecoder(openImg);
  38. }
  39. return result;
  40. }
  41.  
  42. //main function
  43. string GetQR(Mat img)
  44. {
  45. Mat binImg;
  46. //在otsu二值结果的基础上,不断增加阈值,用于识别模糊图像
  47. int thre = threshold(img, binImg, , , cv::THRESH_OTSU);
  48. string result;
  49. while(result.empty() && thre<)
  50. {
  51. threshold(img, binImg, thre, , cv::THRESH_BINARY);
  52. result = GetQRInBinImg(binImg);
  53. thre += ;//阈值步长设为20,步长越大,识别率越低,速度越快
  54. }
  55. return result;
  56. }

二维码开源库zbar、zxing使用心得的更多相关文章

  1. iOS 二维码扫描 通过ZBar ZXing等第三方库

    扫描二维码的开源库有很多如 ZBar.ZXing等 ZBar的使用方法: 下载ZBar SDK 地址https://github.com/bmorton/ZBarSDK ZBarSDK是一个开源的SD ...

  2. 二维码开源库ZBar-吐槽篇

    前不久在网上看到一篇文章<QR-Decoder-OV5640 二维码识别> ,是某开发板的教程.记得对应的开发板以前购买过,当初只是为了看OV5640的JPG的输出效果,结果由于公司奇葩的 ...

  3. 二维码开源库ZBar-MDK STM32F429移植

    前两篇文章已经实现ZBar在Windows平台下的编译和使用,本文将介绍如何把ZBar移植到STM32F429,IDE使用MDK. 1. MDK工程设置 (1)不勾选Use MicroLIB ,使用I ...

  4. 二维码开源库ZBar-实现中文解码

    中文乱码 上篇<ZBar-windows下编译和使用>已经成功解析了条形码,但目标是二维码,经测试二维码中文会出现乱码.下图二维码的内容是"http123测试456", ...

  5. 二维码开源库ZBar-windows下编译和使用

    源码 下载最新Zbar源码(http://zbar.sourceforge.net/),网站的WIKI是空白的,所以只能在源码包里找使用说明了,很遗憾Windows下怎么编译没说明,只是说明了Wind ...

  6. Android二维码开源项目zxing用例简化和生成二维码、条形码

    上一篇讲到:Android二维码开源项目zxing编译,编译出来后有一个自带的測试程序:CaptureActivity比較复杂,我仅仅要是把一些不用的东西去掉,用看起来更方便,二维码和条形码的流行性自 ...

  7. C++二维码相关库编译

    一.瞎想 坐在地铁上闲来无聊,突然想到了二维码,顺手就百度了下相关的资料,目前C++二维码相关的库不多,也就zbar(开源中国上下了半天也没下载下来).zxing,不过这两个库据说都是解析二维码的,不 ...

  8. 个性二维码开源专题<替换元素点>

    基础方法:ChangeFillShape //修改填充形状 ChangeFillShape(...) // 摘要: // 修改填充形状 // // 参数: // g: // 图形画板 // // Fo ...

  9. 个性二维码开源专题<替换定位点>

    基础方法: ChangeFillShape //修改填充形状 ChangeFillShape(...) // 摘要: // 修改填充形状 // // 参数: // g: // 图形画板 // // F ...

随机推荐

  1. 颜色rgb

    1.几种基本颜色的rgb 黑色:R.G.B(0.0.0) 白色:R.G.B(255.255.255) 红色:R.G.B(255.0.0) 绿色:R.G.B(0.255.0) 蓝色:R.G.B(0.0. ...

  2. spring-quartz普通任务与可传参任务

    两者区别与作用: 普通任务:总调度(SchedulerFactoryBean)--> 定时调度器(CronTriggerFactoryBean) --> 调度明细自定义执行方法bean(M ...

  3. C#DataTable操作

    ] 在DataSet中添加DataTable DataSet.Tables.Add(DataTable) 实例: DataSet ds=new DataSet(); DataTable table=n ...

  4. C#DateTimePicker设置自定义格式

    摘自Microsoft TechNet DateTimePicker.CustomFormat 属性 包含日期和时间分隔符的显示字符串文字或格式字符串,必须在子字符串中使用转义符. 例如,若要显示将日 ...

  5. 解决xp共享的批处理文件

    在空白地方点右键选择新建一个文本文档,将默认的“新建 文本文档.txt”文件名改名为以下红色加粗字体内容,再复制红色内容以下的黑字部分到改名后的文档.其他文件生成的方法相同.完成后根据需要双击CMD扩 ...

  6. launchpad bzr

    在lp注册 一个   lp ID,  比如 alangwansui 然后添加 SSH keys.为自己的管理添加权限. 注册一个项目的 比如  melody. 然后就可以开始使用bzr 在这个项目下建 ...

  7. unix-环境高级编程-读书笔记与习题解答-第三篇

    第一章 第五节 进程与控制 该小节比较粗略的阐述了unix操作系统中用于进程控制的三个函数,分别为 : fork , exec, waitpid, 其中 exec 有五种变体, 这些变体实现的功能全部 ...

  8. 如何自定义RecycleView item的间距

    引言 在以前使用ListView和GridView时,设置item之间的间距还是相对比较简单的,因为它们的基本属性里面Android已经定义好了,可以直接设置属性值即可.但Google为了通用性和灵活 ...

  9. My ECMAScript 7 wishlist

    With ECMAScript 6 now feature complete, any further changes to the core of JavaScript will happen in ...

  10. Spring MVC学习总结。

    公司项目用的Spring MVC.顺便学习学习. 其实框架并没有想象中的复杂.尤其对于初学者,总觉得SSH是一些很复杂的东西似的.其实对初学者来说能够用这些框架就足够了.在公司里也是,基本功能会用了就 ...