2017/10/23
Reading barcode with zxing-cpp and OpenCV Volume 2
1년전쯤 작성한 글인데 ZXing-cpp 와 OpenCV를 이용한 바코드 인식 글(https://goo.gl/kRtaYn)을 올렸었는데 관련 댓글이 달리고 다른 활용처가 있어서 다시 시도를 해 보았다.
물론 한번에 되지는 않았다.
ZXing-cpp 빌드는 문제가 없었으나 이를 사용하는경우 아래와 같은 링크 에러가 발생하였다.
error LNK2005: "public: static unsigned int const zxing::DecodeHints::CHARACTER_SET" (?CHARACTER_SET@DecodeHints@zxing@@2IB) already defined in xxx.obj
인터넷 검색을 통해 해결책(https://goo.gl/WkEEcY)을 찾았다.
문제는 Visual C++ 컴파일러만 발생한 것으로 문제가 발생한 부분을 아래와 같이 수정을 하면 해결이 되었다.
Old code:
DecodeHints.h:
static const DecodeHintType CHARACTER_SET = 1 << 30;
DecodeHints.cpp:
const DecodeHintType DecodeHints::CHARACTER_SET;
has been replaced by:
DecodeHints.h:
static const DecodeHintType CHARACTER_SET;
DecodeHints.cpp:
const DecodeHintType DecodeHints::CHARACTER_SET = 1 << 30;
그리고 이전 코드에서는 컴파일에 문제가 있어서 최신 ZXing에 포함되어 있는 opencv cli 코드(zxing-cpp-master\opencv-cli\src\main.cpp)를 이용하여 테스트 해 보았다.
컴파일및 링크는 문제가 없었으나 인식률은 그리 좋아 보이지 않았다.
물론 ZXing을 얼마나 이해하고 잘 쓰는지가 문제가 될 수 있어 좀 더 분석하고 파고들어봐야 할 것 같다.
아래 코드는 테스트에 사용한 코드 이다.
cv::String strFile( CStringA(dlgFile.GetPathName()) ); cv::Mat matImage = cv::imread(strFile); cv::Mat matGray; cv::cvtColor( matImage, matGray, CV_RGB2GRAY ); Ref<LuminanceSource> source = MatSource::create(matGray); bool bHybrid = true; string strResult; try { // Create luminance source Ref<LuminanceSource> source = MatSource::create(matGray); // Search for QR code Ref<Reader> reader; if (true) { reader.reset(new MultiFormatReader); } else { reader.reset(new QRCodeReader); } Ref<Binarizer> binarizer(new GlobalHistogramBinarizer(source)); Ref<BinaryBitmap> bitmap(new BinaryBitmap(binarizer)); Ref<Result> result(reader->decode(bitmap, DecodeHints(DecodeHints::DEFAULT_HINT))); // Get result point count int resultPointCount = result->getResultPoints()->size(); for (int j = 0; j < resultPointCount; j++) { // Draw circle circle(matImage , CvPoint(result->getResultPoints()[j]->getX(), result->getResultPoints()[j]->getY()) , 10, cv::Scalar( 110, 220, 0 ), 2); } // Draw boundary on image if (resultPointCount > 1) { for (int j = 0; j < resultPointCount; j++) { // Get start result point Ref<ResultPoint> previousResultPoint = (j > 0) ? result->getResultPoints()[j - 1] : result->getResultPoints()[resultPointCount - 1]; // Draw line //line(matImage, toCvPoint(previousResultPoint), toCvPoint(result->getResultPoints()[j]), cv::Scalar( 110, 220, 0 ), 2, 8 ); line(matImage, CvPoint(previousResultPoint->getX(), previousResultPoint->getY()) , CvPoint(result->getResultPoints()[j]->getX(), result->getResultPoints()[j]->getY()) , cv::Scalar( 110, 220, 0 ), 2, 8 ); // Update previous point previousResultPoint = result->getResultPoints()[j]; } } if (resultPointCount > 0) { TRACE("Found Barcode : %s\n", result->getText()->getText().c_str()); // Draw text putText(matImage, result->getText()->getText() , CvPoint(result->getResultPoints()[0]->getX(), result->getResultPoints()[0]->getY()) , cv::FONT_HERSHEY_PLAIN, 1, cv::Scalar( 110, 220, 0 )); } // Show captured image cv::namedWindow( "ZXing", cv::WINDOW_AUTOSIZE ); cv::imshow("ZXing", matImage); } catch (const ReaderException& e) { strResult = "zxing::ReaderException: " + string(e.what()); } catch (const zxing::IllegalArgumentException& e) { strResult = "zxing::IllegalArgumentException: " + string(e.what()); } catch (const zxing::Exception& e) { strResult = "zxing::Exception: " + string(e.what()); } catch (const std::exception& e) { strResult = "std::exception: " + string(e.what()); } AfxMessageBox(CString(strResult.c_str()));
Labels:
barcode
,
OpenCV
,
OpenCV 3.3.0
,
ZXing
,
zxing cpp
Subscribe to:
Posts
(
Atom
)