zoukankan      html  css  js  c++  java
  • opencv调用nu-book/zxing-cpp识别二维码

    环境安装:

    1.  zxing-cpp 源码和源码编译后生成的lib,我的版本是V1.0.8,编译方法见:https://www.cnblogs.com/zhenjin-huaxiazongdai/p/12545959.html。zxing-cpp项目路径:https://github.com/nu-book/zxing-cpp

    2. Visual Studio 2017安装https://visualstudio.microsoft.com/zh-hans/vs/older-downloads/,安装完成后在 工具-获取工具和支持 中添加“使用C++的桌面开发”支持。

    3.安装windows opencv并添加环境变量,例如我安装在 D:opencvopencv 文件夹中,添加环境变量  D:opencvopencvuildx64vc15in。观察opencv文件夹我们也可以知道,opencv默认只支持x64,x86需要自己下载源码编译。我安装的版本是 4.1.2 ,下载路径:

    image

    Demo地址https://github.com/SourceCode-Farmer/ZxingDemo

    过程记录:

    一、 添加依赖

    1. 新建Visual C++ Windows控制台应用程序 ZxingDemo,打开项目文件夹有如下文件:

    image

    2. 打开opencv 安装目录下的 build 文件夹,复制 include 文件夹到 ZxingDemo 项目文件夹中,重命名为opencv_header.

    image

    3. 在 ZxingDemo 项目文件夹中新建 opencv_liblib64 文件夹,打开 opencv 安装目录下的 buildx64vc15lib 文件夹,将 opencv_world412.lib 和 opencv_world412d.lib 两个文件复制到 ZxingDemo 项目文件夹中(如果 lib 文件名称有变化,请将所有 lib 文件一股脑复制过来即可)。

    image

    4. 在 ZxingDemo 项目文件夹中新建文件夹 zxing_lib ,复制 zxing-cpp 编译后的 lib 到文件夹中(注意 Zxing-cpp 和 ZxingDemo 编译时的解决方案配置、解决方案平台必须一致)。

    image

    5. 打开 zxing-cpp 源码中的 core 文件夹,复制 src 到 ZxingDemo 项目目录中,重命名文件夹为 zxing_header。

    image

    6. 打开 zxing_header 文件夹,删除当前目录及其子目录中的所有cpp文件。

    ps:如果只做 Qr 码识别,可以删除目录 aztec、maxicode、oned、pdf417 和 textcodec,保留 zxing_header 下 h 文件和 datamatrix 、 qrcode文件下h文件。

    ps:修改文件分组依据,可以以快速删除 cpp 文件

    image

     

    二、 配置依赖

    1. vs 项目右键属性,调整配置为 Release,调整平台为 x64.

    image

    2. 属性 - 配置属性 - c/c++ - 常规 - 附加包含目录 ,添加头文件路径(图片路径按实际做调整,依葫芦画瓢)。

    image

    3. 属性 - 配置属性 - 链接器 - 常规 - 附加库目录,添加 lib 库目录(图片路径按实际做调整,依葫芦画瓢)。

    image

    4.属性 - 配置属性 - 链接器 - 常规 - 附加依赖项,添加 ZxingDemo 项目中所有的 lib 文件名称(根据 lib 文件实际名称调整)。

    image

    三、编码

    1.在 ZxingDemo.cpp 文件中编写代码。

    //按项目实际路径调整
    #pragma comment(lib,"zxing_lib/ZXingCore.lib")
    
    #include "stdafx.h"
    
    #include "zxing_headerHybridBinarizer.h"
    #include "zxing_headerLuminanceSource.h"
    #include "zxing_headerGenericLuminanceSource.h"
    #include "zxing_headerDecodeHints.h"
    #include "zxing_headerBinaryBitmap.h"
    #include "zxing_headerReadBarcode.h"
    #include "zxing_headerTextUtfEncoding.h"
    #include "zxing_headerMultiFormatReader.h"
    
    #include <opencv2opencv.hpp>
    #include <opencv2core	ypes_c.h>
    
    
    static std::string WstringToString(const std::wstring &wstr) {
        std::string str;
        std::mbstate_t state = {};
        const wchar_t *data = wstr.data();
        size_t len = std::wcsrtombs(nullptr, &data, 0, &state);
        if (static_cast<size_t>(-1) != len) {
            std::unique_ptr<char[]> buff(new char[len + 1]);
            len = std::wcsrtombs(buff.get(), &data, len, &state);
            if (static_cast<size_t>(-1) != len) {
                str.assign(buff.get(), len);
            }
        }
        return str;
    }
    
    static void Scan() {
        cv::Mat mat, gray_mat;
        //打开图片
        mat = cv::imread("test.PNG");
        if (mat.empty()) {
            std::cout << "not found image" << std::endl;
            return;
        }
        //转为灰度图
        cv::cvtColor(mat, gray_mat, cv::COLOR_RGBA2GRAY);
        //宽高
        int height = gray_mat.rows;
        int width = gray_mat.cols;
        auto *pixels = new unsigned char[height * width];
        int index = 0;
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                pixels[index++] = gray_mat.at<unsigned char>(i, j);
            }
        }
        //识别
        std::shared_ptr<ZXing::GenericLuminanceSource> luminance = std::make_shared<ZXing::GenericLuminanceSource>(0, 0, width, height, pixels, width * sizeof(unsigned char));
        std::shared_ptr<ZXing::BinaryBitmap> bitmap = std::make_shared<ZXing::HybridBinarizer>(luminance);
        ZXing::DecodeHints hints;
        //根据需要添加format
        std::vector<ZXing::BarcodeFormat> formats = { ZXing::BarcodeFormat(ZXing::BarcodeFormat::QR_CODE) };
        hints.setPossibleFormats(formats);
        auto reader = new ZXing::MultiFormatReader(hints);
        ZXing::Result result = reader->read(*bitmap);
        if (result.status() == ZXing::DecodeStatus::NoError) {
            //识别成功,打印结果
            std::cout << WstringToString(result.text()) << std::endl;
        }
        else {
            std::cout << "Fail" << std::endl;
        }
    }
    
    int main()
    {
        Scan();
        std::cin.get();
        return 0;
    }

    2. 搞一张二维码图片 test.PNG 放到编译输出目录 x64Release 中。

    四、启动

    1. 调整配置为 Release,调整平台为 x64,点击”本地windows调试器”启动测试。

    image

    2.成功输出结果。

    image

    五、常见问题

    1. 编译异常:错误    C4996    'wcsrtombs': This function or variable may be unsafe. Consider using wcsrtombs_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    ZxingDemo    H:cppxingDemoxingDemoxingDemo.cpp    23   
    image

    解决方法:右键项目属性 - 配置属性 – c/c++ - 预处理器 - 预处理器定义,添加如下预处理定义。

    _CRT_SECURE_NO_WARNINGS
    _CRT_NONSTDC_NO_WARNINGS
    _CRT_SECURE_NO_WARNINGS_GLOBALS

    image

    2. 执行异常,启动测试后报错:无法启动此程序,因为计算机中丢失 opencv_world412.dll。尝试重新安装该程序已解决此问题。

    image

    原因:程序找不到opencv_world412.dll,一般情况:1.没安装 opencv 或者没有添加 opencv 环境变量 2.打开 vs2017 后才添加 opencv 环境变量,未生效。

    解决:安装 opencv ,添加 Path 环境变量 buildx64vc15in(或者buildx64vc14in)。关闭 Vs2017 重新打开项目。

  • 相关阅读:
    最简单跨平台的日志库
    linux文件锁
    Linux 获取屏幕分辨率与窗口行列数(c/c++)
    linux 信号机制
    记一次函数异常(getopt_long)
    程序单实例运行
    简单地 Makefile 书写
    学习go的一些笔记
    20200930 10. Netty 核心源码剖析
    20200930 9. TCP 粘包和拆包 及解决方案
  • 原文地址:https://www.cnblogs.com/zhenjin-huaxiazongdai/p/12571824.html
Copyright © 2011-2022 走看看