opencv QR 二维码识别

下载模型 https://github.com/WeChatCV/opencv_3rdparty

opencv 4.5

头文件

#ifndef LANDROIDQRCODE_HPP
#define LANDROIDQRCODE_HPP

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <opencv2/opencv.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/wechat_qrcode.hpp>

#define HIGH_RESOLUTION true
#define DECODE_IMG_UNDISTORT true
#define USE_WECHAT_DECODE true
#ifdef ON_ARM
#define CAM_ID 3
#define DECODE_IMG_VISUALIZATION false
#endif
#ifdef ON_X86
#define CAM_ID 2
#define DECODE_IMG_VISUALIZATION true
#endif

struct SsidPass
{
    std::string ssid;
    std::string pass;
    std::string otid;
};

class LandroidQRcode
{
public:
    LandroidQRcode();
    ~LandroidQRcode(){};
    bool wechatQRDecode();
    bool decodeFrameQR(SsidPass &);
    bool decodeImageQR(SsidPass &);
    void QRCodeShow(cv::Mat &img, std::vector<cv::Point> &points) const;
    template <typename T>
    void initPub();
    void decodePublish();
    void connectWifi();

    bool EnableQRcode();
    bool ScanQRcode(SsidPass &);
    bool ScanQRcode(SsidPass &ssid_pass,cv::Mat &img_in);
    bool SaveQRcode() const;
    bool DisableQRcode();
    cv::VideoCapture cap_;
    std::string data_;

private:
    const int img_width_ = (HIGH_RESOLUTION) ? 1920 : 640;
    const int img_height_ = (HIGH_RESOLUTION) ? 1080 : 360;
    cv::Mat frame_;
    cv::Mat map1_, map2_; 
    cv::QRCodeDetector decoder_ = cv::QRCodeDetector();
    std::vector<cv::Point> points_;
    std::string ssid_, psk_;
};

#endif

函数

#include "LandroidQRcode.hpp"

std::string id_end="\"psk\": \"";

LandroidQRcode::LandroidQRcode()
{
    ssid_ = "";
    psk_ = "";

    cv::Mat K, D;
    if (HIGH_RESOLUTION)
    {
        K = (cv::Mat_<double>(3, 3) << 947.32408, 0.0, 1011.14141, 0.0, 951.18813, 590.92158, 0.0, 0.0, 1.0);
        D = (cv::Mat_<double>(5, 1) << -0.335576, 0.085014, 0.001744, -0.003825, 0.000000);
    }
    else
    {
        K = (cv::Mat_<double>(3, 3) << 319.1774094207188, 0.0, 315.9695951747343, 0.0, 319.5137994758127, 199.07306955419622, 0.0, 0.0, 1.0);
        D = (cv::Mat_<double>(5, 1) << -0.3204769598908819, 0.07196729379479753, -0.0019994529282904004, 0.0008377275431221735, 0.0);
    }

    cv::Size img_size(img_width_, img_height_);
    const double alpha = 1;
    // cv::Mat NewCameraMatrix = getOptimalNewCameraMatrix(K, D, img_size, alpha, img_size, 0);
    initUndistortRectifyMap(K, D, cv::Mat(), K, img_size, CV_16SC2, map1_, map2_);
}

bool LandroidQRcode::wechatQRDecode()
{
    cv::Ptr<cv::wechat_qrcode::WeChatQRCode> wechat_detector;
    std::string detect_prototxt = "./wechat_lib/detect.prototxt";
    std::string detect_caffe_model = "./wechat_lib/detect.caffemodel";
    std::string sr_prototxt = "./wechat_lib/sr.prototxt";
    std::string sr_caffe_model = "./wechat_lib/sr.caffemodel";
    try
    {
        wechat_detector = cv::makePtr<cv::wechat_qrcode::WeChatQRCode>(
            detect_prototxt, detect_caffe_model, sr_prototxt, sr_caffe_model);
    }
    catch (const std::exception &e)
    {
        std::cout << e.what() << std::endl;
    }
    std::vector<cv::Mat> points;
    std::vector<std::string> res = wechat_detector->detectAndDecode(frame_, points);

    if (res.size())
    {
        data_ = res[0];
        return true;
    }
    else
        return false;
}

bool LandroidQRcode::decodeFrameQR(SsidPass &ssid_pass)
{
    if (DECODE_IMG_UNDISTORT)
    {
        cv::Mat UndistortImage;
        remap(frame_, UndistortImage, map1_, map2_, cv::INTER_LINEAR);
        frame_ = UndistortImage;
        // cv::imwrite("UndistortImage.png", frame_);
    }

    if (DECODE_IMG_VISUALIZATION)
    {
        cv::imshow("to detect img", frame_);
        cv::waitKey(1);
    }

    bool if_detected = false;
    if (USE_WECHAT_DECODE)
        if_detected = wechatQRDecode();
    else
    {
        data_ = decoder_.detectAndDecode(frame_, points_);
        if (!points_.empty())
            if_detected = true;
    }

    if (if_detected)
    {
        //std::cout << "QR raw data: " << data_ << std::endl;
        if ((!data_.empty()) && data_[0] == '{')
        {
            int index=data_.find(id_end,10);
            //std::cout<<"*****************"<<index<<std::endl;
            ssid_pass.ssid=data_.substr(10,index-13);
            ssid_pass.pass=data_.substr(index+8,data_.length()-index-8-2);
            return true;
        }
        if (DECODE_IMG_VISUALIZATION && (not USE_WECHAT_DECODE))
            QRCodeShow(frame_, points_);
    }
    else
        return false;
}

bool LandroidQRcode::decodeImageQR(SsidPass &ssid_pass)
{
    frame_ = cv::imread("test.jpg");
    return decodeFrameQR(ssid_pass);
}

void LandroidQRcode::QRCodeShow(cv::Mat &img, std::vector<cv::Point> &points) const
{
    for (int i = 0; i < points.size(); i++)
    {
        cv::Point pt1 = points[i];
        cv::Point pt2 = points[(i + 1) % 4];
        line(img, pt1, pt2, cv::Scalar(255, 0, 0), 3);
    }
    imshow("Detected QR code", img);
    cv::waitKey(2);
}


bool LandroidQRcode::EnableQRcode()
{
    cap_ = cv::VideoCapture(CAM_ID);
    std::cout << "Video captured." << std::endl;
    cap_.set(cv::CAP_PROP_FRAME_WIDTH, img_width_);
    cap_.set(cv::CAP_PROP_FRAME_HEIGHT, img_height_);
    cv::TickMeter meter;
    meter.start();
    if (!cap_.isOpened())
    {
        std::cerr << "Couldn't open video capture device" << CAM_ID << std::endl;
        return false;
    }
    else
    {
        meter.stop();
        std::cout << "Detector initialized in " << std::fixed << std::setprecision(3)
                  << meter.getTimeSec() << "s"
                  << ", " << cap_.get(cv::CAP_PROP_FRAME_WIDTH)
                  << "x" << cap_.get(cv::CAP_PROP_FRAME_HEIGHT) << " @"
                  << cap_.get(cv::CAP_PROP_FPS) << "FPS" << std::endl;
        meter.reset();
        return true;
    }
}

bool LandroidQRcode::ScanQRcode(SsidPass &ssid_pass)
{
    cap_ >> frame_;
    return decodeFrameQR(ssid_pass);
}

bool LandroidQRcode::ScanQRcode(SsidPass &ssid_pass,cv::Mat &img_in)
{
    frame_=img_in;
    return decodeFrameQR(ssid_pass);
}


bool LandroidQRcode::DisableQRcode()
{
    cap_.release();
    cv::destroyAllWindows();
    std::cout << "Cam " << CAM_ID << " released." << std::endl;
    return true;
}

执行

#include "LandroidQRcode.hpp"
#include <unistd.h>

int main()
{
    LandroidQRcode QR_decoder;
    SsidPass ssid_pass;
    cv::Mat my_img;

    if (!QR_decoder.EnableQRcode())//打开相机
        return 0;

    // scan QR by cam video
    while (1)
    {
        QR_decoder.cap_>>my_img;//将相机存入图片,可将图片存入
        if(QR_decoder.ScanQRcode(ssid_pass,my_img))
            std::cout << "QR detected:"
            << ssid_pass.ssid<<"/"<< ssid_pass.pass << std::endl;
        usleep(100000);
    }
    QR_decoder.DisableQRcode();//断开相机
    return 0;
}

cmake文件

cmake_minimum_required(VERSION 3.1)
project( LandroidQRcode LANGUAGES C CXX)

include_directories(include)
find_package(Boost REQUIRED)
set (ON_ARM "OFF")
if(ON_ARM)
    add_definitions(-DON_ARM)
else()
    add_definitions(-DON_X86)
endif()

find_package( OpenCV REQUIRED)
add_executable( QR_main src/QR_main.cpp src/LandroidQRcode.cpp)
target_link_libraries( QR_main ${OpenCV_LIBS})
install(TARGETS QR_main RUNTIME DESTINATION bin)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值