From 8405ee3d1b1f5b9975d56549361f080948ffae11 Mon Sep 17 00:00:00 2001 From: XinJiang1 <1170701029@qq.com> Date: Tue, 24 Dec 2024 17:35:13 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=9B=E8=B1=A1=E5=B7=85=E5=B3=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- camera.cpp | 213 ++++++++++++------- config/color_range_config.txt | 23 +- globals.cpp | 4 + globals.h | 11 + onnxrunner.cpp | 26 ++- onnxrunner.h | 1 + release/config/color_range_config.txt | 23 +- ui_widget.h | 181 ++++++++++------ widget.cpp | 198 +++++++++++++++-- widget.h | 4 +- widget.ui | 295 ++++++++++++++------------ 11 files changed, 674 insertions(+), 305 deletions(-) diff --git a/camera.cpp b/camera.cpp index 7f79c6d..ea42006 100644 --- a/camera.cpp +++ b/camera.cpp @@ -3,9 +3,9 @@ #include // Debug Options -#define GlobalDebug 1 // 全局是否允许打印Debug信息(打印会拖慢处理时间) +#define GlobalDebug 0 // 全局是否允许打印Debug信息(打印会拖慢处理时间) #define DebugDetection 0 // 注意开启这个编译选项会导致图片存储, 处理时间会很慢 -#define DebugDetectionTime 1 // 是否打印处理时间 +#define DebugDetectionTime 0 // 是否打印处理时间 #define DebugLowerMacCOM 0 // 是否打印和下位机通讯的相关信息 camera::camera() {} @@ -144,7 +144,7 @@ bool iniCamera() MIL_INT ProcessingFunction0(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr) { #if(GlobalDebug) - qDebug()<<"回调1"; + qDebug()<<"CallBack1"; #endif int camera_id = 0; #if(GlobalDebug && DebugDetectionTime) @@ -157,26 +157,26 @@ MIL_INT ProcessingFunction0(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr) gDispCurrentPicId0 = ModifiedBufferId0; } - // 拷贝存图图像 - MbufCopy(ModifiedBufferId0, MilImage0); - cv::Mat img = ImageUtils::mil2Mat(MilImage0); - // 将图像推入识别队列 - ImageData recognitionData; - recognitionData.camera_id = camera_id; - recognitionData.image = img; - g_img_Queue[camera_id]->enqueue(recognitionData); - qDebug() << "Callback0: Enqueued image for recognition"; +#if(GlobalDebug && DebugDetectionTime) + timer_detection_time.printElapsedTime("CallBack1: Send mil id for detection"); + timer_detection_time.restart(); +#endif if (SaveImg_Flag) { + // 拷贝存图图像 + MbufCopy(ModifiedBufferId0, MilImage0); + cv::Mat img = ImageUtils::mil2Mat(MilImage0); // 将图像数据推入存储队列 ImageData data; data.camera_id = 0; data.image = img.clone(); // 确保图像数据被复制 g_storageQueue.enqueue(data); - qDebug() << "Callback0: Enqueued image for camera 0"; FuncCount0++; +#if(GlobalDebug && DebugDetectionTime) + qDebug() << "CallBack1: push image to storage queue"; +#endif } // 拷贝艳丽色检测图像 @@ -185,61 +185,89 @@ MIL_INT ProcessingFunction0(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr) MbufClear(MimResizedestination, M_COLOR_BLACK); MimResize(MilImage_Color0, MimResizedestination, 0.5, 1 , M_DEFAULT); +#if(GlobalDebug && DebugDetectionTime) + timer_detection_time.printElapsedTime("CallBack1: High sat detection resize"); + timer_detection_time.restart(); +#endif // 图片镜像翻转 MIL_UNIQUE_BUF_ID MimFlipDedtination = MbufClone(MimResizedestination, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_UNIQUE_ID); MbufClear(MimFlipDedtination, M_COLOR_BLACK); MimFlip(MimResizedestination, MimFlipDedtination, M_FLIP_HORIZONTAL, M_DEFAULT); + cv::Mat img = ImageUtils::mil2Mat(MimFlipDedtination); + + // 将图像推入识别队列 + ImageData recognitionData; + recognitionData.camera_id = camera_id; + recognitionData.image = img; + g_img_Queue[camera_id]->enqueue(recognitionData); +#if(GlobalDebug && DebugDetectionTime) + timer_detection_time.printElapsedTime("CallBack1: High sat detection mirror and push to DL"); + timer_detection_time.restart(); +#endif //艳丽检测mask high_sat_detect(MimFlipDedtination, detection_result0, params); - // 将 Matrox 的检测结果转换为 OpenCV Mat - cv::Mat matrox_mask = ImageUtils::mil2Mat(detection_result0); - cv::threshold(matrox_mask, matrox_mask, 128, 255, cv::THRESH_BINARY); // 确保是二值化 - - // 获取深度学习的检测结果 +#if(GlobalDebug && DebugDetectionTime) + timer_detection_time.printElapsedTime("CallBack1: High sat detection finish"); + timer_detection_time.restart(); +#endif + // 将 Matrox 的检测结果转换为 二维vector + std::vector> matrox_mask = generateMaskFromMatImage(ImageUtils::mil2Mat(detection_result0), widthBlocks, heightBlocks, sizeThreshold); +#if(GlobalDebug && DebugDetectionTime) + timer_detection_time.printElapsedTime("CallBack1: High sat detection to mask"); + timer_detection_time.restart(); +#endif + // 获取深度学习的检测结果并进行合并 + std::vector> merged_mask; + std::vector> dl_mask; ImageData dl_data; - cv::Mat merged_mat_mask; + if(!g_result_Queue[camera_id]->dequeue(dl_data)) { - qWarning() << "Receive empty result from Onnx for camera" << camera_id; + qWarning() << "CallBack1: Receive empty result from Onnx for camera" << camera_id; // 如果没有深度学习的检测结果,使用 Matrox 的检测结果 - merged_mat_mask = matrox_mask; + dl_mask = matrox_mask; + merged_mask = matrox_mask; +#if(GlobalDebug && DebugDetectionTime) + timer_detection_time.printElapsedTime("CallBack1: DL detection error to mask"); + timer_detection_time.restart(); +#endif } else { // 将深度学习的检测结果转换为 OpenCV Mat - cv::Mat dl_mask = dl_data.image; - cv::threshold(dl_mask, dl_mask, 128, 255, cv::THRESH_BINARY); // 确保是二值化 - cv::resize(dl_mask, dl_mask, matrox_mask.size(), 0, 0, cv::INTER_NEAREST); - - // 合并 Matrox 的检测结果和深度学习的检测结果(逻辑“或”) - cv::Mat combined_mask; - cv::bitwise_or(matrox_mask, dl_mask, combined_mask); - - merged_mat_mask = combined_mask; + dl_mask = generateMaskFromMatImage(dl_data.image, widthBlocks, heightBlocks, sizeThreshold); + merged_mask = ImageUtils::mergeMasks(dl_mask, matrox_mask); +#if(GlobalDebug && DebugDetectionTime) + timer_detection_time.printElapsedTime("CallBack2: Wait DL detection and result to mask"); + timer_detection_time.restart(); +#endif } // Update the current Img MIl id + // 更新持久化存储 { - QMutexLocker locker(&gMaskMutex0); - gMask0 = detection_result0; + QMutexLocker locker(&g_detection_result[camera_id].mutex); + g_detection_result[camera_id].dl_mask = dl_mask; + g_detection_result[camera_id].traditional_mask = matrox_mask; } - - mask_0 = generateMaskFromMatImage(merged_mat_mask, widthBlocks, heightBlocks, sizeThreshold); #if(GlobalDebug && DebugDetectionTime) - timer_detection_time.printElapsedTime("Time spent in callback func 0"); + timer_detection_time.printElapsedTime("CallBack1: Push result to g_detection_result"); + timer_detection_time.restart(); #endif + mask_0 = merged_mask; detection_ready.release(); MbufFree(detection_result0); - return 0; } MIL_INT ProcessingFunction1(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr) { +#if(GlobalDebug) + qDebug()<<"CallBack2"; +#endif int camera_id = 1; - // some debug info #if(GlobalDebug && DebugDetectionTime) Timer timer_detection_time; timer_detection_time.restart(); @@ -250,67 +278,104 @@ MIL_INT ProcessingFunction1(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr) QMutexLocker locker(&gDispPicMutex1); gDispCurrentPicId1 = ModifiedBufferId1; } - // 转回OpenCV图像 - MbufCopy(ModifiedBufferId1, MilImage1); - cv::Mat img = ImageUtils::mil2Mat(MilImage1); - // 将图像推入识别队列 - ImageData recognitionData; - recognitionData.camera_id = 1; - recognitionData.image = img; - g_img_Queue[1]->enqueue(recognitionData); - qDebug() << "Callback1: Enqueued image for recognition"; +#if(GlobalDebug && DebugDetectionTime) + timer_detection_time.printElapsedTime("CallBack2: Send mil id for detection"); + timer_detection_time.restart(); +#endif + // 将图像数据推入存储队列 if (SaveImg_Flag) { + // 转回OpenCV图像 + MbufCopy(ModifiedBufferId1, MilImage1); + cv::Mat img = ImageUtils::mil2Mat(MilImage1); ImageData data; data.camera_id = 1; data.image = img.clone(); // 确保图像数据被复制 g_storageQueue.enqueue(data); - qDebug() << "Callback1: Enqueued image for camera 1"; FuncCount1++; - } -#if (GlobalDebug) - qDebug()<<"回调2"; -#endif #if(GlobalDebug && DebugDetectionTime) - Timer timer2; + qDebug() << "CallBack2: push image to storage queue"; #endif + } + //拷贝艳丽色检测图像 MbufCopy(ModifiedBufferId1,MilImage_Color1); MIL_UNIQUE_BUF_ID MimResizedestination = MbufAllocColor(MilSystem, 3, 2048, 512, 8+M_UNSIGNED, M_IMAGE+M_PROC+M_DISP, M_UNIQUE_ID); MbufClear(MimResizedestination, M_COLOR_BLACK); MimResize(MilImage_Color1, MimResizedestination, 0.5, 1 , M_DEFAULT); + +#if(GlobalDebug && DebugDetectionTime) + timer_detection_time.printElapsedTime("CallBack2: High sat detection resize"); + timer_detection_time.restart(); +#endif + + // 将图像推入识别队列 + cv::Mat img = ImageUtils::mil2Mat(MimResizedestination); + ImageData recognitionData; + recognitionData.camera_id = 1; + recognitionData.image = img; + g_img_Queue[1]->enqueue(recognitionData); + +#if(GlobalDebug && DebugDetectionTime) + timer_detection_time.printElapsedTime("CallBack2: Without mirror and push to DL"); + timer_detection_time.restart(); +#endif + // 艳丽检测mask high_sat_detect(MimResizedestination, detection_result1, params); - // 将 Matrox 的检测结果转换为 OpenCV Mat - cv::Mat matrox_mask = ImageUtils::mil2Mat(detection_result1); - cv::threshold(matrox_mask, matrox_mask, 128, 255, cv::THRESH_BINARY); // 确保是二值化 - // 获取深度学习的检测结果 +#if(GlobalDebug && DebugDetectionTime) + timer_detection_time.printElapsedTime("CallBack2: High sat detection finish"); + timer_detection_time.restart(); +#endif + + // 将 Matrox 的检测结果转换为 二维vector + std::vector> matrox_mask = generateMaskFromMatImage(ImageUtils::mil2Mat(detection_result1), widthBlocks, heightBlocks, sizeThreshold); +#if(GlobalDebug && DebugDetectionTime) + timer_detection_time.printElapsedTime("CallBack2: High sat detection to mask"); + timer_detection_time.restart(); +#endif + + // 获取深度学习的检测结果并进行合并 + std::vector> merged_mask; + std::vector> dl_mask; ImageData dl_data; - cv::Mat merged_mat_mask; + if(!g_result_Queue[camera_id]->dequeue(dl_data)) { qWarning() << "Receive empty result from Onnx for camera" << camera_id; // 如果没有深度学习的检测结果,使用 Matrox 的检测结果 - merged_mat_mask = matrox_mask; + dl_mask = matrox_mask; + merged_mask = matrox_mask; +#if(GlobalDebug && DebugDetectionTime) + timer_detection_time.printElapsedTime("CallBack1: DL detection error to mask"); + timer_detection_time.restart(); +#endif } else { // 将深度学习的检测结果转换为 OpenCV Mat - cv::Mat dl_mask = dl_data.image; - cv::threshold(dl_mask, dl_mask, 128, 255, cv::THRESH_BINARY); // 确保是二值化 - cv::resize(dl_mask, dl_mask, matrox_mask.size(), 0, 0, cv::INTER_NEAREST); + dl_mask = generateMaskFromMatImage(dl_data.image, widthBlocks, heightBlocks, sizeThreshold); + merged_mask = ImageUtils::mergeMasks(dl_mask, matrox_mask); +#if(GlobalDebug && DebugDetectionTime) + timer_detection_time.printElapsedTime("CallBack1: Wait DL detection and result to mask"); + timer_detection_time.restart(); +#endif + } - // 合并 Matrox 的检测结果和深度学习的检测结果(逻辑“或”) - cv::Mat combined_mask; - cv::bitwise_or(matrox_mask, dl_mask, combined_mask); - - merged_mat_mask = combined_mask; + // Update the current Img MIl id + // 更新持久化存储 + { + QMutexLocker locker(&g_detection_result[camera_id].mutex); + g_detection_result[camera_id].dl_mask = dl_mask; + g_detection_result[camera_id].traditional_mask = matrox_mask; } #if(GlobalDebug && DebugDetectionTime) - timer2.printElapsedTime("Algorithm Paralled Running Spent: "); + timer_detection_time.printElapsedTime("CallBack2: Push result to g_detection_result"); + timer_detection_time.restart(); #endif + mask_1 = merged_mask; #if(GlobalDebug && DebugDetection) MbufSave(SAVE_PATH_flip,MimFlipDedtination); @@ -318,16 +383,10 @@ MIL_INT ProcessingFunction1(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr) MbufSave(SAVE_PATH_raw,MilImage_Color0); MbufSave(SAVE_PATH_result,detection_result0); #endif - // Update the current Img MIl id - { - QMutexLocker locker(&gMaskMutex1); - gMask1 = detection_result1; - } - mask_1 = generateMaskFromMatImage(merged_mat_mask, widthBlocks, heightBlocks, sizeThreshold); - detection_ready.acquire(); - vector> merged_mask; - vector> mask_tail; + detection_ready.acquire(); + + vector> mask_tail; merged_mask = ImageUtils::mergeMasks(mask_0, mask_1, dual_cam_offset_y); std::tie(merged_mask, mask_tail) = ImageUtils::extractROI(merged_mask, 0, 0, widthBlocks, heightBlocks); @@ -499,7 +558,7 @@ void lab_process_raw(const MIL_ID& inputImage, MIL_ID& outputImageLab, const std void lab_process(const MIL_ID& inputImage, MIL_ID& outputImageLab, const std::map& params) { - const std::vector colors = {"green", "blue", "orange", "black", "red", "purple"}; + const std::vector colors = {"green", "blue", "orange", "black", "red", "purple", "yellow"}; lab_process_raw(inputImage, outputImageLab, params, colors); } diff --git a/config/color_range_config.txt b/config/color_range_config.txt index 1de4562..ecef269 100644 --- a/config/color_range_config.txt +++ b/config/color_range_config.txt @@ -1,10 +1,10 @@ # Green color parameters -green_L_min = 18 -green_L_max = 58 -green_a_min = -35 +green_L_min = 20 +green_L_max = 55 +green_a_min = -32 green_a_max = -11 green_b_min = -7 -green_b_max = 24 +green_b_max = 20 # Blue color parameters blue_L_min = 20 @@ -39,14 +39,23 @@ red_b_min = -99 red_b_max = 32 # Purple color parameters -purple_L_min = 35 -purple_L_max = 72 +purple_L_min = 38 +purple_L_max = 75 purple_a_min = 12 purple_a_max = 22 purple_b_min = -48 purple_b_max = 1 +# yellow color parameters +yellow_L_min = 45 +yellow_L_max = 56 +yellow_a_min = -4 +yellow_a_max = 7 +yellow_b_min = 20 +yellow_b_max = 21 + + # Other parameters lab_denoising = 1 -saturation_threshold = 150 +saturation_threshold = 155 saturation_denoising = 1 diff --git a/globals.cpp b/globals.cpp index 90f2bd4..bcaca63 100644 --- a/globals.cpp +++ b/globals.cpp @@ -15,6 +15,9 @@ MIL_ID gMask0 = 0; QMutex gMaskMutex1; MIL_ID gMask1 = 0; +// 初始化 CameraData 实例 +DetectionResult g_detection_result[2]; + // 初始化检测准备信号量 QSemaphore detection_ready(0); @@ -163,3 +166,4 @@ struct GlobalsInitializer { cleanupGlobalONNXRunner(); // 添加此行 } } globalsInitializerInstance; // 全局实例,确保在程序结束时清理 + diff --git a/globals.h b/globals.h index 787218f..ced5864 100644 --- a/globals.h +++ b/globals.h @@ -34,6 +34,8 @@ extern MIL_ID gMask1; // 检测准备信号量 extern QSemaphore detection_ready; + + // 获取保存目录和配置目录函数 QString getSaveDirectory(); QString getConfigDirectory(); @@ -45,6 +47,15 @@ struct ImageData cv::Mat image; }; +// 添加 DetectionResult 结构体 +struct DetectionResult { + QMutex mutex; // 保护数据的互斥锁 + std::vector> dl_mask; // 深度学习掩膜 + std::vector> traditional_mask; // 传统算法掩膜 +}; + +extern DetectionResult g_detection_result[2]; + // 线程安全队列模板类 template class ThreadSafeQueue{ diff --git a/onnxrunner.cpp b/onnxrunner.cpp index 7a6e1de..f180df4 100644 --- a/onnxrunner.cpp +++ b/onnxrunner.cpp @@ -164,7 +164,7 @@ void ONNXRunner::load(const std::string& modelPath) { // 调用 predict 方法进行预热,避免第一次推理时加载模型导致延迟 try { - for(int i = 0; i < 10; i++) + for(int i = 0; i < 2; i++) this->predict(dummyInput); qDebug() << "ONNX模型预热完成"; } @@ -190,3 +190,27 @@ cv::Mat ONNXRunner::postProcess(const std::vector& detections, const cv::Mat detectionMask = ONNXRunner::createDetectionMask(image, detections, this->scale, this->pad_top, this->pad_left); return detectionMask; } + +void ONNXRunner::warm_up() +{ + // 检查模型是否成功加载 + if (this->net.empty()) { + qCritical() << "加载ONNX模型失败" ; + // 根据需求,可以选择抛出异常、设置状态标志或采取其他错误处理措施 + return; + } + + // 创建一个空的输入矩阵作为预热数据(假定模型输入是 RGB 图像) + cv::Mat dummyInput = cv::Mat::zeros(INPUT_HEIGHT, INPUT_WIDTH, CV_8UC3); // 640x640 的全零矩阵 + + // 调用 predict 方法进行预热,避免第一次推理时加载模型导致延迟 + try { + for(int i = 0; i < 10; i++) + this->predict(dummyInput); + qDebug() << "ONNX模型预热完成"; + } + catch (const std::exception& e) { + qCritical() << "ONNXRunner::predict 异常:" << e.what(); + // 处理异常,例如记录日志或设置状态标志 + } +} diff --git a/onnxrunner.h b/onnxrunner.h index ec41b22..f4fc76d 100644 --- a/onnxrunner.h +++ b/onnxrunner.h @@ -46,6 +46,7 @@ public: cv::Mat preprocessImage(const cv::Mat& image, cv::dnn::Net& net, int& padTop, int& padLeft, float& scale) const; std::vector performInference(cv::dnn::Net& net, const cv::Mat& inputImage) const; std::vector applyNMS(std::vector& detections) const; + void warm_up(); // Constants const float CONFIDENCE_THRESHOLD = 0.2f; const float NMS_THRESHOLD = 0.2f; diff --git a/release/config/color_range_config.txt b/release/config/color_range_config.txt index 1de4562..ecef269 100644 --- a/release/config/color_range_config.txt +++ b/release/config/color_range_config.txt @@ -1,10 +1,10 @@ # Green color parameters -green_L_min = 18 -green_L_max = 58 -green_a_min = -35 +green_L_min = 20 +green_L_max = 55 +green_a_min = -32 green_a_max = -11 green_b_min = -7 -green_b_max = 24 +green_b_max = 20 # Blue color parameters blue_L_min = 20 @@ -39,14 +39,23 @@ red_b_min = -99 red_b_max = 32 # Purple color parameters -purple_L_min = 35 -purple_L_max = 72 +purple_L_min = 38 +purple_L_max = 75 purple_a_min = 12 purple_a_max = 22 purple_b_min = -48 purple_b_max = 1 +# yellow color parameters +yellow_L_min = 45 +yellow_L_max = 56 +yellow_a_min = -4 +yellow_a_max = 7 +yellow_b_min = 20 +yellow_b_max = 21 + + # Other parameters lab_denoising = 1 -saturation_threshold = 150 +saturation_threshold = 155 saturation_denoising = 1 diff --git a/ui_widget.h b/ui_widget.h index 22ce81f..32aadc4 100644 --- a/ui_widget.h +++ b/ui_widget.h @@ -52,6 +52,7 @@ public: QPushButton *btn_start; QPushButton *btn_take_photos; QPushButton *btn_stop; + QPushButton *btn_quit; QSpacerItem *verticalSpacer; QFrame *frame_6; QVBoxLayout *verticalLayout_2; @@ -59,28 +60,32 @@ public: QHBoxLayout *horizontalLayout_4; QLabel *label_2; QSpacerItem *horizontalSpacer; + QCheckBox *mtx_1_overlay; + QCheckBox *dl_1_overlay; QCheckBox *img_1_mirror; - QCheckBox *img_1_overlay; QLabel *camera_1_img; QFrame *frame_2; QHBoxLayout *horizontalLayout_5; QLabel *label_4; QSpacerItem *horizontalSpacer_2; + QCheckBox *mtx_0_overlay; + QCheckBox *dl_0_overlay; QCheckBox *img_0_mirror; - QCheckBox *img_0_overlay; QLabel *camera_0_img; QWidget *tab_3; QLabel *label_title_3; QGroupBox *groupBox_4; - QLabel *label_delaytime; - QLabel *label_encoder; - QLabel *label_encoder_2; + QPushButton *btn_set_lower; + QWidget *layoutWidget; + QVBoxLayout *verticalLayout_4; QSpinBox *spinbox_delaytime; QSpinBox *spinbox_encoder; QSpinBox *spinbox_valve; - QPushButton *btn_set_lower; - QPushButton *btn_exit; - QWidget *tab_4; + QWidget *layoutWidget1; + QVBoxLayout *verticalLayout_5; + QLabel *label_delaytime; + QLabel *label_encoder; + QLabel *label_encoder_2; QLabel *label_title_4; QGroupBox *groupBox_2; QLabel *label_explosure_2; @@ -90,6 +95,7 @@ public: QGroupBox *groupBox_3; QPushButton *btn_test_single; QPushButton *btn_stop_test; + QWidget *tab_4; void setupUi(QWidget *Widget) { @@ -198,21 +204,31 @@ public: btn_start = new QPushButton(groupBox_7); btn_start->setObjectName("btn_start"); btn_start->setMinimumSize(QSize(70, 200)); + btn_start->setStyleSheet(QString::fromUtf8("font: 700 40pt \"Microsoft YaHei UI\";")); verticalLayout_3->addWidget(btn_start); btn_take_photos = new QPushButton(groupBox_7); btn_take_photos->setObjectName("btn_take_photos"); btn_take_photos->setMinimumSize(QSize(70, 200)); + btn_take_photos->setStyleSheet(QString::fromUtf8("font: 700 40pt \"Microsoft YaHei UI\";")); verticalLayout_3->addWidget(btn_take_photos); btn_stop = new QPushButton(groupBox_7); btn_stop->setObjectName("btn_stop"); btn_stop->setMinimumSize(QSize(70, 200)); + btn_stop->setStyleSheet(QString::fromUtf8("font: 700 40pt \"Microsoft YaHei UI\";")); verticalLayout_3->addWidget(btn_stop); + btn_quit = new QPushButton(groupBox_7); + btn_quit->setObjectName("btn_quit"); + btn_quit->setMinimumSize(QSize(70, 200)); + btn_quit->setStyleSheet(QString::fromUtf8("font: 700 40pt \"Microsoft YaHei UI\";")); + + verticalLayout_3->addWidget(btn_quit); + verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Expanding); verticalLayout_3->addItem(verticalSpacer); @@ -240,19 +256,26 @@ public: horizontalLayout_4->addItem(horizontalSpacer); + mtx_1_overlay = new QCheckBox(frame); + mtx_1_overlay->setObjectName("mtx_1_overlay"); + mtx_1_overlay->setEnabled(true); + mtx_1_overlay->setStyleSheet(QString::fromUtf8("font: 12pt \"Microsoft YaHei UI\";")); + + horizontalLayout_4->addWidget(mtx_1_overlay); + + dl_1_overlay = new QCheckBox(frame); + dl_1_overlay->setObjectName("dl_1_overlay"); + dl_1_overlay->setEnabled(true); + dl_1_overlay->setStyleSheet(QString::fromUtf8("font: 12pt \"Microsoft YaHei UI\";")); + + horizontalLayout_4->addWidget(dl_1_overlay); + img_1_mirror = new QCheckBox(frame); img_1_mirror->setObjectName("img_1_mirror"); img_1_mirror->setStyleSheet(QString::fromUtf8("font: 12pt \"Microsoft YaHei UI\";")); horizontalLayout_4->addWidget(img_1_mirror); - img_1_overlay = new QCheckBox(frame); - img_1_overlay->setObjectName("img_1_overlay"); - img_1_overlay->setEnabled(false); - img_1_overlay->setStyleSheet(QString::fromUtf8("font: 12pt \"Microsoft YaHei UI\";")); - - horizontalLayout_4->addWidget(img_1_overlay); - verticalLayout_2->addWidget(frame); @@ -285,6 +308,20 @@ public: horizontalLayout_5->addItem(horizontalSpacer_2); + mtx_0_overlay = new QCheckBox(frame_2); + mtx_0_overlay->setObjectName("mtx_0_overlay"); + mtx_0_overlay->setEnabled(true); + mtx_0_overlay->setStyleSheet(QString::fromUtf8("font: 12pt \"Microsoft YaHei UI\";")); + + horizontalLayout_5->addWidget(mtx_0_overlay); + + dl_0_overlay = new QCheckBox(frame_2); + dl_0_overlay->setObjectName("dl_0_overlay"); + dl_0_overlay->setEnabled(true); + dl_0_overlay->setStyleSheet(QString::fromUtf8("font: 12pt \"Microsoft YaHei UI\";")); + + horizontalLayout_5->addWidget(dl_0_overlay); + img_0_mirror = new QCheckBox(frame_2); img_0_mirror->setObjectName("img_0_mirror"); img_0_mirror->setStyleSheet(QString::fromUtf8("font: 12pt \"Microsoft YaHei UI\";")); @@ -292,13 +329,6 @@ public: horizontalLayout_5->addWidget(img_0_mirror); - img_0_overlay = new QCheckBox(frame_2); - img_0_overlay->setObjectName("img_0_overlay"); - img_0_overlay->setEnabled(false); - img_0_overlay->setStyleSheet(QString::fromUtf8("font: 12pt \"Microsoft YaHei UI\";")); - - horizontalLayout_5->addWidget(img_0_overlay); - verticalLayout_2->addWidget(frame_2); @@ -324,46 +354,70 @@ public: tab_3->setObjectName("tab_3"); label_title_3 = new QLabel(tab_3); label_title_3->setObjectName("label_title_3"); - label_title_3->setGeometry(QRect(0, 10, 171, 41)); + label_title_3->setGeometry(QRect(0, 10, 421, 81)); QFont font1; - font1.setPointSize(20); + font1.setFamilies({QString::fromUtf8("Microsoft YaHei UI")}); + font1.setPointSize(48); + font1.setBold(true); + font1.setItalic(false); label_title_3->setFont(font1); + label_title_3->setStyleSheet(QString::fromUtf8("font: 700 48pt \"Microsoft YaHei UI\";")); groupBox_4 = new QGroupBox(tab_3); groupBox_4->setObjectName("groupBox_4"); - groupBox_4->setGeometry(QRect(10, 60, 341, 191)); - label_delaytime = new QLabel(groupBox_4); - label_delaytime->setObjectName("label_delaytime"); - label_delaytime->setGeometry(QRect(40, 40, 53, 15)); - label_encoder = new QLabel(groupBox_4); - label_encoder->setObjectName("label_encoder"); - label_encoder->setGeometry(QRect(40, 80, 81, 16)); - label_encoder_2 = new QLabel(groupBox_4); - label_encoder_2->setObjectName("label_encoder_2"); - label_encoder_2->setGeometry(QRect(40, 120, 71, 16)); - spinbox_delaytime = new QSpinBox(groupBox_4); - spinbox_delaytime->setObjectName("spinbox_delaytime"); - spinbox_delaytime->setGeometry(QRect(120, 40, 81, 22)); - spinbox_encoder = new QSpinBox(groupBox_4); - spinbox_encoder->setObjectName("spinbox_encoder"); - spinbox_encoder->setGeometry(QRect(120, 80, 81, 22)); - spinbox_valve = new QSpinBox(groupBox_4); - spinbox_valve->setObjectName("spinbox_valve"); - spinbox_valve->setGeometry(QRect(120, 120, 81, 22)); + groupBox_4->setGeometry(QRect(30, 130, 771, 591)); + groupBox_4->setStyleSheet(QString::fromUtf8("font: 700 40pt \"Microsoft YaHei UI\";\n" +"border-color: rgb(0, 0, 0);")); btn_set_lower = new QPushButton(groupBox_4); btn_set_lower->setObjectName("btn_set_lower"); - btn_set_lower->setGeometry(QRect(250, 160, 61, 23)); - btn_exit = new QPushButton(tab_3); - btn_exit->setObjectName("btn_exit"); - btn_exit->setGeometry(QRect(660, 490, 75, 23)); - tabWidget->addTab(tab_3, QString()); - tab_4 = new QWidget(); - tab_4->setObjectName("tab_4"); - label_title_4 = new QLabel(tab_4); + btn_set_lower->setGeometry(QRect(430, 410, 231, 141)); + layoutWidget = new QWidget(groupBox_4); + layoutWidget->setObjectName("layoutWidget"); + layoutWidget->setGeometry(QRect(460, 120, 181, 241)); + verticalLayout_4 = new QVBoxLayout(layoutWidget); + verticalLayout_4->setObjectName("verticalLayout_4"); + verticalLayout_4->setContentsMargins(0, 0, 0, 0); + spinbox_delaytime = new QSpinBox(layoutWidget); + spinbox_delaytime->setObjectName("spinbox_delaytime"); + + verticalLayout_4->addWidget(spinbox_delaytime); + + spinbox_encoder = new QSpinBox(layoutWidget); + spinbox_encoder->setObjectName("spinbox_encoder"); + + verticalLayout_4->addWidget(spinbox_encoder); + + spinbox_valve = new QSpinBox(layoutWidget); + spinbox_valve->setObjectName("spinbox_valve"); + + verticalLayout_4->addWidget(spinbox_valve); + + layoutWidget1 = new QWidget(groupBox_4); + layoutWidget1->setObjectName("layoutWidget1"); + layoutWidget1->setGeometry(QRect(30, 120, 341, 251)); + verticalLayout_5 = new QVBoxLayout(layoutWidget1); + verticalLayout_5->setObjectName("verticalLayout_5"); + verticalLayout_5->setContentsMargins(0, 0, 0, 0); + label_delaytime = new QLabel(layoutWidget1); + label_delaytime->setObjectName("label_delaytime"); + + verticalLayout_5->addWidget(label_delaytime); + + label_encoder = new QLabel(layoutWidget1); + label_encoder->setObjectName("label_encoder"); + + verticalLayout_5->addWidget(label_encoder); + + label_encoder_2 = new QLabel(layoutWidget1); + label_encoder_2->setObjectName("label_encoder_2"); + + verticalLayout_5->addWidget(label_encoder_2); + + label_title_4 = new QLabel(tab_3); label_title_4->setObjectName("label_title_4"); - label_title_4->setGeometry(QRect(50, 30, 91, 21)); - groupBox_2 = new QGroupBox(tab_4); + label_title_4->setGeometry(QRect(920, 150, 91, 21)); + groupBox_2 = new QGroupBox(tab_3); groupBox_2->setObjectName("groupBox_2"); - groupBox_2->setGeometry(QRect(110, 120, 331, 91)); + groupBox_2->setGeometry(QRect(1050, 240, 331, 91)); label_explosure_2 = new QLabel(groupBox_2); label_explosure_2->setObjectName("label_explosure_2"); label_explosure_2->setGeometry(QRect(30, 40, 31, 16)); @@ -376,15 +430,18 @@ public: btn_stop_single = new QPushButton(groupBox_2); btn_stop_single->setObjectName("btn_stop_single"); btn_stop_single->setGeometry(QRect(240, 40, 75, 23)); - groupBox_3 = new QGroupBox(tab_4); + groupBox_3 = new QGroupBox(tab_3); groupBox_3->setObjectName("groupBox_3"); - groupBox_3->setGeometry(QRect(110, 270, 331, 91)); + groupBox_3->setGeometry(QRect(1050, 420, 331, 91)); btn_test_single = new QPushButton(groupBox_3); btn_test_single->setObjectName("btn_test_single"); btn_test_single->setGeometry(QRect(60, 40, 75, 23)); btn_stop_test = new QPushButton(groupBox_3); btn_stop_test->setObjectName("btn_stop_test"); btn_stop_test->setGeometry(QRect(210, 40, 75, 23)); + tabWidget->addTab(tab_3, QString()); + tab_4 = new QWidget(); + tab_4->setObjectName("tab_4"); tabWidget->addTab(tab_4, QString()); horizontalLayout->addWidget(tabWidget); @@ -416,23 +473,24 @@ public: btn_start->setText(QCoreApplication::translate("Widget", "\345\274\200\345\247\213\345\210\206\351\200\211", nullptr)); btn_take_photos->setText(QCoreApplication::translate("Widget", "\346\212\223\345\217\226\345\233\276\347\211\207", nullptr)); btn_stop->setText(QCoreApplication::translate("Widget", "\345\201\234\346\255\242\345\210\206\351\200\211", nullptr)); + btn_quit->setText(QCoreApplication::translate("Widget", "\351\200\200\345\207\272\347\263\273\347\273\237", nullptr)); label_2->setText(QCoreApplication::translate("Widget", "\347\233\270\346\234\2721\357\274\210\351\253\230\344\276\247/\346\260\224\347\275\220\344\276\247\357\274\211", nullptr)); + mtx_1_overlay->setText(QCoreApplication::translate("Widget", "\350\211\262\346\243\200\347\273\223\346\236\234", nullptr)); + dl_1_overlay->setText(QCoreApplication::translate("Widget", "\346\231\272\346\243\200\347\273\223\346\236\234", nullptr)); img_1_mirror->setText(QCoreApplication::translate("Widget", "\345\233\276\347\211\207\351\225\234\345\203\217", nullptr)); - img_1_overlay->setText(QCoreApplication::translate("Widget", "\350\257\206\345\210\253\347\273\223\346\236\234", nullptr)); camera_1_img->setText(QString()); label_4->setText(QCoreApplication::translate("Widget", "\347\233\270\346\234\2720\357\274\210\344\275\216\344\276\247/\345\207\272\351\243\216\345\217\243\344\276\247\357\274\211", nullptr)); + mtx_0_overlay->setText(QCoreApplication::translate("Widget", "\350\211\262\346\243\200\347\273\223\346\236\234", nullptr)); + dl_0_overlay->setText(QCoreApplication::translate("Widget", "\346\231\272\346\243\200\347\273\223\346\236\234", nullptr)); img_0_mirror->setText(QCoreApplication::translate("Widget", "\345\233\276\347\211\207\351\225\234\345\203\217", nullptr)); - img_0_overlay->setText(QCoreApplication::translate("Widget", "\350\257\206\345\210\253\347\273\223\346\236\234", nullptr)); camera_0_img->setText(QString()); tabWidget->setTabText(tabWidget->indexOf(tab_2), QCoreApplication::translate("Widget", "Tab 2", nullptr)); label_title_3->setText(QCoreApplication::translate("Widget", "\345\217\202\346\225\260\350\256\276\347\275\256\347\225\214\351\235\242", nullptr)); groupBox_4->setTitle(QCoreApplication::translate("Widget", "\344\270\213\344\275\215\346\234\272\345\217\202\346\225\260", nullptr)); + btn_set_lower->setText(QCoreApplication::translate("Widget", "\350\256\276\345\256\232\345\217\202\346\225\260", nullptr)); label_delaytime->setText(QCoreApplication::translate("Widget", "\345\273\266\350\277\237\346\227\266\351\227\264", nullptr)); label_encoder->setText(QCoreApplication::translate("Widget", "\347\233\270\346\234\272\345\210\206\351\242\221\347\263\273\346\225\260", nullptr)); label_encoder_2->setText(QCoreApplication::translate("Widget", "\345\226\267\351\230\200\345\210\206\351\242\221\347\263\273\346\225\260", nullptr)); - btn_set_lower->setText(QCoreApplication::translate("Widget", "\347\241\256\345\256\232", nullptr)); - btn_exit->setText(QCoreApplication::translate("Widget", "\345\205\263\346\234\272", nullptr)); - tabWidget->setTabText(tabWidget->indexOf(tab_3), QCoreApplication::translate("Widget", "Tab 3", nullptr)); label_title_4->setText(QCoreApplication::translate("Widget", "\345\226\267\351\230\200\346\265\213\350\257\225\347\225\214\351\235\242", nullptr)); groupBox_2->setTitle(QCoreApplication::translate("Widget", "\346\211\213\345\212\250\345\226\267\351\230\200\346\265\213\350\257\225", nullptr)); label_explosure_2->setText(QCoreApplication::translate("Widget", "\351\200\232\351\201\223", nullptr)); @@ -441,6 +499,7 @@ public: groupBox_3->setTitle(QCoreApplication::translate("Widget", "\350\207\252\345\212\250\345\226\267\351\230\200\346\265\213\350\257\225", nullptr)); btn_test_single->setText(QCoreApplication::translate("Widget", "\345\274\200\345\247\213\346\265\213\350\257\225", nullptr)); btn_stop_test->setText(QCoreApplication::translate("Widget", "\345\201\234\346\255\242\346\265\213\350\257\225", nullptr)); + tabWidget->setTabText(tabWidget->indexOf(tab_3), QCoreApplication::translate("Widget", "Tab 3", nullptr)); tabWidget->setTabText(tabWidget->indexOf(tab_4), QCoreApplication::translate("Widget", "Tab 4", nullptr)); } // retranslateUi diff --git a/widget.cpp b/widget.cpp index f92d3f9..d6dcc03 100644 --- a/widget.cpp +++ b/widget.cpp @@ -72,8 +72,8 @@ Widget::~Widget() void Widget::refreshImage() { // refresh Image 1 and image 0 - refreshSingleImage(0, this->ui->img_0_overlay->isChecked(), this->ui->img_0_mirror->isChecked()); - refreshSingleImage(1, this->ui->img_1_overlay->isChecked(), this->ui->img_1_mirror->isChecked()); + refreshSingleImage(0, this->ui->mtx_0_overlay->isChecked(), this->ui->dl_0_overlay->isChecked(), this->ui->img_0_mirror->isChecked()); + refreshSingleImage(1, this->ui->mtx_1_overlay->isChecked(), this->ui->dl_1_overlay->isChecked(), this->ui->img_1_mirror->isChecked()); // refresh buttons this->ui->btn_start->setEnabled(!this->isCamRunning); this->ui->btn_stop->setEnabled(this->isCamRunning); @@ -96,7 +96,7 @@ void Widget::refreshImage() this->ui->lab_info->setText(info); } -void Widget::refreshSingleImage(int camera_id, bool overlay_result, bool mirror) +void Widget::refreshSingleImage(int camera_id, bool overlay_traditional_result, bool overlay_dl_result, bool mirror) { // 验证摄像头ID的有效性 if (camera_id < 0 || camera_id >= 2) { // 假设只有两个摄像头 @@ -104,12 +104,11 @@ void Widget::refreshSingleImage(int camera_id, bool overlay_result, bool mirror) return; } + // 定义每个摄像头对应的 QLabel + QLabel* cameraLabels[2] = { ui->camera_0_img, ui->camera_1_img }; // 定义每个摄像头对应的变量数组 QMutex* dispPicMutexes[2] = { &gDispPicMutex0, &gDispPicMutex1 }; MIL_ID dispCurrentPicIds[2] = { gDispCurrentPicId0, gDispCurrentPicId1 }; - QMutex* maskMutexes[2] = { &gMaskMutex0, &gMaskMutex1 }; - MIL_ID maskIds[2] = { gMask0, gMask1 }; - QLabel* cameraLabels[2] = { ui->camera_0_img, ui->camera_1_img }; // 获取当前摄像头的数据 QMutex* currentDispMutex = dispPicMutexes[camera_id]; @@ -130,24 +129,91 @@ void Widget::refreshSingleImage(int camera_id, bool overlay_result, bool mirror) return; } - // 如果需要叠加结果,处理掩码 - if (overlay_result) + if (current_id == 0) + return; + + + std::vector> dl_mask; + std::vector> traditional_mask; { - QMutex* currentMaskMutex = maskMutexes[camera_id]; - MIL_ID mask_id; + QMutexLocker locker(&g_detection_result[camera_id].mutex); + dl_mask = g_detection_result[camera_id].dl_mask; + traditional_mask = g_detection_result[camera_id].traditional_mask; + } + // 如果需要叠加结果,处理掩码 + if (overlay_dl_result) + { + if (!dl_mask.empty() && !dl_mask[0].empty()) { - QMutexLocker locker(currentMaskMutex); - mask_id = maskIds[camera_id]; - } - - if (mask_id != 0) { - cv::Mat mask = ImageUtils::mil2Mat(mask_id); - if (!mask.empty()) { - img = ImageUtils::overlayResultOnInput(img, mask, 0.5); + // 将二维 vector 转换为 cv::Mat + int rows = dl_mask.size(); + int cols = dl_mask[0].size(); + cv::Mat dl_mask_mat(rows, cols, CV_8U); + for (int i = 0; i < rows; ++i) + { + if (dl_mask[i].size() != cols) { + qWarning() << "Inconsistent mask row size for dl_mask in Camera ID:" << camera_id; + dl_mask_mat.release(); + break; + } + memcpy(dl_mask_mat.ptr(i), dl_mask[i].data(), cols); } - else { - qWarning() << "Failed to convert MIL mask to Mat for Camera ID:" << camera_id; + + if (!dl_mask_mat.empty()) + { + // 调整掩膜尺寸以匹配图像尺寸 + if (dl_mask_mat.size() != img.size()) { + cv::resize(dl_mask_mat, dl_mask_mat, img.size(), 0, 0, cv::INTER_NEAREST); + } + + // 确保掩膜为二值图像 + cv::threshold(dl_mask_mat, dl_mask_mat, 128, 255, cv::THRESH_BINARY); + + // 创建绿色掩膜 + cv::Mat green_overlay(img.size(), img.type(), cv::Scalar(0, 255, 0)); + green_overlay.setTo(cv::Scalar(0, 255, 0), dl_mask_mat); + + // 叠加掩膜到图像 + cv::addWeighted(green_overlay, 0.5, img, 1.0, 0, img); + } + } + } + + if (overlay_traditional_result) + { + if (!traditional_mask.empty() && !traditional_mask[0].empty()) + { + // 将二维 vector 转换为 cv::Mat + int rows = traditional_mask.size(); + int cols = traditional_mask[0].size(); + cv::Mat traditional_mask_mat(rows, cols, CV_8U); + for (int i = 0; i < rows; ++i) + { + if (traditional_mask[i].size() != cols) { + qWarning() << "Inconsistent mask row size for traditional_mask in Camera ID:" << camera_id; + traditional_mask_mat.release(); + break; + } + memcpy(traditional_mask_mat.ptr(i), traditional_mask[i].data(), cols); + } + + if (!traditional_mask_mat.empty()) + { + // 调整掩膜尺寸以匹配图像尺寸 + if (traditional_mask_mat.size() != img.size()) { + cv::resize(traditional_mask_mat, traditional_mask_mat, img.size(), 0, 0, cv::INTER_NEAREST); + } + + // 确保掩膜为二值图像 + cv::threshold(traditional_mask_mat, traditional_mask_mat, 128, 255, cv::THRESH_BINARY); + + // 创建红色掩膜 + cv::Mat red_overlay(img.size(), img.type(), cv::Scalar(0, 0, 255)); + red_overlay.setTo(cv::Scalar(0, 0, 255), traditional_mask_mat); + + // 叠加掩膜到图像 + cv::addWeighted(red_overlay, 0.5, img, 1.0, 0, img); } } } @@ -171,9 +237,90 @@ void Widget::refreshSingleImage(int camera_id, bool overlay_result, bool mirror) // 更新UI标签 cameraLabels[camera_id]->setPixmap(scaledPixmap); + // // 获取当前摄像头的数据 + // cv::Mat original_image, dl_mask, traditional_mask; + // { + // QMutexLocker locker(&camera_data[camera_id].mutex); + // original_image = camera_data[camera_id].original_image.clone(); + // dl_mask = camera_data[camera_id].dl_mask.clone(); + // traditional_mask = camera_data[camera_id].traditional_mask.clone(); + // } + + // if (original_image.empty()) { + // qWarning() << "Original image is empty for Camera ID:" << camera_id; + // return; + // } + + // // 创建一个可编辑的副本 + // cv::Mat display_img = original_image.clone(); + + // // 确保掩膜为单通道 + // if (!dl_mask.empty() && dl_mask.channels() > 1) { + // cv::cvtColor(dl_mask, dl_mask, cv::COLOR_BGR2GRAY); + // } + // if (!traditional_mask.empty() && traditional_mask.channels() > 1) { + // cv::cvtColor(traditional_mask, traditional_mask, cv::COLOR_BGR2GRAY); + // } + + // // 调整掩膜尺寸并确保二值化 + // if (!dl_mask.empty() && overlay_dl_result) { + // if (dl_mask.size() != original_image.size()) { + // cv::resize(dl_mask, dl_mask, original_image.size(), 0, 0, cv::INTER_NEAREST); + // } + // // 确保掩膜为二值图像 + // cv::threshold(dl_mask, dl_mask, 128, 255, cv::THRESH_BINARY); + // } + + // if (!traditional_mask.empty() && overlay_traditional_result) { + // if (traditional_mask.size() != original_image.size()) { + // cv::resize(traditional_mask, traditional_mask, original_image.size(), 0, 0, cv::INTER_NEAREST); + // } + // // 确保掩膜为二值图像 + // cv::threshold(traditional_mask, traditional_mask, 128, 255, cv::THRESH_BINARY); + // } + + // // 叠加深度学习掩膜(绿色) + // if (!dl_mask.empty() && overlay_dl_result) { + // // 创建绿色掩膜 + // cv::Mat green_overlay(display_img.size(), display_img.type(), cv::Scalar(0, 255, 0)); + // green_overlay.setTo(cv::Scalar(0, 255, 0), dl_mask); + + // // 叠加掩膜 + // cv::addWeighted(display_img, 1.0, green_overlay, 0.5, 0, display_img); + // } + + // // 叠加传统掩膜(红色) + // if (!traditional_mask.empty() && overlay_traditional_result) { + // // 创建红色掩膜 + // cv::Mat red_overlay(display_img.size(), display_img.type(), cv::Scalar(0, 0, 255)); + // red_overlay.setTo(cv::Scalar(0, 0, 255), traditional_mask); + + // // 叠加掩膜 + // cv::addWeighted(display_img, 1.0, red_overlay, 0.5, 0, display_img); + // } + + // // 如果需要镜像处理 + // if (mirror) { + // cv::flip(display_img, display_img, 1); // 水平翻转 + // } + + // // 将OpenCV Mat转换为QPixmap + // QPixmap pixmap = ImageUtils::mat2QPixmap(display_img); + // if (pixmap.isNull()) { + // qWarning() << "Failed to convert Mat to QPixmap for Camera ID:" << camera_id; + // return; + // } + + // // 高质量缩放图像 + // QSize labelSize = cameraLabels[camera_id]->size(); + // QPixmap scaledPixmap = pixmap.scaled(labelSize); + + // // 更新UI标签 + // cameraLabels[camera_id]->setPixmap(scaledPixmap); } + void Widget::on_pushButton_2_clicked() { SaveImg_Flag = 1; @@ -243,6 +390,11 @@ void Widget::on_btn_stop_clicked() void Widget::on_btn_start_clicked() { this->isCamRunning = true; + // 热身两个工作者 + for(int i = 0; i < 2; ++i) + { + g_runner_array[i]->warm_up(); + } // 启动检测工作者线程 for(int i = 0; i < 2; ++i) { @@ -265,3 +417,9 @@ void Widget::on_btn_take_photos_released() SaveImg_Flag = false; } + +void Widget::on_btn_quit_clicked() +{ + qApp->quit(); +} + diff --git a/widget.h b/widget.h index ce9eb71..82df228 100644 --- a/widget.h +++ b/widget.h @@ -27,7 +27,7 @@ public slots: private slots: - void refreshSingleImage(int camera_id, bool overlay_result = true, bool mirror = false); + void refreshSingleImage(int camera_id, bool overlay_traditional_result = false, bool overlay_dl_result = false, bool mirror = false); void on_pushButton_2_clicked(); @@ -41,6 +41,8 @@ private slots: void on_btn_take_photos_released(); + void on_btn_quit_clicked(); + private: Ui::Widget *ui; diff --git a/widget.ui b/widget.ui index d2fc231..3a7e5d4 100644 --- a/widget.ui +++ b/widget.ui @@ -263,6 +263,9 @@ 200 + + font: 700 40pt "Microsoft YaHei UI"; + 开始分选 @@ -276,6 +279,9 @@ 200 + + font: 700 40pt "Microsoft YaHei UI"; + 抓取图片 @@ -289,11 +295,30 @@ 200 + + font: 700 40pt "Microsoft YaHei UI"; + 停止分选 + + + + + 70 + 200 + + + + font: 700 40pt "Microsoft YaHei UI"; + + + 退出系统 + + + @@ -345,6 +370,32 @@ + + + + true + + + font: 12pt "Microsoft YaHei UI"; + + + 色检结果 + + + + + + + true + + + font: 12pt "Microsoft YaHei UI"; + + + 智检结果 + + + @@ -355,19 +406,6 @@ - - - - false - - - font: 12pt "Microsoft YaHei UI"; - - - 识别结果 - - - @@ -423,6 +461,32 @@ border: 4px solid black; + + + + true + + + font: 12pt "Microsoft YaHei UI"; + + + 色检结果 + + + + + + + true + + + font: 12pt "Microsoft YaHei UI"; + + + 智检结果 + + + @@ -436,19 +500,6 @@ border: 4px solid black; - - - - false - - - font: 12pt "Microsoft YaHei UI"; - - - 识别结果 - - - @@ -486,15 +537,21 @@ border: 4px solid black; 0 10 - 171 - 41 + 421 + 81 - 20 + Microsoft YaHei UI + 48 + false + true + + font: 700 48pt "Microsoft YaHei UI"; + 参数设置界面 @@ -502,121 +559,92 @@ border: 4px solid black; - 10 - 60 - 341 - 191 + 30 + 130 + 771 + 591 + + font: 700 40pt "Microsoft YaHei UI"; +border-color: rgb(0, 0, 0); + 下位机参数 - - - - 40 - 40 - 53 - 15 - - - - 延迟时间 - - - - - - 40 - 80 - 81 - 16 - - - - 相机分频系数 - - - - - - 40 - 120 - 71 - 16 - - - - 喷阀分频系数 - - - - - - 120 - 40 - 81 - 22 - - - - - - - 120 - 80 - 81 - 22 - - - - - - - 120 - 120 - 81 - 22 - - - - 250 - 160 - 61 - 23 + 430 + 410 + 231 + 141 - 确定 + 设定参数 + + + + 460 + 120 + 181 + 241 + + + + + + + + + + + + + + + + + + 30 + 120 + 341 + 251 + + + + + + + 延迟时间 + + + + + + + 相机分频系数 + + + + + + + 喷阀分频系数 + + + + + - - - - 660 - 490 - 75 - 23 - - - - 关机 - - - - - - Tab 4 - - 50 - 30 + 920 + 150 91 21 @@ -628,8 +656,8 @@ border: 4px solid black; - 110 - 120 + 1050 + 240 331 91 @@ -690,8 +718,8 @@ border: 4px solid black; - 110 - 270 + 1050 + 420 331 91 @@ -727,6 +755,11 @@ border: 4px solid black; + + + Tab 4 + +