Qt-OpenCV学习笔记--二维码(QR)的生成和识别

一、概述

引用 Libqrencode qrencode 库,生成二维码;

利用 openCV 的 QRCodeDetector 类,检测和识别二维码。

在此做个记录。

上视频!

二维码的生成和识别

二、测试代码

untitled27.pro

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    from2.cpp \
    main.cpp \
    qr.cpp \
    widget.cpp

HEADERS += \
    from2.h \
    qr.h \
    widget.h

FORMS += \
    from2.ui \
    widget.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

unix|win32: LIBS += -L$$PWD/../../../../../libqrencode/lib/ -llibqrencode.dll

INCLUDEPATH += $$PWD/../../../../../libqrencode/include
DEPENDPATH += $$PWD/../../../../../libqrencode/include

unix|win32: LIBS += -L$$PWD/../../../../../opencv/install/x64/mingw/lib/ -llibopencv_world460.dll

INCLUDEPATH += $$PWD/../../../../../opencv/install/include
DEPENDPATH += $$PWD/../../../../../opencv/install/include

from2.h

#ifndef FROM2_H
#define FROM2_H

#include <QWidget>

namespace Ui {
class from2;
}

class from2 : public QWidget
{
    Q_OBJECT

public:
    explicit from2(QWidget *parent = nullptr);
    ~from2();

private slots:
    void on_pushButton_2_clicked();

    void on_pushButton_clicked();

private:
    Ui::from2 *ui;
};

#endif // FROM2_H

qr.h

#ifndef QR_H
#define QR_H

#include <qrencode.h>
#include <qimage.h>
#include <qstring.h>

class QR
{
public:
    QR();

public:
    //生产二维码
    static QImage produceQR(const QString &info);
};

#endif // QR_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

from2.cpp

#include "from2.h"
#include "ui_from2.h"

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect.hpp>

#include <iostream>

#include <string>
#include <sstream>
#include <vector>
#include <QDebug>
#include <QFileDialog>

using namespace cv;
using namespace std;

from2::from2(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::from2)
{
    ui->setupUi(this);
}

from2::~from2()
{
    delete ui;
}

//拆分字符串
vector<string> split(string str,char ch)
{
    //创建字符串盒子
    vector<string> results;
    //将字符串转为字符串流
    stringstream ss(str);
    //创建字符串临时存放点
    string temp;
    //循环切分,并将每一次切分的结果放入盒子
    while(getline(ss,temp,ch))
        {
            results.push_back(temp);
        }
    //返回结果
    return results;
}

//选择二维码
void from2::on_pushButton_2_clicked()
{
    //打开对话框选择二维码
    QString path = QFileDialog::getOpenFileName(this,"选择一个二维码",".","*.jpg *.png *.bmp");
    //显示二维码路径
    ui->lineEdit_5->setText(path);
    //显示二维码
    if(!path.isEmpty())
        {
            //加载图像
            QPixmap* pix= new QPixmap;
            pix->load(path);
            //图像缩放
            QPixmap* npix= new QPixmap;
            *npix = pix->scaled(ui->label->size(),Qt::KeepAspectRatio);
            //显示
            ui->label->setPixmap(*npix);
        }
}

//解码
void from2::on_pushButton_clicked()
{
    //获取二维码路径
    QString qpath = ui->lineEdit_5->text();
    //qstring转string
    string path = qpath.toStdString();
    //载入图像
    Mat src = imread(path,0);

    //显示图像
    //imshow("src",src);

    //创建检测器
    QRCodeDetector detector;

    //检测标识
    bool sign;
    //二维码最小四边形的顶点坐标
    vector<Point> points;

    //检测二维码
    sign = detector.detect(src,points);

    //判断检测是否成功,如果成功,打印顶点坐标
    if(sign)
    {
        for (unsigned int i = 0;i<points.size();i++)
        {
            qDebug() << points[i].x;
            qDebug() << points[i].y;
        }
    }
    else
    {
        qDebug() << "检测失败!";
    }

    //解码
    string infomation;
    Mat dst;
    infomation = detector.decode(src,points,dst);
    //打印解码信息
    QString str0 = QString::fromStdString(infomation);
    qDebug() << str0;
    //显示纠正的二维码
    //imshow("dst",dst);

    //拆分字符串
    vector<string> results = split(infomation,' ');
    string str1 = results[0];
    string str2 = results[1];
    string str3 = results[2];
    string str4 = results[3];
    //显示信息
    ui->lineEdit->setText(QString::fromStdString(str1));
    ui->lineEdit_2->setText(QString::fromStdString(str2));
    ui->lineEdit_3->setText(QString::fromStdString(str3));
    ui->lineEdit_4->setText(QString::fromStdString(str4));

}

main.cpp

#include "widget.h"
#include "from2.h"

#include <QApplication>

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

    Widget w;
    w.show();

    from2 x;
    x.show();

    return a.exec();
}

qr.cpp

#include "qr.h"

#include <QPainter>

QR::QR()
{

}

QImage QR::produceQR(const QString &info)
{
    //放置二维码
    QImage dst;
    //绘制方块大小
    int scale = 4;
    //将字符串转字符集合,同时定义编码格式为UTF8
    QByteArray info_date = info.toUtf8();
    //调用libqrencode库进行编码
    QRcode* qr = QRcode_encodeString(info_date.constData(),0,QR_ECLEVEL_Q,QR_MODE_8,1);

    //绘制
    if (qr && qr->width >0)
    {
        //设置图像大小
        int img_width = qr->width * scale;
        //创建画布
        dst = QImage(img_width,img_width,QImage::Format_Mono);
        //创建油漆工
        QPainter painter(&dst);
        //填充白色背景
        painter.fillRect(0,0,img_width,img_width,Qt::white);
        //设置画笔
        painter.setPen(Qt::NoPen);
        //设置黑色刷子
        painter.setBrush(Qt::black);
        //绘制二维码
        for (int y=0; y<qr->width; y++)
        {
            for (int x=0; x<qr->width; x++)
            {
                //绘制黑块
                if( qr->data[y*qr->width+x] & 1)
                {
                    QRect r(x*scale, y*scale, scale, scale);
                    painter.drawRect(r);
                }

            }
        }
        QRcode_free(qr);
    }

    return dst;
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"

#include "qr.h"

#include <QDebug>
#include <QImage>
#include <QPainter>

QImage img;

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);


}

Widget::~Widget()
{
    delete ui;
}


//调用函数生成二维码
void Widget::on_pushButton_clicked()
{
    //拼接字符串
    QString qstr1 = ui->lineEdit->text();
    QString qstr2 = ui->lineEdit_2->text();
    QString qstr3 = ui->lineEdit_3->text();
    QString qstr4 = ui->lineEdit_4->text();
    QString qstr = qstr1+" "+qstr2+" "+qstr3+" "+qstr4;
    //打印
    qDebug()<<qstr;

    //编译二维码
    QImage qr = QR::produceQR(qstr);

    //设置图像大小
    int x = ui->label->size().width()-20;
    int y = ui->label->size().height()-20;
    QSize size = QSize(x,y);
    img = qr.scaled(size,Qt::KeepAspectRatio);
    //显示
    ui->label->setPixmap(QPixmap::fromImage(img));
}

//保存二维码
void Widget::on_pushButton_2_clicked()
{
    //拼接路径
    QString path = ui->lineEdit_5->text() + ui->lineEdit->text() + ".jpg";

    //设置白框宽度
    int width = 20;
    //新建画板
    QImage dst(300,300,QImage::Format_Mono);
    //创建油漆工
    QPainter p(&dst);
    //填充白色背景
    p.fillRect(0,0,dst.width(),dst.height(),Qt::white);
    //缩放二维码图像尺寸
    QImage src = img.scaled(300-width*2,300-width*2,Qt::KeepAspectRatio);
    //重绘
    p.drawImage(width,width,src);
    //保存
    dst.save(path,"jpg",-1);
}

from2.ui

 widget.ui

三、测试结果

四、总结 

综上,如果配合 热敏打印机扫码枪 ,可以辅助 货物仓储管理

猜你喜欢

转载自blog.csdn.net/ssismm/article/details/128736340