四象巅峰

This commit is contained in:
XinJiang1 2024-12-24 17:35:13 +08:00
parent 863ff21036
commit 8405ee3d1b
11 changed files with 674 additions and 305 deletions

View File

@ -3,9 +3,9 @@
#include <QTimer>
// 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<std::vector<uint8_t>> 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<std::vector<uint8_t>> merged_mask;
std::vector<std::vector<uint8_t>> 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<std::vector<uint8_t>> 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<std::vector<uint8_t>> merged_mask;
std::vector<std::vector<uint8_t>> 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<vector<uint8_t>> merged_mask;
vector<vector<uint8_t>> mask_tail;
detection_ready.acquire();
vector<vector<uint8_t>> 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<std::string, int>& params) {
const std::vector<std::string> colors = {"green", "blue", "orange", "black", "red", "purple"};
const std::vector<std::string> colors = {"green", "blue", "orange", "black", "red", "purple", "yellow"};
lab_process_raw(inputImage, outputImageLab, params, colors);
}

View File

@ -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

View File

@ -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; // 全局实例,确保在程序结束时清理

View File

@ -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<std::vector<uint8_t>> dl_mask; // 深度学习掩膜
std::vector<std::vector<uint8_t>> traditional_mask; // 传统算法掩膜
};
extern DetectionResult g_detection_result[2];
// 线程安全队列模板类
template <typename T>
class ThreadSafeQueue{

View File

@ -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<Detection>& 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();
// 处理异常,例如记录日志或设置状态标志
}
}

View File

@ -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<Detection> performInference(cv::dnn::Net& net, const cv::Mat& inputImage) const;
std::vector<Detection> applyNMS(std::vector<Detection>& detections) const;
void warm_up();
// Constants
const float CONFIDENCE_THRESHOLD = 0.2f;
const float NMS_THRESHOLD = 0.2f;

View File

@ -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

View File

@ -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

View File

@ -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<std::vector<uint8_t>> dl_mask;
std::vector<std::vector<uint8_t>> 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();
}

View File

@ -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;

295
widget.ui
View File

@ -263,6 +263,9 @@
<height>200</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">font: 700 40pt &quot;Microsoft YaHei UI&quot;;</string>
</property>
<property name="text">
<string>开始分选</string>
</property>
@ -276,6 +279,9 @@
<height>200</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">font: 700 40pt &quot;Microsoft YaHei UI&quot;;</string>
</property>
<property name="text">
<string>抓取图片</string>
</property>
@ -289,11 +295,30 @@
<height>200</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">font: 700 40pt &quot;Microsoft YaHei UI&quot;;</string>
</property>
<property name="text">
<string>停止分选</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_quit">
<property name="minimumSize">
<size>
<width>70</width>
<height>200</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">font: 700 40pt &quot;Microsoft YaHei UI&quot;;</string>
</property>
<property name="text">
<string>退出系统</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
@ -345,6 +370,32 @@
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="mtx_1_overlay">
<property name="enabled">
<bool>true</bool>
</property>
<property name="styleSheet">
<string notr="true">font: 12pt &quot;Microsoft YaHei UI&quot;;</string>
</property>
<property name="text">
<string>色检结果</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="dl_1_overlay">
<property name="enabled">
<bool>true</bool>
</property>
<property name="styleSheet">
<string notr="true">font: 12pt &quot;Microsoft YaHei UI&quot;;</string>
</property>
<property name="text">
<string>智检结果</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="img_1_mirror">
<property name="styleSheet">
@ -355,19 +406,6 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="img_1_overlay">
<property name="enabled">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true">font: 12pt &quot;Microsoft YaHei UI&quot;;</string>
</property>
<property name="text">
<string>识别结果</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@ -423,6 +461,32 @@ border: 4px solid black;</string>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="mtx_0_overlay">
<property name="enabled">
<bool>true</bool>
</property>
<property name="styleSheet">
<string notr="true">font: 12pt &quot;Microsoft YaHei UI&quot;;</string>
</property>
<property name="text">
<string>色检结果</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="dl_0_overlay">
<property name="enabled">
<bool>true</bool>
</property>
<property name="styleSheet">
<string notr="true">font: 12pt &quot;Microsoft YaHei UI&quot;;</string>
</property>
<property name="text">
<string>智检结果</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="img_0_mirror">
<property name="styleSheet">
@ -436,19 +500,6 @@ border: 4px solid black;</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="img_0_overlay">
<property name="enabled">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true">font: 12pt &quot;Microsoft YaHei UI&quot;;</string>
</property>
<property name="text">
<string>识别结果</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@ -486,15 +537,21 @@ border: 4px solid black;</string>
<rect>
<x>0</x>
<y>10</y>
<width>171</width>
<height>41</height>
<width>421</width>
<height>81</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>20</pointsize>
<family>Microsoft YaHei UI</family>
<pointsize>48</pointsize>
<italic>false</italic>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">font: 700 48pt &quot;Microsoft YaHei UI&quot;;</string>
</property>
<property name="text">
<string>参数设置界面</string>
</property>
@ -502,121 +559,92 @@ border: 4px solid black;</string>
<widget class="QGroupBox" name="groupBox_4">
<property name="geometry">
<rect>
<x>10</x>
<y>60</y>
<width>341</width>
<height>191</height>
<x>30</x>
<y>130</y>
<width>771</width>
<height>591</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">font: 700 40pt &quot;Microsoft YaHei UI&quot;;
border-color: rgb(0, 0, 0);</string>
</property>
<property name="title">
<string>下位机参数</string>
</property>
<widget class="QLabel" name="label_delaytime">
<property name="geometry">
<rect>
<x>40</x>
<y>40</y>
<width>53</width>
<height>15</height>
</rect>
</property>
<property name="text">
<string>延迟时间</string>
</property>
</widget>
<widget class="QLabel" name="label_encoder">
<property name="geometry">
<rect>
<x>40</x>
<y>80</y>
<width>81</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>相机分频系数</string>
</property>
</widget>
<widget class="QLabel" name="label_encoder_2">
<property name="geometry">
<rect>
<x>40</x>
<y>120</y>
<width>71</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>喷阀分频系数</string>
</property>
</widget>
<widget class="QSpinBox" name="spinbox_delaytime">
<property name="geometry">
<rect>
<x>120</x>
<y>40</y>
<width>81</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QSpinBox" name="spinbox_encoder">
<property name="geometry">
<rect>
<x>120</x>
<y>80</y>
<width>81</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QSpinBox" name="spinbox_valve">
<property name="geometry">
<rect>
<x>120</x>
<y>120</y>
<width>81</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="btn_set_lower">
<property name="geometry">
<rect>
<x>250</x>
<y>160</y>
<width>61</width>
<height>23</height>
<x>430</x>
<y>410</y>
<width>231</width>
<height>141</height>
</rect>
</property>
<property name="text">
<string>确定</string>
<string>设定参数</string>
</property>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>460</x>
<y>120</y>
<width>181</width>
<height>241</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QSpinBox" name="spinbox_delaytime"/>
</item>
<item>
<widget class="QSpinBox" name="spinbox_encoder"/>
</item>
<item>
<widget class="QSpinBox" name="spinbox_valve"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>30</x>
<y>120</y>
<width>341</width>
<height>251</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QLabel" name="label_delaytime">
<property name="text">
<string>延迟时间</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_encoder">
<property name="text">
<string>相机分频系数</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_encoder_2">
<property name="text">
<string>喷阀分频系数</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QPushButton" name="btn_exit">
<property name="geometry">
<rect>
<x>660</x>
<y>490</y>
<width>75</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>关机</string>
</property>
</widget>
</widget>
<widget class="QWidget" name="tab_4">
<attribute name="title">
<string>Tab 4</string>
</attribute>
<widget class="QLabel" name="label_title_4">
<property name="geometry">
<rect>
<x>50</x>
<y>30</y>
<x>920</x>
<y>150</y>
<width>91</width>
<height>21</height>
</rect>
@ -628,8 +656,8 @@ border: 4px solid black;</string>
<widget class="QGroupBox" name="groupBox_2">
<property name="geometry">
<rect>
<x>110</x>
<y>120</y>
<x>1050</x>
<y>240</y>
<width>331</width>
<height>91</height>
</rect>
@ -690,8 +718,8 @@ border: 4px solid black;</string>
<widget class="QGroupBox" name="groupBox_3">
<property name="geometry">
<rect>
<x>110</x>
<y>270</y>
<x>1050</x>
<y>420</y>
<width>331</width>
<height>91</height>
</rect>
@ -727,6 +755,11 @@ border: 4px solid black;</string>
</widget>
</widget>
</widget>
<widget class="QWidget" name="tab_4">
<attribute name="title">
<string>Tab 4</string>
</attribute>
</widget>
</widget>
</item>
</layout>