增加halconGuard类,用于防止halcon算法的输入输出和程序不一致而引起的报错,并且会检查算法文件是否存在,如不存在则会弹窗提示。 增加handleAiGpuThreadGuard类,用于防止因重复调用同一个模型而引起的报错,并且支持不停机更新模型,支持初始化时检测模型文件是否存在。 增加内存占用显示控件。 用户管理增加root权限,默认密码为dseuiroot,模型热更新时需要此权限。 支持缓存界面上的检测数据。 相机模块新增在回调后的指定时间没有取图时则清空容器的功能。 增加等待结果汇总功能,在启用时同一个SN的图片会等待总结果后再进行存图。 存图线程修改为多线程编码,单线程储存,提高IO效率。并且增加根据内存占用的百分比更新存图逻辑的功能,默认占用超过70%不储存OK原图,超过80%不储存原图,超过90%时不储存所有图片。
210 lines
7.1 KiB
C++
210 lines
7.1 KiB
C++
#include <qimage.h>
|
|
#include <qpixmap.h>
|
|
#include <opencv.hpp>
|
|
#include <qdebug.h>
|
|
#include <memory>,。
|
|
#include <iostream>
|
|
#include <thread>
|
|
#include <vector>
|
|
#include <functional>
|
|
#include <filesystem>
|
|
#include <QDir>
|
|
|
|
#pragma execution_character_set("utf-8")
|
|
const std::string softwareVersion = "20260416-2.5.1";//版本号
|
|
const std::string euiJsonVersion = "1.0.6";//json标准版本
|
|
#define GigaByte 1073741824//1GB字节大小
|
|
#define globalDatabasePth "./sqlDatabase/eui_db.db" //全局数据库路径
|
|
#define savePathToDataBase true //是否将存储路径存入到数据库中
|
|
#define saveImgEnable true//是否存储图片
|
|
#define switchToTongYongUi 1 //是否切换到通用UI界面
|
|
#define skipLogin 1 //是否跳过登录界面
|
|
#define jsonRpcEnable false //是否启用JSON RPC服务器
|
|
#define minimumWindowSize 1280, 720//最小窗口大小
|
|
#define histogramLabelTiltFontSize 8 //柱状图标签字体大小
|
|
#define windowMoveFreshRate 60//窗口移动每秒的刷新率
|
|
#define pathDataBaseSaveDate 90//存储存图路径的数据库其数据保留的日期
|
|
#define detDataBaseSaveDate 730//存储检测数据的数据库其数据保留的日期
|
|
|
|
#define sColor_Blue "51, 56, 69"
|
|
#define sColor_BlueWithWhite "64, 68, 81"
|
|
#define sColor_BlueWithBlack "46, 50, 52"
|
|
|
|
#define sColor_Red "232, 17, 35"
|
|
#define sColor_RedWithWhite "241, 112, 122"
|
|
|
|
#define sColor_Green "17, 232, 35"
|
|
#define sColor_GreenWithWhite "112, 241, 122"
|
|
|
|
#define sColor_GoldWithBlack "200, 165, 100"
|
|
#define sColor_Gold "223, 185, 146"
|
|
#define sColor_GoldWithWhite "250, 222, 189"
|
|
|
|
#define sColor_Black "22, 22, 22"
|
|
#define sColor_BlackWithWhite "45, 45, 45"
|
|
|
|
#define REGISTER_META_TYPE_LIST \
|
|
qRegisterMetaType<cv::Mat*>("matPtr"); \
|
|
qRegisterMetaType<std::string>("stdString"); \
|
|
qRegisterMetaType<historyPack>("historyPack"); \
|
|
qRegisterMetaType<Qt::GlobalColor>("QtGlobalColor"); \
|
|
qRegisterMetaType<showImgPack>("showImgPack"); \
|
|
qRegisterMetaType<initStatus>("initStatus"); \
|
|
qRegisterMetaType<cv::Mat>("mat"); \
|
|
qRegisterMetaType<std::vector<cv::Mat>*>("vecmatptr"); \
|
|
qRegisterMetaType<std::vector<std::string>>("vectorstring"); \
|
|
qRegisterMetaType<std::vector<std::pair<QString, int>>>("constvpqi"); \
|
|
qRegisterMetaType<PlcValueViewerStruct>("PlcValueViewerStruct"); \
|
|
qRegisterMetaType<std::vector<std::pair<QString, QVariant>>>("vecQStringQVarint"); \
|
|
qRegisterMetaType<std::vector<QString>>("vecQString");\
|
|
qRegisterMetaType<runCommandWidgetType>("runCommandWidgetType");\
|
|
qRegisterMetaType<std::shared_ptr<std::atomic<int>>>("shared_ptrAtomicInt");\
|
|
qRegisterMetaType<std::shared_ptr<std::atomic<bool>>>("shared_ptrAtomicBool");\
|
|
qRegisterMetaType<std::vector<std::pair<QString, QVariant>>*>("vecQStringQVarintPtr");
|
|
|
|
|
|
struct viewerStruct {
|
|
std::string name;
|
|
int xPos, yPos,width,height;
|
|
std::vector<std::string>viewers;
|
|
};
|
|
enum runCommandWidgetType {
|
|
PlcSim,
|
|
Direct
|
|
};
|
|
enum backendError
|
|
{
|
|
dllNotFound,
|
|
triggerInitFailure,
|
|
triggerConnectionError,
|
|
camerInitFailure
|
|
};
|
|
struct historyPack
|
|
{
|
|
QPixmap img;
|
|
std::shared_ptr<std::string>filePath;
|
|
std::vector<std::string>text;
|
|
};
|
|
static QImage cvMatToQImage(const cv::Mat& src)
|
|
{
|
|
if (src.channels() == 1) { // if grayscale image
|
|
return QImage((uchar*)src.data, src.cols, src.rows, static_cast<int>(src.step), QImage::Format_Grayscale8).copy();
|
|
}
|
|
if (src.channels() == 3) { // if 3 channel color image
|
|
cv::Mat rgbMat;
|
|
cv::cvtColor(src, rgbMat, cv::COLOR_BGR2RGB); // invert BGR to RGB
|
|
return QImage((uchar*)rgbMat.data, src.cols, src.rows, static_cast<int>(src.step), QImage::Format_RGB888).copy();
|
|
}
|
|
return QImage();
|
|
}
|
|
static cv::Mat qImageToCvMat(const QImage& inImage)
|
|
{
|
|
switch (inImage.format())
|
|
{
|
|
case QImage::Format_RGB32:
|
|
case QImage::Format_RGB888:
|
|
{
|
|
|
|
QImage swapped = inImage;
|
|
if (inImage.format() == QImage::Format_RGB32)
|
|
{
|
|
swapped = swapped.convertToFormat(QImage::Format_RGB888);
|
|
}
|
|
cv::Mat matImg = cv::Mat(swapped.height(), swapped.width(),
|
|
CV_8UC3,
|
|
const_cast<uchar*>(swapped.bits()),
|
|
static_cast<size_t>(swapped.bytesPerLine())
|
|
);
|
|
cv::cvtColor(matImg, matImg, cv::COLOR_RGB2BGR);
|
|
return matImg.clone();
|
|
}
|
|
case QImage::Format_Indexed8:
|
|
{
|
|
cv::Mat mat(inImage.height(), inImage.width(),
|
|
CV_8UC1,
|
|
const_cast<uchar*>(inImage.bits()),
|
|
static_cast<size_t>(inImage.bytesPerLine())
|
|
);
|
|
return mat.clone();
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return cv::Mat();
|
|
}
|
|
static void cvMatToQPixMap(const cv::Mat& src,QPixmap& pixmap)
|
|
{
|
|
pixmap = QPixmap::fromImage(cvMatToQImage(src));
|
|
}
|
|
static QPixmap cvMatToQPixMap(const cv::Mat& src)
|
|
{
|
|
return QPixmap::fromImage(cvMatToQImage(src));
|
|
}
|
|
static cv::Mat QPixmapToMat(const QPixmap& pixmap)
|
|
{
|
|
// 将 QPixmap 转换为 QImage
|
|
QImage img = pixmap.toImage();
|
|
|
|
// 确保 QImage 是有效的
|
|
if (img.isNull()) {
|
|
return cv::Mat();
|
|
}
|
|
|
|
// 将 QImage 转换为 cv::Mat
|
|
if (img.format() == QImage::Format_RGB888) {
|
|
// 对于 RGB888 格式,直接转换为 cv::Mat
|
|
return cv::Mat(img.height(), img.width(), CV_8UC3, (void*)img.bits(), img.bytesPerLine()).clone();
|
|
}
|
|
else if (img.format() == QImage::Format_RGBA8888) {
|
|
// 如果是 RGBA 格式,转换为 CV_8UC4 格式
|
|
return cv::Mat(img.height(), img.width(), CV_8UC4, (void*)img.bits(), img.bytesPerLine()).clone();
|
|
}
|
|
else {
|
|
// 对于其他格式,转换为灰度图像
|
|
QImage imgGray = img.convertToFormat(QImage::Format_Grayscale8);
|
|
return cv::Mat(imgGray.height(), imgGray.width(), CV_8UC1, (void*)imgGray.bits(), imgGray.bytesPerLine()).clone();
|
|
}
|
|
}
|
|
static std::string getCurrentDateTime() {
|
|
|
|
// 获取当前时间点
|
|
auto now = std::chrono::system_clock::now();
|
|
|
|
// 转换为字符串
|
|
auto currentTime = std::chrono::system_clock::to_time_t(now);
|
|
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 100;
|
|
std::tm* localTime = std::localtime(¤tTime);
|
|
std::stringstream ss;
|
|
ss << std::put_time(localTime, "%H-%M-%S") << "-" << std::setfill('0') << std::setw(2) << ms.count();
|
|
return ss.str();
|
|
}
|
|
|
|
static void createDirectoryIfNotExists(const std::string& path) {
|
|
// 检查路径是否存在
|
|
if (!std::filesystem::exists(path)) {
|
|
// 创建路径
|
|
try {
|
|
std::filesystem::create_directories(path);
|
|
//std::cout << "已创建文件夹: " << path << std::endl;
|
|
}
|
|
catch (...) {
|
|
qCritical() << "创建文件夹失败!" << QString::fromStdString(path);
|
|
}
|
|
}
|
|
}
|
|
static void createDirectoryIfNotExists(const QString& path) {
|
|
QDir dir;
|
|
dir.mkpath(path);
|
|
}
|
|
|
|
Q_DECLARE_METATYPE(cv::Mat*)
|
|
Q_DECLARE_METATYPE(cv::Mat)
|
|
Q_DECLARE_METATYPE(std::string)
|
|
Q_DECLARE_METATYPE(historyPack)
|
|
Q_DECLARE_METATYPE(Qt::GlobalColor)
|
|
Q_DECLARE_METATYPE(std::shared_ptr<std::atomic<int>>)
|
|
Q_DECLARE_METATYPE(std::shared_ptr<std::atomic<bool>>)
|
|
|
|
|
|
|
|
#pragma once |