|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- /*
- * Copyright (C) 2021 刘臣轩
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
- #include "widget.h"
- #include "ui_widget.h"
-
- Widget::Widget(QWidget* parent)
- : QWidget(parent)
- , ui(new Ui::Widget)
- {
- ui->setupUi(this);
- connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(close()));
- ui->frame->setStyleSheet("#frame {border-image: url(:/new/prefix1/image/主.png);}");
- ui->textEdit->append("开始初始化设备");
-
- // Time
- QTimer* timer = new QTimer(this);
- connect(timer, SIGNAL(timeout()), this, SLOT(timerUpdate()));
- timer->start(500);
-
- initSerial();
- #ifdef Q_OS_WIN
- initCamera();
- #else
- connect(this, SIGNAL(imageCaptured(int, QImage)), this, SLOT(onImageCaptured(int, QImage)));
- ui->textEdit->append("摄像头初始化成功");
- #endif
-
- // Network
- networkManager = new QNetworkAccessManager();
- networkRequest = new QNetworkRequest();
- networkRequest->setHeader(QNetworkRequest::ContentTypeHeader, " application/json;charset=UTF-8");
- url = new QUrl("https://aiapi.jd.com/jdai/garbageImageSearch");
- connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(onRequestFinished(QNetworkReply*)));
-
- ui->label_3->setText("工训大赛");
- ui->label_4->setStyleSheet("border-image: url(:/new/prefix1/image/工训大赛.png);\nborder-radius: 10px;\n");
- ui->label_4->setVisible(true);
- ui->label_5->setVisible(false);
- ui->textEdit->append("设备初始化成功√");
- number = 0;
-
- // Video
- player = new QMediaPlayer;
- videoWidget = new QVideoWidget(this);
- playList = new QMediaPlaylist;
- #ifdef Q_OS_WIN
- playList->addMedia(QUrl::fromLocalFile("../WasteSorting/test.mp4"));
- #else
- playList->addMedia(QUrl::fromLocalFile("/home/pi/WasteSorting/test.mp4"));
- #endif
- playList->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
- player->setPlaylist(playList);
- player->setVideoOutput(videoWidget);
- ui->verticalLayout->addWidget(videoWidget);
- videoWidget->setVisible(false);
-
- videoTimer = new QTimer(this);
- connect(videoTimer, SIGNAL(timeout()), this, SLOT(videoTimerUpdate()));
- videoTimer->setSingleShot(true);
- videoTimer->start(10000);
- }
-
- Widget::~Widget()
- {
- delete ui;
- }
-
- void Widget::timerUpdate()
- {
- QString str = QDateTime::currentDateTime().toString("yyyy年MM月dd日 hh:mm:ss");
- ui->label->setText(str);
- }
-
- void Widget::videoTimerUpdate()
- {
- ui->label_4->setVisible(false);
- player->play();
- videoWidget->setVisible(true);
- ui->label_3->setText("播放视频");
- ui->textEdit->append("播放视频");
- }
-
- void Widget::initSerial()
- {
- ui->textEdit->append("开始初始化串口");
- serialPort = new QSerialPort();
- connect(serialPort, SIGNAL(readyRead()), this, SLOT(serialRead()));
- if (QSerialPortInfo::availablePorts().length() == 0) {
- QMessageBox::critical(this, "错误", "无可用串口设备,请检查硬件连接后重试");
- exit(0);
- }
- #ifdef Q_OS_WIN
- QString portName = QSerialPortInfo::availablePorts()[1].portName();
- qDebug() << portName;
- ui->textEdit->append("尝试连接串口" + portName);
- serialPort->setPortName(portName);
- #else
- QString portName = "ttyUSB0";
- ui->textEdit->append("尝试连接串口ttyUSB0");
- serialPort->setPortName("ttyUSB0");
- #endif
- if (serialPort->open(QIODevice::ReadWrite)) {
- ui->textEdit->append("串口连接成功");
- serialPort->setBaudRate(115200);
- serialPort->setDataBits(QSerialPort::Data8);
- serialPort->setParity(QSerialPort::NoParity);
- serialPort->setStopBits(QSerialPort::OneStop);
- } else {
- QMessageBox::critical(this, "错误", "串口设备" + portName + "无法打开,请检查硬件连接后重试");
- exit(0);
- }
- ui->textEdit->append("串口初始化成功");
- }
-
- void Widget::initCamera()
- {
- // for (QCameraInfo& info : QCameraInfo::availableCameras()) {
- // qDebug() << info.deviceName();
- // }
- int camNum = QCameraInfo::availableCameras().length();
- if (!camNum) {
- QMessageBox::critical(this, "错误", "无可用摄像头,请检查硬件连接后重试");
- exit(0);
- }
- ui->textEdit->append("开始初始化摄像头");
- camera = new QCamera(QCameraInfo::availableCameras()[0], this);
- imageCapture = new QCameraImageCapture(camera);
- connect(imageCapture, SIGNAL(imageCaptured(int, QImage)), this, SLOT(onImageCaptured(int, QImage)));
- camera->setCaptureMode(QCamera::CaptureStillImage);
- imageCapture->setCaptureDestination(QCameraImageCapture::CaptureToBuffer);
- camera->start();
- ui->textEdit->append("摄像头初始化成功");
- }
-
- void Widget::serialRead()
- {
- QByteArray buffer = serialPort->readAll();
- // qDebug() << buffer;
- if (buffer[0] == '\x03' && buffer[1] == '\xFC'
- && buffer[3] == '\xFC' && buffer[4] == '\x03') {
- switch (buffer[2]) {
- case '\x00':
- ui->textEdit->append("取消警报");
- ui->label_3->setText("取消警报");
- ui->label_4->setVisible(true);
- ui->label_5->setVisible(false);
- ui->frame->setStyleSheet("#frame {border-image: url(:/new/prefix1/image/主.png);}");
- videoTimer->start(10000);
- break;
- case '\x01':
- ui->textEdit->append("触发拍照信号");
- ui->label_3->setText("触发拍照");
- videoTimer->stop();
- videoWidget->setVisible(false);
- player->stop();
- #ifdef Q_OS_WIN
- imageCapture->capture();
- #else
- captureImage();
- #endif
- break;
- case '\x02':
- ui->textEdit->append("投递完毕");
- ui->label_3->setText("投递完毕");
- ui->label_4->setVisible(true);
- ui->label_5->setVisible(false);
- ui->frame->setStyleSheet("#frame {border-image: url(:/new/prefix1/image/主.png);}");
- videoTimer->start(10000);
- break;
- case '\x04':
- ui->textEdit->append("满载警报");
- ui->label_3->setText("满载警报");
- ui->label_4->setVisible(false);
- videoTimer->stop();
- videoWidget->setVisible(false);
- player->stop();
- ui->frame->setStyleSheet("#frame {border-image: url(:/new/prefix1/image/满载警报.png);}");
- break;
- case '\x08':
- // qDebug() << "倾倒警报";
- ui->textEdit->append("倾倒警报");
- ui->label_3->setText("倾倒警报");
- ui->label_4->setVisible(false);
- videoTimer->stop();
- videoWidget->setVisible(false);
- player->stop();
- ui->frame->setStyleSheet("#frame {border-image: url(:/new/prefix1/image/倾倒警报.png);}");
- break;
- case '\xFF':
- break;
- }
- }
- }
-
- void Widget::serialWrite(const char data)
- {
- QByteArray buffer("\x30\xCF\x0F\xCF\x30");
- buffer[2] = data;
- serialPort->write(buffer);
- }
-
- void Widget::captureImage()
- {
- system("raspistill -o ../WasteSorting/WasteSorting.jpg -t 1 -br 70 -hf -awb sun");
- QImage image("../WasteSorting/WasteSorting.jpg");
- emit(imageCaptured(0, image));
- }
-
- void Widget::onImageCaptured(int, QImage image)
- {
- // 显示图片
- ui->label_4->setVisible(false);
- ui->label_5->setPixmap(QPixmap::fromImage(image).scaled(405, 306));
- ui->label_5->setVisible(true);
- ui->label_3->setText("识别中");
- ui->frame->setStyleSheet("#frame {border-image: url(:/new/prefix1/image/识别中.png);}");
-
- /* 使用京东垃圾识别 API
- // Base64编码
- QByteArray ba;
- QBuffer buf(&ba);
- image.save(&buf, "JPG", -1);
- QByteArray imageBase64 = ba.toBase64();
- // qDebug() << "data:image/jpg;base64," + imageBase64;
-
- // Request
- sendRequest(imageBase64);
- */
-
- /* 使用TensorFlow Lite */
- #ifdef Q_OS_WIN
- image.save("../WasteSorting/WasteSorting.jpg");
- FILE* fp = _popen("python ../WasteSorting/tensorflow/label_image.py", "rt");
- char buf[255] = { 0 };
- fscanf(fp, "%s", buf);
- _pclose(fp);
- #else
- FILE* fp = popen("python3 ../WasteSorting/tensorflow/label_image.py", "r");
- char buf[255] = { 0 };
- printf("%s", buf);
- fscanf(fp, "%s", buf);
- pclose(fp);
- #endif
- QString cate_name = QString::fromLocal8Bit(buf);
- qDebug() << cate_name;
- classifyFinished(cate_name);
- }
-
- void Widget::sendRequest(QByteArray& imageBase64)
- {
- QUrlQuery query;
- query.addQueryItem("appkey", "3a24b33468565b633d25d426eb0c660c");
- qint64 timestamp = QDateTime::currentDateTime().toMSecsSinceEpoch();
- query.addQueryItem("timestamp", QString::number(timestamp));
- QString sign = "58125e5985e6ef2d385ebfaa646987ba" + QString::number(timestamp);
- QByteArray ba = QCryptographicHash::hash(sign.toUtf8(), QCryptographicHash::Md5);
- query.addQueryItem("sign", ba.toHex());
- url->setQuery(query);
- networkRequest->setUrl(*url);
- // qDebug() << query.toString();
-
- QJsonObject json;
- json.insert("imgBase64", QString(imageBase64));
- json.insert("cityId", "440300");
- QJsonDocument document;
- document.setObject(json);
- QByteArray data = document.toJson(QJsonDocument::Compact);
- // qDebug() << QString(data);
-
- networkManager->post(*networkRequest, data);
- }
-
- void Widget::onRequestFinished(QNetworkReply* reply)
- {
- QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
- if (!statusCode.isValid()) {
- QMessageBox::critical(this, "错误", "网络连接不可用,请检查后重试");
- exit(0);
- }
- QByteArray replyData = reply->readAll();
- QJsonParseError jsonError;
- QJsonDocument document = QJsonDocument::fromJson(replyData, &jsonError);
- if (!document.isNull() && (jsonError.error == QJsonParseError::NoError)) {
- QJsonObject object = document.object().value("result").toObject();
- QJsonArray array = object.value("garbage_info").toArray();
- QJsonObject max = std::max_element(array.begin(), array.end(),
- [](QJsonValue const& a, QJsonValue const& b) { return a.toObject().value("confidence").toDouble()
- < b.toObject().value("confidence").toDouble(); })
- ->toObject();
- QString cate_name = max.value("cate_name").toString();
- QString garbage_name = max.value("garbage_name").toString();
- double confidence = max.value("confidence").toDouble();
- // qDebug() << "cate_name:" << cate_name;
- // qDebug() << "garbage_name:" << garbage_name;
- // qDebug() << "confidence:" << confidence;
- // ui->textEdit->append("cate_name: " + cate_name);
- // ui->textEdit->append("garbage_name: " + garbage_name);
- // ui->textEdit->append("confidence: " + QString::number(confidence));
- classifyFinished(cate_name);
-
- } else {
- serialWrite('\xFF');
- ui->textEdit->append("识别失败,请重试");
- ui->label_3->setText("识别失败");
- ui->label_4->setVisible(true);
- ui->label_5->setVisible(false);
- ui->frame->setStyleSheet("#frame {border-image: url(:/new/prefix1/image/主.png);}");
- }
- }
-
- void Widget::classifyFinished(QString cate_name)
- {
- ui->frame->setStyleSheet("#frame {border-image: url(:/new/prefix1/image/" + cate_name + ".PNG);}");
- ui->label_3->setText("投递中");
- if (cate_name == "识别失败") {
- serialWrite('\xFF');
- ui->textEdit->append("识别失败,请重试");
- ui->label_3->setText("识别失败");
- ui->label_4->setVisible(true);
- ui->label_5->setVisible(false);
- ui->frame->setStyleSheet("#frame {border-image: url(:/new/prefix1/image/主.png);}");
- } else {
- number += 1;
- ui->textEdit->append(QString::number(number) + " " + cate_name + " 1 OK!");
- if (cate_name == "可回收垃圾")
- serialWrite('\x01');
- else if (cate_name == "厨余垃圾")
- serialWrite('\x02');
- else if (cate_name == "有害垃圾")
- serialWrite('\x04');
- else
- serialWrite('\x08');
- }
- }
|