mainwindow.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. #include <QMessageBox>
  2. #include <QException>
  3. #include <QFileDialog>
  4. #include <QPixmap>
  5. #include <QDebug>
  6. #include "mainwindow.h"
  7. #include "ui_mainwindow.h"
  8. #include "opencv2/opencv.hpp"
  9. #include "opencv2/core/core.hpp"
  10. #include "opencv2/highgui/highgui.hpp"
  11. #include "opencv2/imgproc/imgproc.hpp"
  12. using namespace cv;
  13. void MainWindow::Init_SystemState()
  14. {
  15. qDebug() << "Now Using Opencv Version: " << CV_VERSION << "\n";
  16. // qDebug() << cv::getBuildInformation().c_str() << "\n"; // out build infomation
  17. has_Init = false;
  18. doing_Infer = false;
  19. is_paddlex = false;
  20. is_mask = false;
  21. model_Envs[0] = "cpu";
  22. model_Envs[1] = "gpu";
  23. model_Kinds[0] = "det";
  24. model_Kinds[1] = "seg";
  25. model_Kinds[2] = "clas";
  26. model_Kinds[3] = "mask";
  27. model_Kinds[4] = "paddlex";
  28. model_Env = "cpu";
  29. model_Kind = "det";
  30. gpu_Id = 0;
  31. det_threshold = 0.5;
  32. infer_Delay = 50;
  33. ui->cBoxEnv->setCurrentIndex(0); // Initialize the environment to CPU
  34. ui->cBoxKind->setCurrentIndex(0); // Initialization type Det
  35. ui->labelImage1->setStyleSheet("background-color:white;"); // Set the background to initialize the image display area
  36. ui->labelImage2->setStyleSheet("background-color:white;");
  37. // Dynamic link library startup
  38. inferLibrary = new QLibrary("/home/nvidia/Desktop/Deploy_infer/infer_lib/libmodel_infer");
  39. if(!inferLibrary->load()){
  40. //Loading failed
  41. qDebug() << "Load libmodel_infer.so is failed!";
  42. qDebug() << inferLibrary->errorString();
  43. }
  44. else
  45. {
  46. qDebug() << "Load libmodel_infer.so is OK!";
  47. }
  48. // Export model loading / destruction interface in dynamic library
  49. initModel = (InitModel)inferLibrary->resolve("InitModel");
  50. destructModel = (DestructModel)inferLibrary->resolve("DestructModel");
  51. // Export A model insertion interface in dynamic graph
  52. det_ModelPredict = (Det_ModelPredict)inferLibrary->resolve("Det_ModelPredict");
  53. seg_ModelPredict = (Seg_ModelPredict)inferLibrary->resolve("Seg_ModelPredict");
  54. cls_ModelPredict = (Cls_ModelPredict)inferLibrary->resolve("Cls_ModelPredict");
  55. mask_ModelPredict = (Mask_ModelPredict)inferLibrary->resolve("Mask_ModelPredict");
  56. // Thread initialization - Configures the reasoning function
  57. inferThread = new InferThread(this);
  58. inferThread->setInferFuncs(det_ModelPredict, seg_ModelPredict, cls_ModelPredict, mask_ModelPredict);
  59. inferThread->setStopBtn(ui->btnStop);
  60. inferThread->setInferBtn(ui->btnInfer);
  61. inferThread->setDetThreshold(det_threshold);
  62. inferThread->setInferDelay(infer_Delay);
  63. // Configure signals and slots
  64. connect(inferThread, SIGNAL(InferFinished(QImage*, QImage*)),
  65. this, SLOT(ImageUpdate(QImage*, QImage*)),
  66. Qt::BlockingQueuedConnection);
  67. connect(inferThread, SIGNAL(SetState_Btn_StopAndInfer(bool , bool )),
  68. this, SLOT(Btn_StopAndInfer_StateUpdate(bool , bool )),
  69. Qt::BlockingQueuedConnection);
  70. connect(inferThread, SIGNAL(SetCostTime(double )),
  71. this, SLOT(CostTimeUpdate(double )),
  72. Qt::BlockingQueuedConnection);
  73. }
  74. void MainWindow::Init_SystemShow()
  75. {
  76. ui->btnDistory->setEnabled(false); // There is no initial initialization of the model and the destroy button is invalid
  77. ui->btnInfer->setEnabled(false);
  78. ui->btnStop->setEnabled(false);
  79. }
  80. MainWindow::MainWindow(QWidget *parent) :
  81. QMainWindow(parent),
  82. ui(new Ui::MainWindow)
  83. {
  84. ui->setupUi(this);
  85. this->Init_SystemState(); // Initialization state at startup
  86. this->Init_SystemShow(); // Initialize button state at startup
  87. }
  88. MainWindow::~MainWindow()
  89. {
  90. // Wait for thread to end
  91. if (inferThread->doing_Infer)
  92. {
  93. inferThread->break_Infer=false;
  94. while(inferThread->doing_Infer==true); // Wait for thread to stop
  95. }
  96. // Destruction of the model
  97. if (has_Init == true)
  98. {
  99. destructModel();
  100. }
  101. // Unload library
  102. inferLibrary->unload();
  103. delete ui; // Finally close the screen
  104. }
  105. // Model initialization
  106. void MainWindow::on_btnInit_clicked()
  107. {
  108. QString dialog_title = "Load model";
  109. QStringList filters = {"*.pdmodel", "*.pdiparams", "*.yml", "*.yaml"};
  110. QDir model_dir(QFileDialog::getExistingDirectory(this,
  111. dialog_title));
  112. QFileInfoList model_files = model_dir.entryInfoList(filters); // All valid file names obtained by filtering
  113. switch (model_files.count()) {
  114. case 0:
  115. return;
  116. case 3: // det,seg,clas--Load
  117. for (int i = 0; i < 3; i++)
  118. {
  119. QString tag = model_files[i].fileName().split('.')[1];
  120. if (tag == "pdmodel") model_path = model_files[i].filePath();
  121. else if (tag == "pdiparams") param_path = model_files[i].filePath();
  122. else if (tag == "yml" || tag == "yaml") config_path = model_files[i].filePath();
  123. }
  124. break;
  125. case 4: // paddlex和mask--Load
  126. for (int i = 0; i < 4; i++)
  127. {
  128. QString tag = model_files[i].fileName().split('.')[1];
  129. if (tag == "pdmodel") model_path = model_files[i].filePath();
  130. else if (tag == "pdiparams") param_path = model_files[i].filePath();
  131. else if (tag == "yml" || tag == "yaml")
  132. {
  133. if (model_files[i].fileName() == "model.yml" || model_files[i].fileName() == "model.yaml")
  134. config_path = model_files[i].filePath();
  135. }
  136. }
  137. break;
  138. default: // Other undefined situations
  139. QMessageBox::information(this,
  140. tr("Prompt"),
  141. tr("Make sure the following files are correctly included in the models folder:\n*.pdmodel, *.pdiparams, *.yml/*.yaml."),
  142. QMessageBox::Ok,
  143. QMessageBox::Ok);
  144. return;
  145. }
  146. char paddlex_model_type[10]="";
  147. try
  148. {
  149. if (has_Init == true)
  150. {
  151. destructModel(); // Destroy the model and initialize it
  152. if (model_Kind == "paddlex") // Paddlex model special identification
  153. {
  154. is_paddlex = true;
  155. }
  156. if (model_Kind == "mask") // MASKRCNN from Paddlex
  157. {
  158. model_Kind = "paddlex";
  159. is_mask = true;
  160. }
  161. // input string to char*/[]
  162. initModel(model_Kind.toLocal8Bit().data(),
  163. model_path.toLocal8Bit().data(),
  164. param_path.toLocal8Bit().data(),
  165. config_path.toLocal8Bit().data(),
  166. model_Env=="gpu" ? true: false,
  167. gpu_Id, paddlex_model_type);
  168. if (is_paddlex && is_mask==false) // Replace the actual type of the Paddlex model
  169. {
  170. model_Kind = QString::fromLocal8Bit(paddlex_model_type); // to real type
  171. is_paddlex = false;
  172. }
  173. if (is_paddlex==false && is_mask) // Revert to MASKRCNN type
  174. {
  175. model_Kind = "mask"; // to mask type
  176. is_mask = false;
  177. }
  178. }
  179. else
  180. {
  181. if (model_Kind == "paddlex")
  182. {
  183. is_paddlex = true;
  184. }
  185. if (model_Kind == "mask")
  186. {
  187. model_Kind = "paddlex";
  188. is_mask = true;
  189. }
  190. // input string to char*/[]
  191. initModel(model_Kind.toLocal8Bit().data(),
  192. model_path.toLocal8Bit().data(),
  193. param_path.toLocal8Bit().data(),
  194. config_path.toLocal8Bit().data(),
  195. model_Env=="gpu" ? true: false,
  196. gpu_Id, paddlex_model_type);
  197. if (is_paddlex && is_mask==false)
  198. {
  199. model_Kind = QString::fromLocal8Bit(paddlex_model_type); // to real type
  200. is_paddlex = false;
  201. }
  202. if (is_paddlex==false && is_mask)
  203. {
  204. model_Kind = "mask"; // to mask type
  205. is_mask = false;
  206. }
  207. has_Init = true; // Initialization is complete
  208. }
  209. }
  210. catch (QException &e) // Failed to initialize a message
  211. {
  212. QMessageBox::information(this,
  213. tr("Initialization failed"),
  214. tr("1.Please ensure that the model folder correctly contains the following files:\n*.pdmodel, *.pdiparams, *.yml/*.yaml.\n2.Please ensure that the model type is consistent with the loading model."),
  215. QMessageBox::Ok,
  216. QMessageBox::Ok);
  217. if (is_paddlex) // Paddlex is not initialized, restore type
  218. {
  219. model_Kind = "paddlex";
  220. is_paddlex = false;
  221. }
  222. if (is_mask) // Mask is not initialized, restore type
  223. {
  224. model_Kind = "mask";
  225. is_mask = false;
  226. }
  227. return;
  228. }
  229. inferThread->setModelType(model_Kind); // Set the reasoning interface type
  230. // Initialization Successful Tips
  231. QMessageBox::information(this,
  232. tr("Initialization successful"),
  233. QString("Model type: ")+model_Kind+QString(", Runtime environment: ")+model_Env+QString("."),
  234. QMessageBox::Ok,
  235. QMessageBox::Ok);
  236. ui->btnInit->setText("模型已初始化");
  237. ui->btnInfer->setEnabled(true); // Open reasoning function
  238. ui->btnDistory->setEnabled(true); // Open the destruction function
  239. ui->cBoxEnv->setEnabled(false); // Close the choice of running environment
  240. ui->cBoxKind->setEnabled(false); // Turn off the run type selection
  241. ui->lEditGpuId->setEnabled(false); // Disable GPU specification
  242. }
  243. // Model destruction
  244. void MainWindow::on_btnDistory_clicked()
  245. {
  246. if (inferThread->doing_Infer) // Reasoning, it cannot be destroyed, issued a hint
  247. {
  248. QMessageBox::information(this,
  249. tr("Prompt"),
  250. tr("The model is being reasoning, can't be destroyed!\n(after reasoning the completion / termination, the model is destroyed."),
  251. QMessageBox::Ok,
  252. QMessageBox::Ok);
  253. return;
  254. }
  255. if (has_Init == true)
  256. {
  257. destructModel();
  258. has_Init = false;
  259. QMessageBox::information(this,
  260. tr("Prompt"),
  261. tr("The model has been destroyed."),
  262. QMessageBox::Ok,
  263. QMessageBox::Ok);
  264. ui->btnInit->setText("初始化模型");
  265. ui->btnInfer->setEnabled(false);
  266. ui->btnDistory->setEnabled(false);
  267. ui->cBoxEnv->setEnabled(true);
  268. ui->cBoxKind->setEnabled(true);
  269. ui->lEditGpuId->setEnabled(true);
  270. }
  271. else
  272. {
  273. QMessageBox::information(this,
  274. tr("Prompt"),
  275. tr("Not initialized, no need to destroy."),
  276. QMessageBox::Ok,
  277. QMessageBox::Ok);
  278. }
  279. }
  280. // Loading pictures
  281. void MainWindow::on_btnLoadImg_clicked()
  282. {
  283. QString dialog_title = "Loading pictures";
  284. QString filters = "Loading pictures(*.jpg *.jpeg *.png *.JPEG);;";
  285. QUrl img_path = QFileDialog::getOpenFileUrl(this,
  286. dialog_title, QUrl(), filters);
  287. if (img_path.isEmpty())
  288. {
  289. return;
  290. }
  291. img_file = img_path.url().split("//")[1];
  292. qDebug() << "Input Video Path:" << img_file << "\n";
  293. // Picture reading
  294. cv::Mat image = cv::imread(img_file.toLocal8Bit().toStdString()); //BGR
  295. cv::cvtColor(image, image, COLOR_BGR2RGB); // BGR --> RGB
  296. cv::resize(image, image, cv::Size(image.cols/4*4,image.rows/4*4));
  297. QImage image_from_mat((const uchar*)image.data, image.cols, image.rows, QImage::Format_RGB888);
  298. QPixmap pixmap(QPixmap::fromImage(image_from_mat));
  299. // Display images
  300. ui->labelImage1->setPixmap(pixmap);
  301. ui->labelImage1->setScaledContents(true); // Full Label
  302. inferThread->setInputImage(img_file); // Introduced into the reasoning data
  303. img_files = QStringList();
  304. video_file = "";
  305. ui->btnLoadImg->setText("图片已加载");
  306. ui->btnLoadImgs->setText("加载文件夹");
  307. ui->btnLoadVideo->setText("加载视频");
  308. }
  309. // Loading images folder
  310. void MainWindow::on_btnLoadImgs_clicked()
  311. {
  312. QString dialog_title = "Loading images folder";
  313. QStringList filters = {"*.jpg", "*.jpeg", "*.png", "*.JPEG"};
  314. QDir img_dir(QFileDialog::getExistingDirectory(this,
  315. dialog_title));
  316. QFileInfoList img_paths = img_dir.entryInfoList(filters);
  317. if (img_paths.isEmpty())
  318. {
  319. return;
  320. }
  321. img_files.clear();
  322. for (int i = 0; i < img_paths.count(); i++)
  323. {
  324. img_files.append(img_paths[i].filePath());
  325. }
  326. qDebug() << img_files[0] << "\n";
  327. // Display the first image
  328. cv::Mat image = cv::imread(img_files[0].toLocal8Bit().toStdString()); //BGR
  329. cv::cvtColor(image, image, COLOR_BGR2RGB); // BGR --> RGB
  330. cv::resize(image, image, cv::Size(image.cols/4*4,image.rows/4*4));
  331. QImage image_from_mat((const uchar*)image.data, image.cols, image.rows, QImage::Format_RGB888);
  332. QPixmap pixmap(QPixmap::fromImage(image_from_mat));
  333. ui->labelImage1->setPixmap(pixmap);
  334. ui->labelImage1->setScaledContents(true);
  335. inferThread->setInputImages(img_files);
  336. img_file = "";
  337. video_file = "";
  338. ui->btnLoadImg->setText("加载图片");
  339. ui->btnLoadImgs->setText("文件夹已加载");
  340. ui->btnLoadVideo->setText("加载视频");
  341. }
  342. // Load the video stream
  343. void MainWindow::on_btnLoadVideo_clicked()
  344. {
  345. QString dialog_title = "Load video stream";
  346. QString filters = "video(*.mp4 *.MP4);;";
  347. QUrl video_path = QFileDialog::getOpenFileUrl(this,
  348. dialog_title, QUrl(), filters);
  349. if (video_path.isEmpty())
  350. {
  351. return;
  352. }
  353. video_file = video_path.url().split("//")[1];
  354. qDebug() << "Input Video Path:" << video_file.toStdString().c_str() << "\n";
  355. // Display the first image of the video
  356. VideoCapture capture;
  357. Mat frame;
  358. capture.open(video_file.toLocal8Bit().toStdString()); // Read video
  359. if(!capture.isOpened())
  360. {
  361. QMessageBox::information(this,
  362. tr("Prompt"),
  363. tr("1.Video read failed, please check if the video is complete, is it MP4.\n2.(Maybe)Opencv doesn't support the video!"),
  364. QMessageBox::Ok,
  365. QMessageBox::Ok);
  366. return;
  367. }
  368. capture >> frame; // Get the first frame
  369. cvtColor(frame, frame, COLOR_BGR2RGB); // BGR --> RGB
  370. QImage image((const uchar*)frame.data, frame.cols, frame.rows, QImage::Format_RGB888);
  371. ui->labelImage1->setPixmap(QPixmap::fromImage(image));
  372. ui->labelImage1->setScaledContents(true);
  373. capture.release();
  374. inferThread->setInputVideo(video_file);
  375. img_file = "";
  376. img_files = QStringList();
  377. ui->btnLoadImg->setText("加载图片");
  378. ui->btnLoadImgs->setText("加载文件夹");
  379. ui->btnLoadVideo->setText("视频已加载");
  380. }
  381. // Model reasoning - multiple threads
  382. void MainWindow::on_btnInfer_clicked()
  383. {
  384. if (inferThread->dataLoaded != true) // Data is not loaded
  385. {
  386. QMessageBox::information(this,
  387. tr("Prompt"),
  388. tr("Please load the data, then reinforce."),
  389. QMessageBox::Ok,
  390. QMessageBox::Ok);
  391. return;
  392. }
  393. if (has_Init == true && inferThread->doing_Infer == false)
  394. {
  395. ui->btnStop->setEnabled(true); // Stop button start
  396. ui->btnInfer->setEnabled(false); // Inference button off
  397. // Perform the corresponding type of reasoning
  398. inferThread->start();
  399. QMessageBox::information(this,
  400. tr("Prompt"),
  401. tr("Model reasoning"),
  402. QMessageBox::Ok,
  403. QMessageBox::Ok);
  404. }
  405. }
  406. // Reasoning to terminate
  407. void MainWindow::on_btnStop_clicked()
  408. {
  409. if (inferThread->doing_Infer == true)
  410. {
  411. QMessageBox::information(this,
  412. tr("Prompt"),
  413. tr("Stop model reasoning"),
  414. QMessageBox::Ok,
  415. QMessageBox::Ok);
  416. inferThread->break_Infer = true; // Termination Reasoning -> Auto Go to doing_Infer==false
  417. }
  418. else
  419. {
  420. QMessageBox::information(this,
  421. tr("Prompt"),
  422. tr("Not reasoning, no need to terminate the model reasoning"),
  423. QMessageBox::Ok,
  424. QMessageBox::Ok);
  425. }
  426. }
  427. // Select the model running environment
  428. void MainWindow::on_cBoxEnv_currentIndexChanged(int index)
  429. {
  430. if (has_Init) // Has been initialized, this operation is invalid
  431. {
  432. ui->cBoxEnv->setCurrentIndex(old_model_Env);
  433. return;
  434. }
  435. model_Env = model_Envs[index];
  436. old_model_Env = index; // Retain this result
  437. }
  438. // Set the model type
  439. void MainWindow::on_cBoxKind_currentIndexChanged(int index)
  440. {
  441. if (has_Init) // Has been initialized, this operation is invalid
  442. {
  443. ui->cBoxKind->setCurrentIndex(old_model_Kind);
  444. return;
  445. }
  446. model_Kind = model_Kinds[index];
  447. old_model_Kind = index;
  448. }
  449. // Set detection threshold
  450. void MainWindow::on_sBoxThreshold_valueChanged(double arg1)
  451. {
  452. if (inferThread->doing_Infer)
  453. {
  454. ui->sBoxThreshold->setValue(old_det_threshold);
  455. return;
  456. }
  457. det_threshold = (float)arg1;
  458. inferThread->setDetThreshold(det_threshold);
  459. old_det_threshold = det_threshold;
  460. }
  461. // set gpu_id
  462. void MainWindow::on_lEditGpuId_textChanged(const QString &arg1)
  463. {
  464. if (has_Init) // Has been initialized, this operation is invalid
  465. {
  466. ui->lEditGpuId->setText(QString::number(old_gpu_Id));
  467. return;
  468. }
  469. gpu_Id = arg1.toInt(); // If you enter a normal number, resolve to the specified number; otherwise 0
  470. old_gpu_Id = gpu_Id;
  471. }
  472. // Continuous reasoning interval duration setting
  473. void MainWindow::on_sBoxDelay_valueChanged(const QString &arg1)
  474. {
  475. if (inferThread->doing_Infer)
  476. {
  477. ui->sBoxDelay->setValue(old_infer_Delay);
  478. return;
  479. }
  480. infer_Delay = arg1.toInt(); // If you enter a normal number, resolve to the specified number; otherwise 0
  481. inferThread->setInferDelay(infer_Delay);
  482. old_infer_Delay = infer_Delay;
  483. }
  484. /* slot funcs blob */
  485. // update image show
  486. void MainWindow::ImageUpdate(QImage* label1, QImage* label2)
  487. {
  488. if (inferThread->doing_Infer)
  489. {
  490. ui->labelImage1->clear();
  491. ui->labelImage1->setPixmap(QPixmap::fromImage(*label1));
  492. ui->labelImage1->setScaledContents(true); // Full Label
  493. ui->labelImage2->clear();
  494. ui->labelImage2->setPixmap(QPixmap::fromImage(*label2));
  495. ui->labelImage2->setScaledContents(true); // Full Label
  496. }
  497. }
  498. // update btn Enable_state
  499. void MainWindow::Btn_StopAndInfer_StateUpdate(bool stop_state, bool infer_state)
  500. {
  501. ui->btnStop->setEnabled(stop_state);
  502. ui->btnInfer->setEnabled(infer_state);
  503. }
  504. // update label value to show cost time
  505. void MainWindow::CostTimeUpdate(double cost_time)
  506. {
  507. ui->labelCostTime->setText(QString::number(cost_time));
  508. }