2020/07/22

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

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

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


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;
}