OpenCV每日函数之BarcodeDetector类条码检测器

发布时间:2025-01-23 14:01

目录
  • 一、概述
  • 二、类参考
    • 1、函数原型
    • 2、参数详解
  • 三、OpenCV源码
    • 1、源码路径
    • 2、源码代码
  • 四、效果图像示例

    一、概述

    OpenCV在V4.5.3版本的contrib包中提供了一个barcode::BarcodeDetector类,用于条形码的识别。

    二、类参考

    1、函数原型

    构造方法

    cv::barcode::BarcodeDetector::BarcodeDetector	(	const std::string & 	prototxt_path = \"\",
    const std::string & 	model_path = \"\" 
    )	

    decode方法

    bool cv::barcode::BarcodeDetector::decode	(	InputArray 	img,
    InputArray 	points,
    std::vector< std::string > & 	decoded_info,
    std::vector< BarcodeType > & 	decoded_type 
    )	

    detect方法

    bool cv::barcode::BarcodeDetector::detect	(	InputArray 	img,
    OutputArray 	points 
    )	

    detectAndDecode方法

    bool cv::barcode::BarcodeDetector::detectAndDecode	(	InputArray 	img,
    std::vector< std::string > & 	decoded_info,
    std::vector< BarcodeType > & 	decoded_type,
    OutputArray 	points = noArray() 
    )

    2、参数详解

    img 包含条形码的灰度或彩色 (BGR) 图像。
    decoded_info UTF8 编码的字符串输出向量或字符串的空向量(如果代码无法解码)。
    decoded_type BarcodeType 的向量,指定这些条形码的类型
    points 找到的条形码矩形的顶点的可选输出向量。 如果找不到,则为空。

    支持的条形码类型如下。

    enum  	cv::barcode::BarcodeType {
      cv::barcode::NONE,
      cv::barcode::EAN_8,
      cv::barcode::EAN_13,
      cv::barcode::UPC_A,
      cv::barcode::UPC_E,
      cv::barcode::UPC_EAN_EXTENSION
    }

    三、OpenCV源码

    1、源码路径

    opencv_contrib\\modules\\barcode\\src\\barcode.cpp

    2、源码代码

    bool BarcodeDetector::detect(InputArray img, OutputArray points) const
    {
        Mat inarr;
        if (!checkBarInputImage(img, inarr))
        {
            points.release();
            return false;
        }
     
        Detect bardet;
        bardet.init(inarr);
        bardet.localization();
        if (!bardet.computeTransformationPoints())
        { return false; }
        vector> pnts2f = bardet.getTransformationPoints();
        vector trans_points;
        for (auto &i : pnts2f)
        {
            for (const auto &j : i)
            {
                trans_points.push_back(j);
            }
        }
     
        updatePointsResult(points, trans_points);
        return true;
    }
     
    bool BarcodeDetector::decode(InputArray img, InputArray points, vector &decoded_info,
                                 vector &decoded_type) const
    {
        Mat inarr;
        if (!checkBarInputImage(img, inarr))
        {
            return false;
        }
        CV_Assert(points.size().width > 0);
        CV_Assert((points.size().width % 4) == 0);
        vector> src_points;
        Mat bar_points = points.getMat();
        bar_points = bar_points.reshape(2, 1);
        for (int i = 0; i < bar_points.size().width; i += 4)
        {
            vector tempMat = bar_points.colRange(i, i + 4);
            if (contourArea(tempMat) > 0.0)
            {
                src_points.push_back(tempMat);
            }
        }
        CV_Assert(!src_points.empty());
        vector bar_imgs = p->initDecode(inarr, src_points);
        BarDecode bardec;
        bardec.init(bar_imgs);
        bardec.decodeMultiplyProcess();
        const vector info = bardec.getDecodeInformation();
        decoded_info.clear();
        decoded_type.clear();
        bool ok = false;
        for (const auto &res : info)
        {
            if (res.format != NONE)
            {
                ok = true;
            }
     
            decoded_info.emplace_back(res.result);
            decoded_type.emplace_back(res.format);
        }
        return ok;
    }
     
    bool
    BarcodeDetector::detectAndDecode(InputArray img, vector &decoded_info, vector &decoded_type,
                                     OutputArray points_) const
    {
        Mat inarr;
        if (!checkBarInputImage(img, inarr))
        {
            points_.release();
            return false;
        }
        vector points;
        bool ok = this->detect(img, points);
        if (!ok)
        {
            points_.release();
            return false;
        }
        updatePointsResult(points_, points);
        decoded_info.clear();
        decoded_type.clear();
        ok = this->decode(inarr, points, decoded_info, decoded_type);
        return ok;
    }

    四、效果图像示例

    \"OpenCV每日函数之BarcodeDetector类条码检测器_第1张图片\" 示例图像

    参考代码,opencvsharp版本的需要打开barcode并重新编译,所以使用c++代码进行示例。

    cv::Mat mata = cv::imread(\"barcode.png\");
    cv::barcode::BarcodeDetector barcode;
    std::vector info;
    std::vector type;
    Mat points;
    barcode.detectAndDecode(mata, info, type, points);

    识别结果,可以看到第一个和第三个识别结果正确,不知道是否是放在一起的原因,下面把另外两个裁剪出来识别看看。

    \"OpenCV每日函数之BarcodeDetector类条码检测器_第2张图片\"

     

    \"OpenCV每日函数之BarcodeDetector类条码检测器_第3张图片\"

    最后一个没有识别出来

    \"OpenCV每日函数之BarcodeDetector类条码检测器_第4张图片\"

    把最后一个单独裁剪出来在测试下也没有识别出来,不过UPCE类型的应该支持才对,暂时不进行深究。

    到此这篇关于OpenCV每日函数BarcodeDetector条码检测器的文章就介绍到这了,更多相关OpenCV条码检测器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    ItVuer - 免责声明 - 关于我们 - 联系我们

    本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

    桂ICP备16001015号