一、概述
引用 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
三、测试结果
四、总结
综上,如果配合 热敏打印机 和 扫码枪 ,可以辅助 货物 的 仓储管理 。