四象巅峰
This commit is contained in:
parent
863ff21036
commit
8405ee3d1b
213
camera.cpp
213
camera.cpp
@ -3,9 +3,9 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
// Debug Options
|
// Debug Options
|
||||||
#define GlobalDebug 1 // 全局是否允许打印Debug信息(打印会拖慢处理时间)
|
#define GlobalDebug 0 // 全局是否允许打印Debug信息(打印会拖慢处理时间)
|
||||||
#define DebugDetection 0 // 注意开启这个编译选项会导致图片存储, 处理时间会很慢
|
#define DebugDetection 0 // 注意开启这个编译选项会导致图片存储, 处理时间会很慢
|
||||||
#define DebugDetectionTime 1 // 是否打印处理时间
|
#define DebugDetectionTime 0 // 是否打印处理时间
|
||||||
#define DebugLowerMacCOM 0 // 是否打印和下位机通讯的相关信息
|
#define DebugLowerMacCOM 0 // 是否打印和下位机通讯的相关信息
|
||||||
|
|
||||||
camera::camera() {}
|
camera::camera() {}
|
||||||
@ -144,7 +144,7 @@ bool iniCamera()
|
|||||||
MIL_INT ProcessingFunction0(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr)
|
MIL_INT ProcessingFunction0(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr)
|
||||||
{
|
{
|
||||||
#if(GlobalDebug)
|
#if(GlobalDebug)
|
||||||
qDebug()<<"回调1";
|
qDebug()<<"CallBack1";
|
||||||
#endif
|
#endif
|
||||||
int camera_id = 0;
|
int camera_id = 0;
|
||||||
#if(GlobalDebug && DebugDetectionTime)
|
#if(GlobalDebug && DebugDetectionTime)
|
||||||
@ -157,26 +157,26 @@ MIL_INT ProcessingFunction0(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr)
|
|||||||
gDispCurrentPicId0 = ModifiedBufferId0;
|
gDispCurrentPicId0 = ModifiedBufferId0;
|
||||||
|
|
||||||
}
|
}
|
||||||
// 拷贝存图图像
|
|
||||||
MbufCopy(ModifiedBufferId0, MilImage0);
|
|
||||||
cv::Mat img = ImageUtils::mil2Mat(MilImage0);
|
|
||||||
|
|
||||||
// 将图像推入识别队列
|
#if(GlobalDebug && DebugDetectionTime)
|
||||||
ImageData recognitionData;
|
timer_detection_time.printElapsedTime("CallBack1: Send mil id for detection");
|
||||||
recognitionData.camera_id = camera_id;
|
timer_detection_time.restart();
|
||||||
recognitionData.image = img;
|
#endif
|
||||||
g_img_Queue[camera_id]->enqueue(recognitionData);
|
|
||||||
qDebug() << "Callback0: Enqueued image for recognition";
|
|
||||||
|
|
||||||
if (SaveImg_Flag)
|
if (SaveImg_Flag)
|
||||||
{
|
{
|
||||||
|
// 拷贝存图图像
|
||||||
|
MbufCopy(ModifiedBufferId0, MilImage0);
|
||||||
|
cv::Mat img = ImageUtils::mil2Mat(MilImage0);
|
||||||
// 将图像数据推入存储队列
|
// 将图像数据推入存储队列
|
||||||
ImageData data;
|
ImageData data;
|
||||||
data.camera_id = 0;
|
data.camera_id = 0;
|
||||||
data.image = img.clone(); // 确保图像数据被复制
|
data.image = img.clone(); // 确保图像数据被复制
|
||||||
g_storageQueue.enqueue(data);
|
g_storageQueue.enqueue(data);
|
||||||
qDebug() << "Callback0: Enqueued image for camera 0";
|
|
||||||
FuncCount0++;
|
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);
|
MbufClear(MimResizedestination, M_COLOR_BLACK);
|
||||||
MimResize(MilImage_Color0, MimResizedestination, 0.5, 1 , M_DEFAULT);
|
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);
|
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);
|
MbufClear(MimFlipDedtination, M_COLOR_BLACK);
|
||||||
MimFlip(MimResizedestination, MimFlipDedtination, M_FLIP_HORIZONTAL, M_DEFAULT);
|
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
|
//艳丽检测mask
|
||||||
high_sat_detect(MimFlipDedtination, detection_result0, params);
|
high_sat_detect(MimFlipDedtination, detection_result0, params);
|
||||||
|
|
||||||
// 将 Matrox 的检测结果转换为 OpenCV Mat
|
#if(GlobalDebug && DebugDetectionTime)
|
||||||
cv::Mat matrox_mask = ImageUtils::mil2Mat(detection_result0);
|
timer_detection_time.printElapsedTime("CallBack1: High sat detection finish");
|
||||||
cv::threshold(matrox_mask, matrox_mask, 128, 255, cv::THRESH_BINARY); // 确保是二值化
|
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;
|
ImageData dl_data;
|
||||||
cv::Mat merged_mat_mask;
|
|
||||||
if(!g_result_Queue[camera_id]->dequeue(dl_data))
|
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 的检测结果
|
// 如果没有深度学习的检测结果,使用 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
|
else
|
||||||
{
|
{
|
||||||
// 将深度学习的检测结果转换为 OpenCV Mat
|
// 将深度学习的检测结果转换为 OpenCV Mat
|
||||||
cv::Mat dl_mask = dl_data.image;
|
dl_mask = generateMaskFromMatImage(dl_data.image, widthBlocks, heightBlocks, sizeThreshold);
|
||||||
cv::threshold(dl_mask, dl_mask, 128, 255, cv::THRESH_BINARY); // 确保是二值化
|
merged_mask = ImageUtils::mergeMasks(dl_mask, matrox_mask);
|
||||||
cv::resize(dl_mask, dl_mask, matrox_mask.size(), 0, 0, cv::INTER_NEAREST);
|
#if(GlobalDebug && DebugDetectionTime)
|
||||||
|
timer_detection_time.printElapsedTime("CallBack2: Wait DL detection and result to mask");
|
||||||
// 合并 Matrox 的检测结果和深度学习的检测结果(逻辑“或”)
|
timer_detection_time.restart();
|
||||||
cv::Mat combined_mask;
|
#endif
|
||||||
cv::bitwise_or(matrox_mask, dl_mask, combined_mask);
|
|
||||||
|
|
||||||
merged_mat_mask = combined_mask;
|
|
||||||
}
|
}
|
||||||
// Update the current Img MIl id
|
// Update the current Img MIl id
|
||||||
|
// 更新持久化存储
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&gMaskMutex0);
|
QMutexLocker locker(&g_detection_result[camera_id].mutex);
|
||||||
gMask0 = detection_result0;
|
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)
|
#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
|
#endif
|
||||||
|
mask_0 = merged_mask;
|
||||||
detection_ready.release();
|
detection_ready.release();
|
||||||
MbufFree(detection_result0);
|
MbufFree(detection_result0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MIL_INT ProcessingFunction1(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr)
|
MIL_INT ProcessingFunction1(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr)
|
||||||
{
|
{
|
||||||
|
#if(GlobalDebug)
|
||||||
|
qDebug()<<"CallBack2";
|
||||||
|
#endif
|
||||||
int camera_id = 1;
|
int camera_id = 1;
|
||||||
// some debug info
|
|
||||||
#if(GlobalDebug && DebugDetectionTime)
|
#if(GlobalDebug && DebugDetectionTime)
|
||||||
Timer timer_detection_time;
|
Timer timer_detection_time;
|
||||||
timer_detection_time.restart();
|
timer_detection_time.restart();
|
||||||
@ -250,67 +278,104 @@ MIL_INT ProcessingFunction1(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr)
|
|||||||
QMutexLocker locker(&gDispPicMutex1);
|
QMutexLocker locker(&gDispPicMutex1);
|
||||||
gDispCurrentPicId1 = ModifiedBufferId1;
|
gDispCurrentPicId1 = ModifiedBufferId1;
|
||||||
}
|
}
|
||||||
// 转回OpenCV图像
|
#if(GlobalDebug && DebugDetectionTime)
|
||||||
MbufCopy(ModifiedBufferId1, MilImage1);
|
timer_detection_time.printElapsedTime("CallBack2: Send mil id for detection");
|
||||||
cv::Mat img = ImageUtils::mil2Mat(MilImage1);
|
timer_detection_time.restart();
|
||||||
// 将图像推入识别队列
|
#endif
|
||||||
ImageData recognitionData;
|
|
||||||
recognitionData.camera_id = 1;
|
|
||||||
recognitionData.image = img;
|
|
||||||
g_img_Queue[1]->enqueue(recognitionData);
|
|
||||||
qDebug() << "Callback1: Enqueued image for recognition";
|
|
||||||
// 将图像数据推入存储队列
|
// 将图像数据推入存储队列
|
||||||
if (SaveImg_Flag)
|
if (SaveImg_Flag)
|
||||||
{
|
{
|
||||||
|
// 转回OpenCV图像
|
||||||
|
MbufCopy(ModifiedBufferId1, MilImage1);
|
||||||
|
cv::Mat img = ImageUtils::mil2Mat(MilImage1);
|
||||||
ImageData data;
|
ImageData data;
|
||||||
data.camera_id = 1;
|
data.camera_id = 1;
|
||||||
data.image = img.clone(); // 确保图像数据被复制
|
data.image = img.clone(); // 确保图像数据被复制
|
||||||
g_storageQueue.enqueue(data);
|
g_storageQueue.enqueue(data);
|
||||||
qDebug() << "Callback1: Enqueued image for camera 1";
|
|
||||||
FuncCount1++;
|
FuncCount1++;
|
||||||
}
|
|
||||||
#if (GlobalDebug)
|
|
||||||
qDebug()<<"回调2";
|
|
||||||
#endif
|
|
||||||
#if(GlobalDebug && DebugDetectionTime)
|
#if(GlobalDebug && DebugDetectionTime)
|
||||||
Timer timer2;
|
qDebug() << "CallBack2: push image to storage queue";
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
//拷贝艳丽色检测图像
|
//拷贝艳丽色检测图像
|
||||||
MbufCopy(ModifiedBufferId1,MilImage_Color1);
|
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);
|
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);
|
MbufClear(MimResizedestination, M_COLOR_BLACK);
|
||||||
MimResize(MilImage_Color1, MimResizedestination, 0.5, 1 , M_DEFAULT);
|
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
|
// 艳丽检测mask
|
||||||
high_sat_detect(MimResizedestination, detection_result1, params);
|
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;
|
ImageData dl_data;
|
||||||
cv::Mat merged_mat_mask;
|
|
||||||
if(!g_result_Queue[camera_id]->dequeue(dl_data))
|
if(!g_result_Queue[camera_id]->dequeue(dl_data))
|
||||||
{
|
{
|
||||||
qWarning() << "Receive empty result from Onnx for camera" << camera_id;
|
qWarning() << "Receive empty result from Onnx for camera" << camera_id;
|
||||||
// 如果没有深度学习的检测结果,使用 Matrox 的检测结果
|
// 如果没有深度学习的检测结果,使用 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
|
else
|
||||||
{
|
{
|
||||||
// 将深度学习的检测结果转换为 OpenCV Mat
|
// 将深度学习的检测结果转换为 OpenCV Mat
|
||||||
cv::Mat dl_mask = dl_data.image;
|
dl_mask = generateMaskFromMatImage(dl_data.image, widthBlocks, heightBlocks, sizeThreshold);
|
||||||
cv::threshold(dl_mask, dl_mask, 128, 255, cv::THRESH_BINARY); // 确保是二值化
|
merged_mask = ImageUtils::mergeMasks(dl_mask, matrox_mask);
|
||||||
cv::resize(dl_mask, dl_mask, matrox_mask.size(), 0, 0, cv::INTER_NEAREST);
|
#if(GlobalDebug && DebugDetectionTime)
|
||||||
|
timer_detection_time.printElapsedTime("CallBack1: Wait DL detection and result to mask");
|
||||||
|
timer_detection_time.restart();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// 合并 Matrox 的检测结果和深度学习的检测结果(逻辑“或”)
|
// Update the current Img MIl id
|
||||||
cv::Mat combined_mask;
|
// 更新持久化存储
|
||||||
cv::bitwise_or(matrox_mask, dl_mask, combined_mask);
|
{
|
||||||
|
QMutexLocker locker(&g_detection_result[camera_id].mutex);
|
||||||
merged_mat_mask = combined_mask;
|
g_detection_result[camera_id].dl_mask = dl_mask;
|
||||||
|
g_detection_result[camera_id].traditional_mask = matrox_mask;
|
||||||
}
|
}
|
||||||
#if(GlobalDebug && DebugDetectionTime)
|
#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
|
#endif
|
||||||
|
mask_1 = merged_mask;
|
||||||
|
|
||||||
#if(GlobalDebug && DebugDetection)
|
#if(GlobalDebug && DebugDetection)
|
||||||
MbufSave(SAVE_PATH_flip,MimFlipDedtination);
|
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_raw,MilImage_Color0);
|
||||||
MbufSave(SAVE_PATH_result,detection_result0);
|
MbufSave(SAVE_PATH_result,detection_result0);
|
||||||
#endif
|
#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);
|
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);
|
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) {
|
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);
|
lab_process_raw(inputImage, outputImageLab, params, colors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
# Green color parameters
|
# Green color parameters
|
||||||
green_L_min = 18
|
green_L_min = 20
|
||||||
green_L_max = 58
|
green_L_max = 55
|
||||||
green_a_min = -35
|
green_a_min = -32
|
||||||
green_a_max = -11
|
green_a_max = -11
|
||||||
green_b_min = -7
|
green_b_min = -7
|
||||||
green_b_max = 24
|
green_b_max = 20
|
||||||
|
|
||||||
# Blue color parameters
|
# Blue color parameters
|
||||||
blue_L_min = 20
|
blue_L_min = 20
|
||||||
@ -39,14 +39,23 @@ red_b_min = -99
|
|||||||
red_b_max = 32
|
red_b_max = 32
|
||||||
|
|
||||||
# Purple color parameters
|
# Purple color parameters
|
||||||
purple_L_min = 35
|
purple_L_min = 38
|
||||||
purple_L_max = 72
|
purple_L_max = 75
|
||||||
purple_a_min = 12
|
purple_a_min = 12
|
||||||
purple_a_max = 22
|
purple_a_max = 22
|
||||||
purple_b_min = -48
|
purple_b_min = -48
|
||||||
purple_b_max = 1
|
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
|
# Other parameters
|
||||||
lab_denoising = 1
|
lab_denoising = 1
|
||||||
saturation_threshold = 150
|
saturation_threshold = 155
|
||||||
saturation_denoising = 1
|
saturation_denoising = 1
|
||||||
|
|||||||
@ -15,6 +15,9 @@ MIL_ID gMask0 = 0;
|
|||||||
QMutex gMaskMutex1;
|
QMutex gMaskMutex1;
|
||||||
MIL_ID gMask1 = 0;
|
MIL_ID gMask1 = 0;
|
||||||
|
|
||||||
|
// 初始化 CameraData 实例
|
||||||
|
DetectionResult g_detection_result[2];
|
||||||
|
|
||||||
// 初始化检测准备信号量
|
// 初始化检测准备信号量
|
||||||
QSemaphore detection_ready(0);
|
QSemaphore detection_ready(0);
|
||||||
|
|
||||||
@ -163,3 +166,4 @@ struct GlobalsInitializer {
|
|||||||
cleanupGlobalONNXRunner(); // 添加此行
|
cleanupGlobalONNXRunner(); // 添加此行
|
||||||
}
|
}
|
||||||
} globalsInitializerInstance; // 全局实例,确保在程序结束时清理
|
} globalsInitializerInstance; // 全局实例,确保在程序结束时清理
|
||||||
|
|
||||||
|
|||||||
11
globals.h
11
globals.h
@ -34,6 +34,8 @@ extern MIL_ID gMask1;
|
|||||||
// 检测准备信号量
|
// 检测准备信号量
|
||||||
extern QSemaphore detection_ready;
|
extern QSemaphore detection_ready;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 获取保存目录和配置目录函数
|
// 获取保存目录和配置目录函数
|
||||||
QString getSaveDirectory();
|
QString getSaveDirectory();
|
||||||
QString getConfigDirectory();
|
QString getConfigDirectory();
|
||||||
@ -45,6 +47,15 @@ struct ImageData
|
|||||||
cv::Mat image;
|
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>
|
template <typename T>
|
||||||
class ThreadSafeQueue{
|
class ThreadSafeQueue{
|
||||||
|
|||||||
@ -164,7 +164,7 @@ void ONNXRunner::load(const std::string& modelPath) {
|
|||||||
|
|
||||||
// 调用 predict 方法进行预热,避免第一次推理时加载模型导致延迟
|
// 调用 predict 方法进行预热,避免第一次推理时加载模型导致延迟
|
||||||
try {
|
try {
|
||||||
for(int i = 0; i < 10; i++)
|
for(int i = 0; i < 2; i++)
|
||||||
this->predict(dummyInput);
|
this->predict(dummyInput);
|
||||||
qDebug() << "ONNX模型预热完成";
|
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);
|
cv::Mat detectionMask = ONNXRunner::createDetectionMask(image, detections, this->scale, this->pad_top, this->pad_left);
|
||||||
return detectionMask;
|
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();
|
||||||
|
// 处理异常,例如记录日志或设置状态标志
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -46,6 +46,7 @@ public:
|
|||||||
cv::Mat preprocessImage(const cv::Mat& image, cv::dnn::Net& net, int& padTop, int& padLeft, float& scale) const;
|
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> performInference(cv::dnn::Net& net, const cv::Mat& inputImage) const;
|
||||||
std::vector<Detection> applyNMS(std::vector<Detection>& detections) const;
|
std::vector<Detection> applyNMS(std::vector<Detection>& detections) const;
|
||||||
|
void warm_up();
|
||||||
// Constants
|
// Constants
|
||||||
const float CONFIDENCE_THRESHOLD = 0.2f;
|
const float CONFIDENCE_THRESHOLD = 0.2f;
|
||||||
const float NMS_THRESHOLD = 0.2f;
|
const float NMS_THRESHOLD = 0.2f;
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
# Green color parameters
|
# Green color parameters
|
||||||
green_L_min = 18
|
green_L_min = 20
|
||||||
green_L_max = 58
|
green_L_max = 55
|
||||||
green_a_min = -35
|
green_a_min = -32
|
||||||
green_a_max = -11
|
green_a_max = -11
|
||||||
green_b_min = -7
|
green_b_min = -7
|
||||||
green_b_max = 24
|
green_b_max = 20
|
||||||
|
|
||||||
# Blue color parameters
|
# Blue color parameters
|
||||||
blue_L_min = 20
|
blue_L_min = 20
|
||||||
@ -39,14 +39,23 @@ red_b_min = -99
|
|||||||
red_b_max = 32
|
red_b_max = 32
|
||||||
|
|
||||||
# Purple color parameters
|
# Purple color parameters
|
||||||
purple_L_min = 35
|
purple_L_min = 38
|
||||||
purple_L_max = 72
|
purple_L_max = 75
|
||||||
purple_a_min = 12
|
purple_a_min = 12
|
||||||
purple_a_max = 22
|
purple_a_max = 22
|
||||||
purple_b_min = -48
|
purple_b_min = -48
|
||||||
purple_b_max = 1
|
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
|
# Other parameters
|
||||||
lab_denoising = 1
|
lab_denoising = 1
|
||||||
saturation_threshold = 150
|
saturation_threshold = 155
|
||||||
saturation_denoising = 1
|
saturation_denoising = 1
|
||||||
|
|||||||
181
ui_widget.h
181
ui_widget.h
@ -52,6 +52,7 @@ public:
|
|||||||
QPushButton *btn_start;
|
QPushButton *btn_start;
|
||||||
QPushButton *btn_take_photos;
|
QPushButton *btn_take_photos;
|
||||||
QPushButton *btn_stop;
|
QPushButton *btn_stop;
|
||||||
|
QPushButton *btn_quit;
|
||||||
QSpacerItem *verticalSpacer;
|
QSpacerItem *verticalSpacer;
|
||||||
QFrame *frame_6;
|
QFrame *frame_6;
|
||||||
QVBoxLayout *verticalLayout_2;
|
QVBoxLayout *verticalLayout_2;
|
||||||
@ -59,28 +60,32 @@ public:
|
|||||||
QHBoxLayout *horizontalLayout_4;
|
QHBoxLayout *horizontalLayout_4;
|
||||||
QLabel *label_2;
|
QLabel *label_2;
|
||||||
QSpacerItem *horizontalSpacer;
|
QSpacerItem *horizontalSpacer;
|
||||||
|
QCheckBox *mtx_1_overlay;
|
||||||
|
QCheckBox *dl_1_overlay;
|
||||||
QCheckBox *img_1_mirror;
|
QCheckBox *img_1_mirror;
|
||||||
QCheckBox *img_1_overlay;
|
|
||||||
QLabel *camera_1_img;
|
QLabel *camera_1_img;
|
||||||
QFrame *frame_2;
|
QFrame *frame_2;
|
||||||
QHBoxLayout *horizontalLayout_5;
|
QHBoxLayout *horizontalLayout_5;
|
||||||
QLabel *label_4;
|
QLabel *label_4;
|
||||||
QSpacerItem *horizontalSpacer_2;
|
QSpacerItem *horizontalSpacer_2;
|
||||||
|
QCheckBox *mtx_0_overlay;
|
||||||
|
QCheckBox *dl_0_overlay;
|
||||||
QCheckBox *img_0_mirror;
|
QCheckBox *img_0_mirror;
|
||||||
QCheckBox *img_0_overlay;
|
|
||||||
QLabel *camera_0_img;
|
QLabel *camera_0_img;
|
||||||
QWidget *tab_3;
|
QWidget *tab_3;
|
||||||
QLabel *label_title_3;
|
QLabel *label_title_3;
|
||||||
QGroupBox *groupBox_4;
|
QGroupBox *groupBox_4;
|
||||||
QLabel *label_delaytime;
|
QPushButton *btn_set_lower;
|
||||||
QLabel *label_encoder;
|
QWidget *layoutWidget;
|
||||||
QLabel *label_encoder_2;
|
QVBoxLayout *verticalLayout_4;
|
||||||
QSpinBox *spinbox_delaytime;
|
QSpinBox *spinbox_delaytime;
|
||||||
QSpinBox *spinbox_encoder;
|
QSpinBox *spinbox_encoder;
|
||||||
QSpinBox *spinbox_valve;
|
QSpinBox *spinbox_valve;
|
||||||
QPushButton *btn_set_lower;
|
QWidget *layoutWidget1;
|
||||||
QPushButton *btn_exit;
|
QVBoxLayout *verticalLayout_5;
|
||||||
QWidget *tab_4;
|
QLabel *label_delaytime;
|
||||||
|
QLabel *label_encoder;
|
||||||
|
QLabel *label_encoder_2;
|
||||||
QLabel *label_title_4;
|
QLabel *label_title_4;
|
||||||
QGroupBox *groupBox_2;
|
QGroupBox *groupBox_2;
|
||||||
QLabel *label_explosure_2;
|
QLabel *label_explosure_2;
|
||||||
@ -90,6 +95,7 @@ public:
|
|||||||
QGroupBox *groupBox_3;
|
QGroupBox *groupBox_3;
|
||||||
QPushButton *btn_test_single;
|
QPushButton *btn_test_single;
|
||||||
QPushButton *btn_stop_test;
|
QPushButton *btn_stop_test;
|
||||||
|
QWidget *tab_4;
|
||||||
|
|
||||||
void setupUi(QWidget *Widget)
|
void setupUi(QWidget *Widget)
|
||||||
{
|
{
|
||||||
@ -198,21 +204,31 @@ public:
|
|||||||
btn_start = new QPushButton(groupBox_7);
|
btn_start = new QPushButton(groupBox_7);
|
||||||
btn_start->setObjectName("btn_start");
|
btn_start->setObjectName("btn_start");
|
||||||
btn_start->setMinimumSize(QSize(70, 200));
|
btn_start->setMinimumSize(QSize(70, 200));
|
||||||
|
btn_start->setStyleSheet(QString::fromUtf8("font: 700 40pt \"Microsoft YaHei UI\";"));
|
||||||
|
|
||||||
verticalLayout_3->addWidget(btn_start);
|
verticalLayout_3->addWidget(btn_start);
|
||||||
|
|
||||||
btn_take_photos = new QPushButton(groupBox_7);
|
btn_take_photos = new QPushButton(groupBox_7);
|
||||||
btn_take_photos->setObjectName("btn_take_photos");
|
btn_take_photos->setObjectName("btn_take_photos");
|
||||||
btn_take_photos->setMinimumSize(QSize(70, 200));
|
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);
|
verticalLayout_3->addWidget(btn_take_photos);
|
||||||
|
|
||||||
btn_stop = new QPushButton(groupBox_7);
|
btn_stop = new QPushButton(groupBox_7);
|
||||||
btn_stop->setObjectName("btn_stop");
|
btn_stop->setObjectName("btn_stop");
|
||||||
btn_stop->setMinimumSize(QSize(70, 200));
|
btn_stop->setMinimumSize(QSize(70, 200));
|
||||||
|
btn_stop->setStyleSheet(QString::fromUtf8("font: 700 40pt \"Microsoft YaHei UI\";"));
|
||||||
|
|
||||||
verticalLayout_3->addWidget(btn_stop);
|
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);
|
verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Expanding);
|
||||||
|
|
||||||
verticalLayout_3->addItem(verticalSpacer);
|
verticalLayout_3->addItem(verticalSpacer);
|
||||||
@ -240,19 +256,26 @@ public:
|
|||||||
|
|
||||||
horizontalLayout_4->addItem(horizontalSpacer);
|
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 = new QCheckBox(frame);
|
||||||
img_1_mirror->setObjectName("img_1_mirror");
|
img_1_mirror->setObjectName("img_1_mirror");
|
||||||
img_1_mirror->setStyleSheet(QString::fromUtf8("font: 12pt \"Microsoft YaHei UI\";"));
|
img_1_mirror->setStyleSheet(QString::fromUtf8("font: 12pt \"Microsoft YaHei UI\";"));
|
||||||
|
|
||||||
horizontalLayout_4->addWidget(img_1_mirror);
|
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);
|
verticalLayout_2->addWidget(frame);
|
||||||
|
|
||||||
@ -285,6 +308,20 @@ public:
|
|||||||
|
|
||||||
horizontalLayout_5->addItem(horizontalSpacer_2);
|
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 = new QCheckBox(frame_2);
|
||||||
img_0_mirror->setObjectName("img_0_mirror");
|
img_0_mirror->setObjectName("img_0_mirror");
|
||||||
img_0_mirror->setStyleSheet(QString::fromUtf8("font: 12pt \"Microsoft YaHei UI\";"));
|
img_0_mirror->setStyleSheet(QString::fromUtf8("font: 12pt \"Microsoft YaHei UI\";"));
|
||||||
@ -292,13 +329,6 @@ public:
|
|||||||
|
|
||||||
horizontalLayout_5->addWidget(img_0_mirror);
|
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);
|
verticalLayout_2->addWidget(frame_2);
|
||||||
|
|
||||||
@ -324,46 +354,70 @@ public:
|
|||||||
tab_3->setObjectName("tab_3");
|
tab_3->setObjectName("tab_3");
|
||||||
label_title_3 = new QLabel(tab_3);
|
label_title_3 = new QLabel(tab_3);
|
||||||
label_title_3->setObjectName("label_title_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;
|
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->setFont(font1);
|
||||||
|
label_title_3->setStyleSheet(QString::fromUtf8("font: 700 48pt \"Microsoft YaHei UI\";"));
|
||||||
groupBox_4 = new QGroupBox(tab_3);
|
groupBox_4 = new QGroupBox(tab_3);
|
||||||
groupBox_4->setObjectName("groupBox_4");
|
groupBox_4->setObjectName("groupBox_4");
|
||||||
groupBox_4->setGeometry(QRect(10, 60, 341, 191));
|
groupBox_4->setGeometry(QRect(30, 130, 771, 591));
|
||||||
label_delaytime = new QLabel(groupBox_4);
|
groupBox_4->setStyleSheet(QString::fromUtf8("font: 700 40pt \"Microsoft YaHei UI\";\n"
|
||||||
label_delaytime->setObjectName("label_delaytime");
|
"border-color: rgb(0, 0, 0);"));
|
||||||
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));
|
|
||||||
btn_set_lower = new QPushButton(groupBox_4);
|
btn_set_lower = new QPushButton(groupBox_4);
|
||||||
btn_set_lower->setObjectName("btn_set_lower");
|
btn_set_lower->setObjectName("btn_set_lower");
|
||||||
btn_set_lower->setGeometry(QRect(250, 160, 61, 23));
|
btn_set_lower->setGeometry(QRect(430, 410, 231, 141));
|
||||||
btn_exit = new QPushButton(tab_3);
|
layoutWidget = new QWidget(groupBox_4);
|
||||||
btn_exit->setObjectName("btn_exit");
|
layoutWidget->setObjectName("layoutWidget");
|
||||||
btn_exit->setGeometry(QRect(660, 490, 75, 23));
|
layoutWidget->setGeometry(QRect(460, 120, 181, 241));
|
||||||
tabWidget->addTab(tab_3, QString());
|
verticalLayout_4 = new QVBoxLayout(layoutWidget);
|
||||||
tab_4 = new QWidget();
|
verticalLayout_4->setObjectName("verticalLayout_4");
|
||||||
tab_4->setObjectName("tab_4");
|
verticalLayout_4->setContentsMargins(0, 0, 0, 0);
|
||||||
label_title_4 = new QLabel(tab_4);
|
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->setObjectName("label_title_4");
|
||||||
label_title_4->setGeometry(QRect(50, 30, 91, 21));
|
label_title_4->setGeometry(QRect(920, 150, 91, 21));
|
||||||
groupBox_2 = new QGroupBox(tab_4);
|
groupBox_2 = new QGroupBox(tab_3);
|
||||||
groupBox_2->setObjectName("groupBox_2");
|
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 = new QLabel(groupBox_2);
|
||||||
label_explosure_2->setObjectName("label_explosure_2");
|
label_explosure_2->setObjectName("label_explosure_2");
|
||||||
label_explosure_2->setGeometry(QRect(30, 40, 31, 16));
|
label_explosure_2->setGeometry(QRect(30, 40, 31, 16));
|
||||||
@ -376,15 +430,18 @@ public:
|
|||||||
btn_stop_single = new QPushButton(groupBox_2);
|
btn_stop_single = new QPushButton(groupBox_2);
|
||||||
btn_stop_single->setObjectName("btn_stop_single");
|
btn_stop_single->setObjectName("btn_stop_single");
|
||||||
btn_stop_single->setGeometry(QRect(240, 40, 75, 23));
|
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->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 = new QPushButton(groupBox_3);
|
||||||
btn_test_single->setObjectName("btn_test_single");
|
btn_test_single->setObjectName("btn_test_single");
|
||||||
btn_test_single->setGeometry(QRect(60, 40, 75, 23));
|
btn_test_single->setGeometry(QRect(60, 40, 75, 23));
|
||||||
btn_stop_test = new QPushButton(groupBox_3);
|
btn_stop_test = new QPushButton(groupBox_3);
|
||||||
btn_stop_test->setObjectName("btn_stop_test");
|
btn_stop_test->setObjectName("btn_stop_test");
|
||||||
btn_stop_test->setGeometry(QRect(210, 40, 75, 23));
|
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());
|
tabWidget->addTab(tab_4, QString());
|
||||||
|
|
||||||
horizontalLayout->addWidget(tabWidget);
|
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_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_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_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));
|
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_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());
|
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));
|
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_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());
|
camera_0_img->setText(QString());
|
||||||
tabWidget->setTabText(tabWidget->indexOf(tab_2), QCoreApplication::translate("Widget", "Tab 2", nullptr));
|
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));
|
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));
|
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_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->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));
|
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));
|
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));
|
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));
|
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));
|
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_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));
|
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));
|
tabWidget->setTabText(tabWidget->indexOf(tab_4), QCoreApplication::translate("Widget", "Tab 4", nullptr));
|
||||||
} // retranslateUi
|
} // retranslateUi
|
||||||
|
|
||||||
|
|||||||
194
widget.cpp
194
widget.cpp
@ -72,8 +72,8 @@ Widget::~Widget()
|
|||||||
void Widget::refreshImage()
|
void Widget::refreshImage()
|
||||||
{
|
{
|
||||||
// refresh Image 1 and image 0
|
// refresh Image 1 and image 0
|
||||||
refreshSingleImage(0, this->ui->img_0_overlay->isChecked(), this->ui->img_0_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->img_1_overlay->isChecked(), this->ui->img_1_mirror->isChecked());
|
refreshSingleImage(1, this->ui->mtx_1_overlay->isChecked(), this->ui->dl_1_overlay->isChecked(), this->ui->img_1_mirror->isChecked());
|
||||||
// refresh buttons
|
// refresh buttons
|
||||||
this->ui->btn_start->setEnabled(!this->isCamRunning);
|
this->ui->btn_start->setEnabled(!this->isCamRunning);
|
||||||
this->ui->btn_stop->setEnabled(this->isCamRunning);
|
this->ui->btn_stop->setEnabled(this->isCamRunning);
|
||||||
@ -96,7 +96,7 @@ void Widget::refreshImage()
|
|||||||
this->ui->lab_info->setText(info);
|
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的有效性
|
// 验证摄像头ID的有效性
|
||||||
if (camera_id < 0 || camera_id >= 2) { // 假设只有两个摄像头
|
if (camera_id < 0 || camera_id >= 2) { // 假设只有两个摄像头
|
||||||
@ -104,12 +104,11 @@ void Widget::refreshSingleImage(int camera_id, bool overlay_result, bool mirror)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 定义每个摄像头对应的 QLabel
|
||||||
|
QLabel* cameraLabels[2] = { ui->camera_0_img, ui->camera_1_img };
|
||||||
// 定义每个摄像头对应的变量数组
|
// 定义每个摄像头对应的变量数组
|
||||||
QMutex* dispPicMutexes[2] = { &gDispPicMutex0, &gDispPicMutex1 };
|
QMutex* dispPicMutexes[2] = { &gDispPicMutex0, &gDispPicMutex1 };
|
||||||
MIL_ID dispCurrentPicIds[2] = { gDispCurrentPicId0, gDispCurrentPicId1 };
|
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];
|
QMutex* currentDispMutex = dispPicMutexes[camera_id];
|
||||||
@ -130,24 +129,91 @@ void Widget::refreshSingleImage(int camera_id, bool overlay_result, bool mirror)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (current_id == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<std::vector<uint8_t>> dl_mask;
|
||||||
|
std::vector<std::vector<uint8_t>> traditional_mask;
|
||||||
|
{
|
||||||
|
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_result)
|
if (overlay_dl_result)
|
||||||
{
|
{
|
||||||
QMutex* currentMaskMutex = maskMutexes[camera_id];
|
if (!dl_mask.empty() && !dl_mask[0].empty())
|
||||||
MIL_ID mask_id;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
QMutexLocker locker(currentMaskMutex);
|
// 将二维 vector 转换为 cv::Mat
|
||||||
mask_id = maskIds[camera_id];
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask_id != 0) {
|
if (!dl_mask_mat.empty())
|
||||||
cv::Mat mask = ImageUtils::mil2Mat(mask_id);
|
{
|
||||||
if (!mask.empty()) {
|
// 调整掩膜尺寸以匹配图像尺寸
|
||||||
img = ImageUtils::overlayResultOnInput(img, mask, 0.5);
|
if (dl_mask_mat.size() != img.size()) {
|
||||||
|
cv::resize(dl_mask_mat, dl_mask_mat, img.size(), 0, 0, cv::INTER_NEAREST);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
qWarning() << "Failed to convert MIL mask to Mat for Camera ID:" << camera_id;
|
// 确保掩膜为二值图像
|
||||||
|
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标签
|
// 更新UI标签
|
||||||
cameraLabels[camera_id]->setPixmap(scaledPixmap);
|
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()
|
void Widget::on_pushButton_2_clicked()
|
||||||
{
|
{
|
||||||
SaveImg_Flag = 1;
|
SaveImg_Flag = 1;
|
||||||
@ -243,6 +390,11 @@ void Widget::on_btn_stop_clicked()
|
|||||||
void Widget::on_btn_start_clicked()
|
void Widget::on_btn_start_clicked()
|
||||||
{
|
{
|
||||||
this->isCamRunning = true;
|
this->isCamRunning = true;
|
||||||
|
// 热身两个工作者
|
||||||
|
for(int i = 0; i < 2; ++i)
|
||||||
|
{
|
||||||
|
g_runner_array[i]->warm_up();
|
||||||
|
}
|
||||||
// 启动检测工作者线程
|
// 启动检测工作者线程
|
||||||
for(int i = 0; i < 2; ++i)
|
for(int i = 0; i < 2; ++i)
|
||||||
{
|
{
|
||||||
@ -265,3 +417,9 @@ void Widget::on_btn_take_photos_released()
|
|||||||
SaveImg_Flag = false;
|
SaveImg_Flag = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Widget::on_btn_quit_clicked()
|
||||||
|
{
|
||||||
|
qApp->quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
4
widget.h
4
widget.h
@ -27,7 +27,7 @@ public slots:
|
|||||||
|
|
||||||
private 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();
|
void on_pushButton_2_clicked();
|
||||||
|
|
||||||
@ -41,6 +41,8 @@ private slots:
|
|||||||
|
|
||||||
void on_btn_take_photos_released();
|
void on_btn_take_photos_released();
|
||||||
|
|
||||||
|
void on_btn_quit_clicked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::Widget *ui;
|
Ui::Widget *ui;
|
||||||
|
|
||||||
|
|||||||
273
widget.ui
273
widget.ui
@ -263,6 +263,9 @@
|
|||||||
<height>200</height>
|
<height>200</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">font: 700 40pt "Microsoft YaHei UI";</string>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>开始分选</string>
|
<string>开始分选</string>
|
||||||
</property>
|
</property>
|
||||||
@ -276,6 +279,9 @@
|
|||||||
<height>200</height>
|
<height>200</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">font: 700 40pt "Microsoft YaHei UI";</string>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>抓取图片</string>
|
<string>抓取图片</string>
|
||||||
</property>
|
</property>
|
||||||
@ -289,11 +295,30 @@
|
|||||||
<height>200</height>
|
<height>200</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">font: 700 40pt "Microsoft YaHei UI";</string>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>停止分选</string>
|
<string>停止分选</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</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 "Microsoft YaHei UI";</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>退出系统</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
@ -345,6 +370,32 @@
|
|||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="mtx_1_overlay">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">font: 12pt "Microsoft YaHei UI";</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 "Microsoft YaHei UI";</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>智检结果</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="img_1_mirror">
|
<widget class="QCheckBox" name="img_1_mirror">
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
@ -355,19 +406,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="img_1_overlay">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="styleSheet">
|
|
||||||
<string notr="true">font: 12pt "Microsoft YaHei UI";</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>识别结果</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -423,6 +461,32 @@ border: 4px solid black;</string>
|
|||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="mtx_0_overlay">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">font: 12pt "Microsoft YaHei UI";</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 "Microsoft YaHei UI";</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>智检结果</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="img_0_mirror">
|
<widget class="QCheckBox" name="img_0_mirror">
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
@ -436,19 +500,6 @@ border: 4px solid black;</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="img_0_overlay">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="styleSheet">
|
|
||||||
<string notr="true">font: 12pt "Microsoft YaHei UI";</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>识别结果</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -486,15 +537,21 @@ border: 4px solid black;</string>
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>10</y>
|
<y>10</y>
|
||||||
<width>171</width>
|
<width>421</width>
|
||||||
<height>41</height>
|
<height>81</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<pointsize>20</pointsize>
|
<family>Microsoft YaHei UI</family>
|
||||||
|
<pointsize>48</pointsize>
|
||||||
|
<italic>false</italic>
|
||||||
|
<bold>true</bold>
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">font: 700 48pt "Microsoft YaHei UI";</string>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>参数设置界面</string>
|
<string>参数设置界面</string>
|
||||||
</property>
|
</property>
|
||||||
@ -502,121 +559,92 @@ border: 4px solid black;</string>
|
|||||||
<widget class="QGroupBox" name="groupBox_4">
|
<widget class="QGroupBox" name="groupBox_4">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>10</x>
|
<x>30</x>
|
||||||
<y>60</y>
|
<y>130</y>
|
||||||
<width>341</width>
|
<width>771</width>
|
||||||
<height>191</height>
|
<height>591</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">font: 700 40pt "Microsoft YaHei UI";
|
||||||
|
border-color: rgb(0, 0, 0);</string>
|
||||||
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>下位机参数</string>
|
<string>下位机参数</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QLabel" name="label_delaytime">
|
<widget class="QPushButton" name="btn_set_lower">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>40</x>
|
<x>430</x>
|
||||||
<y>40</y>
|
<y>410</y>
|
||||||
<width>53</width>
|
<width>231</width>
|
||||||
<height>15</height>
|
<height>141</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<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">
|
<property name="text">
|
||||||
<string>延迟时间</string>
|
<string>延迟时间</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
<widget class="QLabel" name="label_encoder">
|
<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">
|
<property name="text">
|
||||||
<string>相机分频系数</string>
|
<string>相机分频系数</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
<widget class="QLabel" name="label_encoder_2">
|
<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">
|
<property name="text">
|
||||||
<string>喷阀分频系数</string>
|
<string>喷阀分频系数</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QSpinBox" name="spinbox_delaytime">
|
</item>
|
||||||
<property name="geometry">
|
</layout>
|
||||||
<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>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>确定</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
</widget>
|
||||||
</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">
|
<widget class="QLabel" name="label_title_4">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>50</x>
|
<x>920</x>
|
||||||
<y>30</y>
|
<y>150</y>
|
||||||
<width>91</width>
|
<width>91</width>
|
||||||
<height>21</height>
|
<height>21</height>
|
||||||
</rect>
|
</rect>
|
||||||
@ -628,8 +656,8 @@ border: 4px solid black;</string>
|
|||||||
<widget class="QGroupBox" name="groupBox_2">
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>110</x>
|
<x>1050</x>
|
||||||
<y>120</y>
|
<y>240</y>
|
||||||
<width>331</width>
|
<width>331</width>
|
||||||
<height>91</height>
|
<height>91</height>
|
||||||
</rect>
|
</rect>
|
||||||
@ -690,8 +718,8 @@ border: 4px solid black;</string>
|
|||||||
<widget class="QGroupBox" name="groupBox_3">
|
<widget class="QGroupBox" name="groupBox_3">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>110</x>
|
<x>1050</x>
|
||||||
<y>270</y>
|
<y>420</y>
|
||||||
<width>331</width>
|
<width>331</width>
|
||||||
<height>91</height>
|
<height>91</height>
|
||||||
</rect>
|
</rect>
|
||||||
@ -727,6 +755,11 @@ border: 4px solid black;</string>
|
|||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab_4">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Tab 4</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user