relative path version

This commit is contained in:
XinJiang1 2024-12-22 22:29:54 +08:00
parent 18e2f3080d
commit 50b8c37a9c
13 changed files with 4848 additions and 147 deletions

1
.gitignore vendored
View File

@ -5,4 +5,5 @@ debug
.qtc_clangd
Makefile*
*.pro.user*
*.pro.user
.idea

View File

@ -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);
@ -615,7 +616,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);
@ -695,102 +696,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 modelPath = (getConfigDirectory() + "/dimo_11.14.onnx").toStdString();
// std::string imagePath = "C:/Users/admin/Desktop/config/463_12.5_M2.bmp";
// cv::Mat image = cv::imread(imagePath);
@ -1070,32 +993,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,
@ -1105,7 +1002,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);

View File

@ -15,3 +15,27 @@ MIL_ID gMask1 = 0;
// 双相机结果同步
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;
}

View File

@ -6,6 +6,8 @@
#include <QMutex>
#include <opencv2/opencv.hpp>
#include <QSemaphore>
#include <QDir>
#include <QCoreApplication>
// 图片显示0
extern QMutex gDispPicMutex0;
@ -23,4 +25,7 @@ extern MIL_ID gMask1;
extern QSemaphore detection_ready;
QString getSaveDirectory();
QString getConfigDirectory();
#endif // GLOBALS_H

View File

@ -256,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);
}

View File

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

2356
release/config/1.dcf Normal file

File diff suppressed because it is too large Load Diff

2353
release/config/2.dcf Normal file

File diff suppressed because it is too large Load Diff

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

@ -35,7 +35,7 @@ public:
QPushButton *btn_reconnect;
QWidget *tab_2;
QLabel *lab_info;
QPushButton *pushButton;
QPushButton *btn_start;
QPushButton *btn_stop;
QLabel *camera_1_img;
QLabel *label_2;
@ -124,9 +124,9 @@ public:
QFont font;
font.setPointSize(28);
lab_info->setFont(font);
pushButton = new QPushButton(tab_2);
pushButton->setObjectName("pushButton");
pushButton->setGeometry(QRect(20, 130, 101, 41));
btn_start = new QPushButton(tab_2);
btn_start->setObjectName("btn_start");
btn_start->setGeometry(QRect(20, 130, 101, 41));
btn_stop = new QPushButton(tab_2);
btn_stop->setObjectName("btn_stop");
btn_stop->setGeometry(QRect(20, 190, 101, 41));
@ -237,7 +237,7 @@ public:
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));
pushButton->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_stop->setText(QCoreApplication::translate("Widget", "\345\201\234\346\255\242\345\210\206\351\200\211", nullptr));
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));

View File

@ -25,11 +25,12 @@ Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
this->isCamRunning = false;
ui->setupUi(this);
ui->camera_0_img->setScaledContents(true);
ui->camera_1_img->setScaledContents(true);
iniColor();
iniLowMac();
iniCamera();
@ -48,8 +49,12 @@ Widget::~Widget()
void Widget::refreshImage()
{
// refresh Image 1 and image 0
refreshSingleImage(0, false);
refreshSingleImage(1, false);
// refresh buttons
this->ui->btn_start->setEnabled(!this->isCamRunning);
this->ui->btn_stop->setEnabled(this->isCamRunning);
}
void Widget::refreshSingleImage(int camera_id, bool overlay_result)
@ -118,10 +123,6 @@ void Widget::refreshSingleImage(int camera_id, bool overlay_result)
}
void Widget::on_pushButton_clicked()
{
Start_camera();
}
void Widget::on_pushButton_2_clicked()
{
@ -149,7 +150,8 @@ void Widget::on_btn_goto_sort_clicked()
void Widget::on_btn_stop_clicked()
{
// 回复显示的图片
this->isCamRunning = false;
// 恢复显示的图片
{
QMutexLocker locker(&gDispPicMutex0);
gDispCurrentPicId0 = 0;
@ -164,3 +166,10 @@ void Widget::on_btn_stop_clicked()
DestoryLowMac();
}
void Widget::on_btn_start_clicked()
{
this->isCamRunning = true;
Start_camera();
}

View File

@ -28,17 +28,18 @@ private slots:
void refreshSingleImage(int camera_id, bool overlay_result = true);
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_btn_goto_sort_clicked();
void on_btn_stop_clicked();
void on_btn_start_clicked();
private:
Ui::Widget *ui;
bool isCamRunning;
};
#endif // WIDGET_H

View File

@ -274,7 +274,7 @@
<string>准备中</string>
</property>
</widget>
<widget class="QPushButton" name="pushButton">
<widget class="QPushButton" name="btn_start">
<property name="geometry">
<rect>
<x>20</x>