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:
Post Comments
(
Atom
)
No comments :
Post a Comment