zbar+opencv检测图片中的二维码或条形码

zbar本身自带检测二维码条形码功能,这里使用opencv只是做一些简单的读取图片,灰度图片以及显示条形码和二维码时用到一些绘制

// barcode-qrcodescanner.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <zbar.h>
#pragma comment( lib,"winmm.lib" ) 
using namespace std; 

typedef struct
{
    string type;
    string data;
    vector <cv::Point> location;
} decodedObject;

// 识别条形码或二维码
void decode(cv::Mat &im, vector<decodedObject>&decodedObjects)
{

    // 创建zbar 扫描检测对象
    zbar::ImageScanner scanner;

    // 配置扫描器
    scanner.set_config(zbar::ZBAR_NONE, zbar::ZBAR_CFG_ENABLE, 1);

    // 图片转为灰度图
    cv::Mat imGray;
    cv::cvtColor(im, imGray, cv::COLOR_BGR2GRAY);

    // 将图片数据转换为zbar图片对象
    zbar::Image image(im.cols, im.rows, "Y800", (uchar *)imGray.data, im.cols * im.rows);

    // 扫描检测
    int n = scanner.scan(image);

    // 打印检测结果
    for (zbar::Image::SymbolIterator symbol = image.symbol_begin(); symbol != image.symbol_end(); ++symbol)
    {
        decodedObject obj;

        obj.type = symbol->get_type_name();
        obj.data = symbol->get_data();

        // 检测到的对象类型和数据
        cout << "Type : " << obj.type << endl;
        cout << "Data : " << obj.data << endl << endl;

        // 对象所处的位置
        for (int i = 0; i < symbol->get_location_size(); i++)
        {
            obj.location.push_back(cv::Point(symbol->get_location_x(i), symbol->get_location_y(i)));
        }

        decodedObjects.push_back(obj);
    }
}

// 显示条形码和二维码在图片中的区域
void display(cv::Mat &im, vector<decodedObject>&decodedObjects)
{ 
    for (int i = 0; i < decodedObjects.size(); i++)
    {
        vector<cv::Point> points = decodedObjects[i].location;
        vector<cv::Point> hull;
         
        if (points.size() > 4)
            convexHull(points, hull);
        else
            hull = points;
        
        int n = hull.size();

        for (int j = 0; j < n; j++)
        {
            cv::line(im, hull[j], hull[(j + 1) % n], cv::Scalar(255, 0, 0), 3);
        }

    }

    // 显示结果
    cv::imshow("Results", im);
    cv::waitKey(0);

}

int main(int argc, char* argv[])
{

    // opencv读取图片
    cv::Mat im = cv::imread("zbar-test.jpg");
     
    vector<decodedObject> decodedObjects;

    // 查找二维码或条形码
    decode(im, decodedObjects);

    // 显示位置
    display(im, decodedObjects);

    return EXIT_SUCCESS;
}

这里用到zbar所以需要去下载一个zbar库,因为我用的是vs2017并且项目配置的是x64位。这里有个配置好的需要的下载

 

猜你喜欢

转载自www.cnblogs.com/zzatp/p/9154502.html