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


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

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

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

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

    #include <iostream>
    #include <includezbar.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;
    }
  • 相关阅读:
    地址级联选择器(element-china-area-data插件)
    el-table在每一行拿到对应的index(scope.$index)
    el-table中的label换行问题(重点white-space)
    调用outlook来发送邮件
    利用apifox来测试API
    注解@ConfigurationProperties使用方法
    异步加载js,兼容IE
    Exceptionless安装的一些坑
    MVC 源码系列之控制器执行(二)
    MVC 源码系列之控制器执行(一)
  • 原文地址:https://www.cnblogs.com/skyrudy/p/4955641.html
Copyright © 2020-2023  润新知