二維碼開源庫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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM