四象巅峰

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> #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);
} }

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

@ -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)
if (overlay_result) return;
std::vector<std::vector<uint8_t>> dl_mask;
std::vector<std::vector<uint8_t>> traditional_mask;
{ {
QMutex* currentMaskMutex = maskMutexes[camera_id]; QMutexLocker locker(&g_detection_result[camera_id].mutex);
MIL_ID mask_id; 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); // 将二维 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);
if (mask_id != 0) { for (int i = 0; i < rows; ++i)
cv::Mat mask = ImageUtils::mil2Mat(mask_id); {
if (!mask.empty()) { if (dl_mask[i].size() != cols) {
img = ImageUtils::overlayResultOnInput(img, mask, 0.5); 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标签 // 更新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();
}

View File

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

295
widget.ui
View File

@ -263,6 +263,9 @@
<height>200</height> <height>200</height>
</size> </size>
</property> </property>
<property name="styleSheet">
<string notr="true">font: 700 40pt &quot;Microsoft YaHei UI&quot;;</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 &quot;Microsoft YaHei UI&quot;;</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 &quot;Microsoft YaHei UI&quot;;</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 &quot;Microsoft YaHei UI&quot;;</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 &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> <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 &quot;Microsoft YaHei UI&quot;;</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 &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> <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 &quot;Microsoft YaHei UI&quot;;</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 &quot;Microsoft YaHei UI&quot;;</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 &quot;Microsoft YaHei UI&quot;;
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">
<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"> <widget class="QPushButton" name="btn_set_lower">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>250</x> <x>430</x>
<y>160</y> <y>410</y>
<width>61</width> <width>231</width>
<height>23</height> <height>141</height>
</rect> </rect>
</property> </property>
<property name="text"> <property name="text">
<string>确定</string> <string>设定参数</string>
</property> </property>
</widget> </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>
<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>