You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

widget.cpp 13 kB

5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. /*
  2. * Copyright (C) 2021 刘臣轩
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "widget.h"
  18. #include "ui_widget.h"
  19. Widget::Widget(QWidget* parent)
  20. : QWidget(parent)
  21. , ui(new Ui::Widget)
  22. {
  23. ui->setupUi(this);
  24. connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(close()));
  25. ui->frame->setStyleSheet("#frame {border-image: url(:/new/prefix1/image/主.png);}");
  26. ui->textEdit->append("开始初始化设备");
  27. // Time
  28. QTimer* timer = new QTimer(this);
  29. connect(timer, SIGNAL(timeout()), this, SLOT(timerUpdate()));
  30. timer->start(500);
  31. initSerial();
  32. #ifdef Q_OS_WIN
  33. initCamera();
  34. #else
  35. connect(this, SIGNAL(imageCaptured(int, QImage)), this, SLOT(onImageCaptured(int, QImage)));
  36. ui->textEdit->append("摄像头初始化成功");
  37. #endif
  38. // Network
  39. networkManager = new QNetworkAccessManager();
  40. networkRequest = new QNetworkRequest();
  41. networkRequest->setHeader(QNetworkRequest::ContentTypeHeader, " application/json;charset=UTF-8");
  42. url = new QUrl("https://aiapi.jd.com/jdai/garbageImageSearch");
  43. connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(onRequestFinished(QNetworkReply*)));
  44. ui->label_3->setText("工训大赛");
  45. ui->label_4->setStyleSheet("border-image: url(:/new/prefix1/image/工训大赛.png);\nborder-radius: 10px;\n");
  46. ui->label_4->setVisible(true);
  47. ui->label_5->setVisible(false);
  48. ui->textEdit->append("设备初始化成功√");
  49. number = 0;
  50. // Video
  51. player = new QMediaPlayer;
  52. videoWidget = new QVideoWidget(this);
  53. playList = new QMediaPlaylist;
  54. #ifdef Q_OS_WIN
  55. playList->addMedia(QUrl::fromLocalFile("../WasteSorting/test.mp4"));
  56. #else
  57. playList->addMedia(QUrl::fromLocalFile("/home/pi/Desktop/WasteSorting/test.mp4"));
  58. #endif
  59. playList->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
  60. player->setPlaylist(playList);
  61. player->setVideoOutput(videoWidget);
  62. ui->verticalLayout->addWidget(videoWidget);
  63. videoWidget->setVisible(false);
  64. videoTimer = new QTimer(this);
  65. connect(videoTimer, SIGNAL(timeout()), this, SLOT(videoTimerUpdate()));
  66. videoTimer->setSingleShot(true);
  67. videoTimer->start(10000);
  68. }
  69. Widget::~Widget()
  70. {
  71. delete ui;
  72. }
  73. void Widget::timerUpdate()
  74. {
  75. QString str = QDateTime::currentDateTime().toString("yyyy年MM月dd日 hh:mm:ss");
  76. ui->label->setText(str);
  77. }
  78. void Widget::videoTimerUpdate()
  79. {
  80. ui->label_4->setVisible(false);
  81. player->play();
  82. videoWidget->setVisible(true);
  83. ui->label_3->setText("播放视频");
  84. ui->textEdit->append("播放视频");
  85. }
  86. void Widget::initSerial()
  87. {
  88. ui->textEdit->append("开始初始化串口");
  89. serialPort = new QSerialPort();
  90. connect(serialPort, SIGNAL(readyRead()), this, SLOT(serialRead()));
  91. if (QSerialPortInfo::availablePorts().length() == 0) {
  92. QMessageBox::critical(this, "错误", "无可用串口设备,请检查硬件连接后重试");
  93. exit(0);
  94. }
  95. #ifdef Q_OS_WIN
  96. QString portName = QSerialPortInfo::availablePorts()[1].portName();
  97. qDebug() << portName;
  98. ui->textEdit->append("尝试连接串口" + portName);
  99. serialPort->setPortName(portName);
  100. #else
  101. QString portName = "ttyUSB0";
  102. ui->textEdit->append("尝试连接串口ttyUSB0");
  103. serialPort->setPortName("ttyUSB0");
  104. #endif
  105. if (serialPort->open(QIODevice::ReadWrite)) {
  106. ui->textEdit->append("串口连接成功");
  107. serialPort->setBaudRate(115200);
  108. serialPort->setDataBits(QSerialPort::Data8);
  109. serialPort->setParity(QSerialPort::NoParity);
  110. serialPort->setStopBits(QSerialPort::OneStop);
  111. } else {
  112. QMessageBox::critical(this, "错误", "串口设备" + portName + "无法打开,请检查硬件连接后重试");
  113. exit(0);
  114. }
  115. ui->textEdit->append("串口初始化成功");
  116. }
  117. void Widget::initCamera()
  118. {
  119. // for (QCameraInfo& info : QCameraInfo::availableCameras()) {
  120. // qDebug() << info.deviceName();
  121. // }
  122. int camNum = QCameraInfo::availableCameras().length();
  123. if (!camNum) {
  124. QMessageBox::critical(this, "错误", "无可用摄像头,请检查硬件连接后重试");
  125. exit(0);
  126. }
  127. ui->textEdit->append("开始初始化摄像头");
  128. camera = new QCamera(QCameraInfo::availableCameras()[0], this);
  129. imageCapture = new QCameraImageCapture(camera);
  130. connect(imageCapture, SIGNAL(imageCaptured(int, QImage)), this, SLOT(onImageCaptured(int, QImage)));
  131. camera->setCaptureMode(QCamera::CaptureStillImage);
  132. imageCapture->setCaptureDestination(QCameraImageCapture::CaptureToBuffer);
  133. camera->start();
  134. ui->textEdit->append("摄像头初始化成功");
  135. }
  136. void Widget::serialRead()
  137. {
  138. QByteArray buffer = serialPort->readAll();
  139. // qDebug() << buffer;
  140. if (buffer[0] == '\x03' && buffer[1] == '\xFC'
  141. && buffer[3] == '\xFC' && buffer[4] == '\x03') {
  142. switch (buffer[2]) {
  143. case '\x00':
  144. ui->textEdit->append("取消警报");
  145. ui->label_3->setText("取消警报");
  146. ui->label_4->setVisible(true);
  147. ui->label_5->setVisible(false);
  148. ui->frame->setStyleSheet("#frame {border-image: url(:/new/prefix1/image/主.png);}");
  149. videoTimer->start(10000);
  150. break;
  151. case '\x01':
  152. ui->textEdit->append("触发拍照信号");
  153. ui->label_3->setText("触发拍照");
  154. videoTimer->stop();
  155. videoWidget->setVisible(false);
  156. player->stop();
  157. #ifdef Q_OS_WIN
  158. imageCapture->capture();
  159. #else
  160. captureImage();
  161. #endif
  162. break;
  163. case '\x02':
  164. ui->textEdit->append("投递完毕");
  165. ui->label_3->setText("投递完毕");
  166. ui->label_4->setVisible(true);
  167. ui->label_5->setVisible(false);
  168. ui->frame->setStyleSheet("#frame {border-image: url(:/new/prefix1/image/主.png);}");
  169. videoTimer->start(10000);
  170. break;
  171. case '\x04':
  172. ui->textEdit->append("满载警报");
  173. ui->label_3->setText("满载警报");
  174. ui->label_4->setVisible(false);
  175. videoTimer->stop();
  176. videoWidget->setVisible(false);
  177. player->stop();
  178. ui->frame->setStyleSheet("#frame {border-image: url(:/new/prefix1/image/满载警报.png);}");
  179. break;
  180. case '\x08':
  181. // qDebug() << "倾倒警报";
  182. ui->textEdit->append("倾倒警报");
  183. ui->label_3->setText("倾倒警报");
  184. ui->label_4->setVisible(false);
  185. videoTimer->stop();
  186. videoWidget->setVisible(false);
  187. player->stop();
  188. ui->frame->setStyleSheet("#frame {border-image: url(:/new/prefix1/image/倾倒警报.png);}");
  189. break;
  190. case '\xFF':
  191. break;
  192. }
  193. }
  194. }
  195. void Widget::serialWrite(const char data)
  196. {
  197. QByteArray buffer("\x30\xCF\x0F\xCF\x30");
  198. buffer[2] = data;
  199. serialPort->write(buffer);
  200. }
  201. void Widget::captureImage()
  202. {
  203. system("raspistill -o ../WasteSorting/WasteSorting.jpg -t 1 -br 70 -hf -awb sun");
  204. QImage image("../WasteSorting/WasteSorting.jpg");
  205. emit(imageCaptured(0, image));
  206. }
  207. void Widget::onImageCaptured(int, QImage image)
  208. {
  209. // 显示图片
  210. ui->label_4->setVisible(false);
  211. ui->label_5->setPixmap(QPixmap::fromImage(image).scaled(405, 306));
  212. ui->label_5->setVisible(true);
  213. ui->label_3->setText("识别中");
  214. ui->frame->setStyleSheet("#frame {border-image: url(:/new/prefix1/image/识别中.png);}");
  215. /* 使用京东垃圾识别 API
  216. // Base64编码
  217. QByteArray ba;
  218. QBuffer buf(&ba);
  219. image.save(&buf, "JPG", -1);
  220. QByteArray imageBase64 = ba.toBase64();
  221. // qDebug() << "data:image/jpg;base64," + imageBase64;
  222. // Request
  223. sendRequest(imageBase64);
  224. */
  225. /* 使用TensorFlow Lite */
  226. #ifdef Q_OS_WIN
  227. image.save("../WasteSorting/WasteSorting.jpg");
  228. FILE* fp = _popen("python ../WasteSorting/tensorflow/label_image.py", "rt");
  229. char buf[255] = { 0 };
  230. fscanf(fp, "%s", buf);
  231. _pclose(fp);
  232. #else
  233. FILE* fp = popen("python3 ../WasteSorting/tensorflow/label_image.py", "r");
  234. char buf[255] = { 0 };
  235. printf("%s", buf);
  236. fscanf(fp, "%s", buf);
  237. pclose(fp);
  238. #endif
  239. QString cate_name = QString::fromLocal8Bit(buf);
  240. qDebug() << cate_name;
  241. classifyFinished(cate_name);
  242. }
  243. void Widget::sendRequest(QByteArray& imageBase64)
  244. {
  245. QUrlQuery query;
  246. query.addQueryItem("appkey", "3a24b33468565b633d25d426eb0c660c");
  247. qint64 timestamp = QDateTime::currentDateTime().toMSecsSinceEpoch();
  248. query.addQueryItem("timestamp", QString::number(timestamp));
  249. QString sign = "58125e5985e6ef2d385ebfaa646987ba" + QString::number(timestamp);
  250. QByteArray ba = QCryptographicHash::hash(sign.toUtf8(), QCryptographicHash::Md5);
  251. query.addQueryItem("sign", ba.toHex());
  252. url->setQuery(query);
  253. networkRequest->setUrl(*url);
  254. // qDebug() << query.toString();
  255. QJsonObject json;
  256. json.insert("imgBase64", QString(imageBase64));
  257. json.insert("cityId", "440300");
  258. QJsonDocument document;
  259. document.setObject(json);
  260. QByteArray data = document.toJson(QJsonDocument::Compact);
  261. // qDebug() << QString(data);
  262. networkManager->post(*networkRequest, data);
  263. }
  264. void Widget::onRequestFinished(QNetworkReply* reply)
  265. {
  266. QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
  267. if (!statusCode.isValid()) {
  268. QMessageBox::critical(this, "错误", "网络连接不可用,请检查后重试");
  269. exit(0);
  270. }
  271. QByteArray replyData = reply->readAll();
  272. QJsonParseError jsonError;
  273. QJsonDocument document = QJsonDocument::fromJson(replyData, &jsonError);
  274. if (!document.isNull() && (jsonError.error == QJsonParseError::NoError)) {
  275. QJsonObject object = document.object().value("result").toObject();
  276. QJsonArray array = object.value("garbage_info").toArray();
  277. QJsonObject max = std::max_element(array.begin(), array.end(),
  278. [](QJsonValue const& a, QJsonValue const& b) { return a.toObject().value("confidence").toDouble()
  279. < b.toObject().value("confidence").toDouble(); })
  280. ->toObject();
  281. QString cate_name = max.value("cate_name").toString();
  282. QString garbage_name = max.value("garbage_name").toString();
  283. double confidence = max.value("confidence").toDouble();
  284. // qDebug() << "cate_name:" << cate_name;
  285. // qDebug() << "garbage_name:" << garbage_name;
  286. // qDebug() << "confidence:" << confidence;
  287. // ui->textEdit->append("cate_name: " + cate_name);
  288. // ui->textEdit->append("garbage_name: " + garbage_name);
  289. // ui->textEdit->append("confidence: " + QString::number(confidence));
  290. classifyFinished(cate_name);
  291. } else {
  292. serialWrite('\xFF');
  293. ui->textEdit->append("识别失败,请重试");
  294. ui->label_3->setText("识别失败");
  295. ui->label_4->setVisible(true);
  296. ui->label_5->setVisible(false);
  297. ui->frame->setStyleSheet("#frame {border-image: url(:/new/prefix1/image/主.png);}");
  298. }
  299. }
  300. void Widget::classifyFinished(QString cate_name)
  301. {
  302. number += 1;
  303. ui->textEdit->append(QString::number(number) + " " + cate_name + " 1 OK!");
  304. ui->frame->setStyleSheet("#frame {border-image: url(:/new/prefix1/image/" + cate_name + ".PNG);}");
  305. ui->label_3->setText("投递中");
  306. if (cate_name == "识别失败") {
  307. serialWrite('\xFF');
  308. ui->textEdit->append("识别失败,请重试");
  309. ui->label_3->setText("识别失败");
  310. ui->label_4->setVisible(true);
  311. ui->label_5->setVisible(false);
  312. ui->frame->setStyleSheet("#frame {border-image: url(:/new/prefix1/image/主.png);}");
  313. } else if (cate_name == "可回收物")
  314. serialWrite('\x01');
  315. else if (cate_name == "厨余垃圾")
  316. serialWrite('\x02');
  317. else if (cate_name == "有害垃圾")
  318. serialWrite('\x04');
  319. else
  320. serialWrite('\x08');
  321. }

No Description

Contributors (1)