二维码开源库zbar、zxing使用心得

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

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

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

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

#include <iostream>
#include <include\zbar.h>
#include "opencv/cv.h"
#include "opencv/highgui.h"

using namespace std;
using namespace cv;
using namespace zbar;

//zbar接口
string ZbarDecoder(Mat img)
{
    string result;
    ImageScanner scanner;
    const void *raw = (&img)->data;
    // configure the reader
    scanner.set_config(ZBAR_QRCODE, ZBAR_CFG_ENABLE, 1);
    // wrap image data
    Image image(img.cols, img.rows, "Y800", raw, img.cols * img.rows);
    // scan the image for barcodes
    int n = scanner.scan(image);
    // extract results
    result = image.symbol_begin()->get_data();
    image.set_data(NULL, 0);
    return result;
}

//对二值图像进行识别,如果失败则开运算进行二次识别
string GetQRInBinImg(Mat binImg)
{
    string result = ZbarDecoder(binImg);
    if(result.empty())
    {
        Mat openImg;
        Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));
        morphologyEx(binImg, openImg, MORPH_OPEN, element);
        result = ZbarDecoder(openImg);
    }
    return result;
}

//main function
string GetQR(Mat img)
{
    Mat binImg;
    //在otsu二值结果的基础上,不断增加阈值,用于识别模糊图像
    int thre = threshold(img, binImg, 0, 255, cv::THRESH_OTSU);
    string result;
    while(result.empty() && thre<255)
    {
        threshold(img, binImg, thre, 255, cv::THRESH_BINARY);
        result = GetQRInBinImg(binImg);
        thre += 20;//阈值步长设为20,步长越大,识别率越低,速度越快
    }
    return result;
}

 

转载于:https://www.cnblogs.com/skyrudy/p/4955641.html

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: OpenCV和ZBar是两个常用的开源,可以用于实现摄像头识别二维码的功能。 首先,OpenCV是一款用于计算机视觉的开源,它提供了丰富的图像处理和计算机视觉算法,可以用来处理图像和视频。OpenCV支持各种程序设计语言,包括C++、Python等,因此非常方便开发者进行二维码的图像处理和识别。 而ZBar是一款专门用于二维码和条形码扫描的开源。它提供了各种功能强大的接口,可以对摄像头捕捉到的图像进行二维码的识别。ZBar支持多种编程语言,如C、C++、Python等,因此可以与OpenCV结合使用。 要实现摄像头识别二维码的功能,可以按照以下步骤进行: 1. 首先,使用OpenCV打开摄像头,获取实时图像流。 2. 将摄像头捕捉到的图像传递给ZBar进行二维码的识别。ZBar提供了相关的函数和接口,可以将摄像头捕获的图像进行处理,并识别其中的二维码。 3. 当ZBar识别到二维码时,可以通过回调函数或其他方式将识别到的二维码信息传递给应用程序,可以对识别到的二维码进行相关的操作,如解析二维码内容,打开对应的链接或进行其他业务处理。 总的来说,通过将OpenCV和ZBar结合使用,我们可以实现摄像头实时识别二维码的功能。这样,我们可以利用摄像头实时获取图像流,并通过ZBar对图像进行识别,从而实现对二维码的实时扫描和处理。 ### 回答2: OpenCV是一个开源的计算机视觉,提供了丰富的图像处理和计算机视觉算法。而ZBar是一个开源的条码和二维码识别,能够通过摄像头进行实时的二维码识别。 使用OpenCV和ZBar实现摄像头识别二维码的步骤如下: 1. 首先,我们需要使用OpenCV中的VideoCapture类来打开摄像头,并获取实时的视频帧。 2. 在每一帧中,我们将使用ZBar提供的二维码识别功能。通过将每一帧转换为灰度图像,可以提高识别效果。 3. 在灰度图像上,我们可以使用ZBar的Scanner类进行二维码的扫描。Scanner类可以检测到图像中的所有二维码,并返回相关信息。 4. 当扫描到二维码时,我们可以从Scanner类中获取二维码的内容。 5. 最后,我们可以使用OpenCV提供的绘图功能,在视频帧上标记出识别到的二维码的位置和内容。 通过以上步骤,我们可以实现摄像头实时识别二维码的功能。这种方法可以应用于一些需要实时扫描二维码的场景,例如门禁系统、物流追踪等。同时,OpenCV和ZBar开源特性也使得开发者能够根据自己的需求进行定制和修改,提高二维码识别的准确率和效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值