Compare commits

...

5 Commits

Author SHA1 Message Date
703b1430f6 双相机显示与mask合并 2024-12-23 18:12:44 +08:00
f56b876119 ugly ui but full functions 2024-12-23 01:04:07 +08:00
50b8c37a9c relative path version 2024-12-22 22:29:54 +08:00
18e2f3080d dual cam verssion 2024-12-22 21:28:09 +08:00
fd7df4545e double mask + memory overflow 7 2024-12-22 17:17:07 +08:00
18 changed files with 3214 additions and 1209 deletions

3
.gitignore vendored
View File

@ -3,6 +3,7 @@ build
release release
debug debug
.qtc_clangd .qtc_clangd
Makefile* Makefile.*
*.pro.user* *.pro.user*
*.pro.user
.idea .idea

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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 0 // 是否打印处理时间 #define DebugDetectionTime 1 // 是否打印处理时间
#define DebugLowerMacCOM 0 // 是否打印和下位机通讯的相关信息 #define DebugLowerMacCOM 0 // 是否打印和下位机通讯的相关信息
camera::camera() {} camera::camera() {}
@ -46,7 +46,7 @@ ONNXRunner runner;
std::map<std::string, int> params; std::map<std::string, int> params;
int dual_cam_offset_y = 89; // 双相机之间的上下偏移值 int dual_cam_offset_y = 0; // 双相机之间的上下偏移值
int widthBlocks = 20; // 输出的喷阀通道数 int widthBlocks = 20; // 输出的喷阀通道数
int heightBlocks = 512; // 输出的Mask高度 int heightBlocks = 512; // 输出的Mask高度
int sizeThreshold = 20; // 转化为喷阀的每块要求像素个数 int sizeThreshold = 20; // 转化为喷阀的每块要求像素个数
@ -84,8 +84,9 @@ bool iniCamera()
MsysAlloc(M_DEFAULT, M_SYSTEM_RADIENTEVCL, M_DEV0, M_DEFAULT, &MilSystem); MsysAlloc(M_DEFAULT, M_SYSTEM_RADIENTEVCL, M_DEV0, M_DEFAULT, &MilSystem);
//分配相机 digitier //分配相机 digitier
MdigAlloc(MilSystem,M_DEV0,MIL_TEXT("C:/Users/Administrator/Desktop/cotton_double/config/1.dcf"),M_DEFAULT,&MilDigitizer0); QString config_dir = getConfigDirectory();
MdigAlloc(MilSystem,M_DEV1,MIL_TEXT("C:/Users/Administrator/Desktop/cotton_double/config/2.dcf"),M_DEFAULT,&MilDigitizer1); MdigAlloc(MilSystem,M_DEV0,(config_dir + "/1.dcf").toStdWString(), M_DEFAULT,&MilDigitizer0);
MdigAlloc(MilSystem,M_DEV1,(config_dir + "/2.dcf").toStdWString(), M_DEFAULT,&MilDigitizer1);
//给MilImage分配空间 //给MilImage分配空间
MbufAllocColor(MilSystem,3,BufSizeX0,BufSizeY0,8 + M_UNSIGNED,M_IMAGE + M_GRAB + M_PROC,&MilImage0); MbufAllocColor(MilSystem,3,BufSizeX0,BufSizeY0,8 + M_UNSIGNED,M_IMAGE + M_GRAB + M_PROC,&MilImage0);
@ -95,7 +96,7 @@ bool iniCamera()
MbufAllocColor(MilSystem,3,BufSizeX0,BufSizeY0,8 + M_UNSIGNED,M_IMAGE + M_GRAB + M_PROC,&detection_result0); MbufAllocColor(MilSystem,3,BufSizeX0,BufSizeY0,8 + M_UNSIGNED,M_IMAGE + M_GRAB + M_PROC,&detection_result0);
MbufAllocColor(MilSystem,3,BufSizeX1,BufSizeY1,8 + M_UNSIGNED,M_IMAGE + M_GRAB + M_PROC,&detection_result1); MbufAllocColor(MilSystem,3,BufSizeX1,BufSizeY1,8 + M_UNSIGNED,M_IMAGE + M_GRAB + M_PROC,&detection_result1);
MbufAllocColor(MilSystem,3,BufSizeX0,BufSizeY0,8 + M_UNSIGNED,M_IMAGE + M_GRAB + M_PROC,&MilImage_Onnx0); MbufAllocColor(MilSystem,3,BufSizeX0,BufSizeY0,8 + M_UNSIGNED,M_IMAGE + M_GRAB + M_PROC,&MilImage_Onnx0);
MbufAllocColor(MilSystem,3,BufSizeX1,BufSizeY1,8 + M_UNSIGNED,M_IMAGE + M_GRAB + M_PROC,&MilImage_Onnx1);; MbufAllocColor(MilSystem,3,BufSizeX1,BufSizeY1,8 + M_UNSIGNED,M_IMAGE + M_GRAB + M_PROC,&MilImage_Onnx1);
//给每一个bufferlist分配空间 //给每一个bufferlist分配空间
@ -158,17 +159,22 @@ MIL_INT ProcessingFunction0(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr)
} }
if(SaveImg_Flag) if (SaveImg_Flag)
{ {
//拷贝存图图像 // 拷贝存图图像
MbufCopy(ModifiedBufferId0,MilImage0); MbufCopy(ModifiedBufferId0, MilImage0);
//Mil保存路径 cv::Mat img = ImageUtils::mil2Mat(MilImage0);
QString MilImgPath = QString("C:/Users/Pc/Desktop/cotton_double2/Img1/%1.bmp").arg(FuncCount0);
MIL_STRING MilImagePath = MilImgPath.toStdWString(); // 将图像数据推入存储队列
MbufExport(MilImagePath,M_BMP,MilImage0); ImageData data;
qDebug()<<"回调1成功存储照片:"<<FuncCount0<<""; data.camera_id = 0;
data.image = img.clone(); // 确保图像数据被复制
g_storageQueue.enqueue(data);
qDebug() << "Callback0: Enqueued image for camera 0";
FuncCount0++; FuncCount0++;
} }
#if(GlobalDebug) #if(GlobalDebug)
qDebug()<<"回调1"; qDebug()<<"回调1";
#endif #endif
@ -186,6 +192,15 @@ MIL_INT ProcessingFunction0(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr)
//艳丽检测mask //艳丽检测mask
high_sat_detect(MimFlipDedtination, detection_result0, params); high_sat_detect(MimFlipDedtination, detection_result0, params);
//Onnx检测mask
// MbufCopy(ModifiedBufferId0,MilImage_Onnx0);
// cv::Mat image = ImageUtils::mil2Mat(MilImage_Onnx0);
// cv::Mat Img_Onnx;
// std::vector<Detection> result = runner.predict(image);
// Img_Onnx = runner.postProcess(result, image);
// std::vector<std::vector<uint8_t>> mask_Onnx1 = generateMaskFromImage2(Img_Onnx, widthBlocks, heightBlocks, sizeThreshold);
// Update the current Img MIl id // Update the current Img MIl id
{ {
QMutexLocker locker(&gMaskMutex0); QMutexLocker locker(&gMaskMutex0);
@ -193,48 +208,16 @@ MIL_INT ProcessingFunction0(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr)
} }
auto [mask_tmp, newTail] = generateMaskWithTail(detection_result0, tail_0, widthBlocks, heightBlocks, sizeThreshold, rowRange, skipLeftCols, skipRightCols); auto [mask_tmp, newTail] = generateMaskWithTail(detection_result0, tail_0, widthBlocks, heightBlocks, sizeThreshold, rowRange, skipLeftCols, skipRightCols);
tail_0 = newTail; tail_0 = newTail;
mask_0 = mask_tmp;
bool isReady;
vector<vector<uint8_t>> merged_mask; vector<vector<uint8_t>> merged_mask;
vector<vector<uint8_t>> mask_tail;
{ merged_mask = ImageUtils::mergeMasks(mask_tmp, mask_tmp); // merge the result of onnx and high sat
QMutexLocker locker_self(&imgDetectionReadyMutex);
imgDetectionReady0 = true;
// QMutexLocker locker_other(&imgDetectionReady1Mutex);
isReady = imgDetectionReady0 & imgDetectionReady1;
if(isReady)
{
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);
}
}
// 没有两个都完成就不发送
if(!isReady)
return 0;
// 发送前的处理 mask_0 = merged_mask;
// 将每个结果左右扩展扩展半径默认为1
auto mask_expaned = expandMaskHorizontally(merged_mask, expansionRaidus); detection_ready.release();
// 将结果的左右补充上0让物体大小符合要求 MbufFree(detection_result0);
PadColumns(mask_expaned,padLeft,padRight,0);
//将mask扩展到合适的大小
std::vector<std::vector<uint8_t>> mask_Total = expandArray(mask_expaned,64);
// save masks
#if(GlobalDebug && DebugDetection)
VectorToImg(mask_1,"C:/Users/Pc/Desktop/img/mask" + std::to_string(FuncCount1) + ".bmp");
VectorToImg(mask_1,"C:/Users/Pc/Desktop/img/mask_ignored" + std::to_string(FuncCount1) + ".bmp");
VectorToImg(mask_Total,"C:/Users/Pc/Desktop/img/mask_expended" + std::to_string(FuncCount1) + ".bmp");
#endif
// 发送到下位机
bool result_Low = get_valve_data(mask_Total);
if(!result_Low)
{
qWarning()<<"下位机发送失败";
}
return 0; return 0;
} }
@ -255,23 +238,26 @@ MIL_INT ProcessingFunction1(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr)
// Update the current Img MIl id // Update the current Img MIl id
{ {
QMutexLocker locker(&gDispPicMutex1); QMutexLocker locker(&gDispPicMutex1);
gDispCurrentPicId1 = ModifiedBufferId1; gDispCurrentPicId1 = ModifiedBufferId1;
} }
if(SaveImg_Flag) if (SaveImg_Flag)
{ {
//拷贝存图数据 // 拷贝存图图像
MbufCopy(ModifiedBufferId1,MilImage1); MbufCopy(ModifiedBufferId1, MilImage1);
//Mil保存路径 cv::Mat img = ImageUtils::mil2Mat(MilImage1);
QString MilImgPath = QString("C:/Users/Pc/Desktop/cotton_double2/Img2/%1.bmp").arg(FuncCount1);
MIL_STRING MilImagePath = MilImgPath.toStdWString(); // 将图像数据推入存储队列
MbufExport(MilImagePath,M_BMP,MilImage1); ImageData data;
qDebug()<<"回调2成功存储照片:"<<FuncCount1<<""; data.camera_id = 1;
data.image = img.clone(); // 确保图像数据被复制
g_storageQueue.enqueue(data);
qDebug() << "Callback1: Enqueued image for camera 1";
FuncCount1++; FuncCount1++;
} }
#if (GlobalDebug) #if (GlobalDebug)
qDebug()<<"回调2"; qDebug()<<"回调2";
#endif #endif
@ -286,13 +272,13 @@ MIL_INT ProcessingFunction1(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr)
MimResize(MilImage_Color1, MimResizedestination, 0.5, 1 , M_DEFAULT); MimResize(MilImage_Color1, MimResizedestination, 0.5, 1 , M_DEFAULT);
#if(GlobalDebug && DebugDetectionTime) #if(GlobalDebug && DebugDetectionTime)
Timer timer2; Timer timer2;
#endif #endif
//艳丽检测mask //艳丽检测mask
high_sat_detect(MimResizedestination, detection_result1, params); high_sat_detect(MimResizedestination, detection_result1, params);
#if(GlobalDebug && DebugDetectionTime) #if(GlobalDebug && DebugDetectionTime)
timer2.printElapsedTime("Algorithm Spent: "); timer2.printElapsedTime("Algorithm Spent: ");
#endif #endif
@ -313,25 +299,12 @@ MIL_INT ProcessingFunction1(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr)
tail_1 = newTail; tail_1 = newTail;
mask_1 = mask_tmp; mask_1 = mask_tmp;
bool isReady; detection_ready.acquire();
vector<vector<uint8_t>> merged_mask; vector<vector<uint8_t>> merged_mask;
vector<vector<uint8_t>> mask_tail; vector<vector<uint8_t>> mask_tail;
{ merged_mask = ImageUtils::mergeMasks(mask_0, mask_1, dual_cam_offset_y);
QMutexLocker locker_self(&imgDetectionReadyMutex); std::tie(merged_mask, mask_tail) = ImageUtils::extractROI(merged_mask, 0, 0, widthBlocks, heightBlocks);
imgDetectionReady1 = true;
// QMutexLocker locker_other(&imgDetectionReady0Mutex);
isReady = imgDetectionReady0 & imgDetectionReady1;
if(isReady)
{
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);
}
}
// 没有两个都完成就不发送
if(!isReady)
return 0;
// 发送前的处理 // 发送前的处理
// 将每个结果左右扩展扩展半径默认为1 // 将每个结果左右扩展扩展半径默认为1
@ -345,7 +318,7 @@ MIL_INT ProcessingFunction1(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr)
VectorToImg(mask_1,"C:/Users/Pc/Desktop/img/mask" + std::to_string(FuncCount1) + ".bmp"); VectorToImg(mask_1,"C:/Users/Pc/Desktop/img/mask" + std::to_string(FuncCount1) + ".bmp");
VectorToImg(mask_1,"C:/Users/Pc/Desktop/img/mask_ignored" + std::to_string(FuncCount1) + ".bmp"); VectorToImg(mask_1,"C:/Users/Pc/Desktop/img/mask_ignored" + std::to_string(FuncCount1) + ".bmp");
VectorToImg(mask_Total,"C:/Users/Pc/Desktop/img/mask_expended" + std::to_string(FuncCount1) + ".bmp"); VectorToImg(mask_Total,"C:/Users/Pc/Desktop/img/mask_expended" + std::to_string(FuncCount1) + ".bmp");
#endif #endif \
// 发送到下位机 // 发送到下位机
bool result_Low = get_valve_data(mask_Total); bool result_Low = get_valve_data(mask_Total);
if(!result_Low) if(!result_Low)
@ -353,11 +326,12 @@ MIL_INT ProcessingFunction1(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr)
qWarning()<<"下位机发送失败"; qWarning()<<"下位机发送失败";
} }
#if(GlobalDebug && DebugDetectionTime) #if(GlobalDebug && DebugDetectionTime)
timer_detection_time.printElapsedTime("Time of Processing From Get into Ca" timer_detection_time.printElapsedTime("Time of Processing From Get into Ca"
"..0llBack to Sent to Lower Mac"); "..0llBack to Sent to Lower Mac");
#endif #endif
MbufFree(detection_result1);
return 0; return 0;
} }
@ -383,8 +357,6 @@ bool DestoryCamera()
MbufFree(MilImage_Color1); MbufFree(MilImage_Color1);
MbufFree(MilImage_Onnx0); MbufFree(MilImage_Onnx0);
MbufFree(MilImage_Onnx1); MbufFree(MilImage_Onnx1);
MbufFree(detection_result0);
MbufFree(detection_result1);
MdigFree(MilDigitizer0); MdigFree(MilDigitizer0);
MdigFree(MilDigitizer1); MdigFree(MilDigitizer1);
MsysFree(MilSystem); MsysFree(MilSystem);
@ -663,7 +635,7 @@ std::vector<std::vector<uint8_t>> generateMaskFromImage(const MIL_ID& inputImage
// std::cerr << "无法加载图像,请检查路径是否正确: " << imagePath << std::endl; // std::cerr << "无法加载图像,请检查路径是否正确: " << imagePath << std::endl;
// exit(EXIT_FAILURE); // exit(EXIT_FAILURE);
// } // }
cv::Mat image=mil2mat(inputImage); cv::Mat image=ImageUtils::mil2Mat(inputImage);
// 确保图像是二值化的 // 确保图像是二值化的
cv::threshold(image, image, 128, 255, cv::THRESH_BINARY); cv::threshold(image, image, 128, 255, cv::THRESH_BINARY);
@ -743,104 +715,24 @@ std::vector<std::vector<uint8_t>> generateMaskFromImage2(const cv::Mat& image, i
mask[i][j] = true; mask[i][j] = true;
} }
} }
} }
return mask; return mask;
} }
void convert_to_uint8(const MIL_ID& input_img, MIL_ID& output_img) {
MIL_INT size_x = MbufInquire(input_img, M_SIZE_X, M_NULL);
MIL_INT size_y = MbufInquire(input_img, M_SIZE_Y, M_NULL);
MIL_INT channel_num = MbufInquire(input_img, M_SIZE_BAND, M_NULL);
MbufAlloc2d(MilSystem, size_x, size_y, 8 + M_UNSIGNED, M_IMAGE + M_PROC + M_DISP, &output_img);
if(channel_num == 1) {
MimArith(output_img, input_img, output_img, M_ADD);
MimArith(output_img, 255.0, output_img, M_MULT_CONST);
} else if(channel_num == 3) {
MimConvert(input_img, output_img, M_RGB_TO_L);
MimArith(output_img, M_NULL, output_img, M_NOT);
} else {
cout << "Unsupported channel number!" << endl;
}
}
Mat mil2mat(const MIL_ID mil_img) {
// 获取 MIL 图像的宽度、高度和通道数
MIL_INT width, height, channels, bitDepth;
MbufInquire(mil_img, M_SIZE_X, &width);
MbufInquire(mil_img, M_SIZE_Y, &height);
MbufInquire(mil_img, M_SIZE_BAND, &channels);
MbufInquire(mil_img, M_SIZE_BIT, &bitDepth);
if (channels == 1) {
// 单通道图像,直接读取整个缓冲区
Mat grayImage(height, width, CV_8UC1);
if (bitDepth == 1) {
MIL_ID temp_img;
convert_to_uint8(mil_img, temp_img);
MbufGet(temp_img, grayImage.data);
MbufFree(temp_img);
} else {
MbufGet(mil_img, grayImage.data);
}
return grayImage;
}
if (channels == 3) {
// 多通道图像,分通道读取
MIL_ID redChannel, greenChannel, blueChannel;
MbufAlloc2d(MilSystem, width, height, 8 + M_UNSIGNED, M_IMAGE + M_PROC, &redChannel);
MbufAlloc2d(MilSystem, width, height, 8 + M_UNSIGNED, M_IMAGE + M_PROC, &greenChannel);
MbufAlloc2d(MilSystem, width, height, 8 + M_UNSIGNED, M_IMAGE + M_PROC, &blueChannel);
// 将 MIL 图像的各个通道复制到单通道缓冲区
MbufCopyColor(mil_img, redChannel, M_RED);
MbufCopyColor(mil_img, greenChannel, M_GREEN);
MbufCopyColor(mil_img, blueChannel, M_BLUE);
// 分别读取每个通道的数据
Mat redMat(height, width, CV_8UC1);
Mat greenMat(height, width, CV_8UC1);
Mat blueMat(height, width, CV_8UC1);
MbufGet(redChannel, redMat.data);
MbufGet(greenChannel, greenMat.data);
MbufGet(blueChannel, blueMat.data);
// 释放通道缓冲区
MbufFree(redChannel);
MbufFree(greenChannel);
MbufFree(blueChannel);
// 合并通道
std::vector<Mat> bgrChannels = {blueMat, greenMat, redMat};
Mat colorImage;
cv::merge(bgrChannels, colorImage);
return colorImage;
}
// 不支持的通道数
std::cerr << "[Error] Unsupported number of channels: " << channels << std::endl;
return Mat();
}
bool iniColor() bool iniColor()
{ {
read_params_from_file("C:/Users/Administrator/Desktop/cotton_double/config/color_range_config.txt", params); read_params_from_file((getConfigDirectory()+"/color_range_config.txt").toStdString(), params);
return 1; return 1;
} }
bool iniOnnx() bool iniOnnx()
{ {
std::string modelPath = "C:/Users/admin/Desktop/config/dimo_11.14.onnx"; std::string modelPath = (getConfigDirectory() + "/dimo_369_640.onnx").toStdString();
// std::string imagePath = "C:/Users/admin/Desktop/config/463_12.5_M2.bmp";
// cv::Mat image = cv::imread(imagePath);
runner.load(modelPath); runner.load(modelPath);
@ -1004,6 +896,10 @@ bool DestoryLowMac()
bool get_valve_data(std::vector<std::vector<uint8_t>> mask) bool get_valve_data(std::vector<std::vector<uint8_t>> mask)
{ {
if (mask[0].size() % 8 != 0) {
std::cerr << "Error: mask 的第 0 行的列数应该为 8 的倍数。" << std::endl;
return false;
}
uint8_t* mask_buf = new uint8_t[4096 + 8]; // 创建缓冲区大小为3072 + 8 uint8_t* mask_buf = new uint8_t[4096 + 8]; // 创建缓冲区大小为3072 + 8
mask_buf[0] = 0xAA; // 起始标志 mask_buf[0] = 0xAA; // 起始标志
mask_buf[1] = 0x10; // 高位数据长度 (352 字节 -> 0x0160) mask_buf[1] = 0x10; // 高位数据长度 (352 字节 -> 0x0160)
@ -1015,18 +911,14 @@ bool get_valve_data(std::vector<std::vector<uint8_t>> mask)
int idx = 5; // 从 mask_buf[5] 开始存储数据 int idx = 5; // 从 mask_buf[5] 开始存储数据
for (int i = 0; i < 512; i++) // 遍历512行 for (int i = 0; i < 512; i++) // 遍历512行
{ {
uint8_t byte = 0; for (int j = 0; j < int(64 / 8); j++) // 遍历64列
int bit_count = 0; {
for (int j = 0; j < 64; j++) // 遍历64列 uint8_t byte = 0;
{ for (int bit_idx = 0; bit_idx < 8; bit_idx++)
byte = (byte << 1) | (uint8_t)mask[i][j]; // 将每个二进制位加入到字节中
bit_count++;
if (bit_count == 8 || j == 63) // 每8个二进制位打包成一个字节
{ {
mask_buf[idx++] = byte; byte |= (mask[i][ j * 8 + bit_idx] & 0x01) << bit_idx; // 每个字节内,低字节优先
byte = 0; // 重置byte开始下一个字节
bit_count = 0;
} }
mask_buf[idx++] = byte;
} }
} }
@ -1066,11 +958,10 @@ bool get_valve_data(std::vector<std::vector<uint8_t>> mask)
delete[] mask_buf; // 释放内存 delete[] mask_buf; // 释放内存
return 1; return true;
} }
void Start_camera() void Start_camera()
{ {
MdigProcess(MilDigitizer0, MilGrabBufferList0, 20, M_START, M_DEFAULT,ProcessingFunction0, M_NULL); MdigProcess(MilDigitizer0, MilGrabBufferList0, 20, M_START, M_DEFAULT,ProcessingFunction0, M_NULL);
@ -1119,32 +1010,6 @@ std::vector<std::vector<uint8_t> > expandArray(const std::vector<std::vector<uin
return array_total; return array_total;
} }
void VectorToImg(const std::vector<std::vector<uint8_t> > &array, const std::string &image_path)
{
int height = array.size();
int width = array[0].size();
// 创建一个Mat对象来表示图像CV_8UC1表示单通道8位无符号整数类型用于黑白图像
Mat image(height, width, CV_8UC1);
// 遍历二维向量,设置图像像素值
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (array[y][x] == 1)
{
image.at<uchar>(y, x) = 255; // 白色像素对应灰度值255
} else
{
image.at<uchar>(y, x) = 0; // 黑色像素对应灰度值0
}
}
}
// 将图像保存为文件传入的image_path指定保存路径和文件名
imwrite(image_path, image);
}
vector<vector<uint8_t>> generateMask( vector<vector<uint8_t>> generateMask(
const MIL_ID& inputImg, const MIL_ID& inputImg,
@ -1154,7 +1019,7 @@ vector<vector<uint8_t>> generateMask(
int skipLeftCols, int skipLeftCols,
int skipRightCols int skipRightCols
) { ) {
cv::Mat image = mil2mat(inputImg); cv::Mat image = ImageUtils::mil2Mat(inputImg);
// Ensure the image is binary // Ensure the image is binary
cv::threshold(image, image, 128, 255, cv::THRESH_BINARY); cv::threshold(image, image, 128, 255, cv::THRESH_BINARY);

View File

@ -20,7 +20,6 @@
#include <QTcpSocket> #include <QTcpSocket>
#include <QTcpServer> #include <QTcpServer>
#include "globals.h" #include "globals.h"
#include "img_utils.h" #include "img_utils.h"

View File

@ -14,6 +14,7 @@ SOURCES += \
img_utils.cpp \ img_utils.cpp \
main.cpp \ main.cpp \
onnxrunner.cpp \ onnxrunner.cpp \
storageworker.cpp \
widget.cpp widget.cpp
HEADERS += \ HEADERS += \
@ -21,6 +22,7 @@ HEADERS += \
globals.h \ globals.h \
img_utils.h \ img_utils.h \
onnxrunner.h \ onnxrunner.h \
storageworker.h \
widget.h widget.h
FORMS += \ FORMS += \

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject> <!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 15.0.0, 2024-12-21T22:26:46. --> <!-- Written by QtCreator 15.0.0, 2024-12-23T16:03:42. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>

View File

@ -14,7 +14,30 @@ QMutex gMaskMutex1;
MIL_ID gMask1 = 0; MIL_ID gMask1 = 0;
// 双相机结果同步 // 双相机结果同步
QMutex imgDetectionReadyMutex; QSemaphore detection_ready(0);
QMutex imgDetectionReady1Mutex;
bool imgDetectionReady0 = false;
bool imgDetectionReady1 = false; QString getSaveDirectory() {
QDir appDir(QCoreApplication::applicationDirPath());
QString saveDir = appDir.filePath("images");
if (!appDir.exists(saveDir)) {
appDir.mkdir("images"); // 创建目录,如果不存在
}
return saveDir;
}
QString getConfigDirectory() {
QDir appDir(QCoreApplication::applicationDirPath());
QString saveDir = appDir.filePath("config");
if (!appDir.exists(saveDir)) {
appDir.mkdir("config"); // 创建目录,如果不存在
}
return saveDir;
}
ThreadSafeQueue<ImageData> g_storageQueue;

View File

@ -5,6 +5,9 @@
#include <MIL.h> #include <MIL.h>
#include <QMutex> #include <QMutex>
#include <opencv2/opencv.hpp> #include <opencv2/opencv.hpp>
#include <QSemaphore>
#include <QDir>
#include <QCoreApplication>
// 图片显示0 // 图片显示0
extern QMutex gDispPicMutex0; extern QMutex gDispPicMutex0;
@ -20,9 +23,60 @@ extern MIL_ID gMask0;
extern QMutex gMaskMutex1; extern QMutex gMaskMutex1;
extern MIL_ID gMask1; extern MIL_ID gMask1;
extern QMutex imgDetectionReadyMutex; extern QSemaphore detection_ready;
extern QMutex imgDetectionReady1Mutex;
extern bool imgDetectionReady0;
extern bool imgDetectionReady1;
QString getSaveDirectory();
QString getConfigDirectory();
// 定义一个结构体来存储图像数据及其来源相机ID
struct ImageData
{
int camera_id;
cv::Mat image;
};
template <typename T>
class ThreadSafeQueue{
public:
// 添加元素到队列
void enqueue(const T& item)
{
std::unique_lock<std::mutex> lock(mutex_);
queue_.push(item);
cond_var_.notify_one();
}
// 从队列中移除并获取元素
bool dequeue(T& item)
{
std::unique_lock<std::mutex> lock(mutex_);
while (queue_.empty() && !stop_)
{
cond_var_.wait(lock);
}
if (queue_.empty())
return false;
item = std::move(queue_.front());
queue_.pop();
return true;
}
// 停止队列,唤醒所有等待的线程
void stop()
{
std::unique_lock<std::mutex> lock(mutex_);
stop_ = true;
cond_var_.notify_all();
}
private:
std::queue<T> queue_;
std::mutex mutex_;
std::condition_variable cond_var_;
bool stop_ = false;
};
// 定义全局存储队列
extern ThreadSafeQueue<ImageData> g_storageQueue;
#endif // GLOBALS_H #endif // GLOBALS_H

View File

@ -15,19 +15,22 @@ QPixmap ImageUtils::mat2QPixmap(const cv::Mat& mat)
// 灰度图像 // 灰度图像
img = QImage(mat.data, mat.cols, mat.rows, static_cast<int>(mat.step), QImage::Format_Grayscale8).copy(); img = QImage(mat.data, mat.cols, mat.rows, static_cast<int>(mat.step), QImage::Format_Grayscale8).copy();
} }
else if(mat.channels() == 3){ else if(mat.channels() == 3)
{
// 彩色图像 (OpenCV 默认是 BGR需要转换为 RGB) // 彩色图像 (OpenCV 默认是 BGR需要转换为 RGB)
cv::Mat rgb; cv::Mat rgb;
cv::cvtColor(mat, rgb, cv::COLOR_BGR2RGB); cv::cvtColor(mat, rgb, cv::COLOR_BGR2RGB);
img = QImage(rgb.data, rgb.cols, rgb.rows, static_cast<int>(rgb.step), QImage::Format_RGB888).copy(); img = QImage(rgb.data, rgb.cols, rgb.rows, static_cast<int>(rgb.step), QImage::Format_RGB888).copy();
} }
else if(mat.channels() == 4){ else if(mat.channels() == 4)
{
// 如果需要处理带有透明通道的图像 (BGRA 转 RGBA) // 如果需要处理带有透明通道的图像 (BGRA 转 RGBA)
cv::Mat rgba; cv::Mat rgba;
cv::cvtColor(mat, rgba, cv::COLOR_BGRA2RGBA); cv::cvtColor(mat, rgba, cv::COLOR_BGRA2RGBA);
img = QImage(rgba.data, rgba.cols, rgba.rows, static_cast<int>(rgba.step), QImage::Format_RGBA8888).copy(); img = QImage(rgba.data, rgba.cols, rgba.rows, static_cast<int>(rgba.step), QImage::Format_RGBA8888).copy();
} }
else{ else
{
// 不支持的图像格式 // 不支持的图像格式
std::cout << "Unsupported Mat format with channels:" << mat.channels(); std::cout << "Unsupported Mat format with channels:" << mat.channels();
return QPixmap(); return QPixmap();
@ -253,28 +256,29 @@ std::pair<std::vector<std::vector<uint8_t> >, std::vector<std::vector<uint8_t> >
return { roi_mask, remaining_mask }; return { roi_mask, remaining_mask };
} }
// cv::Mat overlayResultOnInput(const cv::Mat& cv_input, const cv::Mat& total_result, double alpha = 0.5, int colormap = cv::COLORMAP_JET) { void VectorToImg(const std::vector<std::vector<uint8_t> > &array, const std::string &image_path)
{
int height = array.size();
int width = array[0].size();
// } // 创建一个Mat对象来表示图像CV_8UC1表示单通道8位无符号整数类型用于黑白图像
cv::Mat image(height, width, CV_8UC1);
// 遍历二维向量,设置图像像素值
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (array[y][x] == 1)
{
image.at<uchar>(y, x) = 255; // 白色像素对应灰度值255
} else
{
image.at<uchar>(y, x) = 0; // 黑色像素对应灰度值0
}
}
}
// 合并两个二值掩码,通过按位或操作,并考虑垂直偏移 offset_y // 将图像保存为文件传入的image_path指定保存路径和文件名
// std::vector<std::vector<uint8_t>> mergeMasks( imwrite(image_path, image);
// const std::vector<std::vector<uint8_t>>& mask1, }
// const std::vector<std::vector<uint8_t>>& mask2,
// int offset_y = 0
// ) {
// }
// 提取 ROI 并返回剩余部分
// std::pair<std::vector<std::vector<uint8_t>>, std::vector<std::vector<uint8_t>>>
// extractROI(
// const std::vector<std::vector<uint8_t>>& merged_mask,
// int roi_x,
// int roi_y,
// int roi_width,
// int roi_height
// ) {
// }

View File

@ -40,6 +40,8 @@ public:
int roi_width, int roi_width,
int roi_height int roi_height
); );
};
static void VectorToImg(const std::vector<std::vector<uint8_t> > &array, const std::string &image_path);
};
#endif // IMG_UTILS_H #endif // IMG_UTILS_H

View File

@ -17,12 +17,14 @@
/ /
/ /
/ /
/
/
[CAMERA_NAME] [CAMERA_NAME]
no name no name
[CONFIG_FILE] [CONFIG_FILE]
50CF 50CF
ODYSSEY ODYSSEY
Mon Dec 9 16:10:06 2024 Mon Dec 23 11:31:47 2024
[INFO_FILE_REV] [INFO_FILE_REV]
0010.0019.0000 0010.0019.0000
RADIENT/eVCL/DUAL RADIENT/eVCL/DUAL
@ -64,7 +66,7 @@ VDC_IN_CH1
VDC_IN_CH2 0x0 VDC_IN_CH2 0x0
VDC_IN_CH3 0x0 VDC_IN_CH3 0x0
VDC_IN_CH_C 0x0 VDC_IN_CH_C 0x0
VDC_DIGITIZER 0x0 VDC_DIGITIZER 0x1
VDC_PSG_MODE_1_CHECK 0x1 VDC_PSG_MODE_1_CHECK 0x1
VDC_PSG_MODE_2_CHECKS 0x0 VDC_PSG_MODE_2_CHECKS 0x0
VDC_PSG_MODE_3_CHECKS 0x0 VDC_PSG_MODE_3_CHECKS 0x0
@ -111,16 +113,16 @@ VDT_STD_CL
VDT_STD_DIGITAL 0x0 VDT_STD_DIGITAL 0x0
VDT_NOVERT 0x1 VDT_NOVERT 0x1
VDT_HSYNC 0x0 VDT_HSYNC 0x0
VDT_HBPORCH 0x0 VDT_HBPORCH 0x10
VDT_HFPORCH 0x0 VDT_HFPORCH 0x0
VDT_HACTIVE 0x1000 VDT_HACTIVE 0x1000
VDT_HTOTAL 0x1000 VDT_HTOTAL 0x1010
VDT_HSYNC_FREQ 0x4c4b VDT_HSYNC_FREQ 0x4bff
VDT_VSYNC 0x0 VDT_VSYNC 0x0
VDT_VBPORCH 0x0 VDT_VBPORCH 0x0
VDT_VFPORCH 0x0 VDT_VFPORCH 0x0
VDT_VACTIVE 0x400 VDT_VACTIVE 0x200
VDT_VTOTAL 0x400 VDT_VTOTAL 0x200
VDT_VSYNC_FREQ 0x0 VDT_VSYNC_FREQ 0x0
VDT_CL_IMAGE_SIZE_X 0x0 VDT_CL_IMAGE_SIZE_X 0x0
VDT_CL_IMAGE_SIZE_Y 0x0 VDT_CL_IMAGE_SIZE_Y 0x0
@ -1558,11 +1560,11 @@ DEF_INFO_XSIZE_DIVISOR
DEF_INFO_YSIZE_DIVISOR 0x1 DEF_INFO_YSIZE_DIVISOR 0x1
DEF_ADD_HACTIVE_MULTIPLEX 0x0 DEF_ADD_HACTIVE_MULTIPLEX 0x0
DEF_ADD_VACTIVE_MULTIPLEX 0x0 DEF_ADD_VACTIVE_MULTIPLEX 0x0
DEF_HTOTAL_ENTRY 0x1000 DEF_HTOTAL_ENTRY 0x1010
DEF_HACTIVE_ENTRY 0x1000 DEF_HACTIVE_ENTRY 0x1000
DEF_VTOTAL_ENTRY 0x400 DEF_VTOTAL_ENTRY 0x200
DEF_VACTIVE_ENTRY 0x400 DEF_VACTIVE_ENTRY 0x200
DEF_CL_NEW_HCROPPING 0x0 DEF_CL_NEW_HCROPPING 0x10
DEF_CL_NEW_VCROPPING 0x0 DEF_CL_NEW_VCROPPING 0x0
DEF_NTSC 0x0 DEF_NTSC 0x0
DEF_PAL 0x0 DEF_PAL 0x0
@ -1576,20 +1578,20 @@ DEF_VINTRL_ODD_EVEN
DEF_VSVAL_EQUA_ZERO 0x1 DEF_VSVAL_EQUA_ZERO 0x1
DEF_VEVAL_EQUA_VTOTAL 0x1 DEF_VEVAL_EQUA_VTOTAL 0x1
DEF_DIGITIZER_MASTER 0x0 DEF_DIGITIZER_MASTER 0x0
DEF_CASE_HVBLANK_ZERO 0x1 DEF_CASE_HVBLANK_ZERO 0x0
DEF_ADD_3MAX_TOTAL_HVBLANK_ZERO 0x3 DEF_ADD_3MAX_TOTAL_HVBLANK_ZERO 0x0
DEF_ADD_HTOTAL_EQUA_HEVAL 0x0 DEF_ADD_HTOTAL_EQUA_HEVAL 0x0
DEF_HOR_COUNT_MAX_BITWISE 0xffff DEF_HOR_COUNT_MAX_BITWISE 0xffff
DEF_VERT_COUNT_MAX_BITWISE 0xffff DEF_VERT_COUNT_MAX_BITWISE 0xffff
DEF_DIG_HTOTAL 0x1002 DEF_DIG_HTOTAL 0x100f
DEF_DIG_VTOTAL 0x3ff DEF_DIG_VTOTAL 0x1ff
DEF_TEST_MODE_HFP_MIN 0x0 DEF_TEST_MODE_HFP_MIN 0x0
DEF_TEST_MODE_HSY_HBP_MIN_CL 0x0 DEF_TEST_MODE_HSY_HBP_MIN_CL 0x0
DEF_TEST_MODE_VFP_MIN 0x0 DEF_TEST_MODE_VFP_MIN 0x0
DEF_TEST_MODE_VBP_MIN 0x0 DEF_TEST_MODE_VBP_MIN 0x0
DEF_TEST_MODE_VS_VBP_MIN_ANA_DIG_CL 0x0 DEF_TEST_MODE_VS_VBP_MIN_ANA_DIG_CL 0x0
DEF_HSVAL_EQUA_ZERO 0x1 DEF_HSVAL_EQUA_ZERO 0x0
DEF_HEVAL_EQUA_HTOTAL 0x0 DEF_HEVAL_EQUA_HTOTAL 0x1
DEF_HTOTAL_OVERFLOW 0x0 DEF_HTOTAL_OVERFLOW 0x0
DEF_HACTIVE_OVERFLOW 0x0 DEF_HACTIVE_OVERFLOW 0x0
DEF_VTOTAL_OVERFLOW 0x0 DEF_VTOTAL_OVERFLOW 0x0
@ -1612,8 +1614,8 @@ DEF_TIMER0_PIPE_DELAY1
DEF_TIMER1_PIPE_DELAY1 0x0 DEF_TIMER1_PIPE_DELAY1 0x0
DEF_TMR0_CLKTMR1_CNT 0x0 DEF_TMR0_CLKTMR1_CNT 0x0
DEF_TMR1_CLKTMR0_CNT 0x0 DEF_TMR1_CLKTMR0_CNT 0x0
DEF_TIMER01_CLK_HS_FREQ 0x4c41 DEF_TIMER01_CLK_HS_FREQ 0x4c03
DEF_TIMER01_CLK_HS_PERIOD 0xc81b DEF_TIMER01_CLK_HS_PERIOD 0xc8be
DEF_TIMER0_CLK_HS_PERIOD_DLY1_CNT 0x0 DEF_TIMER0_CLK_HS_PERIOD_DLY1_CNT 0x0
DEF_TIMER0_CLK_HS_PERIOD_DLY2_CNT 0x0 DEF_TIMER0_CLK_HS_PERIOD_DLY2_CNT 0x0
DEF_TIMER0_CLK_HS_PERIOD_T1_CNT 0x0 DEF_TIMER0_CLK_HS_PERIOD_T1_CNT 0x0
@ -1729,7 +1731,7 @@ DEF_DIG1_BYTESORDER
INFO_CUSTOM 0x0 INFO_CUSTOM 0x0
INFO_REGISTER_REV 0x1 INFO_REGISTER_REV 0x1
INFO_XSIZE 0x1000 INFO_XSIZE 0x1000
INFO_YSIZE 0x400 INFO_YSIZE 0x200
INFO_TYPE 0x1 INFO_TYPE 0x1
INFO_BAYER 0x0 INFO_BAYER 0x0
INFO_BURSTSIZE 0x0 INFO_BURSTSIZE 0x0
@ -1922,18 +1924,18 @@ INFO_MASK_T2CTLH
INFO_MASK_T3CTLL 0x0 INFO_MASK_T3CTLL 0x0
INFO_MASK_T3CTLH 0x0 INFO_MASK_T3CTLH 0x0
DIG_HCNT 0x1 DIG_HCNT 0x1
DIG_HTOTAL 0x1002 DIG_HTOTAL 0x100f
DIG_HSCNT 0x0 DIG_HSCNT 0x0
DIG_HECNT 0x1 DIG_HECNT 0x1
DIG_HSSYNC 0x0 DIG_HSSYNC 0x0
DIG_HESYNC 0x0 DIG_HESYNC 0x0
DIG_HSVAL 0x0 DIG_HSVAL 0x10
DIG_HEVAL 0xfff DIG_HEVAL 0x100f
DIG_HSCLM 0x0 DIG_HSCLM 0x0
DIG_HECLM 0x0 DIG_HECLM 0x0
DIG_HCTL 0x1e0 DIG_HCTL 0x1e0
DIG_VCNT 0x1 DIG_VCNT 0x1
DIG_VTOTAL 0x3ff DIG_VTOTAL 0x1ff
DIG_VSCNT 0x0 DIG_VSCNT 0x0
DIG_VECNT 0x0 DIG_VECNT 0x0
DIG_VSSYNC 0x0 DIG_VSSYNC 0x0
@ -2348,5 +2350,5 @@ DIG_IOCTL1H
DIG_IOCTL0_L not_modified DIG_IOCTL0_L not_modified
DIG_ENCTL not_modified DIG_ENCTL not_modified
[EOF] [EOF]
00007FF687B3AAA8 0x400b8 00007FF72205AAA8 0x400c2
00007FF687B3AA90 0x48b1c582 00007FF72205AA90 0x48b9cbd0

View File

@ -0,0 +1,52 @@
# Green color parameters
green_L_min = 18
green_L_max = 58
green_a_min = -35
green_a_max = -11
green_b_min = -7
green_b_max = 24
# Blue color parameters
blue_L_min = 20
blue_L_max = 43
blue_a_min = -13
blue_a_max = 22
blue_b_min = -48
blue_b_max = -3
# Orange color parameters
orange_L_min = 62
orange_L_max = 77
orange_a_min = 7
orange_a_max = 15
orange_b_min = 30
orange_b_max = 48
# Black color parameters
black_L_min = 1
black_L_max = 11
black_a_min = -5
black_a_max = 2
black_b_min = -3
black_b_max = 6
# Red color parameters
red_L_min = 20
red_L_max = 44
red_a_min = 10
red_a_max = 30
red_b_min = -99
red_b_max = 32
# Purple color parameters
purple_L_min = 35
purple_L_max = 72
purple_a_min = 12
purple_a_max = 22
purple_b_min = -48
purple_b_max = 1
# Other parameters
lab_denoising = 1
saturation_threshold = 150
saturation_denoising = 1

View File

@ -11,11 +11,17 @@
#include <QtCore/QVariant> #include <QtCore/QVariant>
#include <QtWidgets/QApplication> #include <QtWidgets/QApplication>
#include <QtWidgets/QCheckBox>
#include <QtWidgets/QFrame>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QGroupBox> #include <QtWidgets/QGroupBox>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLabel> #include <QtWidgets/QLabel>
#include <QtWidgets/QPushButton> #include <QtWidgets/QPushButton>
#include <QtWidgets/QSpacerItem>
#include <QtWidgets/QSpinBox> #include <QtWidgets/QSpinBox>
#include <QtWidgets/QTabWidget> #include <QtWidgets/QTabWidget>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget> #include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -23,24 +29,46 @@ QT_BEGIN_NAMESPACE
class Ui_Widget class Ui_Widget
{ {
public: public:
QHBoxLayout *horizontalLayout;
QTabWidget *tabWidget; QTabWidget *tabWidget;
QWidget *tab; QWidget *tab;
QPushButton *pushButton; QVBoxLayout *verticalLayout;
QPushButton *pushButton_2; QGroupBox *groupBox_5;
QGridLayout *gridLayout;
QPushButton *btn_goto_sort; QPushButton *btn_goto_sort;
QPushButton *btn_0to3; QPushButton *btn_0to3;
QPushButton *pushButtonStart;
QPushButton *pushButton_2;
QGroupBox *groupBox; QGroupBox *groupBox;
QHBoxLayout *horizontalLayout_2;
QLabel *label; QLabel *label;
QLabel *lab_lowermachine_isconnect; QLabel *lab_lowermachine_isconnect;
QPushButton *btn_reconnect; QPushButton *btn_reconnect;
QWidget *tab_2; QWidget *tab_2;
QHBoxLayout *horizontalLayout_3;
QGroupBox *groupBox_7;
QVBoxLayout *verticalLayout_3;
QLabel *lab_info; QLabel *lab_info;
QPushButton *btn_start; QPushButton *btn_start;
QPushButton *btn_take_photos;
QPushButton *btn_stop; QPushButton *btn_stop;
QLabel *camera_0_img; QSpacerItem *verticalSpacer;
QLabel *camera_1_img; QFrame *frame_6;
QVBoxLayout *verticalLayout_2;
QFrame *frame;
QHBoxLayout *horizontalLayout_4;
QLabel *label_2; QLabel *label_2;
QLabel *label_3; QSpacerItem *horizontalSpacer;
QCheckBox *img_1_mirror;
QCheckBox *img_1_overlay;
QLabel *camera_1_img;
QFrame *frame_2;
QHBoxLayout *horizontalLayout_5;
QLabel *label_4;
QSpacerItem *horizontalSpacer_2;
QCheckBox *img_0_mirror;
QCheckBox *img_0_overlay;
QLabel *camera_0_img;
QWidget *tab_3; QWidget *tab_3;
QLabel *label_title_3; QLabel *label_title_3;
QGroupBox *groupBox_4; QGroupBox *groupBox_4;
@ -67,33 +95,55 @@ public:
{ {
if (Widget->objectName().isEmpty()) if (Widget->objectName().isEmpty())
Widget->setObjectName("Widget"); Widget->setObjectName("Widget");
Widget->resize(800, 600); Widget->resize(1920, 1080);
horizontalLayout = new QHBoxLayout(Widget);
horizontalLayout->setObjectName("horizontalLayout");
tabWidget = new QTabWidget(Widget); tabWidget = new QTabWidget(Widget);
tabWidget->setObjectName("tabWidget"); tabWidget->setObjectName("tabWidget");
tabWidget->setGeometry(QRect(0, 0, 801, 601)); tabWidget->setEnabled(true);
tab = new QWidget(); tab = new QWidget();
tab->setObjectName("tab"); tab->setObjectName("tab");
pushButton = new QPushButton(tab); verticalLayout = new QVBoxLayout(tab);
pushButton->setObjectName("pushButton"); verticalLayout->setObjectName("verticalLayout");
pushButton->setGeometry(QRect(100, 130, 201, 61)); groupBox_5 = new QGroupBox(tab);
pushButton_2 = new QPushButton(tab); groupBox_5->setObjectName("groupBox_5");
pushButton_2->setObjectName("pushButton_2"); gridLayout = new QGridLayout(groupBox_5);
pushButton_2->setGeometry(QRect(400, 120, 181, 71)); gridLayout->setObjectName("gridLayout");
btn_goto_sort = new QPushButton(tab); btn_goto_sort = new QPushButton(groupBox_5);
btn_goto_sort->setObjectName("btn_goto_sort"); btn_goto_sort->setObjectName("btn_goto_sort");
btn_goto_sort->setGeometry(QRect(120, 290, 121, 61));
btn_0to3 = new QPushButton(tab); gridLayout->addWidget(btn_goto_sort, 2, 0, 1, 1);
btn_0to3 = new QPushButton(groupBox_5);
btn_0to3->setObjectName("btn_0to3"); btn_0to3->setObjectName("btn_0to3");
btn_0to3->setGeometry(QRect(410, 290, 141, 61));
gridLayout->addWidget(btn_0to3, 2, 1, 1, 1);
pushButtonStart = new QPushButton(groupBox_5);
pushButtonStart->setObjectName("pushButtonStart");
gridLayout->addWidget(pushButtonStart, 1, 0, 1, 1);
pushButton_2 = new QPushButton(groupBox_5);
pushButton_2->setObjectName("pushButton_2");
gridLayout->addWidget(pushButton_2, 1, 1, 1, 1);
verticalLayout->addWidget(groupBox_5);
groupBox = new QGroupBox(tab); groupBox = new QGroupBox(tab);
groupBox->setObjectName("groupBox"); groupBox->setObjectName("groupBox");
groupBox->setGeometry(QRect(160, 390, 401, 131)); horizontalLayout_2 = new QHBoxLayout(groupBox);
horizontalLayout_2->setObjectName("horizontalLayout_2");
horizontalLayout_2->setSizeConstraint(QLayout::SizeConstraint::SetDefaultConstraint);
label = new QLabel(groupBox); label = new QLabel(groupBox);
label->setObjectName("label"); label->setObjectName("label");
label->setGeometry(QRect(40, 70, 41, 16));
horizontalLayout_2->addWidget(label);
lab_lowermachine_isconnect = new QLabel(groupBox); lab_lowermachine_isconnect = new QLabel(groupBox);
lab_lowermachine_isconnect->setObjectName("lab_lowermachine_isconnect"); lab_lowermachine_isconnect->setObjectName("lab_lowermachine_isconnect");
lab_lowermachine_isconnect->setGeometry(QRect(90, 60, 31, 31));
QPalette palette; QPalette palette;
QBrush brush(QColor(237, 212, 0, 255)); QBrush brush(QColor(237, 212, 0, 255));
brush.setStyle(Qt::SolidPattern); brush.setStyle(Qt::SolidPattern);
@ -112,41 +162,163 @@ public:
palette.setBrush(QPalette::Disabled, QPalette::Window, brush); palette.setBrush(QPalette::Disabled, QPalette::Window, brush);
palette.setBrush(QPalette::Disabled, QPalette::AlternateBase, brush1); palette.setBrush(QPalette::Disabled, QPalette::AlternateBase, brush1);
lab_lowermachine_isconnect->setPalette(palette); lab_lowermachine_isconnect->setPalette(palette);
btn_reconnect = new QPushButton(tab);
horizontalLayout_2->addWidget(lab_lowermachine_isconnect);
btn_reconnect = new QPushButton(groupBox);
btn_reconnect->setObjectName("btn_reconnect"); btn_reconnect->setObjectName("btn_reconnect");
btn_reconnect->setGeometry(QRect(590, 440, 101, 41));
horizontalLayout_2->addWidget(btn_reconnect);
verticalLayout->addWidget(groupBox);
verticalLayout->setStretch(0, 5);
verticalLayout->setStretch(1, 1);
tabWidget->addTab(tab, QString()); tabWidget->addTab(tab, QString());
tab_2 = new QWidget(); tab_2 = new QWidget();
tab_2->setObjectName("tab_2"); tab_2->setObjectName("tab_2");
lab_info = new QLabel(tab_2); horizontalLayout_3 = new QHBoxLayout(tab_2);
horizontalLayout_3->setObjectName("horizontalLayout_3");
groupBox_7 = new QGroupBox(tab_2);
groupBox_7->setObjectName("groupBox_7");
verticalLayout_3 = new QVBoxLayout(groupBox_7);
verticalLayout_3->setSpacing(20);
verticalLayout_3->setObjectName("verticalLayout_3");
verticalLayout_3->setContentsMargins(9, 9, 9, -1);
lab_info = new QLabel(groupBox_7);
lab_info->setObjectName("lab_info"); lab_info->setObjectName("lab_info");
lab_info->setGeometry(QRect(20, 50, 151, 81)); lab_info->setEnabled(true);
QFont font; QFont font;
font.setPointSize(28); font.setPointSize(28);
lab_info->setFont(font); lab_info->setFont(font);
btn_start = new QPushButton(tab_2);
verticalLayout_3->addWidget(lab_info);
btn_start = new QPushButton(groupBox_7);
btn_start->setObjectName("btn_start"); btn_start->setObjectName("btn_start");
btn_start->setGeometry(QRect(20, 130, 101, 41)); btn_start->setMinimumSize(QSize(70, 200));
btn_stop = new QPushButton(tab_2);
verticalLayout_3->addWidget(btn_start);
btn_take_photos = new QPushButton(groupBox_7);
btn_take_photos->setObjectName("btn_take_photos");
btn_take_photos->setMinimumSize(QSize(70, 200));
verticalLayout_3->addWidget(btn_take_photos);
btn_stop = new QPushButton(groupBox_7);
btn_stop->setObjectName("btn_stop"); btn_stop->setObjectName("btn_stop");
btn_stop->setGeometry(QRect(20, 190, 101, 41)); btn_stop->setMinimumSize(QSize(70, 200));
camera_0_img = new QLabel(tab_2);
camera_0_img->setObjectName("camera_0_img"); verticalLayout_3->addWidget(btn_stop);
camera_0_img->setGeometry(QRect(160, 40, 591, 191));
camera_0_img->setStyleSheet(QString::fromUtf8("background-color: rgb(129, 129, 129);\n" verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Expanding);
"border: 4px solid black;"));
camera_1_img = new QLabel(tab_2); verticalLayout_3->addItem(verticalSpacer);
horizontalLayout_3->addWidget(groupBox_7);
frame_6 = new QFrame(tab_2);
frame_6->setObjectName("frame_6");
verticalLayout_2 = new QVBoxLayout(frame_6);
verticalLayout_2->setObjectName("verticalLayout_2");
frame = new QFrame(frame_6);
frame->setObjectName("frame");
frame->setFrameShape(QFrame::Shape::StyledPanel);
frame->setFrameShadow(QFrame::Shadow::Raised);
horizontalLayout_4 = new QHBoxLayout(frame);
horizontalLayout_4->setObjectName("horizontalLayout_4");
label_2 = new QLabel(frame);
label_2->setObjectName("label_2");
label_2->setStyleSheet(QString::fromUtf8("font: 18pt \"Microsoft YaHei UI\";"));
horizontalLayout_4->addWidget(label_2);
horizontalSpacer = new QSpacerItem(864, 20, QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Minimum);
horizontalLayout_4->addItem(horizontalSpacer);
img_1_mirror = new QCheckBox(frame);
img_1_mirror->setObjectName("img_1_mirror");
img_1_mirror->setStyleSheet(QString::fromUtf8("font: 12pt \"Microsoft YaHei UI\";"));
horizontalLayout_4->addWidget(img_1_mirror);
img_1_overlay = new QCheckBox(frame);
img_1_overlay->setObjectName("img_1_overlay");
img_1_overlay->setEnabled(false);
img_1_overlay->setStyleSheet(QString::fromUtf8("font: 12pt \"Microsoft YaHei UI\";"));
horizontalLayout_4->addWidget(img_1_overlay);
verticalLayout_2->addWidget(frame);
camera_1_img = new QLabel(frame_6);
camera_1_img->setObjectName("camera_1_img"); camera_1_img->setObjectName("camera_1_img");
camera_1_img->setGeometry(QRect(160, 290, 591, 191)); QSizePolicy sizePolicy(QSizePolicy::Policy::Ignored, QSizePolicy::Policy::Ignored);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
sizePolicy.setHeightForWidth(camera_1_img->sizePolicy().hasHeightForWidth());
camera_1_img->setSizePolicy(sizePolicy);
camera_1_img->setStyleSheet(QString::fromUtf8("background-color: rgb(129, 129, 129);\n" camera_1_img->setStyleSheet(QString::fromUtf8("background-color: rgb(129, 129, 129);\n"
"border: 4px solid black;")); "border: 4px solid black;"));
camera_1_img->setLineWidth(1); camera_1_img->setLineWidth(1);
label_2 = new QLabel(tab_2);
label_2->setObjectName("label_2"); verticalLayout_2->addWidget(camera_1_img);
label_2->setGeometry(QRect(160, 270, 141, 16));
label_3 = new QLabel(tab_2); frame_2 = new QFrame(frame_6);
label_3->setObjectName("label_3"); frame_2->setObjectName("frame_2");
label_3->setGeometry(QRect(160, 20, 141, 16)); frame_2->setFrameShape(QFrame::Shape::StyledPanel);
frame_2->setFrameShadow(QFrame::Shadow::Raised);
horizontalLayout_5 = new QHBoxLayout(frame_2);
horizontalLayout_5->setObjectName("horizontalLayout_5");
label_4 = new QLabel(frame_2);
label_4->setObjectName("label_4");
label_4->setStyleSheet(QString::fromUtf8("font: 18pt \"Microsoft YaHei UI\";"));
horizontalLayout_5->addWidget(label_4);
horizontalSpacer_2 = new QSpacerItem(840, 20, QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Minimum);
horizontalLayout_5->addItem(horizontalSpacer_2);
img_0_mirror = new QCheckBox(frame_2);
img_0_mirror->setObjectName("img_0_mirror");
img_0_mirror->setStyleSheet(QString::fromUtf8("font: 12pt \"Microsoft YaHei UI\";"));
img_0_mirror->setChecked(true);
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);
camera_0_img = new QLabel(frame_6);
camera_0_img->setObjectName("camera_0_img");
sizePolicy.setHeightForWidth(camera_0_img->sizePolicy().hasHeightForWidth());
camera_0_img->setSizePolicy(sizePolicy);
camera_0_img->setStyleSheet(QString::fromUtf8("background-color: rgb(129, 129, 129);\n"
"border: 4px solid black;"));
camera_0_img->setLineWidth(1);
verticalLayout_2->addWidget(camera_0_img);
verticalLayout_2->setStretch(1, 5);
verticalLayout_2->setStretch(3, 5);
horizontalLayout_3->addWidget(frame_6);
horizontalLayout_3->setStretch(0, 4);
horizontalLayout_3->setStretch(1, 10);
tabWidget->addTab(tab_2, QString()); tabWidget->addTab(tab_2, QString());
tab_3 = new QWidget(); tab_3 = new QWidget();
tab_3->setObjectName("tab_3"); tab_3->setObjectName("tab_3");
@ -215,6 +387,9 @@ public:
btn_stop_test->setGeometry(QRect(210, 40, 75, 23)); btn_stop_test->setGeometry(QRect(210, 40, 75, 23));
tabWidget->addTab(tab_4, QString()); tabWidget->addTab(tab_4, QString());
horizontalLayout->addWidget(tabWidget);
retranslateUi(Widget); retranslateUi(Widget);
tabWidget->setCurrentIndex(1); tabWidget->setCurrentIndex(1);
@ -226,22 +401,29 @@ public:
void retranslateUi(QWidget *Widget) void retranslateUi(QWidget *Widget)
{ {
Widget->setWindowTitle(QCoreApplication::translate("Widget", "Widget", nullptr)); Widget->setWindowTitle(QCoreApplication::translate("Widget", "Widget", nullptr));
pushButton->setText(QCoreApplication::translate("Widget", "\345\274\200\345\247\213", nullptr)); groupBox_5->setTitle(QCoreApplication::translate("Widget", "GroupBox", nullptr));
pushButton_2->setText(QCoreApplication::translate("Widget", "\344\277\235\345\255\230\345\233\276\347\211\207", nullptr));
btn_goto_sort->setText(QCoreApplication::translate("Widget", "\345\201\234\346\255\242", nullptr)); btn_goto_sort->setText(QCoreApplication::translate("Widget", "\345\201\234\346\255\242", nullptr));
btn_0to3->setText(QCoreApplication::translate("Widget", "\345\226\267\351\230\200\346\265\213\350\257\225", nullptr)); btn_0to3->setText(QCoreApplication::translate("Widget", "\345\226\267\351\230\200\346\265\213\350\257\225", nullptr));
pushButtonStart->setText(QCoreApplication::translate("Widget", "\345\274\200\345\247\213", nullptr));
pushButton_2->setText(QCoreApplication::translate("Widget", "\344\277\235\345\255\230\345\233\276\347\211\207", nullptr));
groupBox->setTitle(QCoreApplication::translate("Widget", "\350\277\236\346\216\245\347\212\266\346\200\201\357\274\232", nullptr)); groupBox->setTitle(QCoreApplication::translate("Widget", "\350\277\236\346\216\245\347\212\266\346\200\201\357\274\232", nullptr));
label->setText(QCoreApplication::translate("Widget", "\344\270\213\344\275\215\346\234\272", nullptr)); label->setText(QCoreApplication::translate("Widget", "\344\270\213\344\275\215\346\234\272", nullptr));
lab_lowermachine_isconnect->setText(QString()); lab_lowermachine_isconnect->setText(QString());
btn_reconnect->setText(QCoreApplication::translate("Widget", "\351\207\215\346\226\260\350\277\236\346\216\245", nullptr)); btn_reconnect->setText(QCoreApplication::translate("Widget", "\351\207\215\346\226\260\350\277\236\346\216\245", nullptr));
tabWidget->setTabText(tabWidget->indexOf(tab), QCoreApplication::translate("Widget", "Tab 1", nullptr)); tabWidget->setTabText(tabWidget->indexOf(tab), QCoreApplication::translate("Widget", "Tab 1", nullptr));
lab_info->setText(QCoreApplication::translate("Widget", "\345\207\206\345\244\207\344\270\255", nullptr)); groupBox_7->setTitle(QCoreApplication::translate("Widget", "\346\216\247\345\210\266\345\217\212\347\212\266\346\200\201", nullptr));
lab_info->setText(QCoreApplication::translate("Widget", "\347\212\266\346\200\201", nullptr));
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_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));
camera_0_img->setText(QString());
camera_1_img->setText(QString());
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));
label_3->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)); img_1_mirror->setText(QCoreApplication::translate("Widget", "\345\233\276\347\211\207\351\225\234\345\203\217", nullptr));
img_1_overlay->setText(QCoreApplication::translate("Widget", "\350\257\206\345\210\253\347\273\223\346\236\234", nullptr));
camera_1_img->setText(QString());
label_4->setText(QCoreApplication::translate("Widget", "\347\233\270\346\234\2720\357\274\210\344\275\216\344\276\247/\345\207\272\351\243\216\345\217\243\344\276\247\357\274\211", nullptr));
img_0_mirror->setText(QCoreApplication::translate("Widget", "\345\233\276\347\211\207\351\225\234\345\203\217", nullptr));
img_0_overlay->setText(QCoreApplication::translate("Widget", "\350\257\206\345\210\253\347\273\223\346\236\234", nullptr));
camera_0_img->setText(QString());
tabWidget->setTabText(tabWidget->indexOf(tab_2), QCoreApplication::translate("Widget", "Tab 2", nullptr)); 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));

View File

@ -14,25 +14,39 @@
#include <QDateTime> #include <QDateTime>
#include <img_utils.h> #include <img_utils.h>
using namespace std; using namespace std;
// 硬编码参数值 // 硬编码参数值
int file_delay = 1270; // 延迟时间(毫秒) int file_delay = 1270; // 延迟时间(毫秒)
int file_encoder = 12000; // 编码器值++ int file_encoder = 12000; // 编码器值++
int file_valve = 200; // 阀门通道 int file_valve = 200; // 阀门通道
Widget::Widget(QWidget *parent) Widget::Widget(QWidget *parent)
: QWidget(parent) : QWidget(parent)
, ui(new Ui::Widget) , ui(new Ui::Widget)
{ {
this->isCamRunning = false;
ui->setupUi(this); ui->setupUi(this);
ui->camera_0_img->setScaledContents(true); ui->camera_0_img->setScaledContents(false);
ui->camera_1_img->setScaledContents(false);
iniOnnx();
iniColor(); iniColor();
iniLowMac(); iniLowMac();
iniCamera(); iniCamera();
// 初始化存储工作者和线程
storageWorker = new StorageWorker();
storageWorker->moveToThread(&storageThread);
connect(&storageThread, &QThread::started, storageWorker, &StorageWorker::process);
connect(this, &Widget::destroyed, &storageThread, &QThread::quit);
connect(&storageThread, &QThread::finished, storageWorker, &QObject::deleteLater);
storageThread.start();
// 启动显示定时器,每秒检查一次 // 启动显示定时器,每秒检查一次
QTimer* timer = new QTimer(this); QTimer* timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &Widget::refreshImage); connect(timer, &QTimer::timeout, this, &Widget::refreshImage);
@ -41,89 +55,124 @@ Widget::Widget(QWidget *parent)
Widget::~Widget() Widget::~Widget()
{ {
// DestoryCamera(); // 停止存储线程
g_storageQueue.stop();
storageThread.quit();
storageThread.wait();
// 现有清理代码...
DestoryCamera();
DestoryLowMac();
delete ui;
} }
void Widget::refreshImage() void Widget::refreshImage()
{ {
refreshSingleImage(0); // refresh Image 1 and image 0
refreshSingleImage(1); refreshSingleImage(0, this->ui->img_0_overlay->isChecked(), this->ui->img_0_mirror->isChecked());
refreshSingleImage(1, this->ui->img_1_overlay->isChecked(), this->ui->img_1_mirror->isChecked());
// refresh buttons
this->ui->btn_start->setEnabled(!this->isCamRunning);
this->ui->btn_stop->setEnabled(this->isCamRunning);
this->ui->btn_take_photos->setEnabled(this->isCamRunning);
// refresh info
QString info;
if(this->isCamRunning)
{
if(SaveImg_Flag==1)
{
info = "存图中!!";
}
else
{
info = "运行";
};
}else {
info = "停止";
};
this->ui->lab_info->setText(info);
} }
void Widget::refreshSingleImage(int camera_id, bool overlay_result) void Widget::refreshSingleImage(int camera_id, bool overlay_result, bool mirror)
{ {
// 更新当前的图片0 // 验证摄像头ID的有效性
MIL_ID current_id = 0; if (camera_id < 0 || camera_id >= 2) { // 假设只有两个摄像头
if (camera_id == 0) qWarning() << "Invalid Camera ID:" << camera_id;
{ // 获取当前图片 return;
}
// 定义每个摄像头对应的变量数组
QMutex* dispPicMutexes[2] = { &gDispPicMutex0, &gDispPicMutex1 };
MIL_ID dispCurrentPicIds[2] = { gDispCurrentPicId0, gDispCurrentPicId1 };
QMutex* maskMutexes[2] = { &gMaskMutex0, &gMaskMutex1 };
MIL_ID maskIds[2] = { gMask0, gMask1 };
QLabel* cameraLabels[2] = { ui->camera_0_img, ui->camera_1_img };
// 获取当前摄像头的数据
QMutex* currentDispMutex = dispPicMutexes[camera_id];
MIL_ID current_id;
{
QMutexLocker locker(currentDispMutex);
current_id = dispCurrentPicIds[camera_id];
}
if (current_id == 0)
return;
// 将MIL图像转换为OpenCV Mat
cv::Mat img = ImageUtils::mil2Mat(current_id);
if (img.empty()) {
qWarning() << "Failed to convert MIL image to Mat for Camera ID:" << camera_id;
return;
}
// 如果需要叠加结果,处理掩码
if (overlay_result)
{
QMutex* currentMaskMutex = maskMutexes[camera_id];
MIL_ID mask_id;
{ {
QMutexLocker locker(&gDispPicMutex0); QMutexLocker locker(currentMaskMutex);
current_id = gDispCurrentPicId0; mask_id = maskIds[camera_id];
} }
if (current_id == 0)
return; if (mask_id != 0) {
cv::Mat img = ImageUtils::mil2Mat(current_id);
//进行结果的转化叠加
if (overlay_result)
{
MIL_ID mask_id = 0;
{
QMutexLocker locker(&gMaskMutex0);
mask_id = gMask0;
}
cv::Mat mask = ImageUtils::mil2Mat(mask_id); cv::Mat mask = ImageUtils::mil2Mat(mask_id);
img = ImageUtils::overlayResultOnInput(img,mask,0.5); if (!mask.empty()) {
} img = ImageUtils::overlayResultOnInput(img, mask, 0.5);
//刷新显示
QPixmap pixmap0 = ImageUtils::mat2QPixmap(img);
if (!pixmap0.isNull())
{
ui->camera_0_img->setPixmap(pixmap0);
}
}
// 更新当前的图片1
else if (camera_id == 1)
{
{
QMutexLocker locker(&gDispPicMutex1);
current_id = gDispCurrentPicId1;
if (current_id == 0)
return;
cv::Mat img = ImageUtils::mil2Mat(current_id);
//进行结果的转化叠加
if (overlay_result)
{
MIL_ID mask_id = 0;
{
QMutexLocker locker(&gMaskMutex1);
mask_id = gMask1;
}
cv::Mat mask = ImageUtils::mil2Mat(mask_id);
img = ImageUtils::overlayResultOnInput(img,mask,0.5);
} }
//刷新显示 else {
QPixmap pixmap1 = ImageUtils::mat2QPixmap(img); qWarning() << "Failed to convert MIL mask to Mat for Camera ID:" << camera_id;
if (!pixmap1.isNull())
{
ui->camera_1_img->setPixmap(pixmap1);
} }
} }
} }
else
// 如果需要镜像处理
if (mirror)
{ {
qWarning() << "The given Camera ID is wrong!"; cv::flip(img, img, 1); // 水平翻转
} }
// 将OpenCV Mat转换为QPixmap
QPixmap pixmap = ImageUtils::mat2QPixmap(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_clicked()
{
Start_camera();
}
void Widget::on_pushButton_2_clicked() void Widget::on_pushButton_2_clicked()
{ {
SaveImg_Flag = 1; SaveImg_Flag = 1;
@ -147,3 +196,41 @@ void Widget::on_btn_goto_sort_clicked()
DestoryLowMac(); DestoryLowMac();
} }
void Widget::on_btn_stop_clicked()
{
this->isCamRunning = false;
// 恢复显示的图片
{
QMutexLocker locker(&gDispPicMutex0);
gDispCurrentPicId0 = 0;
}
ui->camera_0_img->clear();
{
QMutexLocker locker(&gDispPicMutex1);
gDispCurrentPicId1 = 0;
}
ui->camera_1_img->clear();
DestoryCamera();
DestoryLowMac();
}
void Widget::on_btn_start_clicked()
{
this->isCamRunning = true;
Start_camera();
}
void Widget::on_btn_take_photos_pressed()
{
SaveImg_Flag = true;
}
void Widget::on_btn_take_photos_released()
{
SaveImg_Flag = false;
}

View File

@ -1,11 +1,12 @@
#ifndef WIDGET_H #ifndef WIDGET_H
#define WIDGET_H #define WIDGET_H
#include <QThread>
#include <QWidget> #include <QWidget>
#include <camera.h> #include <camera.h>
#include <QTcpServer> #include <QTcpServer>
#include <QPushButton> #include <QPushButton>
#include "globals.h" #include "globals.h"
#include "storageworker.h"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
namespace Ui { namespace Ui {
@ -26,17 +27,27 @@ public slots:
private slots: private slots:
void refreshSingleImage(int camera_id, bool overlay_result = true); void refreshSingleImage(int camera_id, bool overlay_result = true, bool mirror = false);
void on_pushButton_clicked();
void on_pushButton_2_clicked(); void on_pushButton_2_clicked();
void on_btn_goto_sort_clicked(); void on_btn_goto_sort_clicked();
void on_btn_stop_clicked();
void on_btn_start_clicked();
void on_btn_take_photos_pressed();
void on_btn_take_photos_released();
private: private:
Ui::Widget *ui; Ui::Widget *ui;
bool isCamRunning;
QThread storageThread; // 存储线程
StorageWorker* storageWorker; // 存储工作者
}; };
#endif // WIDGET_H #endif // WIDGET_H

1307
widget.ui

File diff suppressed because it is too large Load Diff