|
|
// ai.cpp
|
|
|
#include "ai.h"
|
|
|
#include "ui_ai.h"
|
|
|
#include <QVBoxLayout>
|
|
|
#include <QHBoxLayout>
|
|
|
#include <QFileDialog>
|
|
|
#include <QNetworkRequest>
|
|
|
#include <QFile>
|
|
|
#include <QNetworkReply>
|
|
|
#include <QUrl>
|
|
|
#include <QJsonDocument>
|
|
|
#include <QJsonObject>
|
|
|
#include <QJsonArray>
|
|
|
#include <QMovie>
|
|
|
#include <QtTextToSpeech/QTextToSpeech>
|
|
|
#include <QBuffer>
|
|
|
#include <QString>
|
|
|
#include "message.h"
|
|
|
#include <QSqlQuery>
|
|
|
#include <QSqlDatabase>
|
|
|
#include <QMessageBox>
|
|
|
|
|
|
ai::ai(QWidget *parent) :
|
|
|
QWidget(parent),
|
|
|
ui(new Ui::ai)
|
|
|
{
|
|
|
// 显示车牌图片
|
|
|
lb_pix = new QLabel;
|
|
|
lb_pix->setFixedSize(490, 350);
|
|
|
lb_pix->setScaledContents(true);
|
|
|
// 加载并显示名为 'fen.png' 的图片
|
|
|
QPixmap pixmap(":/fen.png"); // 假设图片文件已添加到 Qt 的资源文件中
|
|
|
pixmap = pixmap.scaled(lb_pix->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
|
|
lb_pix->setPixmap(pixmap);
|
|
|
|
|
|
// 设置窗口的背景图片
|
|
|
lb_pix->setStyleSheet("background-image: url(:/fen.png);"
|
|
|
"background-position: center;"
|
|
|
"background-repeat: no-repeat;"
|
|
|
"background-size: cover;");
|
|
|
|
|
|
// 设置载入车牌按钮
|
|
|
btn_load = new QPushButton("载入车牌");
|
|
|
btn_load->setFixedSize(90, 45);
|
|
|
btn_load->setStyleSheet("QPushButton {"
|
|
|
"background-color: qlineargradient(spread:pad, x1:0.52, y1:1, x2:0.54, y2:0, "
|
|
|
"stop:0.0112994 rgba(173, 216, 230, 255), "
|
|
|
"stop:1 rgba(204, 229, 255, 255)); "
|
|
|
"color: rgb(255, 255, 255); "
|
|
|
"border: 2px solid rgba(170, 255, 255, 200); "
|
|
|
"border-radius: 10px; "
|
|
|
"padding: 5px 10px; "
|
|
|
"font: 16pt \"Candara\"; "
|
|
|
"box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.3);"
|
|
|
"}"
|
|
|
"QPushButton:hover {"
|
|
|
"background-color: qlineargradient(spread:pad, x1:0.52, y1:1, x2:0.54, y2:0, "
|
|
|
"stop:0.0112994 rgba(204, 229, 255, 255), "
|
|
|
"stop:1 rgba(173, 216, 230, 255)); "
|
|
|
"border: 2px solid rgba(173, 216, 230, 255);"
|
|
|
"}"
|
|
|
"QPushButton:pressed {"
|
|
|
"background-color: rgba(204, 229, 255, 150); "
|
|
|
"box-shadow: inset 0px 0px 5px rgba(0, 0, 0, 0.2);"
|
|
|
"}");
|
|
|
|
|
|
// 设置识别按钮
|
|
|
btn_decode = new QPushButton("识别");
|
|
|
btn_decode->setFixedSize(90, 45);
|
|
|
btn_decode->setStyleSheet("QPushButton {"
|
|
|
"background-color: qlineargradient(spread:pad, x1:0.52, y1:1, x2:0.54, y2:0, "
|
|
|
"stop:0.0112994 rgba(173, 216, 230, 255), "
|
|
|
"stop:1 rgba(204, 229, 255, 255)); "
|
|
|
"color: rgb(255, 255, 255); "
|
|
|
"border: 2px solid rgba(170, 255, 255, 200); "
|
|
|
"border-radius: 10px; "
|
|
|
"padding: 5px 10px; "
|
|
|
"font: 16pt \"Candara\"; "
|
|
|
"box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.3);"
|
|
|
"}"
|
|
|
"QPushButton:hover {"
|
|
|
"background-color: qlineargradient(spread:pad, x1:0.52, y1:1, x2:0.54, y2:0, "
|
|
|
"stop:0.0112994 rgba(204, 229, 255, 255), "
|
|
|
"stop:1 rgba(173, 216, 230, 255)); "
|
|
|
"border: 2px solid rgba(173, 216, 230, 255);"
|
|
|
"}"
|
|
|
"QPushButton:pressed {"
|
|
|
"background-color: rgba(204, 229, 255, 150); "
|
|
|
"box-shadow: inset 0px 0px 5px rgba(0, 0, 0, 0.2);"
|
|
|
"}");
|
|
|
|
|
|
|
|
|
// 设置车牌路径输入框
|
|
|
le_path = new QLineEdit;
|
|
|
le_path->setPlaceholderText("车牌图片路径:");
|
|
|
le_path->setMinimumHeight(30);
|
|
|
le_path->setStyleSheet("QLineEdit {"
|
|
|
"border: 1px solid rgba(170, 255, 255, 200); "
|
|
|
"border-radius: 10px; "
|
|
|
"padding: 5px 10px; "
|
|
|
"font: 15pt \"微软雅黑\";"
|
|
|
"}");
|
|
|
|
|
|
|
|
|
// 设置识别结果输入框
|
|
|
le_code = new QLineEdit;
|
|
|
le_code->setPlaceholderText("识别结果:");
|
|
|
le_code->setMinimumHeight(33);
|
|
|
le_code->setStyleSheet("QLineEdit {"
|
|
|
"border: 1px solid rgba(170, 255, 255, 200); "
|
|
|
"border-radius: 10px; "
|
|
|
"padding: 5px 10px; "
|
|
|
"font: 18pt \"微软雅黑\";"
|
|
|
|
|
|
"}");
|
|
|
|
|
|
speeker = new QTextToSpeech;
|
|
|
httpmanager = new QNetworkAccessManager;
|
|
|
connect(httpmanager, SIGNAL(finished(QNetworkReply*)), this, SLOT(read_ack(QNetworkReply*)));
|
|
|
|
|
|
// // 2. 排版
|
|
|
QHBoxLayout *hbox = new QHBoxLayout;
|
|
|
hbox->addWidget(btn_load);
|
|
|
hbox->addWidget(btn_decode);
|
|
|
|
|
|
QVBoxLayout *mainbox = new QVBoxLayout;
|
|
|
// 车牌图片
|
|
|
mainbox->addWidget(lb_pix);
|
|
|
|
|
|
mainbox->addWidget(le_path);
|
|
|
mainbox->addWidget(le_code);
|
|
|
|
|
|
mainbox->addLayout(hbox);
|
|
|
setLayout(mainbox);
|
|
|
|
|
|
// 5. 前后台挂接
|
|
|
connect(btn_load, SIGNAL(clicked(bool)), this, SLOT(load_pix()));
|
|
|
connect(btn_decode, SIGNAL(clicked(bool)), this, SLOT(decode_pix()));
|
|
|
mes = new message;
|
|
|
connect(this, SIGNAL(mySignals(QString)), mes, SLOT(mySlot(QString)));
|
|
|
connect(this, SIGNAL(Signal_out(QString)), mes, SLOT(Slot_out(QString)));
|
|
|
|
|
|
}
|
|
|
|
|
|
void ai::load_pix()
|
|
|
{
|
|
|
QString filename = QFileDialog::getOpenFileName(this, "打开车牌照片", ".", "Images (*.png *.bmp *.jpg)");
|
|
|
if (filename.isEmpty()) {
|
|
|
return; // 如果没有选择文件,直接返回
|
|
|
}
|
|
|
|
|
|
QPixmap pixmap(filename);
|
|
|
if (!pixmap.isNull()) {
|
|
|
// 调整图片大小,以适应QLabel的大小
|
|
|
pixmap = pixmap.scaled(lb_pix->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
|
|
lb_pix->setPixmap(pixmap);
|
|
|
} else {
|
|
|
|
|
|
qDebug() << "无法加载图片";
|
|
|
}
|
|
|
le_path->setText(filename);
|
|
|
}
|
|
|
|
|
|
|
|
|
void ai::decode_pix()
|
|
|
{
|
|
|
// 向百度发送一个二维码识别请求(HTTP)
|
|
|
QNetworkRequest myrequset;
|
|
|
|
|
|
// 填充请求url
|
|
|
myrequset.setUrl(QUrl("https://aip.baidubce.com/rest/2.0/ocr/v1/license_plate?access_token=24.45460c2347791a4df2f2eaf275fe956c.2592000.1737857078.282335-116856660"));
|
|
|
// 填充header
|
|
|
myrequset.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
|
|
|
|
|
// 填充请求的body
|
|
|
// 1. 挖出照片内容
|
|
|
QFile file(le_path->text());
|
|
|
file.open(QIODevice::ReadOnly);
|
|
|
QByteArray buf = file.readAll();
|
|
|
|
|
|
// 2. 转成base64及urlcode
|
|
|
QByteArray buf64 = buf.toBase64().toPercentEncoding();
|
|
|
QByteArray body = "image=" + buf64;
|
|
|
// 发送完整的一次识别请求
|
|
|
httpmanager->post(myrequset, body);
|
|
|
}
|
|
|
|
|
|
// 结果解析
|
|
|
void ai::read_ack(QNetworkReply *r)
|
|
|
{
|
|
|
// 提取json格式的返回
|
|
|
QByteArray buf = r->readAll();
|
|
|
qDebug() << buf;
|
|
|
|
|
|
// 提取json中的内容
|
|
|
QJsonDocument myjson = QJsonDocument::fromJson(buf);
|
|
|
QJsonObject node = myjson.object();
|
|
|
QJsonObject arr = node.value("words_result").toObject();
|
|
|
QString text = arr.value("number").toString();
|
|
|
le_code->setText(text);
|
|
|
speeker->say(text+"已识别");
|
|
|
speeker->setVolume(1.0); // 设置最大音量
|
|
|
speeker->setRate(-0.2); //放慢速度
|
|
|
|
|
|
|
|
|
// 判断是否已经进入
|
|
|
QSqlDatabase db = QSqlDatabase::database("text01"); // 使用相同的连接名 "text01"
|
|
|
if (!db.isOpen() && !db.open()) {
|
|
|
qDebug() << "数据库连接失败!";
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
QString number = QString("SELECT * FROM car_number WHERE number='%1'").arg(text);
|
|
|
QSqlQuery query(db);
|
|
|
|
|
|
if (query.exec(number) && query.next()) {
|
|
|
emit Signal_out(text);
|
|
|
} else {
|
|
|
emit mySignals(text);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
ai::~ai()
|
|
|
{
|
|
|
delete ui;
|
|
|
delete mes;
|
|
|
}
|