#include "widget.h" #include "ui_widget.h" #include #include #include #include #include #include // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; // 硬编码参数值 int file_delay = 1180; // 延迟时间(毫秒) int file_encoder = 12000; // 行频 int file_valve = 200; // 喷阀触发频率 //下位机参数 int lowmac_dp = 350; //偏振延迟时间 int lowmac_sm = 1200; //吹气量 valve/12 = 吹气时间ms int lowmac_ts = 10; //模板匹配阈值 int lowmac_sg = 65; //偏振绿色通道大小阈值 int lowmac_td = 7; //偏振红色通道差值 Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { this->isCamRunning = false; ui->setupUi(this); // 确认 tabWidget 是 QTabWidget 类型 QTabWidget* tab = qobject_cast(ui->tabWidget); if (tab) { QTabBar* tabBar = tab->tabBar(); if (tabBar) { tabBar->hide(); // 隐藏 TabBar } else { qWarning() << "tabBar() 返回 nullptr!"; } } else { qWarning() << "ui->tabWidget 不是 QTabWidget 类型!"; } ui->camera_0_img->setScaledContents(false); ui->camera_1_img->setScaledContents(false); iniOnnx(); // iniColor(); loadConfig(getConfigDirectory()+"/color_range_config.txt"); // 读取配置文件 iniLowMac(); iniCamera(); update_machine_num(); update_colorlist(); // 更新色彩列表 update_polar(); // 更新偏振相机界面 // 初始化存储工作者和线程 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); timer->start(40); // 每40毫秒秒刷新一次界面 ui->tabWidget->setCurrentIndex(1); // on_btn_start_clicked(); // 显示启动倒计时 showStartupCountdown(); } void Widget::showStartupCountdown() { CountdownDialog* countdown = new CountdownDialog(10, this); countdown->setAttribute(Qt::WA_DeleteOnClose); // 对话框关闭后自动删除 // 连接倒计时完成信号 connect(countdown, &CountdownDialog::countdownFinished, this, &Widget::onCountdownFinished); // 连接对话框的关闭事件,以处理用户提前关闭 connect(countdown, &QDialog::rejected, this, &Widget::onCountdownCancelled); countdown->show(); // 非模态显示,允许用户在倒计时期间与主窗口交互 } void Widget::onCountdownCancelled() { qDebug() << "用户取消了启动倒计时。"; // 根据需求处理取消后的操作,例如不启动识别任务 // 可以选择什么都不做,或者提供提示 } void Widget::onCountdownFinished() { qDebug() << "启动倒计时结束,继续执行开机操作。"; on_btn_start_clicked(); } Widget::~Widget() { // 停止存储线程 g_storageQueue.stop(); storageThread.quit(); storageThread.wait(); // 现有清理代码... DestoryCamera(); DestoryLowMac(); delete ui; } void Widget::refreshImage() { // refresh Image 1 and image 0 refreshSingleImage(0, this->ui->mtx_0_overlay->isChecked(), this->ui->dl_0_overlay->isChecked(), this->ui->img_0_mirror->isChecked()); refreshSingleImage(1, this->ui->mtx_1_overlay->isChecked(), this->ui->dl_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 checkouts this->ui->dl_enable_0->setEnabled(!this->isCamRunning); this->ui->dl_enable_1->setEnabled(!this->isCamRunning); this->ui->tra_enable_0->setEnabled(!this->isCamRunning); this->ui->tra_enable_1->setEnabled(!this->isCamRunning); this->ui->btn_quit->setEnabled(!this->isCamRunning); // refresh settings buttons this->ui->btn_setColor->setEnabled(!this->isCamRunning); this->ui->btn_reset_color->setEnabled(!this->isCamRunning); this->ui->btn_del_color->setEnabled(!this->isCamRunning); this->ui->btn_add_color->setEnabled(!this->isCamRunning); this->ui->btn_reset_polar->setEnabled(!this->isCamRunning); this->ui->btn_save_polar->setEnabled(!this->isCamRunning); this->ui->btn_set_lower->setEnabled(!this->isCamRunning); // QDateTime now = QDateTime::currentDateTime(); ui->label_currentDateTime->setText(now.toString("yyyy-MM-dd hh:mm:ss")); if (this->isCamRunning) { // 计算启动至今的秒数差 qint64 elapsedSeconds = this->startTime.secsTo(now); // 转化为小时、分钟、秒 qint64 hours = elapsedSeconds / 3600; qint64 minutes = (elapsedSeconds % 3600) / 60; qint64 seconds = elapsedSeconds % 60; // 将“总运行时间”的小时/分钟分别更新到 UI ui->label_totalHours->setText(QString::number(hours)); // e.g. "482" ui->label_totalMinutes->setText(QString::number(minutes)); // e.g. "52" // 拼接“今日运行时长”一句话 (根据实际需求,可直接使用上面 hours、minutes、seconds) QString todayRunStr = QString("今日运行时长:%1小时%2分钟%3秒") .arg(hours) .arg(minutes) .arg(seconds); ui->label_todayRunningTime->setText(todayRunStr); } else { // 如果设备没在运行,UI可以显示默认内容或保持不变 // 下面示例:将运行时长重置为 0 ui->label_totalHours->setText("0"); ui->label_totalMinutes->setText("0"); ui->label_todayRunningTime->setText("今日运行时长:0小时0分钟0秒"); } // refresh info QString info; if(this->isCamRunning) { if(SaveImg_Flag==1) { info = "存图中!!"; } else { if(g_camera_error.load()){ info = "图像问题!!!"; } else { info = "运行"; } }; }else { info = "停止"; }; this->ui->lab_info->setText(info); ui->label_valve_actions->setText(QLocale(QLocale::English).toString(g_valveActionCount)); } void Widget::refreshSingleImage(int camera_id, bool overlay_traditional_result, bool overlay_dl_result, bool mirror) { // 验证摄像头ID的有效性 if (camera_id < 0 || camera_id >= 2) { // 假设只有两个摄像头 qWarning() << "Invalid Camera ID:" << camera_id; return; } // 定义每个摄像头对应的 QLabel QLabel* cameraLabels[2] = { ui->camera_0_img, ui->camera_1_img }; // 定义每个摄像头对应的变量数组 QMutex* dispPicMutexes[2] = { &gDispPicMutex0, &gDispPicMutex1 }; MIL_ID dispCurrentPicIds[2] = { gDispCurrentPicId0, gDispCurrentPicId1 }; // 获取当前摄像头的数据 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 (current_id == 0) return; std::vector> dl_mask; std::vector> traditional_mask; { QMutexLocker locker(&g_detection_result[camera_id].mutex); dl_mask = g_detection_result[camera_id].dl_mask; traditional_mask = g_detection_result[camera_id].traditional_mask; } // 如果需要叠加结果,处理掩码 if (overlay_dl_result && g_dl_enable[camera_id]) { if (!dl_mask.empty() && !dl_mask[0].empty()) { // 将二维 vector 转换为 cv::Mat int rows = dl_mask.size(); int cols = dl_mask[0].size(); cv::Mat dl_mask_mat(rows, cols, CV_8U); for (int i = 0; i < rows; ++i) { if (dl_mask[i].size() != cols) { qWarning() << "Inconsistent mask row size for dl_mask in Camera ID:" << camera_id; dl_mask_mat.release(); break; } memcpy(dl_mask_mat.ptr(i), dl_mask[i].data(), cols); } if (!dl_mask_mat.empty()) { // 调整掩膜尺寸以匹配图像尺寸 if (dl_mask_mat.size() != img.size()) { cv::resize(dl_mask_mat, dl_mask_mat, img.size(), 0, 0, cv::INTER_NEAREST); } // 确保掩膜为二值图像 cv::threshold(dl_mask_mat, dl_mask_mat, 128, 255, cv::THRESH_BINARY); // 创建绿色掩膜 cv::Mat green_overlay(img.size(), img.type(), cv::Scalar(0, 255, 0)); green_overlay.setTo(cv::Scalar(0, 255, 0), dl_mask_mat); // 叠加掩膜到图像 cv::addWeighted(green_overlay, 0.5, img, 1.0, 0, img); } } } if (overlay_traditional_result & g_traditional_enable[camera_id]) { if (!traditional_mask.empty() && !traditional_mask[0].empty()) { // 将二维 vector 转换为 cv::Mat int rows = traditional_mask.size(); int cols = traditional_mask[0].size(); cv::Mat traditional_mask_mat(rows, cols, CV_8U); for (int i = 0; i < rows; ++i) { if (traditional_mask[i].size() != cols) { qWarning() << "Inconsistent mask row size for traditional_mask in Camera ID:" << camera_id; traditional_mask_mat.release(); break; } memcpy(traditional_mask_mat.ptr(i), traditional_mask[i].data(), cols); } if (!traditional_mask_mat.empty()) { // 调整掩膜尺寸以匹配图像尺寸 if (traditional_mask_mat.size() != img.size()) { cv::resize(traditional_mask_mat, traditional_mask_mat, img.size(), 0, 0, cv::INTER_NEAREST); } // 确保掩膜为二值图像 cv::threshold(traditional_mask_mat, traditional_mask_mat, 128, 255, cv::THRESH_BINARY); // 创建红色掩膜 cv::Mat red_overlay(img.size(), img.type(), cv::Scalar(0, 0, 255)); red_overlay.setTo(cv::Scalar(0, 0, 255), traditional_mask_mat); // 叠加掩膜到图像 cv::addWeighted(red_overlay, 0.5, img, 1.0, 0, img); } } } // 如果需要镜像处理 if (mirror) { 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_2_clicked() { SaveImg_Flag = 1; } void Widget::on_btn_stop_clicked() { DestoryLowMac(); this->isCamRunning = false; // 恢复显示的图片 { QMutexLocker locker(&gDispPicMutex0); gDispCurrentPicId0 = 0; } ui->camera_0_img->clear(); { QMutexLocker locker(&gDispPicMutex1); gDispCurrentPicId1 = 0; } ui->camera_1_img->clear(); } void Widget::on_btn_start_clicked() { // 设置相机参数 setLowMacParam(); g_dl_enable[0] = !this->ui->dl_enable_0->isChecked(); g_dl_enable[1] = !this->ui->dl_enable_0->isChecked(); g_traditional_enable[0] = !this->ui->tra_enable_0->isChecked(); g_traditional_enable[1] = !this->ui->tra_enable_1->isChecked(); this->isCamRunning = true; this->startTime = QDateTime::currentDateTime(); // 从这里开始计算设备运行时间 // 热身两个工作者 for(int i = 0; i < 2; ++i) { g_runner_array[i]->warm_up(); } // 启动检测工作者线程 for(int i = 0; i < 2; ++i) { g_recognitionRunning[i]->store(true); g_recognitionThread[i] = new std::thread(detectionWorker, i); // 获取线程的本地句柄 HANDLE hThread = static_cast(g_recognitionThread[i]->native_handle()); // 设置线程优先级为最高 if(!SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST)) { std::cerr << "SET thread " << i << " failed, error code:" << GetLastError() << std::endl; } } Start_camera(); } void Widget::on_btn_take_photos_pressed() { SaveImg_Flag = true; } void Widget::on_btn_take_photos_released() { SaveImg_Flag = false; } void Widget::on_btn_quit_clicked() { // // 停止检测工作者线程 // for(int i = 0; i < 2; ++i) // { // g_recognitionRunning[i]->store(false); // g_img_Queue[i]->stop(); // 停止队列以唤醒线程 // } // // 等待检测工作者线程结束 // for(int i = 0; i < 2; ++i) // { // if(g_recognitionThread[i] && g_recognitionThread[i]->joinable()) // { // g_recognitionThread[i]->join(); // delete g_recognitionThread[i]; // g_recognitionThread[i] = nullptr; // } // if(g_recognitionRunning[i]) // { // delete g_recognitionRunning[i]; // g_recognitionRunning[i] = nullptr; // } // } DestoryCamera(); DestoryLowMac(); qApp->quit(); } void Widget::on_btn_set_lower_clicked() { // 硬编码参数值 lowmac_sm = ui->spinbox_maintime->value(); params["lowmac_sm"]=lowmac_sm; params["machine_num"] = ui->spinbox_machine_code->value(); params["max_valves_together"] = ui->spinbox_max_valves_together->value(); saveConfig(getConfigDirectory()+"/color_range_config.txt", params, colors); // 两个过去的参量不支持读取配置文件 file_encoder = ui->spinbox_encoder->text().toInt(); // 编码器值++ file_valve = ui->spinbox_valve->text().toInt(); // 阀门通道 } void Widget::update_machine_num() { ui->lab_machine_num->setText(QString("%1号机").arg(params["machine_num"])); ui->spinbox_machine_code->setValue(params["machine_num"]); ui->spinbox_maintime->setValue(params["lowmac_sm"]); } void Widget::on_btn_set_valve_clicked() { ui->tabWidget->setCurrentIndex(2); } void Widget::on_btn_tab3_backtab2_clicked() { ui->tabWidget->setCurrentIndex(1); } void Widget::on_btn_live_clicked() { ui->tabWidget->setCurrentIndex(1); } void Widget::on_btn_tab3_backtab2_2_clicked() { ui->tabWidget->setCurrentIndex(5); } void Widget::on_btn_settings_clicked() { ui->tabWidget->setCurrentIndex(2); } bool Widget::saveConfig(const QString &filePath, const std::map& params_to_set, const std::vector& color_vector_to_set) { QFile file(filePath); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { qWarning() << "无法打开配置文件进行写入:" << filePath; return false; } QTextStream out(&file); // Qt 6 默认使用 UTF-8 编码,无需设置编码 // 保存每种颜色的参数 for (const auto &color : color_vector_to_set) { std::string color_lower = color; // 将颜色名称首字母小写以匹配键名 if (!color_lower.empty()) { color_lower[0] = static_cast(std::tolower(color_lower[0])); } try { // 使用 at() 方法访问元素 out << QString::fromStdString(color_lower) << "_L_min = " << QString::number(params_to_set.at(color_lower + "_L_min")) << "\n"; out << QString::fromStdString(color_lower) << "_L_max = " << QString::number(params_to_set.at(color_lower + "_L_max")) << "\n"; out << QString::fromStdString(color_lower) << "_a_min = " << QString::number(params_to_set.at(color_lower + "_a_min")) << "\n"; out << QString::fromStdString(color_lower) << "_a_max = " << QString::number(params_to_set.at(color_lower + "_a_max")) << "\n"; out << QString::fromStdString(color_lower) << "_b_min = " << QString::number(params_to_set.at(color_lower + "_b_min")) << "\n"; out << QString::fromStdString(color_lower) << "_b_max = " << QString::number(params_to_set.at(color_lower + "_b_max")) << "\n\n"; } catch (const std::out_of_range& e) { qWarning() << "缺少参数:" << QString::fromStdString(color_lower + "_L_min") << "等在颜色" << QString::fromStdString(color_lower); // 根据需要,您可以决定如何处理缺少的参数,例如设置默认值或跳过 continue; } } // 保存其他参数(不涉及颜色参数) for (const auto ¶m : params_to_set) { std::string key = param.first; // 如果不是颜色参数,则保存 if (key.find("_L_min") == std::string::npos && key.find("_L_max") == std::string::npos && key.find("_a_min") == std::string::npos && key.find("_a_max") == std::string::npos && key.find("_b_min") == std::string::npos && key.find("_b_max") == std::string::npos) { out << QString::fromStdString(key) << " = " << QString::number(param.second) << "\n"; } } file.close(); qDebug() << "配置已成功保存到" << filePath; return true; } bool Widget::loadConfig(const QString &filePath) { QFile file(filePath); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qWarning() << "无法打开配置文件进行读取:" << filePath; return false; } QTextStream in(&file); // Qt 6 默认使用 UTF-8 编码,无需设置编码 // 清空当前配置 colors.clear(); params.clear(); while (!in.atEnd()) { QString line = in.readLine().trimmed(); // 跳过空行和注释行 if (line.isEmpty() || line.startsWith("#")) continue; // 处理键值对 QStringList keyValue = line.split("="); if (keyValue.size() != 2) continue; // 无效行 QString key = keyValue[0].trimmed(); QString valueStr = keyValue[1].trimmed(); bool ok; int value = valueStr.toInt(&ok); if (!ok) { qWarning() << "无效的数值:" << valueStr << "在行:" << line; continue; } std::string key_std = key.toStdString(); params[key_std] = value; // 检查是否为颜色参数(格式为 color_property,例如 green_L_min) size_t underscorePos = key_std.find('_'); if (underscorePos != std::string::npos) { std::string colorName = key_std.substr(0, underscorePos); size_t second_underscore = key_std.find('_', underscorePos + 1); if (second_underscore != std::string::npos) { // 提取第二个部分,例如 "L"、"a"、"b" std::string param_type = key_std.substr(underscorePos + 1, second_underscore - underscorePos - 1); // 过滤不需要的参数类型 if ((param_type != "L") && (param_type != "a") && (param_type != "b")) continue; // 避免重复添加颜色 if (std::find(colors.begin(), colors.end(), colorName) == colors.end()) { colors.push_back(colorName); } } } } file.close(); lowmac_dp = params["lowmac_dp"]; //偏振延迟时间 lowmac_ts = params["lowmac_ts"]; //模板匹配阈值 lowmac_sg = params["lowmac_sg"]; //偏振绿色通道大小阈值 lowmac_td = params["lowmac_td"]; //偏振红色通道差值 file_delay = params["file_delay"]; // 延迟时间 expansionRaidus = params["expansionRaidus"]; // 扩展半径 sizeThreshold = params["sizeThreshold"]; // 大小过滤 qDebug() << "配置已成功从" << filePath << "加载"; // qDebug()<comboBox_colorlist->currentText().toLocal8Bit().constData(); if (!(std::find(colors.begin(), colors.end(), current_color) != colors.end())) return; // 设置当前色彩 params[current_color+"_L_min"]=ui->spinBox_L_min->value(); params[current_color+"_L_max"]=ui->spinBox_L_max->value(); params[current_color+"_a_min"]=ui->spinBox_A_min->value(); params[current_color+"_a_max"]=ui->spinBox_A_max->value(); params[current_color+"_b_min"]=ui->spinBox_B_min->value(); params[current_color+"_b_max"]=ui->spinBox_B_max->value(); // 准备写入本地 params["file_delay"]=ui->spinbox_delaytime->value(); params["saturation_threshold"]=ui->spb_saturation->value(); // 这个参数会通过params直接被调用无需赋值给其他全局变量 params["sizeThreshold"]=ui->spinbox_msize_color->value(); params["expansionRaidus"]=ui->spb_expandsize->value(); // 写入内存进行使用 file_delay = params["file_delay"]; sizeThreshold = params["sizeThreshold"]; expansionRaidus = params["expansionRaidus"]; // 存入本地 saveConfig(getConfigDirectory()+"/color_range_config.txt",params,colors); } void Widget::update_colorlist() { ui->comboBox_colorlist->clear(); for(auto color :colors) { ui->comboBox_colorlist->addItem(QString::fromStdString(color)); } } void Widget::on_comboBox_colorlist_currentIndexChanged(int index) { std::string current_color=ui->comboBox_colorlist->currentText().toLocal8Bit().constData(); if (!(std::find(colors.begin(), colors.end(), current_color) != colors.end())) return; int l_min = params[current_color+"_L_min"]; int l_max = params[current_color+"_L_max"]; int a_min = params[current_color+"_a_min"]; int a_max = params[current_color+"_a_max"]; int b_min = params[current_color+"_b_min"]; int b_max = params[current_color+"_b_max"]; ui->spinBox_L_max->setValue(l_max); ui->spinBox_L_min->setValue(l_min); ui->spinBox_A_max->setValue(a_max); ui->spinBox_A_min->setValue(a_min); ui->spinBox_B_max->setValue(b_max); ui->spinBox_B_min->setValue(b_min); } void Widget::on_btn_add_color_clicked() { std::string current_color=ui->lineEdit_color->text().toLocal8Bit().constData(); // 空不添加 if(current_color== "") { QMessageBox::warning(this, "什么颜色?", "这名字起的不雅"); return; } // 必须跟之前所有颜色都不一致 if (!(std::find(colors.begin(), colors.end(), current_color) != colors.end())) { colors.push_back(current_color); } else { QMessageBox::warning(this, "已有名字", "这名字跟别的色撞了"); return; } // 存盘刷界面 params[current_color+"_L_min"]=ui->spinBox_L_min->value(); params[current_color+"_L_max"]=ui->spinBox_L_max->value(); params[current_color+"_a_min"]=ui->spinBox_A_min->value(); params[current_color+"_a_max"]=ui->spinBox_A_max->value(); params[current_color+"_b_min"]=ui->spinBox_B_min->value(); params[current_color+"_b_max"]=ui->spinBox_B_max->value(); saveConfig(getConfigDirectory()+"/color_range_config.txt",params,colors); update_colorlist(); ui->lineEdit_color->clear(); } void Widget::on_btn_del_color_clicked() { // 获取当前选中的颜色文本 QString currentColorQStr = ui->comboBox_colorlist->currentText(); if (currentColorQStr.isEmpty()) { QMessageBox::warning(this, "删除颜色", "当前没有选中的颜色。"); return; } std::string currentColor = currentColorQStr.toStdString(); std::string color_lower = currentColor; if (!color_lower.empty()) { color_lower[0] = static_cast(std::tolower(color_lower[0])); } // 确认删除 QMessageBox::StandardButton reply; reply = QMessageBox::question(this, "删除颜色", QString("确定要删除颜色 '%1' 吗?").arg(currentColorQStr), QMessageBox::Yes | QMessageBox::No); if (reply != QMessageBox::Yes) return; // 查找颜色在 colors 向量中的位置 auto it = std::find(colors.begin(), colors.end(), currentColor); if (it != colors.end()) { // 计算索引 size_t index = std::distance(colors.begin(), it); // 从 colors 向量中删除 colors.erase(it); // 从 params 映射中删除相关参数 params.erase(color_lower + "_L_min"); params.erase(color_lower + "_L_max"); params.erase(color_lower + "_a_min"); params.erase(color_lower + "_a_max"); params.erase(color_lower + "_b_min"); params.erase(color_lower + "_b_max"); // 更新配置文件 saveConfig(getConfigDirectory()+"/color_range_config.txt",params,colors); // 更新 UI update_colorlist(); // 如果还有颜色,选择被删除颜色后的第一个颜色 if (!colors.empty()) { if (index >= colors.size()) index = colors.size() - 1; ui->comboBox_colorlist->setCurrentIndex(static_cast(index)); } else { // 如果没有颜色,重置所有 spinBox ui->spinBox_L_min->setValue(0); ui->spinBox_L_max->setValue(0); ui->spinBox_A_min->setValue(0); ui->spinBox_A_max->setValue(0); ui->spinBox_B_min->setValue(0); ui->spinBox_B_max->setValue(0); } QMessageBox::information(this, "删除颜色", QString("颜色 '%1' 已成功删除。").arg(currentColorQStr)); } else { QMessageBox::warning(this, "删除颜色", "未找到选中的颜色。"); } } void Widget::on_btn_reset_color_clicked() { // 新增全部还原槽 // 确认重置 QMessageBox::StandardButton reply; reply = QMessageBox::question(this, "全部还原", "确定要将配置还原为默认设置吗?", QMessageBox::Yes | QMessageBox::No); if (reply != QMessageBox::Yes) return; // 初始化默认配置 initDefaultConfig(); saveConfig(getConfigDirectory()+"/color_range_config.txt",params,colors); // 更新 UI update_colorlist(); // 选择第一个颜色(如果有) if (!colors.empty()) { ui->comboBox_colorlist->setCurrentIndex(0); } else { // 如果没有颜色,重置所有 spinBox ui->spinBox_L_min->setValue(0); ui->spinBox_L_max->setValue(0); ui->spinBox_A_min->setValue(0); ui->spinBox_A_max->setValue(0); ui->spinBox_B_min->setValue(0); ui->spinBox_B_max->setValue(0); } QMessageBox::information(this, "全部还原", "配置已成功还原为默认设置。"); } void Widget::on_btn_tab_color_clicked() { ui->tabWidget->setCurrentIndex(3); } void Widget::on_btn_tab3_backtab2_3_clicked() { ui->tabWidget->setCurrentIndex(5); } void Widget::on_btn_tab3_backtab2_5_clicked() { ui->tabWidget->setCurrentIndex(1); } void Widget::on_btn_tab_color_2_clicked() { ui->tabWidget->setCurrentIndex(3); } void Widget::on_btn_tab3_backtab2_6_clicked() { ui->tabWidget->setCurrentIndex(4); } void Widget::on_btn_tab3_backtab2_7_clicked() { ui->tabWidget->setCurrentIndex(5); } void Widget::on_btn_tab3_backtab2_8_clicked() { ui->tabWidget->setCurrentIndex(1); } void Widget::on_btn_tab_color_3_clicked() { ui->tabWidget->setCurrentIndex(3); } void Widget::on_btn_tab3_backtab2_9_clicked() { ui->tabWidget->setCurrentIndex(4); } void Widget::on_btn_tab3_backtab2_4_clicked() { ui->tabWidget->setCurrentIndex(4); } void Widget::on_btn_save_polar_clicked() { QMessageBox::StandardButton reply; reply = QMessageBox::question(this, "确定保存", "确定要将偏振配置保存吗?", QMessageBox::Yes | QMessageBox::No); if (reply != QMessageBox::Yes) return; params["lowmac_td"]=ui->spb_diff->value(); params["lowmac_sg"]=ui->spb_green->value(); params["lowmac_dp"]=ui->spb_delay_polar->value(); params["lowmac_ts"]=ui->spb_msize_polar->value(); lowmac_dp = params["lowmac_dp"]; //偏振延迟时间 lowmac_ts = params["lowmac_ts"]; //模板匹配阈值 lowmac_sg = params["lowmac_sg"]; //偏振绿色通道大小阈值 lowmac_td = params["lowmac_td"]; //偏振红色通道差值 saveConfig(getConfigDirectory()+"/color_range_config.txt",params,colors); } void Widget::on_btn_reset_polar_clicked() { QMessageBox::StandardButton reply; reply = QMessageBox::question(this, "确定重置", "确定要将偏振部分配置重置吗?", QMessageBox::Yes | QMessageBox::No); if (reply != QMessageBox::Yes) return; params["lowmac_td"]= 7; params["lowmac_sg"]= 65; params["lowmac_dp"]= 350; params["lowmac_ts"]= 10; lowmac_dp = params["lowmac_dp"]; //偏振延迟时间 lowmac_ts = params["lowmac_ts"]; //模板匹配阈值 lowmac_sg = params["lowmac_sg"]; //偏振绿色通道大小阈值 lowmac_td = params["lowmac_td"]; //偏振红色通道差值 saveConfig(getConfigDirectory()+"/color_range_config.txt",params,colors); update_polar(); } void Widget::update_polar() { ui->spb_green->setValue(lowmac_sg); ui->spb_diff->setValue(lowmac_td); ui->spb_delay_polar->setValue(lowmac_dp); ui->spb_msize_polar->setValue(lowmac_ts); } void Widget::on_tabWidget_currentChanged(int index) { update_machine_num(); update_colorlist(); // 更新色彩列表 update_polar(); // 更新偏振相机界面 }