双相机 v1.0

This commit is contained in:
XinJiang1 2024-12-21 23:41:15 +08:00
parent 0bd7b2b8f1
commit 49240c7ba5
6 changed files with 47 additions and 34 deletions

View File

@ -3,7 +3,7 @@
#include <QTimer> #include <QTimer>
// Debug Options // Debug Options
#define GlobalDebug 0 // 全局是否允许打印Debug信息打印会拖慢处理时间 #define GlobalDebug 1 // 全局是否允许打印Debug信息打印会拖慢处理时间
#define DebugDetection 0 // 注意开启这个编译选项会导致图片存储, 处理时间会很慢 #define DebugDetection 0 // 注意开启这个编译选项会导致图片存储, 处理时间会很慢
#define DebugDetectionTime 0 // 是否打印处理时间 #define DebugDetectionTime 0 // 是否打印处理时间
#define DebugLowerMacCOM 0 // 是否打印和下位机通讯的相关信息 #define DebugLowerMacCOM 0 // 是否打印和下位机通讯的相关信息
@ -154,7 +154,6 @@ MIL_INT ProcessingFunction0(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr)
{ {
QMutexLocker locker(&gDispPicMutex0); QMutexLocker locker(&gDispPicMutex0);
// MbufCopy(ModifiedBufferId0,gDispCurrentPic0);
gDispCurrentPicId0 = ModifiedBufferId0; gDispCurrentPicId0 = ModifiedBufferId0;
} }
@ -194,18 +193,18 @@ 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; mask_0 = mask_tmp;
bool isReady; bool isReady;
vector<vector<uint8_t>> merged_mask; vector<vector<uint8_t>> merged_mask;
vector<vector<uint8_t>> mask_tail; vector<vector<uint8_t>> mask_tail;
{ {
QMutexLocker locker_self(&imgDetectionReady0Mutex); QMutexLocker locker_self(&imgDetectionReadyMutex);
imgDetectionReady1 = true; imgDetectionReady0 = true;
QMutexLocker locker_other(&imgDetectionReady1Mutex); // QMutexLocker locker_other(&imgDetectionReady1Mutex);
isReady = imgDetectionReady0 & imgDetectionReady1; isReady = imgDetectionReady0 & imgDetectionReady1;
if(isReady) if(isReady)
{ {
@ -319,9 +318,9 @@ MIL_INT ProcessingFunction1(MIL_INT HookType, MIL_ID HookId, void *HookDataPtr)
vector<vector<uint8_t>> mask_tail; vector<vector<uint8_t>> mask_tail;
{ {
QMutexLocker locker_self(&imgDetectionReady1Mutex); QMutexLocker locker_self(&imgDetectionReadyMutex);
imgDetectionReady1 = true; imgDetectionReady1 = true;
QMutexLocker locker_other(&imgDetectionReady0Mutex); // QMutexLocker locker_other(&imgDetectionReady0Mutex);
isReady = imgDetectionReady0 & imgDetectionReady1; isReady = imgDetectionReady0 & imgDetectionReady1;
if(isReady) if(isReady)
@ -794,9 +793,9 @@ Mat mil2mat(const MIL_ID mil_img) {
if (channels == 3) { if (channels == 3) {
// 多通道图像,分通道读取 // 多通道图像,分通道读取
MIL_ID redChannel, greenChannel, blueChannel; MIL_ID redChannel, greenChannel, blueChannel;
MbufAlloc2d(M_DEFAULT, width, height, 8 + M_UNSIGNED, M_IMAGE + M_PROC, &redChannel); MbufAlloc2d(MilSystem, width, height, 8 + M_UNSIGNED, M_IMAGE + M_PROC, &redChannel);
MbufAlloc2d(M_DEFAULT, width, height, 8 + M_UNSIGNED, M_IMAGE + M_PROC, &greenChannel); MbufAlloc2d(MilSystem, width, height, 8 + M_UNSIGNED, M_IMAGE + M_PROC, &greenChannel);
MbufAlloc2d(M_DEFAULT, width, height, 8 + M_UNSIGNED, M_IMAGE + M_PROC, &blueChannel); MbufAlloc2d(MilSystem, width, height, 8 + M_UNSIGNED, M_IMAGE + M_PROC, &blueChannel);
// 将 MIL 图像的各个通道复制到单通道缓冲区 // 将 MIL 图像的各个通道复制到单通道缓冲区
MbufCopyColor(mil_img, redChannel, M_RED); MbufCopyColor(mil_img, redChannel, M_RED);

View File

@ -14,7 +14,7 @@ QMutex gMaskMutex1;
MIL_ID gMask1 = 0; MIL_ID gMask1 = 0;
// 双相机结果同步 // 双相机结果同步
QMutex imgDetectionReady0Mutex; QMutex imgDetectionReadyMutex;
QMutex imgDetectionReady1Mutex; QMutex imgDetectionReady1Mutex;
bool imgDetectionReady0 = false; bool imgDetectionReady0 = false;
bool imgDetectionReady1 = false; bool imgDetectionReady1 = false;

View File

@ -20,7 +20,7 @@ extern MIL_ID gMask0;
extern QMutex gMaskMutex1; extern QMutex gMaskMutex1;
extern MIL_ID gMask1; extern MIL_ID gMask1;
extern QMutex imgDetectionReady0Mutex; extern QMutex imgDetectionReadyMutex;
extern QMutex imgDetectionReady1Mutex; extern QMutex imgDetectionReady1Mutex;
extern bool imgDetectionReady0; extern bool imgDetectionReady0;
extern bool imgDetectionReady1; extern bool imgDetectionReady1;

View File

@ -95,7 +95,6 @@ cv::Mat ImageUtils::mil2Mat(const MIL_ID mil_img)
// 不支持的通道数 // 不支持的通道数
std::cerr << "[Error] Unsupported number of channels: " << channels << std::endl; std::cerr << "[Error] Unsupported number of channels: " << channels << std::endl;
return Mat(); return Mat();
} }
void ImageUtils::convert_to_uint8(const MIL_ID& input_img, MIL_ID& output_img) { void ImageUtils::convert_to_uint8(const MIL_ID& input_img, MIL_ID& output_img) {
@ -115,7 +114,8 @@ void ImageUtils::convert_to_uint8(const MIL_ID& input_img, MIL_ID& output_img) {
} }
} }
cv::Mat overlayResultOnInput(const cv::Mat& cv_input, const cv::Mat& total_result, double alpha = 0.5, int colormap = cv::COLORMAP_JET) { cv::Mat ImageUtils::overlayResultOnInput(const cv::Mat &cv_input, const cv::Mat &total_result, double alpha, int colormap)
{
// 1. 确保 total_result 的尺寸与 cv_input 一致 // 1. 确保 total_result 的尺寸与 cv_input 一致
cv::Mat resized_total_result; cv::Mat resized_total_result;
if (total_result.size() != cv_input.size()) { if (total_result.size() != cv_input.size()) {
@ -153,13 +153,8 @@ cv::Mat overlayResultOnInput(const cv::Mat& cv_input, const cv::Mat& total_resul
return overlay; return overlay;
} }
std::vector<std::vector<uint8_t> > ImageUtils::mergeMasks(const std::vector<std::vector<uint8_t> > &mask1, const std::vector<std::vector<uint8_t> > &mask2, int offset_y)
// 合并两个二值掩码,通过按位或操作,并考虑垂直偏移 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
) {
if (mask1.empty() || mask1[0].empty() || mask2.empty() || mask2[0].empty()) { if (mask1.empty() || mask1[0].empty() || mask2.empty() || mask2[0].empty()) {
throw std::invalid_argument("输入的掩码不能为空"); throw std::invalid_argument("输入的掩码不能为空");
} }
@ -220,15 +215,8 @@ std::vector<std::vector<uint8_t>> mergeMasks(
return merged_mask; return merged_mask;
} }
// 提取 ROI 并返回剩余部分 std::pair<std::vector<std::vector<uint8_t> >, std::vector<std::vector<uint8_t> > > ImageUtils::extractROI(const std::vector<std::vector<uint8_t> > &merged_mask, int roi_x, int roi_y, int roi_width, int roi_height)
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
) {
if (merged_mask.empty() || merged_mask[0].empty()) { if (merged_mask.empty() || merged_mask[0].empty()) {
throw std::invalid_argument("merged_mask 不能为空"); throw std::invalid_argument("merged_mask 不能为空");
} }
@ -264,3 +252,29 @@ extractROI(
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) {
// }
// 合并两个二值掩码,通过按位或操作,并考虑垂直偏移 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
// ) {
// }

View File

@ -6,7 +6,6 @@
#include <QImage> #include <QImage>
#include <opencv2/opencv.hpp> #include <opencv2/opencv.hpp>
#include <Mil.h> #include <Mil.h>
#include <camera.h>
#include <utility> #include <utility>
extern MIL_ID MilSystem; extern MIL_ID MilSystem;
@ -32,6 +31,7 @@ public:
int offset_y = 0 int offset_y = 0
); );
static std::pair<std::vector<std::vector<uint8_t>>, std::vector<std::vector<uint8_t>>> static std::pair<std::vector<std::vector<uint8_t>>, std::vector<std::vector<uint8_t>>>
extractROI( extractROI(
const std::vector<std::vector<uint8_t>>& merged_mask, const std::vector<std::vector<uint8_t>>& merged_mask,

View File

@ -36,7 +36,7 @@ Widget::Widget(QWidget *parent)
// 启动显示定时器,每秒检查一次 // 启动显示定时器,每秒检查一次
QTimer* timer = new QTimer(this); QTimer* timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &Widget::refreshImage); connect(timer, &QTimer::timeout, this, &Widget::refreshImage);
timer->start(100); // 每50毫秒秒刷新一次界面 timer->start(50); // 每50毫秒秒刷新一次界面
} }
Widget::~Widget() Widget::~Widget()