opencv

Barcode 읽기

꼰대코더 2025. 2. 23. 16:25

일과 관련해서 이미지 중의 Barcode를 자동으로 찾아내서 디코딩하는 라이브러리를 조사해 보았다. *Windows VC++환경

(어디까지나 가지고 있는 특정 이미지를 사용)

라이브러리 결과 참고
OpenCV
(cv::barcode::BarcodeDetector)
위치 특정 불가 VER 4.80 이상 필요
zbar  같은 바코드영역들을  하나로 묶어서 결과 출력  x64 버젼이 필요
ZXing 같은 바코드영역들이 수평으로 존재하지 않는 한 각각 다른 결과로 출력 다운로드

 

 

결국 ZXing 을 선택하게 되었다. 

#include <iostream>
#include "opencv2/opencv.hpp"
#include "ReadBarcode.h"
#include "BarcodeFormat.h"


int main(int argc, char** argv)
{
    int width, height;
    unsigned char* data;

    cv::Mat img = cv::imread("d:\\166331_webtech_chart_printpdf-2.tif");
    data = (unsigned char*)img.ptr();
    width = img.cols;
    height = img.rows;


    // 읽어들인 이미지 픽셀 포맷에 따라라
    // ImageFormat::Lum, ImageFormat::LumA, ImageFormat::RGB, ImageFormat::RGBA
    auto image = ZXing::ImageView(data, width, height, ZXing::ImageFormat::BGR);

    // 가능한 옵션들 * 지정하지 않으면 디폴트로 반대 설정으로 됨.
    //options.setTryHarder(false);      // 빠르게
    //options.setTryRotate(false);      // 회전하지 않기
    //options.setTryInvert(false);      // 흑백 변환 않기
    //options.setTryDownscale(false);   // 작게 스케일 않기
    //options.setMaxNumberOfSymbols(1); // 1개만 검색

    ZXing::ReaderOptions options;
    options.setFormats(ZXing::BarcodeFormat::Any);

    auto barcodes = ZXing::ReadBarcodes(image, options);

    for (const auto& b : barcodes) {
        std::cout << ZXing::ToString(b.format()) << ": " << b.text() << "\n";
        std::cout << "Rotation:   " << b.orientation() << " deg\n";
        cv::line(img, cv::Point(b.position().topLeft().x, b.position().topLeft().y), cv::Point(b.position().bottomRight().x, b.position().topLeft().y), cv::Scalar(255, 0, 0), 2);
        cv::line(img, cv::Point(b.position().bottomRight().x, b.position().topLeft().y), cv::Point(b.position().bottomRight().x, b.position().bottomRight().y), cv::Scalar(255, 0, 0), 2);
        cv::line(img, cv::Point(b.position().topLeft().x, b.position().bottomRight().y), cv::Point(b.position().bottomRight().x, b.position().bottomRight().y), cv::Scalar(255, 0, 0), 2);
        cv::line(img, cv::Point(b.position().topLeft().x, b.position().topLeft().y), cv::Point(b.position().topLeft().x, b.position().bottomRight().y), cv::Scalar(255, 0, 0), 2);
    }

    cv::imwrite( "output.png", img);
    return 0;
}