2020/07/22

ZXing-cpp 라이브러리를 이용한 QRCode 인식

ZXing-cpp(https://github.com/glassechidna/zxing-cpp) 라이브러리를 이용한 QRCode 인식을 해 보았다.

그간 ZXing-cpp 라이브러리를 보다 쉽게 사용하기 위해 OpenCV 라이브러리를 포함하여 만들려 했으나 굳이 그럴 필요 없이 기본 사양으로 만들어 OpenCV Raw 데이터를 이용하여 바코드 검사를 수행하도록 해 보았다. 다행스럽게도 동작이 잘 되었다. 디버그 모드에서 인식속도와 인식률은 떨어지지만 동작은 잘 되었다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
try
{
    zxing::ArrayRef<char> greyData((char*)pBuff, nWidth * nHeight);
    zxing::Ref< zxing::LuminanceSource > source(new zxing::GreyscaleLuminanceSource(greyData, nWidth, nHeight, 0, 0, nWidth, nHeight));
 
    zxing::Ref< zxing::Binarizer> binarizer(new zxing::GlobalHistogramBinarizer(source));
    zxing::Ref< zxing::BinaryBitmap> bitmap(new zxing::BinaryBitmap(binarizer));
 
    zxing::Ref< zxing::Reader > reader;
    reader.reset(new zxing::MultiFormatReader);
    zxing::Ref< zxing::Result> result(reader->decode(bitmap, zxing::DecodeHints(zxing::DecodeHints::DEFAULT_HINT)));
 
    zxing::Ref< zxing::String > ResultString = result->getText();
    if ( ResultString->getText().length() > 0 )
    {
        ++nDetectedBarcodeCount;
        strncpy_s( szResult, nBufSize, ResultString->getText().c_str(), _TRUNCATE );
 
        strcat_s(szExtraResult, nBufSize, zxing::BarcodeFormat::barcodeFormatNames[result->getBarcodeFormat().value]);
         
        // Get result point count
        char szPoint[20];
        zxing::ArrayRef< zxing::Ref<zxing::ResultPoint> > resultPoints = result->getResultPoints();
        if ( resultPoints->size() > 0 ) strcat_s(szExtraResult, nBufSize, "|");
        for (int p = 0; p < resultPoints->size(); p++)
        {
            sprintf_s(szPoint, 20, "%.1fx%.1f", resultPoints[p]->getX(), resultPoints[p]->getY());
 
            if (p > 0) strcat_s(szExtraResult, nBufSize, ","); // Add Seprator
            strcat_s(szExtraResult, nBufSize, szPoint);
        }
    }
}
catch (const zxing::ReaderException& e)
{
    char szLog[2048] = { 0 };
    sprintf_s(szLog, _TRUNCATE, "zxing::ReaderException: %s", e.what());
    CZXingBarcode::writeLog(szLog);
 
    nErrorCode = -101;
}
catch (const zxing::IllegalArgumentException& e)
{
    char szLog[2048] = { 0 };
    sprintf_s(szLog, _TRUNCATE, "zxing::IllegalArgumentException: %s", e.what());
    CZXingBarcode::writeLog(szLog);
 
    nErrorCode = -102;
}
catch (const zxing::Exception& e)
{
    char szLog[2048] = { 0 };
    sprintf_s(szLog, _TRUNCATE, "zxing::Exception: %s", e.what());
    CZXingBarcode::writeLog(szLog);
 
    nErrorCode = -103;
}
catch (const std::exception& e)
{
    char szLog[2048] = { 0 };
    sprintf_s(szLog, _TRUNCATE, "std::exception: %s", e.what());
    CZXingBarcode::writeLog(szLog);
 
    nErrorCode = -104;
}