Compare commits
5 Commits
49240c7ba5
...
703b1430f6
| Author | SHA1 | Date | |
|---|---|---|---|
| 703b1430f6 | |||
| f56b876119 | |||
| 50b8c37a9c | |||
| 18e2f3080d | |||
| fd7df4545e |
3
.gitignore
vendored
3
.gitignore
vendored
@ -3,6 +3,7 @@ build
|
||||
release
|
||||
debug
|
||||
.qtc_clangd
|
||||
Makefile*
|
||||
Makefile.*
|
||||
*.pro.user*
|
||||
*.pro.user
|
||||
.idea
|
||||
|
||||
1031
Makefile.Debug
1031
Makefile.Debug
File diff suppressed because one or more lines are too long
1031
Makefile.Release
1031
Makefile.Release
File diff suppressed because one or more lines are too long
275
camera.cpp
275
camera.cpp
@ -3,9 +3,9 @@
|
||||
#include <QTimer>
|
||||
|
||||
// Debug Options
|
||||
#define GlobalDebug 1 // 全局是否允许打印Debug信息(打印会拖慢处理时间)
|
||||
#define GlobalDebug 0 // 全局是否允许打印Debug信息(打印会拖慢处理时间)
|
||||
#define DebugDetection 0 // 注意开启这个编译选项会导致图片存储, 处理时间会很慢
|
||||
#define DebugDetectionTime 0 // 是否打印处理时间
|
||||
#define DebugDetectionTime 1 // 是否打印处理时间
|
||||
#define DebugLowerMacCOM 0 // 是否打印和下位机通讯的相关信息
|
||||
|
||||
camera::camera() {}
|
||||
@ -46,7 +46,7 @@ ONNXRunner runner;
|
||||
|
||||
|
||||
std::map<std::string, int> params;
|
||||
int dual_cam_offset_y = 89; // 双相机之间的上下偏移值
|
||||
int dual_cam_offset_y = 0; // 双相机之间的上下偏移值
|
||||
int widthBlocks = 20; // 输出的喷阀通道数
|
||||
int heightBlocks = 512; // 输出的Mask高度
|
||||
int sizeThreshold = 20; // 转化为喷阀的每块要求像素个数
|
||||
@ -84,8 +84,9 @@ bool iniCamera()
|
||||
MsysAlloc(M_DEFAULT, M_SYSTEM_RADIENTEVCL, M_DEV0, M_DEFAULT, &MilSystem);
|
||||
|
||||
//分配相机 digitier
|
||||
MdigAlloc(MilSystem,M_DEV0,MIL_TEXT("C:/Users/Administrator/Desktop/cotton_double/config/1.dcf"),M_DEFAULT,&MilDigitizer0);
|
||||
MdigAlloc(MilSystem,M_DEV1,MIL_TEXT("C:/Users/Administrator/Desktop/cotton_double/config/2.dcf"),M_DEFAULT,&MilDigitizer1);
|
||||
QString config_dir = getConfigDirectory();
|
||||
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分配空间
|
||||
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,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,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分配空间
|
||||
@ -158,17 +159,22 @@ MIL_INT ProcessingFunction0(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr)
|
||||
|
||||
}
|
||||
|
||||
if(SaveImg_Flag)
|
||||
if (SaveImg_Flag)
|
||||
{
|
||||
//拷贝存图图像
|
||||
MbufCopy(ModifiedBufferId0,MilImage0);
|
||||
//Mil保存路径
|
||||
QString MilImgPath = QString("C:/Users/Pc/Desktop/cotton_double2/Img1/%1.bmp").arg(FuncCount0);
|
||||
MIL_STRING MilImagePath = MilImgPath.toStdWString();
|
||||
MbufExport(MilImagePath,M_BMP,MilImage0);
|
||||
qDebug()<<"回调1成功存储照片:"<<FuncCount0<<"张";
|
||||
// 拷贝存图图像
|
||||
MbufCopy(ModifiedBufferId0, MilImage0);
|
||||
cv::Mat img = ImageUtils::mil2Mat(MilImage0);
|
||||
|
||||
// 将图像数据推入存储队列
|
||||
ImageData data;
|
||||
data.camera_id = 0;
|
||||
data.image = img.clone(); // 确保图像数据被复制
|
||||
g_storageQueue.enqueue(data);
|
||||
qDebug() << "Callback0: Enqueued image for camera 0";
|
||||
|
||||
FuncCount0++;
|
||||
}
|
||||
|
||||
#if(GlobalDebug)
|
||||
qDebug()<<"回调1";
|
||||
#endif
|
||||
@ -186,6 +192,15 @@ MIL_INT ProcessingFunction0(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr)
|
||||
//艳丽检测mask
|
||||
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
|
||||
{
|
||||
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);
|
||||
|
||||
tail_0 = newTail;
|
||||
mask_0 = mask_tmp;
|
||||
|
||||
bool isReady;
|
||||
vector<vector<uint8_t>> merged_mask;
|
||||
vector<vector<uint8_t>> mask_tail;
|
||||
|
||||
{
|
||||
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;
|
||||
merged_mask = ImageUtils::mergeMasks(mask_tmp, mask_tmp); // merge the result of onnx and high sat
|
||||
|
||||
// 发送前的处理
|
||||
// 将每个结果左右扩展,扩展半径默认为1
|
||||
auto mask_expaned = expandMaskHorizontally(merged_mask, expansionRaidus);
|
||||
// 将结果的左右补充上0,让物体大小符合要求
|
||||
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()<<"下位机发送失败";
|
||||
}
|
||||
mask_0 = merged_mask;
|
||||
|
||||
detection_ready.release();
|
||||
MbufFree(detection_result0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -255,23 +238,26 @@ MIL_INT ProcessingFunction1(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr)
|
||||
|
||||
// Update the current Img MIl id
|
||||
{
|
||||
QMutexLocker locker(&gDispPicMutex1);
|
||||
gDispCurrentPicId1 = ModifiedBufferId1;
|
||||
QMutexLocker locker(&gDispPicMutex1);
|
||||
gDispCurrentPicId1 = ModifiedBufferId1;
|
||||
}
|
||||
|
||||
if(SaveImg_Flag)
|
||||
if (SaveImg_Flag)
|
||||
{
|
||||
//拷贝存图数据
|
||||
MbufCopy(ModifiedBufferId1,MilImage1);
|
||||
//Mil保存路径
|
||||
QString MilImgPath = QString("C:/Users/Pc/Desktop/cotton_double2/Img2/%1.bmp").arg(FuncCount1);
|
||||
MIL_STRING MilImagePath = MilImgPath.toStdWString();
|
||||
MbufExport(MilImagePath,M_BMP,MilImage1);
|
||||
qDebug()<<"回调2成功存储照片:"<<FuncCount1<<"张";
|
||||
// 拷贝存图图像
|
||||
MbufCopy(ModifiedBufferId1, MilImage1);
|
||||
cv::Mat img = ImageUtils::mil2Mat(MilImage1);
|
||||
|
||||
// 将图像数据推入存储队列
|
||||
ImageData data;
|
||||
data.camera_id = 1;
|
||||
data.image = img.clone(); // 确保图像数据被复制
|
||||
g_storageQueue.enqueue(data);
|
||||
qDebug() << "Callback1: Enqueued image for camera 1";
|
||||
|
||||
FuncCount1++;
|
||||
}
|
||||
|
||||
|
||||
#if (GlobalDebug)
|
||||
qDebug()<<"回调2";
|
||||
#endif
|
||||
@ -286,13 +272,13 @@ MIL_INT ProcessingFunction1(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr)
|
||||
MimResize(MilImage_Color1, MimResizedestination, 0.5, 1 , M_DEFAULT);
|
||||
|
||||
|
||||
|
||||
#if(GlobalDebug && DebugDetectionTime)
|
||||
Timer timer2;
|
||||
#endif
|
||||
//艳丽检测mask
|
||||
high_sat_detect(MimResizedestination, detection_result1, params);
|
||||
|
||||
|
||||
#if(GlobalDebug && DebugDetectionTime)
|
||||
timer2.printElapsedTime("Algorithm Spent: ");
|
||||
#endif
|
||||
@ -313,25 +299,12 @@ MIL_INT ProcessingFunction1(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr)
|
||||
|
||||
tail_1 = newTail;
|
||||
mask_1 = mask_tmp;
|
||||
bool isReady;
|
||||
detection_ready.acquire();
|
||||
vector<vector<uint8_t>> merged_mask;
|
||||
vector<vector<uint8_t>> mask_tail;
|
||||
|
||||
{
|
||||
QMutexLocker locker_self(&imgDetectionReadyMutex);
|
||||
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;
|
||||
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);
|
||||
|
||||
// 发送前的处理
|
||||
// 将每个结果左右扩展,扩展半径默认为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_ignored" + 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);
|
||||
if(!result_Low)
|
||||
@ -353,11 +326,12 @@ MIL_INT ProcessingFunction1(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr)
|
||||
qWarning()<<"下位机发送失败";
|
||||
}
|
||||
|
||||
|
||||
#if(GlobalDebug && DebugDetectionTime)
|
||||
timer_detection_time.printElapsedTime("Time of Processing From Get into Ca"
|
||||
"..0llBack to Sent to Lower Mac");
|
||||
#endif
|
||||
|
||||
MbufFree(detection_result1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -383,8 +357,6 @@ bool DestoryCamera()
|
||||
MbufFree(MilImage_Color1);
|
||||
MbufFree(MilImage_Onnx0);
|
||||
MbufFree(MilImage_Onnx1);
|
||||
MbufFree(detection_result0);
|
||||
MbufFree(detection_result1);
|
||||
MdigFree(MilDigitizer0);
|
||||
MdigFree(MilDigitizer1);
|
||||
MsysFree(MilSystem);
|
||||
@ -663,7 +635,7 @@ std::vector<std::vector<uint8_t>> generateMaskFromImage(const MIL_ID& inputImage
|
||||
// std::cerr << "无法加载图像,请检查路径是否正确: " << imagePath << std::endl;
|
||||
// exit(EXIT_FAILURE);
|
||||
// }
|
||||
cv::Mat image=mil2mat(inputImage);
|
||||
cv::Mat image=ImageUtils::mil2Mat(inputImage);
|
||||
// 确保图像是二值化的
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool iniOnnx()
|
||||
{
|
||||
|
||||
std::string modelPath = "C:/Users/admin/Desktop/config/dimo_11.14.onnx";
|
||||
// std::string imagePath = "C:/Users/admin/Desktop/config/463_12.5_M2.bmp";
|
||||
// cv::Mat image = cv::imread(imagePath);
|
||||
std::string modelPath = (getConfigDirectory() + "/dimo_369_640.onnx").toStdString();
|
||||
|
||||
runner.load(modelPath);
|
||||
|
||||
@ -1004,6 +896,10 @@ bool DestoryLowMac()
|
||||
|
||||
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
|
||||
mask_buf[0] = 0xAA; // 起始标志
|
||||
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] 开始存储数据
|
||||
for (int i = 0; i < 512; i++) // 遍历512行
|
||||
{
|
||||
uint8_t byte = 0;
|
||||
int bit_count = 0;
|
||||
for (int j = 0; j < 64; j++) // 遍历64列
|
||||
{
|
||||
byte = (byte << 1) | (uint8_t)mask[i][j]; // 将每个二进制位加入到字节中
|
||||
bit_count++;
|
||||
if (bit_count == 8 || j == 63) // 每8个二进制位打包成一个字节
|
||||
for (int j = 0; j < int(64 / 8); j++) // 遍历64列
|
||||
{
|
||||
uint8_t byte = 0;
|
||||
for (int bit_idx = 0; bit_idx < 8; bit_idx++)
|
||||
{
|
||||
mask_buf[idx++] = byte;
|
||||
byte = 0; // 重置byte,开始下一个字节
|
||||
bit_count = 0;
|
||||
byte |= (mask[i][ j * 8 + bit_idx] & 0x01) << bit_idx; // 每个字节内,低字节优先
|
||||
}
|
||||
mask_buf[idx++] = byte;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1066,11 +958,10 @@ bool get_valve_data(std::vector<std::vector<uint8_t>> mask)
|
||||
|
||||
delete[] mask_buf; // 释放内存
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Start_camera()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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(
|
||||
const MIL_ID& inputImg,
|
||||
@ -1154,7 +1019,7 @@ vector<vector<uint8_t>> generateMask(
|
||||
int skipLeftCols,
|
||||
int skipRightCols
|
||||
) {
|
||||
cv::Mat image = mil2mat(inputImg);
|
||||
cv::Mat image = ImageUtils::mil2Mat(inputImg);
|
||||
|
||||
// Ensure the image is binary
|
||||
cv::threshold(image, image, 128, 255, cv::THRESH_BINARY);
|
||||
|
||||
1
camera.h
1
camera.h
@ -20,7 +20,6 @@
|
||||
|
||||
#include <QTcpSocket>
|
||||
#include <QTcpServer>
|
||||
|
||||
#include "globals.h"
|
||||
#include "img_utils.h"
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@ SOURCES += \
|
||||
img_utils.cpp \
|
||||
main.cpp \
|
||||
onnxrunner.cpp \
|
||||
storageworker.cpp \
|
||||
widget.cpp
|
||||
|
||||
HEADERS += \
|
||||
@ -21,6 +22,7 @@ HEADERS += \
|
||||
globals.h \
|
||||
img_utils.h \
|
||||
onnxrunner.h \
|
||||
storageworker.h \
|
||||
widget.h
|
||||
|
||||
FORMS += \
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!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>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
|
||||
31
globals.cpp
31
globals.cpp
@ -14,7 +14,30 @@ QMutex gMaskMutex1;
|
||||
MIL_ID gMask1 = 0;
|
||||
|
||||
// 双相机结果同步
|
||||
QMutex imgDetectionReadyMutex;
|
||||
QMutex imgDetectionReady1Mutex;
|
||||
bool imgDetectionReady0 = false;
|
||||
bool imgDetectionReady1 = false;
|
||||
QSemaphore detection_ready(0);
|
||||
|
||||
|
||||
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;
|
||||
|
||||
62
globals.h
62
globals.h
@ -5,6 +5,9 @@
|
||||
#include <MIL.h>
|
||||
#include <QMutex>
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <QSemaphore>
|
||||
#include <QDir>
|
||||
#include <QCoreApplication>
|
||||
|
||||
// 图片显示0
|
||||
extern QMutex gDispPicMutex0;
|
||||
@ -20,9 +23,60 @@ extern MIL_ID gMask0;
|
||||
extern QMutex gMaskMutex1;
|
||||
extern MIL_ID gMask1;
|
||||
|
||||
extern QMutex imgDetectionReadyMutex;
|
||||
extern QMutex imgDetectionReady1Mutex;
|
||||
extern bool imgDetectionReady0;
|
||||
extern bool imgDetectionReady1;
|
||||
extern QSemaphore detection_ready;
|
||||
|
||||
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
|
||||
|
||||
@ -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();
|
||||
}
|
||||
else if(mat.channels() == 3){
|
||||
else if(mat.channels() == 3)
|
||||
{
|
||||
// 彩色图像 (OpenCV 默认是 BGR,需要转换为 RGB)
|
||||
cv::Mat rgb;
|
||||
cv::cvtColor(mat, rgb, cv::COLOR_BGR2RGB);
|
||||
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)
|
||||
cv::Mat rgba;
|
||||
cv::cvtColor(mat, rgba, cv::COLOR_BGRA2RGBA);
|
||||
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();
|
||||
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 };
|
||||
}
|
||||
|
||||
// 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
|
||||
// std::vector<std::vector<uint8_t>> mergeMasks(
|
||||
// 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
|
||||
// ) {
|
||||
|
||||
// }
|
||||
// 将图像保存为文件,传入的image_path指定保存路径和文件名
|
||||
imwrite(image_path, image);
|
||||
}
|
||||
|
||||
@ -40,6 +40,8 @@ public:
|
||||
int roi_width,
|
||||
int roi_height
|
||||
);
|
||||
};
|
||||
|
||||
static void VectorToImg(const std::vector<std::vector<uint8_t> > &array, const std::string &image_path);
|
||||
|
||||
};
|
||||
#endif // IMG_UTILS_H
|
||||
|
||||
@ -17,12 +17,14 @@
|
||||
/
|
||||
/
|
||||
/
|
||||
/
|
||||
/
|
||||
[CAMERA_NAME]
|
||||
no name
|
||||
[CONFIG_FILE]
|
||||
50CF
|
||||
ODYSSEY
|
||||
Mon Dec 9 16:10:06 2024
|
||||
Mon Dec 23 11:31:47 2024
|
||||
[INFO_FILE_REV]
|
||||
0010.0019.0000
|
||||
RADIENT/eVCL/DUAL
|
||||
@ -64,7 +66,7 @@ VDC_IN_CH1
|
||||
VDC_IN_CH2 0x0
|
||||
VDC_IN_CH3 0x0
|
||||
VDC_IN_CH_C 0x0
|
||||
VDC_DIGITIZER 0x0
|
||||
VDC_DIGITIZER 0x1
|
||||
VDC_PSG_MODE_1_CHECK 0x1
|
||||
VDC_PSG_MODE_2_CHECKS 0x0
|
||||
VDC_PSG_MODE_3_CHECKS 0x0
|
||||
@ -111,16 +113,16 @@ VDT_STD_CL
|
||||
VDT_STD_DIGITAL 0x0
|
||||
VDT_NOVERT 0x1
|
||||
VDT_HSYNC 0x0
|
||||
VDT_HBPORCH 0x0
|
||||
VDT_HBPORCH 0x10
|
||||
VDT_HFPORCH 0x0
|
||||
VDT_HACTIVE 0x1000
|
||||
VDT_HTOTAL 0x1000
|
||||
VDT_HSYNC_FREQ 0x4c4b
|
||||
VDT_HTOTAL 0x1010
|
||||
VDT_HSYNC_FREQ 0x4bff
|
||||
VDT_VSYNC 0x0
|
||||
VDT_VBPORCH 0x0
|
||||
VDT_VFPORCH 0x0
|
||||
VDT_VACTIVE 0x400
|
||||
VDT_VTOTAL 0x400
|
||||
VDT_VACTIVE 0x200
|
||||
VDT_VTOTAL 0x200
|
||||
VDT_VSYNC_FREQ 0x0
|
||||
VDT_CL_IMAGE_SIZE_X 0x0
|
||||
VDT_CL_IMAGE_SIZE_Y 0x0
|
||||
@ -1558,11 +1560,11 @@ DEF_INFO_XSIZE_DIVISOR
|
||||
DEF_INFO_YSIZE_DIVISOR 0x1
|
||||
DEF_ADD_HACTIVE_MULTIPLEX 0x0
|
||||
DEF_ADD_VACTIVE_MULTIPLEX 0x0
|
||||
DEF_HTOTAL_ENTRY 0x1000
|
||||
DEF_HTOTAL_ENTRY 0x1010
|
||||
DEF_HACTIVE_ENTRY 0x1000
|
||||
DEF_VTOTAL_ENTRY 0x400
|
||||
DEF_VACTIVE_ENTRY 0x400
|
||||
DEF_CL_NEW_HCROPPING 0x0
|
||||
DEF_VTOTAL_ENTRY 0x200
|
||||
DEF_VACTIVE_ENTRY 0x200
|
||||
DEF_CL_NEW_HCROPPING 0x10
|
||||
DEF_CL_NEW_VCROPPING 0x0
|
||||
DEF_NTSC 0x0
|
||||
DEF_PAL 0x0
|
||||
@ -1576,20 +1578,20 @@ DEF_VINTRL_ODD_EVEN
|
||||
DEF_VSVAL_EQUA_ZERO 0x1
|
||||
DEF_VEVAL_EQUA_VTOTAL 0x1
|
||||
DEF_DIGITIZER_MASTER 0x0
|
||||
DEF_CASE_HVBLANK_ZERO 0x1
|
||||
DEF_ADD_3MAX_TOTAL_HVBLANK_ZERO 0x3
|
||||
DEF_CASE_HVBLANK_ZERO 0x0
|
||||
DEF_ADD_3MAX_TOTAL_HVBLANK_ZERO 0x0
|
||||
DEF_ADD_HTOTAL_EQUA_HEVAL 0x0
|
||||
DEF_HOR_COUNT_MAX_BITWISE 0xffff
|
||||
DEF_VERT_COUNT_MAX_BITWISE 0xffff
|
||||
DEF_DIG_HTOTAL 0x1002
|
||||
DEF_DIG_VTOTAL 0x3ff
|
||||
DEF_DIG_HTOTAL 0x100f
|
||||
DEF_DIG_VTOTAL 0x1ff
|
||||
DEF_TEST_MODE_HFP_MIN 0x0
|
||||
DEF_TEST_MODE_HSY_HBP_MIN_CL 0x0
|
||||
DEF_TEST_MODE_VFP_MIN 0x0
|
||||
DEF_TEST_MODE_VBP_MIN 0x0
|
||||
DEF_TEST_MODE_VS_VBP_MIN_ANA_DIG_CL 0x0
|
||||
DEF_HSVAL_EQUA_ZERO 0x1
|
||||
DEF_HEVAL_EQUA_HTOTAL 0x0
|
||||
DEF_HSVAL_EQUA_ZERO 0x0
|
||||
DEF_HEVAL_EQUA_HTOTAL 0x1
|
||||
DEF_HTOTAL_OVERFLOW 0x0
|
||||
DEF_HACTIVE_OVERFLOW 0x0
|
||||
DEF_VTOTAL_OVERFLOW 0x0
|
||||
@ -1612,8 +1614,8 @@ DEF_TIMER0_PIPE_DELAY1
|
||||
DEF_TIMER1_PIPE_DELAY1 0x0
|
||||
DEF_TMR0_CLKTMR1_CNT 0x0
|
||||
DEF_TMR1_CLKTMR0_CNT 0x0
|
||||
DEF_TIMER01_CLK_HS_FREQ 0x4c41
|
||||
DEF_TIMER01_CLK_HS_PERIOD 0xc81b
|
||||
DEF_TIMER01_CLK_HS_FREQ 0x4c03
|
||||
DEF_TIMER01_CLK_HS_PERIOD 0xc8be
|
||||
DEF_TIMER0_CLK_HS_PERIOD_DLY1_CNT 0x0
|
||||
DEF_TIMER0_CLK_HS_PERIOD_DLY2_CNT 0x0
|
||||
DEF_TIMER0_CLK_HS_PERIOD_T1_CNT 0x0
|
||||
@ -1729,7 +1731,7 @@ DEF_DIG1_BYTESORDER
|
||||
INFO_CUSTOM 0x0
|
||||
INFO_REGISTER_REV 0x1
|
||||
INFO_XSIZE 0x1000
|
||||
INFO_YSIZE 0x400
|
||||
INFO_YSIZE 0x200
|
||||
INFO_TYPE 0x1
|
||||
INFO_BAYER 0x0
|
||||
INFO_BURSTSIZE 0x0
|
||||
@ -1922,18 +1924,18 @@ INFO_MASK_T2CTLH
|
||||
INFO_MASK_T3CTLL 0x0
|
||||
INFO_MASK_T3CTLH 0x0
|
||||
DIG_HCNT 0x1
|
||||
DIG_HTOTAL 0x1002
|
||||
DIG_HTOTAL 0x100f
|
||||
DIG_HSCNT 0x0
|
||||
DIG_HECNT 0x1
|
||||
DIG_HSSYNC 0x0
|
||||
DIG_HESYNC 0x0
|
||||
DIG_HSVAL 0x0
|
||||
DIG_HEVAL 0xfff
|
||||
DIG_HSVAL 0x10
|
||||
DIG_HEVAL 0x100f
|
||||
DIG_HSCLM 0x0
|
||||
DIG_HECLM 0x0
|
||||
DIG_HCTL 0x1e0
|
||||
DIG_VCNT 0x1
|
||||
DIG_VTOTAL 0x3ff
|
||||
DIG_VTOTAL 0x1ff
|
||||
DIG_VSCNT 0x0
|
||||
DIG_VECNT 0x0
|
||||
DIG_VSSYNC 0x0
|
||||
@ -2348,5 +2350,5 @@ DIG_IOCTL1H
|
||||
DIG_IOCTL0_L not_modified
|
||||
DIG_ENCTL not_modified
|
||||
[EOF]
|
||||
00007FF687B3AAA8 0x400b8
|
||||
00007FF687B3AA90 0x48b1c582
|
||||
00007FF72205AAA8 0x400c2
|
||||
00007FF72205AA90 0x48b9cbd0
|
||||
52
release/config/color_range_config.txt
Normal file
52
release/config/color_range_config.txt
Normal 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
|
||||
276
ui_widget.h
276
ui_widget.h
@ -11,11 +11,17 @@
|
||||
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QtWidgets/QCheckBox>
|
||||
#include <QtWidgets/QFrame>
|
||||
#include <QtWidgets/QGridLayout>
|
||||
#include <QtWidgets/QGroupBox>
|
||||
#include <QtWidgets/QHBoxLayout>
|
||||
#include <QtWidgets/QLabel>
|
||||
#include <QtWidgets/QPushButton>
|
||||
#include <QtWidgets/QSpacerItem>
|
||||
#include <QtWidgets/QSpinBox>
|
||||
#include <QtWidgets/QTabWidget>
|
||||
#include <QtWidgets/QVBoxLayout>
|
||||
#include <QtWidgets/QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -23,24 +29,46 @@ QT_BEGIN_NAMESPACE
|
||||
class Ui_Widget
|
||||
{
|
||||
public:
|
||||
QHBoxLayout *horizontalLayout;
|
||||
QTabWidget *tabWidget;
|
||||
QWidget *tab;
|
||||
QPushButton *pushButton;
|
||||
QPushButton *pushButton_2;
|
||||
QVBoxLayout *verticalLayout;
|
||||
QGroupBox *groupBox_5;
|
||||
QGridLayout *gridLayout;
|
||||
QPushButton *btn_goto_sort;
|
||||
QPushButton *btn_0to3;
|
||||
QPushButton *pushButtonStart;
|
||||
QPushButton *pushButton_2;
|
||||
QGroupBox *groupBox;
|
||||
QHBoxLayout *horizontalLayout_2;
|
||||
QLabel *label;
|
||||
QLabel *lab_lowermachine_isconnect;
|
||||
QPushButton *btn_reconnect;
|
||||
QWidget *tab_2;
|
||||
QHBoxLayout *horizontalLayout_3;
|
||||
QGroupBox *groupBox_7;
|
||||
QVBoxLayout *verticalLayout_3;
|
||||
QLabel *lab_info;
|
||||
QPushButton *btn_start;
|
||||
QPushButton *btn_take_photos;
|
||||
QPushButton *btn_stop;
|
||||
QLabel *camera_0_img;
|
||||
QLabel *camera_1_img;
|
||||
QSpacerItem *verticalSpacer;
|
||||
QFrame *frame_6;
|
||||
QVBoxLayout *verticalLayout_2;
|
||||
QFrame *frame;
|
||||
QHBoxLayout *horizontalLayout_4;
|
||||
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;
|
||||
QLabel *label_title_3;
|
||||
QGroupBox *groupBox_4;
|
||||
@ -67,33 +95,55 @@ public:
|
||||
{
|
||||
if (Widget->objectName().isEmpty())
|
||||
Widget->setObjectName("Widget");
|
||||
Widget->resize(800, 600);
|
||||
Widget->resize(1920, 1080);
|
||||
horizontalLayout = new QHBoxLayout(Widget);
|
||||
horizontalLayout->setObjectName("horizontalLayout");
|
||||
tabWidget = new QTabWidget(Widget);
|
||||
tabWidget->setObjectName("tabWidget");
|
||||
tabWidget->setGeometry(QRect(0, 0, 801, 601));
|
||||
tabWidget->setEnabled(true);
|
||||
tab = new QWidget();
|
||||
tab->setObjectName("tab");
|
||||
pushButton = new QPushButton(tab);
|
||||
pushButton->setObjectName("pushButton");
|
||||
pushButton->setGeometry(QRect(100, 130, 201, 61));
|
||||
pushButton_2 = new QPushButton(tab);
|
||||
pushButton_2->setObjectName("pushButton_2");
|
||||
pushButton_2->setGeometry(QRect(400, 120, 181, 71));
|
||||
btn_goto_sort = new QPushButton(tab);
|
||||
verticalLayout = new QVBoxLayout(tab);
|
||||
verticalLayout->setObjectName("verticalLayout");
|
||||
groupBox_5 = new QGroupBox(tab);
|
||||
groupBox_5->setObjectName("groupBox_5");
|
||||
gridLayout = new QGridLayout(groupBox_5);
|
||||
gridLayout->setObjectName("gridLayout");
|
||||
btn_goto_sort = new QPushButton(groupBox_5);
|
||||
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->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->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->setObjectName("label");
|
||||
label->setGeometry(QRect(40, 70, 41, 16));
|
||||
|
||||
horizontalLayout_2->addWidget(label);
|
||||
|
||||
lab_lowermachine_isconnect = new QLabel(groupBox);
|
||||
lab_lowermachine_isconnect->setObjectName("lab_lowermachine_isconnect");
|
||||
lab_lowermachine_isconnect->setGeometry(QRect(90, 60, 31, 31));
|
||||
QPalette palette;
|
||||
QBrush brush(QColor(237, 212, 0, 255));
|
||||
brush.setStyle(Qt::SolidPattern);
|
||||
@ -112,41 +162,163 @@ public:
|
||||
palette.setBrush(QPalette::Disabled, QPalette::Window, brush);
|
||||
palette.setBrush(QPalette::Disabled, QPalette::AlternateBase, brush1);
|
||||
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->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());
|
||||
tab_2 = new QWidget();
|
||||
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->setGeometry(QRect(20, 50, 151, 81));
|
||||
lab_info->setEnabled(true);
|
||||
QFont font;
|
||||
font.setPointSize(28);
|
||||
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->setGeometry(QRect(20, 130, 101, 41));
|
||||
btn_stop = new QPushButton(tab_2);
|
||||
btn_start->setMinimumSize(QSize(70, 200));
|
||||
|
||||
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->setGeometry(QRect(20, 190, 101, 41));
|
||||
camera_0_img = new QLabel(tab_2);
|
||||
camera_0_img->setObjectName("camera_0_img");
|
||||
camera_0_img->setGeometry(QRect(160, 40, 591, 191));
|
||||
camera_0_img->setStyleSheet(QString::fromUtf8("background-color: rgb(129, 129, 129);\n"
|
||||
"border: 4px solid black;"));
|
||||
camera_1_img = new QLabel(tab_2);
|
||||
btn_stop->setMinimumSize(QSize(70, 200));
|
||||
|
||||
verticalLayout_3->addWidget(btn_stop);
|
||||
|
||||
verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Expanding);
|
||||
|
||||
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->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"
|
||||
"border: 4px solid black;"));
|
||||
camera_1_img->setLineWidth(1);
|
||||
label_2 = new QLabel(tab_2);
|
||||
label_2->setObjectName("label_2");
|
||||
label_2->setGeometry(QRect(160, 270, 141, 16));
|
||||
label_3 = new QLabel(tab_2);
|
||||
label_3->setObjectName("label_3");
|
||||
label_3->setGeometry(QRect(160, 20, 141, 16));
|
||||
|
||||
verticalLayout_2->addWidget(camera_1_img);
|
||||
|
||||
frame_2 = new QFrame(frame_6);
|
||||
frame_2->setObjectName("frame_2");
|
||||
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());
|
||||
tab_3 = new QWidget();
|
||||
tab_3->setObjectName("tab_3");
|
||||
@ -215,6 +387,9 @@ public:
|
||||
btn_stop_test->setGeometry(QRect(210, 40, 75, 23));
|
||||
tabWidget->addTab(tab_4, QString());
|
||||
|
||||
horizontalLayout->addWidget(tabWidget);
|
||||
|
||||
|
||||
retranslateUi(Widget);
|
||||
|
||||
tabWidget->setCurrentIndex(1);
|
||||
@ -226,22 +401,29 @@ public:
|
||||
void retranslateUi(QWidget *Widget)
|
||||
{
|
||||
Widget->setWindowTitle(QCoreApplication::translate("Widget", "Widget", nullptr));
|
||||
pushButton->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_5->setTitle(QCoreApplication::translate("Widget", "GroupBox", 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));
|
||||
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));
|
||||
label->setText(QCoreApplication::translate("Widget", "\344\270\213\344\275\215\346\234\272", nullptr));
|
||||
lab_lowermachine_isconnect->setText(QString());
|
||||
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));
|
||||
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_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));
|
||||
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_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));
|
||||
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));
|
||||
|
||||
219
widget.cpp
219
widget.cpp
@ -14,25 +14,39 @@
|
||||
#include <QDateTime>
|
||||
#include <img_utils.h>
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
// 硬编码参数值
|
||||
int file_delay = 1270; // 延迟时间(毫秒)
|
||||
int file_encoder = 12000; // 编码器值++
|
||||
int file_valve = 200; // 阀门通道
|
||||
|
||||
Widget::Widget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::Widget)
|
||||
{
|
||||
this->isCamRunning = false;
|
||||
|
||||
ui->setupUi(this);
|
||||
ui->camera_0_img->setScaledContents(true);
|
||||
|
||||
ui->camera_0_img->setScaledContents(false);
|
||||
ui->camera_1_img->setScaledContents(false);
|
||||
|
||||
iniOnnx();
|
||||
iniColor();
|
||||
iniLowMac();
|
||||
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);
|
||||
connect(timer, &QTimer::timeout, this, &Widget::refreshImage);
|
||||
@ -41,89 +55,124 @@ Widget::Widget(QWidget *parent)
|
||||
|
||||
Widget::~Widget()
|
||||
{
|
||||
// DestoryCamera();
|
||||
// 停止存储线程
|
||||
g_storageQueue.stop();
|
||||
storageThread.quit();
|
||||
storageThread.wait();
|
||||
|
||||
// 现有清理代码...
|
||||
DestoryCamera();
|
||||
DestoryLowMac();
|
||||
|
||||
delete ui;
|
||||
|
||||
}
|
||||
|
||||
void Widget::refreshImage()
|
||||
{
|
||||
refreshSingleImage(0);
|
||||
refreshSingleImage(1);
|
||||
// refresh Image 1 and image 0
|
||||
refreshSingleImage(0, this->ui->img_0_overlay->isChecked(), this->ui->img_0_mirror->isChecked());
|
||||
refreshSingleImage(1, this->ui->img_1_overlay->isChecked(), this->ui->img_1_mirror->isChecked());
|
||||
// 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
|
||||
MIL_ID current_id = 0;
|
||||
if (camera_id == 0)
|
||||
{ // 获取当前图片
|
||||
// 验证摄像头ID的有效性
|
||||
if (camera_id < 0 || camera_id >= 2) { // 假设只有两个摄像头
|
||||
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);
|
||||
current_id = gDispCurrentPicId0;
|
||||
QMutexLocker locker(currentMaskMutex);
|
||||
mask_id = maskIds[camera_id];
|
||||
}
|
||||
if (current_id == 0)
|
||||
return;
|
||||
cv::Mat img = ImageUtils::mil2Mat(current_id);
|
||||
//进行结果的转化叠加
|
||||
if (overlay_result)
|
||||
{
|
||||
MIL_ID mask_id = 0;
|
||||
{
|
||||
QMutexLocker locker(&gMaskMutex0);
|
||||
mask_id = gMask0;
|
||||
}
|
||||
|
||||
if (mask_id != 0) {
|
||||
cv::Mat mask = ImageUtils::mil2Mat(mask_id);
|
||||
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);
|
||||
if (!mask.empty()) {
|
||||
img = ImageUtils::overlayResultOnInput(img, mask, 0.5);
|
||||
}
|
||||
//刷新显示
|
||||
QPixmap pixmap1 = ImageUtils::mat2QPixmap(img);
|
||||
if (!pixmap1.isNull())
|
||||
{
|
||||
ui->camera_1_img->setPixmap(pixmap1);
|
||||
|
||||
else {
|
||||
qWarning() << "Failed to convert MIL mask to Mat for Camera ID:" << camera_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
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()
|
||||
{
|
||||
SaveImg_Flag = 1;
|
||||
@ -147,3 +196,41 @@ void Widget::on_btn_goto_sort_clicked()
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
19
widget.h
19
widget.h
@ -1,11 +1,12 @@
|
||||
#ifndef WIDGET_H
|
||||
#define WIDGET_H
|
||||
|
||||
#include <QThread>
|
||||
#include <QWidget>
|
||||
#include <camera.h>
|
||||
#include <QTcpServer>
|
||||
#include <QPushButton>
|
||||
#include "globals.h"
|
||||
#include "storageworker.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui {
|
||||
@ -26,17 +27,27 @@ public slots:
|
||||
|
||||
private slots:
|
||||
|
||||
void refreshSingleImage(int camera_id, bool overlay_result = true);
|
||||
|
||||
void on_pushButton_clicked();
|
||||
void refreshSingleImage(int camera_id, bool overlay_result = true, bool mirror = false);
|
||||
|
||||
void on_pushButton_2_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:
|
||||
Ui::Widget *ui;
|
||||
|
||||
bool isCamRunning;
|
||||
|
||||
QThread storageThread; // 存储线程
|
||||
StorageWorker* storageWorker; // 存储工作者
|
||||
|
||||
};
|
||||
#endif // WIDGET_H
|
||||
|
||||
Loading…
Reference in New Issue
Block a user