加载界面增加了一个展示控制台信息的窗口。
修复三协无反馈信号的bug。 handleai模型建议在mission中独立初始化。
This commit is contained in:
+1
-6
@@ -24,7 +24,7 @@ class qtFuncBridge : public QObject {
|
||||
Q_OBJECT
|
||||
signals:
|
||||
// 日志相关
|
||||
void loadingWindow_appendLog(const QString& text, const QColor& color);
|
||||
void loadingWindow_appendInitLog(const QString& text, const QColor& color);
|
||||
void loadingWindow_modifyLog(int col, const QString& text, const QColor& color);
|
||||
void loadingWindow_clearLog();
|
||||
|
||||
@@ -58,11 +58,6 @@ signals:
|
||||
void loadingWindow_SetErrorIcon();
|
||||
void loadingWindow_SetErrorText(QString text);
|
||||
|
||||
// 初始化日志
|
||||
int loadingWindow_appendInitLog(QString text, QString color);
|
||||
void loadingWindow_modifyInitLog(QString text, QString color, int col);
|
||||
void loadingWindow_clearInitLog();
|
||||
|
||||
// 警告日志
|
||||
void loadingWindow_appendWarningLog(QString text);
|
||||
void loadingWindow_clearWarningLog();
|
||||
|
||||
+1
-1
@@ -132,7 +132,7 @@ public:
|
||||
QString::number(address[batteryOffset].triggerAddr), sn, 1, camera->config.oriSaveFormat);//创建数据包
|
||||
camera->captureImage(data);//拍照
|
||||
data->saveObjectName = saveObjectName;
|
||||
generalDet->ansyncProcess(data, address[batteryOffset], ("D" + address[0].completeAddr + "_0"));//处理算法 并在取到图片后发送完成信号
|
||||
generalDet->ansyncProcess(data, address[batteryOffset], ("D" + address[0].completeAddr + "_1"));//处理算法 并在取到图片后发送完成信号
|
||||
data->resultImgShowSet.push_back(showImgPack(viewerName, "结果图"));
|
||||
}
|
||||
private:
|
||||
|
||||
@@ -156,7 +156,7 @@ void cameraManager::run(){
|
||||
if (cameraStruct.module_ptr->initParas(initByte)){
|
||||
camera* _camera = new camera(cameraStruct, cameras.size(), bridge);
|
||||
cameras.insert(std::make_pair(cameraStruct.key, _camera));
|
||||
emit bridge->loadingWindow_appendLog("相机" + QString::fromStdString(cameraStruct.key) + "初始化成功", "green");
|
||||
emit bridge->loadingWindow_appendInitLog("相机" + QString::fromStdString(cameraStruct.key) + "初始化成功", "green");
|
||||
qDebug() << "[INFO] " << " initParas success!";
|
||||
cameraStruct.init = true;
|
||||
}
|
||||
@@ -165,7 +165,7 @@ void cameraManager::run(){
|
||||
cameraStruct.module_ptr->readData(vec_mat, errorStr);
|
||||
initReuslt = false;
|
||||
qCritical() << "[Error] " << " moduleName:" << QString::fromStdString(cameraStruct.dllPath) << " initParas failed!";
|
||||
emit bridge->loadingWindow_appendLog("相机" + QString::fromStdString(cameraStruct.key) + "初始化失败->" + errorStr, "red");
|
||||
emit bridge->loadingWindow_appendInitLog("相机" + QString::fromStdString(cameraStruct.key) + "初始化失败->" + errorStr, "red");
|
||||
}
|
||||
}
|
||||
if (initReuslt == true){
|
||||
@@ -202,7 +202,7 @@ bool cameraManager::loadModule(cameraStruct& _cameraStruct){
|
||||
if (!m_lib->isLoaded()){
|
||||
|
||||
qDebug() << "[Error] " << " Loaded error:" << m_lib->errorString();
|
||||
bridge->loadingWindow_appendLog("加载相机模块" + dllPath + "失败->" + m_lib->errorString(), "red");
|
||||
emit bridge->loadingWindow_appendInitLog("加载相机模块" + dllPath + "失败->" + m_lib->errorString(), "red");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ bool triggerManager::connectHost(){
|
||||
libLoadedflag = m_lib->load();
|
||||
if (!m_lib->isLoaded()){
|
||||
//emit _core._qtFunc.sendErrorToMainwindow(dllNotFound);
|
||||
emit bridge->loadingWindow_appendLog("找不到" + triggerFileName,"red");
|
||||
emit bridge->loadingWindow_appendInitLog("找不到" + triggerFileName,"red");
|
||||
return false;
|
||||
}
|
||||
if (libLoadedflag){
|
||||
@@ -79,7 +79,7 @@ bool triggerManager::connectHost(){
|
||||
initFailure = trigger->initParas(QByteArray());
|
||||
#endif
|
||||
|
||||
emit bridge->loadingWindow_appendLog(triggerFileName + "连接到" + IpAndPort,QColor("white"));
|
||||
emit bridge->loadingWindow_appendInitLog(triggerFileName + "连接到" + IpAndPort,QColor("white"));
|
||||
|
||||
}
|
||||
|
||||
@@ -87,14 +87,14 @@ bool triggerManager::connectHost(){
|
||||
//emit _core._qtFunc.sendErrorToMainwindow(triggerInitFailure);
|
||||
delete m_lib;
|
||||
m_lib = nullptr;
|
||||
emit bridge->loadingWindow_appendLog(triggerFileName + "初始化失败","red");
|
||||
emit bridge->loadingWindow_appendInitLog(triggerFileName + "初始化失败","red");
|
||||
status = InitFailure;
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
status = InitOK;
|
||||
init = true;
|
||||
emit bridge->loadingWindow_appendLog(triggerFileName + "连接成功","green");
|
||||
emit bridge->loadingWindow_appendInitLog(triggerFileName + "连接成功","green");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ public:
|
||||
}
|
||||
_detProcess->init();
|
||||
bridge = bridgeIn;
|
||||
emit bridge->loadingWindow_appendLog(u8"核心加载成功,正在初始化",QColor("white"));
|
||||
emit bridge->loadingWindow_appendInitLog(u8"核心加载成功,正在初始化",QColor("white"));
|
||||
_detProcess->start();
|
||||
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ public:
|
||||
bool initOnce = false;
|
||||
detProcess(SQLiteDB* dbIn, nlohmann::ordered_json& jsonIn, qtFuncBridge* bridgeIn):
|
||||
db(dbIn),bridge(bridgeIn), missionJson(jsonIn){
|
||||
|
||||
}
|
||||
~detProcess() {
|
||||
safeShutdownDelete(_serviceManager._triggerManager);
|
||||
@@ -120,6 +119,7 @@ public:
|
||||
bool res3 = waitrForInitResult(_serviceManager._triggerManager);
|
||||
|
||||
if (res1 == true && res2 == true && res3 == true) {
|
||||
emit bridge->loadingWindow_appendInitLog("初始化Mission中...", "yellow");
|
||||
_missionLoader.loadMission(missionJson["missionDllPath"]);
|
||||
_missionLoader.getmission(missionJson["missionDllPath"])->initBasic(
|
||||
&_serviceManager,
|
||||
|
||||
@@ -9,20 +9,23 @@
|
||||
//#include <appCore.hpp>
|
||||
#include <serviceModule.h>
|
||||
#include <nlohmannJson.hpp>
|
||||
#include <qmutex.h>
|
||||
#include <quuid.h>
|
||||
const bool enableHandleAiModel = true; // 是否启用HandleAI模型
|
||||
class handleAiModelSeg
|
||||
{
|
||||
class handleAiModelSeg {
|
||||
public:
|
||||
bool initFlag = false;
|
||||
std::string path;
|
||||
int gpuIndex =0;
|
||||
std::mutex* gpuMutex;
|
||||
handleAiModelSeg(std::string pathIn, int gpuIndexIn, std::mutex* mutex){
|
||||
int gpuIndex = 0,batchSize = 64;
|
||||
QMutex gpuMutex;
|
||||
handleAiModelSeg(std::string pathIn, int gpuIndexIn, int batchSizeIn = 64){
|
||||
path = pathIn;
|
||||
gpuIndex = gpuIndexIn;
|
||||
gpuMutex = mutex;
|
||||
batchSize = batchSizeIn;
|
||||
};
|
||||
std::string init() {
|
||||
segPtr = handdleAI::CreateSegObj((char*)path.c_str(),gpuIndex);
|
||||
segPtr = handdleAI::CreateSegObjS((char*)path.c_str(), batchSize, gpuIndex);
|
||||
initFlag = true;
|
||||
return path;
|
||||
}
|
||||
bool destroy(){
|
||||
@@ -31,27 +34,27 @@ public:
|
||||
handdleAI::DestroySegObj(segPtr);
|
||||
return true;
|
||||
}
|
||||
cv::Mat Evaluate(cv::Mat& in){
|
||||
gpuMutex->lock();
|
||||
cv::Mat res = segPtr->Evaluate(in);
|
||||
gpuMutex->unlock();
|
||||
return res;
|
||||
cv::Mat Evaluate(cv::Mat& input){
|
||||
QMutexLocker locker(&gpuMutex);
|
||||
return segPtr->Evaluate(input);
|
||||
}
|
||||
handdleAI::pSegmentation* segPtr = nullptr;
|
||||
};
|
||||
class handleAiModelCls{
|
||||
|
||||
public:
|
||||
bool initFlag = false;
|
||||
std::string path;
|
||||
int gpuIndex = 0;
|
||||
std::mutex* gpuMutex;
|
||||
handleAiModelCls(std::string pathIn, int gpuIndexIn, std::mutex* mutex){
|
||||
int gpuIndex = 0, batchSize = 1;
|
||||
QMutex gpuMutex;
|
||||
handleAiModelCls(std::string pathIn, int gpuIndexIn, int batchSizeIn = 1){
|
||||
path = pathIn;
|
||||
gpuIndex = gpuIndexIn;
|
||||
gpuMutex = mutex;
|
||||
batchSize = batchSizeIn;
|
||||
};
|
||||
std::string init(){
|
||||
clsPtr = handdleAI::CreateClsObjV3((char*)path.c_str(), gpuIndex,1);
|
||||
clsPtr = handdleAI::CreateClsObjV3((char*)path.c_str(), gpuIndex, batchSize);
|
||||
initFlag = true;
|
||||
return path;
|
||||
}
|
||||
bool destroy(){
|
||||
@@ -60,26 +63,26 @@ public:
|
||||
handdleAI::DestroyClsObj(clsPtr);
|
||||
return true;
|
||||
}
|
||||
int Evaluate(cv::Mat& in){
|
||||
gpuMutex->lock();
|
||||
int res = clsPtr->Evaluate(in);
|
||||
gpuMutex->unlock();
|
||||
return res;
|
||||
int Evaluate(cv::Mat& input){
|
||||
QMutexLocker locker(&gpuMutex);
|
||||
return clsPtr->Evaluate(input);
|
||||
}
|
||||
handdleAI::pClassification* clsPtr;
|
||||
handdleAI::pClassification* clsPtr = nullptr;
|
||||
};
|
||||
class handleAiModelDet{
|
||||
public:
|
||||
bool initFlag = false;
|
||||
std::string path;
|
||||
int gpuIndex = 0;
|
||||
std::mutex* gpuMutex;
|
||||
handleAiModelDet(std::string pathIn, int gpuIndexIn, std::mutex* mutex){
|
||||
int gpuIndex = 0,batchSize = 1;
|
||||
QMutex gpuMutex;
|
||||
handleAiModelDet(std::string pathIn, int gpuIndexIn,int batchSizeIn = 1){
|
||||
path = pathIn;
|
||||
gpuIndex = gpuIndexIn;
|
||||
gpuMutex = mutex;
|
||||
batchSize = batchSizeIn;
|
||||
};
|
||||
std::string init(){
|
||||
detPtr = handdleAI::CreateDetObjS((char*)path.c_str(), 1, gpuIndex);
|
||||
detPtr = handdleAI::CreateDetObjS((char*)path.c_str(), batchSize, gpuIndex);
|
||||
initFlag = true;
|
||||
return path;
|
||||
}
|
||||
bool destroy(){
|
||||
@@ -88,13 +91,12 @@ public:
|
||||
handdleAI::DestroyDetObj(detPtr);
|
||||
return true;
|
||||
}
|
||||
bool Evaluate(cv::Mat& in, std::vector<handdleAI::Bbox>& result){
|
||||
gpuMutex->lock();
|
||||
result=detPtr->Evaluate(in);
|
||||
gpuMutex->unlock();
|
||||
bool Evaluate(cv::Mat& input, std::vector<handdleAI::Bbox>& result){
|
||||
QMutexLocker locker(&gpuMutex);
|
||||
result=detPtr->Evaluate(input);
|
||||
return true;
|
||||
}
|
||||
handdleAI::pDetection* detPtr;
|
||||
handdleAI::pDetection* detPtr = nullptr;
|
||||
};
|
||||
class handleAiModelManager :public serviceModule{
|
||||
|
||||
@@ -102,7 +104,6 @@ public:
|
||||
enum type{
|
||||
seg, cls, det
|
||||
};
|
||||
bool initFlag = false;
|
||||
std::string basePath;
|
||||
handleAiModelManager(nlohmann::ordered_json& json, qtFuncBridge* bridgeIn)
|
||||
:bridge(bridgeIn){
|
||||
@@ -129,37 +130,39 @@ public:
|
||||
int gpuIndex = clsModel.value()["gpuIndex"];
|
||||
insertClsModelPath(keyName, modelPath, gpuIndex);
|
||||
}
|
||||
jsonAvailable = true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "handleAiModelManager读取配置文件异常: " << e.what() << std::endl;
|
||||
}
|
||||
};
|
||||
bool insertSegModelPath(std::string keyName,std::string modelPath ,int gpuIndex){
|
||||
handleAiModelSeg* insertSegModelPath(std::string keyName,std::string modelPath ,int gpuIndex){
|
||||
auto mapResult = segModels.find(keyName);
|
||||
if (mapResult != segModels.end())//已有数据
|
||||
return true;
|
||||
handleAiModelSeg* segModel = new handleAiModelSeg(modelPath, gpuIndex, gpuMutex[gpuIndex]);
|
||||
return nullptr;
|
||||
handleAiModelSeg* segModel = new handleAiModelSeg(modelPath, gpuIndex);
|
||||
segModels.insert(std::make_pair(keyName, segModel));
|
||||
return segModel;
|
||||
}
|
||||
bool insertDetModelPath(std::string keyName, std::string modelPath, int gpuIndex){
|
||||
handleAiModelDet* insertDetModelPath(std::string keyName, std::string modelPath, int gpuIndex){
|
||||
auto mapResult = detModels.find(keyName);
|
||||
if (mapResult != detModels.end())//已有数据
|
||||
return true;
|
||||
handleAiModelDet* detModel = new handleAiModelDet(modelPath, gpuIndex, gpuMutex[gpuIndex]);
|
||||
return nullptr;
|
||||
handleAiModelDet* detModel = new handleAiModelDet(modelPath, gpuIndex);
|
||||
detModels.insert(std::make_pair(keyName, detModel));
|
||||
return detModel;
|
||||
}
|
||||
bool insertClsModelPath(std::string keyName, std::string modelPath, int gpuIndex){
|
||||
handleAiModelCls* insertClsModelPath(std::string keyName, std::string modelPath, int gpuIndex){
|
||||
auto mapResult = clsModels.find(keyName);
|
||||
if (mapResult != clsModels.end())//已有数据
|
||||
return true;
|
||||
handleAiModelCls* clsModel = new handleAiModelCls(modelPath, gpuIndex, gpuMutex[gpuIndex]);
|
||||
return nullptr;
|
||||
handleAiModelCls* clsModel = new handleAiModelCls(modelPath, gpuIndex);
|
||||
clsModels.insert(std::make_pair(keyName, clsModel));
|
||||
return clsModel;
|
||||
}
|
||||
//
|
||||
handleAiModelSeg* getSegModel(std::string modelName){
|
||||
auto mapResult = segModels.find(modelName);
|
||||
if (mapResult == segModels.end())//已有数据
|
||||
if (mapResult == segModels.end())//没有数据
|
||||
return nullptr;
|
||||
return mapResult->second;
|
||||
}
|
||||
@@ -176,36 +179,59 @@ public:
|
||||
return mapResult->second;
|
||||
}
|
||||
|
||||
//handdleAI::pSegmentation* insertSegModelAndInit(std::string modelPath, int gpuIndex, int batchSize = 64) {
|
||||
// std::string uuid = QUuid().createUuid().toString().toStdString();
|
||||
// handleAiModelSeg* segModel = new handleAiModelSeg(modelPath, gpuIndex, batchSize);
|
||||
// bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(modelPath) + "[SEG]检测模型初始化中..."), "white");
|
||||
// //segModel->init();
|
||||
// bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(modelPath) + "[SEG]初始化成功..."), "white");
|
||||
// segModels.insert(std::make_pair(uuid, segModel));
|
||||
// return segModel->segPtr;
|
||||
//}
|
||||
//handdleAI::pClassification* insertClsModelAndInit(std::string modelPath, int gpuIndex, int batchSize = 1) {
|
||||
// std::string uuid = QUuid().createUuid().toString().toStdString();
|
||||
// handleAiModelCls* clsModel = new handleAiModelCls(modelPath, gpuIndex, batchSize);
|
||||
// bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(modelPath) + "[CLS]检测模型初始化中..."), "white");
|
||||
// //clsModel->init();
|
||||
// bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(modelPath) + "[CLS]初始化成功..."), "white");
|
||||
// clsModels.insert(std::make_pair(uuid, clsModel));
|
||||
// return clsModel->clsPtr;
|
||||
//}
|
||||
//handdleAI::pDetection* insertDetModelAndInit(std::string modelPath, int gpuIndex, int batchSize = 1) {
|
||||
// std::string uuid = QUuid().createUuid().toString().toStdString();
|
||||
// handleAiModelDet* detModel = new handleAiModelDet(modelPath, gpuIndex, batchSize);
|
||||
// bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(modelPath) + "[DET]检测模型初始化中..."), "white");
|
||||
// //detModel->init();
|
||||
// bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(modelPath) + "[DET]初始化成功..."), "white");
|
||||
// detModels.insert(std::make_pair(uuid, detModel));
|
||||
// return detModel->detPtr;
|
||||
//}
|
||||
void run(){
|
||||
if (init == true || jsonAvailable == false)
|
||||
return;
|
||||
if (enableHandleAiModel == true) {
|
||||
std::vector<std::future<std::string>> futures;
|
||||
for (auto& model : segModels)
|
||||
{
|
||||
for (auto& model : segModels){
|
||||
if (model.second->initFlag == true) continue;
|
||||
futures.push_back(std::async(std::launch::async, &handleAiModelSeg::init, model.second));
|
||||
bridge->loadingWindow_appendLog(QString::fromStdString(fileManager::getFileName(model.second->path) + "检测模型初始化中..."), "white");
|
||||
emit bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(model.second->path) + "检测模型初始化中..."), "white");
|
||||
}
|
||||
for (auto& model : clsModels)
|
||||
{
|
||||
for (auto& model : clsModels){
|
||||
if (model.second->initFlag == true) continue;
|
||||
futures.push_back(std::async(std::launch::async, &handleAiModelCls::init, model.second));
|
||||
bridge->loadingWindow_appendLog(QString::fromStdString(fileManager::getFileName(model.second->path) + "检测模型初始化中..."), "white");
|
||||
emit bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(model.second->path) + "检测模型初始化中..."), "white");
|
||||
}
|
||||
for (auto& model : detModels)
|
||||
{
|
||||
for (auto& model : detModels){
|
||||
if (model.second->initFlag == true) continue;
|
||||
futures.push_back(std::async(std::launch::async, &handleAiModelDet::init, model.second));
|
||||
bridge->loadingWindow_appendLog(QString::fromStdString(fileManager::getFileName(model.second->path) + "检测模型初始化中..."), "white");
|
||||
emit bridge->loadingWindow_appendInitLog(QString::fromStdString(fileManager::getFileName(model.second->path) + "检测模型初始化中..."), "white");
|
||||
}
|
||||
for (int i = 0; i < futures.size(); i++)
|
||||
{
|
||||
for (int i = 0; i < futures.size(); i++){
|
||||
futures[i].wait();
|
||||
std::string result = futures[i].get();
|
||||
bridge->loadingWindow_appendLog(
|
||||
emit bridge->loadingWindow_appendInitLog(
|
||||
QString::fromStdString(fileManager::getFileName(result)) + "成功( " + QString::number(i + 1) + "/" + QString::number(futures.size()) + ")", "green");
|
||||
qDebug() << QString::fromStdString(fileManager::getFileName(result) + "成功");
|
||||
std::cout << fileManager::getFileName(result) + "成功" << std::endl;
|
||||
}
|
||||
init = true;
|
||||
status = InitOK;
|
||||
}
|
||||
else {
|
||||
@@ -215,8 +241,7 @@ public:
|
||||
|
||||
|
||||
}
|
||||
~handleAiModelManager()
|
||||
{
|
||||
~handleAiModelManager(){
|
||||
if (enableHandleAiModel) {
|
||||
for (auto& model : detModels)
|
||||
model.second->destroy();
|
||||
@@ -231,11 +256,8 @@ private:
|
||||
std::unordered_map<std::string, handleAiModelSeg*> segModels;
|
||||
std::unordered_map<std::string, handleAiModelCls*> clsModels;
|
||||
std::unordered_map<std::string, handleAiModelDet*> detModels;
|
||||
std::vector<std::mutex*>gpuMutex = std::vector<std::mutex*>(6, new std::mutex());
|
||||
int gpuCnt = 1;//gpu数量
|
||||
bool init = false;
|
||||
nlohmann::json handleAiJson;
|
||||
bool jsonAvailable = false;
|
||||
qtFuncBridge* bridge;
|
||||
};
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ public:
|
||||
//异步启动检测
|
||||
void ansyncProcess(std::shared_ptr <detData> data, addressTemplate address, QByteArray completeSignal = "") {
|
||||
QFuture<void> future = QtConcurrent::run([this, data, address, completeSignal]() {
|
||||
process(data, address);
|
||||
process(data, address, completeSignal);
|
||||
});
|
||||
}
|
||||
//启动检测
|
||||
@@ -37,7 +37,8 @@ public:
|
||||
while (data->oriImgs.size() < data->imgAmountMin) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
_triggerManager->writeShort(completeSignal);
|
||||
if(completeSignal != "")
|
||||
_triggerManager->writeShort(completeSignal);
|
||||
//等待图片满足要求后,储存原图,异步执行算法函数
|
||||
auto resultData = algoEvaluate(data, _handleAiModels, address);
|
||||
// 确保线程安全退出
|
||||
|
||||
@@ -17,12 +17,12 @@ public:
|
||||
QLabel* sign = nullptr;
|
||||
QMovie* movie = nullptr;
|
||||
QTextEdit* initLog = nullptr;
|
||||
QTextEdit* consoleLog = nullptr;
|
||||
fancyButtonText* retryBtn = new fancyButtonText("重试", 100, 50, "重新进行初始化");
|
||||
fancyButtonText* manualBtn = new fancyButtonText("离线模式", 180, 50, "离线模式");
|
||||
QGridLayout* glayout = new QGridLayout(this);
|
||||
QVBoxLayout* vlayout = new QVBoxLayout(this);
|
||||
loadingWidget(qtFuncBridge* bridgeIn)
|
||||
{
|
||||
QGridLayout* logLayout = new QGridLayout(this);
|
||||
loadingWidget(qtFuncBridge* bridgeIn){
|
||||
bridge = bridgeIn;
|
||||
glayout->setAlignment(Qt::AlignCenter);
|
||||
connect(retryBtn, &QPushButton::clicked, [=]()
|
||||
@@ -32,8 +32,7 @@ public:
|
||||
emit bridge->reInitConfig();
|
||||
});
|
||||
}
|
||||
void start()
|
||||
{
|
||||
void start(){
|
||||
if (isRunning == true)
|
||||
stop();
|
||||
QPalette palette;
|
||||
@@ -46,7 +45,7 @@ public:
|
||||
movie->start();
|
||||
|
||||
sign->setMovie(movie);
|
||||
|
||||
//初始化日志
|
||||
initLog = new QTextEdit();
|
||||
initLog->setAlignment(Qt::AlignCenter);
|
||||
initLog->setStyleSheet(QString("background-color: transparent;"
|
||||
@@ -59,17 +58,34 @@ public:
|
||||
initLog->setTextColor(Qt::white);
|
||||
initLog->append("正在初始化...");
|
||||
|
||||
vlayout->addWidget(initLog);
|
||||
logLayout->addWidget(initLog, 0, 0);
|
||||
|
||||
//控制台日志
|
||||
consoleLog = new QTextEdit();
|
||||
consoleLog->setAlignment(Qt::AlignCenter);
|
||||
consoleLog->setStyleSheet(QString("background-color: black;"
|
||||
"border: 1px solid white;"
|
||||
"border-radius: 0px;"));
|
||||
consoleLog->setReadOnly(true);
|
||||
consoleLog->setFixedWidth(720);
|
||||
QFont font2("微软雅黑", 7);
|
||||
consoleLog->setFont(font2);
|
||||
consoleLog->setTextColor(Qt::white);
|
||||
consoleLog->append("控制台日志...");
|
||||
logLayout->addWidget(consoleLog, 1, 0,Qt::AlignCenter|Qt::AlignTop);
|
||||
|
||||
//重试或者离线模式等按钮
|
||||
QHBoxLayout* btnLayout = new QHBoxLayout();
|
||||
btnLayout->setAlignment(Qt::AlignLeft);
|
||||
btnLayout->addWidget(manualBtn);
|
||||
manualBtn->hide();
|
||||
btnLayout->addWidget(retryBtn);
|
||||
retryBtn->hide();
|
||||
|
||||
vlayout->addLayout(btnLayout);
|
||||
logLayout->addLayout(btnLayout, 2, 0,Qt::AlignLeft);
|
||||
|
||||
glayout->addWidget(sign, 0, 0);
|
||||
glayout->addLayout(vlayout, 1, 0);
|
||||
glayout->addLayout(logLayout, 1, 0);
|
||||
glayout->setRowStretch(0, 5);
|
||||
glayout->setRowStretch(1, 4);
|
||||
//screenshot_ = QPixmap::grabWindow(widget->winId());
|
||||
@@ -77,8 +93,7 @@ public:
|
||||
isRunning = true;
|
||||
initOK = true;
|
||||
}
|
||||
void stop()
|
||||
{
|
||||
void stop(){
|
||||
if (isRunning == false)
|
||||
return;
|
||||
isRunning = false;
|
||||
@@ -91,10 +106,8 @@ public:
|
||||
movie = nullptr;
|
||||
initLog = nullptr;
|
||||
}
|
||||
void setError()
|
||||
{
|
||||
if (isRunning == true)
|
||||
{
|
||||
void setError(){
|
||||
if (isRunning == true){
|
||||
if (movie != nullptr)
|
||||
delete movie;
|
||||
movie = nullptr;
|
||||
@@ -105,8 +118,15 @@ public:
|
||||
manualBtn->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
int appendLog(const QString& text, const QColor& color = Qt::white) {
|
||||
int appendConsoleLog(const QString& text) {
|
||||
if (consoleLog && initOK == true) {
|
||||
QMutexLocker locker(&mutex);
|
||||
consoleLog->append(text);
|
||||
return consoleLog->document()->blockCount();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
int appendInitLog(const QString& text, const QColor& color = Qt::white) {
|
||||
if (initLog && initOK == true) {
|
||||
QMutexLocker locker(&mutex);
|
||||
initLog->setTextColor(color);
|
||||
@@ -141,6 +161,7 @@ public:
|
||||
}
|
||||
void clearLog() {
|
||||
initLog->clear();
|
||||
consoleLog->clear();
|
||||
}
|
||||
protected:
|
||||
#if 0
|
||||
|
||||
@@ -395,7 +395,9 @@ public slots:
|
||||
void recvInitFinished(initStatus input){
|
||||
switch (input){
|
||||
case initStatus::InitOK:
|
||||
_loadingWidget.clearLog();
|
||||
backEndInit = true;
|
||||
logService::getInstance()->disableLoadingWidgetOutput();
|
||||
if (isLogin == true)
|
||||
loading(false);
|
||||
break;
|
||||
|
||||
@@ -29,7 +29,7 @@ logService::logService(){
|
||||
_qtRediretor = std::make_unique<qtRediretor>();
|
||||
|
||||
// STD日志到Qt日志界面、Qt主界面、spdLog
|
||||
_stdConsoleRedirector->registerCallback([this](const std::string& output) {
|
||||
_stdConsoleRedirector->registerCallback("qtLogWidget",[this](const std::string& output) {
|
||||
if (!output.empty() && output != "\n") {
|
||||
QString outPutMsg = QString::fromStdString(output);
|
||||
_logToQtWidget->sendStdLogSignal(outPutMsg); // Qt日志界面
|
||||
@@ -39,14 +39,21 @@ logService::logService(){
|
||||
});
|
||||
|
||||
// STD日志到控制台
|
||||
_stdConsoleRedirector->registerCallback([this](const std::string& output) {
|
||||
_stdConsoleRedirector->registerCallback("console",[this](const std::string& output) {
|
||||
if (!output.empty() && output != "\n") {
|
||||
_stdConsoleRedirector->writeToConsole(output);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// STD日志到加载界面
|
||||
_stdConsoleRedirector->registerCallback("loadingWidget", [this](const std::string& output) {
|
||||
if (!output.empty() && output != "\n") {
|
||||
emit _logToQtWidget->loadingWindow_appendConsoleLog(QString::fromStdString(output));
|
||||
}
|
||||
});
|
||||
|
||||
// QT日志到spdLog和Qt日志界面
|
||||
_qtRediretor->registerCallback([this](const QString& output) {
|
||||
_qtRediretor->registerCallback("qtLogWidget",[this](const QString& output) {
|
||||
if (!output.isEmpty()) {
|
||||
qtLogger->LogDebug("[QT]" + output.toStdString());
|
||||
_logToQtWidget->sendQtLogSignal(output); // Qt日志界面
|
||||
@@ -54,7 +61,7 @@ logService::logService(){
|
||||
});
|
||||
|
||||
// QT日志到控制台
|
||||
_qtRediretor->registerCallback([this](const QString& output) {
|
||||
_qtRediretor->registerCallback("console", [this](const QString& output) {
|
||||
if (!output.isEmpty()) {
|
||||
_stdConsoleRedirector->writeToConsole(output.toStdString());
|
||||
}
|
||||
@@ -64,23 +71,15 @@ logService::logService(){
|
||||
qDebug() << "Failed to initialize logService:" << e.what();
|
||||
}
|
||||
}
|
||||
logService::~logService(){
|
||||
logService::~logService() {
|
||||
try {
|
||||
_stdConsoleRedirector.reset();
|
||||
_qtRediretor.reset();
|
||||
_logToQtWidget.reset();
|
||||
qtLogger.reset();
|
||||
} catch (const std::exception& e) {
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
// 析构函数中不应抛出异常,只记录错误
|
||||
qDebug() << "Error in logService destructor:" << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
void logService::disableConsole(){
|
||||
if (_stdConsoleRedirector) {
|
||||
_stdConsoleRedirector->eraseSecondCallback();
|
||||
}
|
||||
if (_qtRediretor) {
|
||||
_qtRediretor->eraseSecondCallback();
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,7 @@ signals:
|
||||
void mainWindowStdLogSignal(const QString& logMsg);
|
||||
void stdLogSignal(const QString& logMsg);
|
||||
void qtLogSignal(const QString& logMsg);
|
||||
void loadingWindow_appendConsoleLog(const QString& logMsg);
|
||||
};
|
||||
class logService : public QThread
|
||||
{
|
||||
@@ -47,8 +48,20 @@ public:
|
||||
static logService* getInstance();
|
||||
|
||||
// 禁用控制台输出
|
||||
void disableConsole();
|
||||
|
||||
void disableConsoleOutput(){
|
||||
if (_stdConsoleRedirector) {
|
||||
_stdConsoleRedirector->eraseCallback("console");
|
||||
}
|
||||
if (_qtRediretor) {
|
||||
_qtRediretor->eraseCallback("console");
|
||||
}
|
||||
}
|
||||
// 禁用加载界面输出
|
||||
void disableLoadingWidgetOutput() {
|
||||
if (_stdConsoleRedirector) {
|
||||
_stdConsoleRedirector->eraseCallback("loadingWidget");
|
||||
}
|
||||
}
|
||||
// 获取日志组件
|
||||
logToQtWidget* getLogWidget() const { return _logToQtWidget.get(); }
|
||||
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
// 全局指针,用于消息处理函数
|
||||
static qtRediretor* qtRediretor_Ptr = nullptr;
|
||||
|
||||
static void qtMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg)
|
||||
{
|
||||
static void qtMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg) {
|
||||
if (!qtRediretor_Ptr) {
|
||||
return;
|
||||
}
|
||||
@@ -21,32 +20,30 @@ static void qtMessageHandler(QtMsgType type, const QMessageLogContext& context,
|
||||
qtRediretor_Ptr->sendMsg(outputMessage);
|
||||
}
|
||||
|
||||
qtRediretor::qtRediretor()
|
||||
{
|
||||
qtRediretor::qtRediretor(){
|
||||
qtRediretor_Ptr = this;
|
||||
qInstallMessageHandler(qtMessageHandler);
|
||||
}
|
||||
|
||||
void qtRediretor::registerCallback(CallbackType callback)
|
||||
{
|
||||
void qtRediretor::registerCallback(std::string key,CallbackType callback) {
|
||||
std::lock_guard<std::mutex> lock(consoleLock);
|
||||
callbacks.push_back(callback);
|
||||
callbacks.insert(std::make_pair(key,callback));
|
||||
}
|
||||
|
||||
void qtRediretor::sendMsg(const QString& msg)
|
||||
{
|
||||
void qtRediretor::sendMsg(const QString& msg){
|
||||
|
||||
std::lock_guard<std::mutex> lock(consoleLock);
|
||||
for (const auto& callback : callbacks) {
|
||||
if (callback) {
|
||||
callback(msg);
|
||||
if (callback.second) {
|
||||
callback.second(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void qtRediretor::eraseSecondCallback()
|
||||
{
|
||||
void qtRediretor::eraseCallback(std::string key) {
|
||||
|
||||
std::lock_guard<std::mutex> lock(consoleLock);
|
||||
if (callbacks.size() > 1) {
|
||||
callbacks.erase(callbacks.begin() + 1, callbacks.end());
|
||||
callbacks.erase(key);
|
||||
}
|
||||
}
|
||||
@@ -7,17 +7,16 @@
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
|
||||
class qtRediretor
|
||||
{
|
||||
class qtRediretor{
|
||||
public:
|
||||
qtRediretor();
|
||||
~qtRediretor() = default;
|
||||
|
||||
using CallbackType = std::function<void(const QString&)>;
|
||||
|
||||
void registerCallback(CallbackType callback);
|
||||
void registerCallback(std::string key, CallbackType callback);
|
||||
void sendMsg(const QString& msg);
|
||||
void eraseSecondCallback();
|
||||
void eraseCallback(std::string key);
|
||||
|
||||
// 禁用拷贝构造和赋值操作
|
||||
qtRediretor(const qtRediretor&) = delete;
|
||||
@@ -25,5 +24,5 @@ public:
|
||||
|
||||
private:
|
||||
std::mutex consoleLock;
|
||||
std::vector<CallbackType> callbacks;
|
||||
std::map<std::string, CallbackType> callbacks;
|
||||
};
|
||||
@@ -56,17 +56,17 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void registerCallback(CallbackType callback) {
|
||||
void registerCallback(std::string key,CallbackType callback) {
|
||||
if (callback) {
|
||||
std::lock_guard<std::recursive_mutex> lock(consoleLock);
|
||||
callbacks.push_back(callback);
|
||||
callbacks.insert(std::make_pair(key,callback));
|
||||
}
|
||||
}
|
||||
|
||||
void eraseSecondCallback() {
|
||||
void eraseCallback(std::string key) {
|
||||
std::lock_guard<std::recursive_mutex> lock(consoleLock);
|
||||
if (callbacks.size() > 1) {
|
||||
callbacks.erase(callbacks.begin() + 1, callbacks.end());
|
||||
if (callbacks.size() >= 1) {
|
||||
callbacks.erase(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,12 +121,12 @@ private:
|
||||
std::ostream& originalStream;
|
||||
std::streambuf* originalBuffer;
|
||||
std::string buffer;
|
||||
std::vector<CallbackType> callbacks;
|
||||
std::map<std::string,CallbackType> callbacks;
|
||||
mutable std::recursive_mutex consoleLock; // 使用递归锁
|
||||
|
||||
// 异步处理相关
|
||||
std::thread asyncThread;
|
||||
std::queue<std::pair<std::string, std::vector<CallbackType>>> asyncQueue;
|
||||
std::queue<std::pair<std::string, std::map<std::string, CallbackType>>> asyncQueue;
|
||||
std::mutex asyncMutex;
|
||||
std::condition_variable asyncCondition;
|
||||
std::atomic<bool> stopAsyncThread;
|
||||
@@ -157,12 +157,12 @@ private:
|
||||
|
||||
// 执行回调函数
|
||||
const std::string& bufferContent = item.first;
|
||||
const std::vector<CallbackType>& callbackList = item.second;
|
||||
const std::map<std::string, CallbackType>& callbackList = item.second;
|
||||
|
||||
for (const auto& callback : callbackList) {
|
||||
if (callback) {
|
||||
if (callback.second) {
|
||||
try {
|
||||
callback(bufferContent);
|
||||
callback.second(bufferContent);
|
||||
} catch (...) {
|
||||
// 忽略回调函数中的异常,防止影响其他回调
|
||||
}
|
||||
@@ -185,7 +185,7 @@ private:
|
||||
|
||||
if (asyncProcessingEnabled && !callbacks.empty()) {
|
||||
// 异步处理回调函数
|
||||
std::vector<CallbackType> callbacksCopy = callbacks;
|
||||
auto callbacksCopy = callbacks;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(asyncMutex);
|
||||
asyncQueue.emplace(std::move(bufferCopy), std::move(callbacksCopy));
|
||||
@@ -194,9 +194,9 @@ private:
|
||||
} else {
|
||||
// 同步处理(用于关闭时或禁用异步时)
|
||||
for (const auto& callback : callbacks) {
|
||||
if (callback) {
|
||||
if (callback.second) {
|
||||
try {
|
||||
callback(bufferCopy);
|
||||
callback.second(bufferCopy);
|
||||
} catch (...) {
|
||||
// 忽略回调函数中的异常
|
||||
}
|
||||
|
||||
@@ -116,11 +116,12 @@ void connectSignalAndSlot(appCore* _core, MainWindow* _MainWindow, qtFuncBridge*
|
||||
_MainWindow->_logWidget, &logWidget::recvQtLogMsg);
|
||||
QObject::connect(_core->_logService->getLogWidget(), &logToQtWidget::mainWindowStdLogSignal,
|
||||
_MainWindow->_displayWidget, &displayWidget::recvMainWindowStdLogMsg);
|
||||
|
||||
QObject::connect(_core->_logService->getLogWidget(), &logToQtWidget::loadingWindow_appendConsoleLog,
|
||||
_MainWindow, [=](const QString& text) {_MainWindow->_loadingWidget.appendConsoleLog(text); });
|
||||
//BackEnd To Front
|
||||
//等待界面
|
||||
QObject::connect(bridge, &qtFuncBridge::loadingWindow_appendLog,
|
||||
_MainWindow, [=](const QString& text, const QColor& color) {_MainWindow->_loadingWidget.appendLog(text, color); });
|
||||
QObject::connect(bridge, &qtFuncBridge::loadingWindow_appendInitLog,
|
||||
_MainWindow, [=](const QString& text, const QColor& color) {_MainWindow->_loadingWidget.appendInitLog(text, color); });
|
||||
QObject::connect(bridge, &qtFuncBridge::loadingWindow_modifyLog,
|
||||
_MainWindow, [=](int col, const QString& text, const QColor& color) {_MainWindow->_loadingWidget.modifyLog(col, text, color); });
|
||||
QObject::connect(bridge, &qtFuncBridge::loadingWindow_clearLog,
|
||||
@@ -219,7 +220,7 @@ int main(int argc, char* argv[])
|
||||
#if HIDE_CONSOLE
|
||||
if (config.consoleHandle) {
|
||||
ShowWindow(config.consoleHandle, SW_HIDE);
|
||||
_core._logService->disableConsole();
|
||||
_core._logService->disableConsoleOutput();
|
||||
}// 隐藏控制台窗口
|
||||
#endif
|
||||
w.registerQuitFunc([&]() {
|
||||
|
||||
@@ -0,0 +1,303 @@
|
||||
#include <581_YuHan_hanhou.h>
|
||||
|
||||
void handleAiProcess(cv::Mat& src, cv::Mat& segRes, cv::Mat& Paint,
|
||||
bool& silieResult, bool& fanZheResult,
|
||||
cv::Point offset, handdleAI::pClassification* clsPtr, std::vector<cv::Mat>& clsImgs){
|
||||
|
||||
std::vector<std::vector<cv::Point>> contours;
|
||||
cv::findContours(segRes, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
|
||||
int cnt = 0;
|
||||
for (int i = 0; i < contours.size(); i++){
|
||||
cv::Rect originRect = cv::boundingRect(contours[i]);
|
||||
cv::Rect rect = originRect;
|
||||
rect.x += offset.x;
|
||||
rect.y += offset.y;
|
||||
|
||||
if (originRect.width < 50 || originRect.height < 50)
|
||||
continue;
|
||||
std::vector<cv::Mat> clsImgVec = cutImg2ClsVec(rect, src);
|
||||
std::vector<int> clsRes;//true ok
|
||||
bool isNg = false;
|
||||
for (auto& cls : clsImgVec) {
|
||||
int Result = clsPtr->Evaluate(cls);
|
||||
if (Result == 1)isNg = true;
|
||||
clsRes.push_back(Result);
|
||||
}
|
||||
clsImgs.insert(clsImgs.end(), clsImgVec.begin(), clsImgVec.end());
|
||||
if (isNg == true)
|
||||
{
|
||||
cv::Scalar color = cv::Scalar(0, 255, 255, 30);
|
||||
//cv::rectangle(Paint, originRect, color, 4);
|
||||
drawContours(Paint, contours, i, cv::Scalar(0, 255, 255, 30), 3, cv::LINE_8, cv::noArray(), INT_MAX, cv::Point(offset.x, offset.y));
|
||||
//putTextHusky(Paint, utf8_to_gbk("NG").c_str(), cv::Point(originRect.x - originRect.width / 2, originRect.y - originRect.height / 2 - 50), cv::Scalar(0, 255, 0), 50);
|
||||
silieResult = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//drawContours(Paint, contours, i, cv::Scalar(0, 255, 0, 30), 3, LINE_8, noArray(), INT_MAX, cv::Point(offset.x, offset.y));
|
||||
}
|
||||
//if (clsRes == 1) {
|
||||
// cv::Scalar color = cv::Scalar(0, 0, 255, 30);
|
||||
// cv::rectangle(Paint, paintRect, color, 4);
|
||||
// putTextHusky(Paint, utf8_to_gbk("撕裂").c_str(), cv::Point(paintRect.x - paintRect.width / 2, paintRect.y - paintRect.height / 2 - 50), cv::Scalar(0, 255, 0), 50);
|
||||
// silieResult = false;
|
||||
//}
|
||||
//else if (clsRes == 2) {
|
||||
// cv::Scalar color = cv::Scalar(0, 0, 255, 30);
|
||||
// cv::rectangle(Paint, paintRect, color, 4);
|
||||
// putTextHusky(Paint, utf8_to_gbk("翻折").c_str(), cv::Point(paintRect.x - paintRect.width / 2, paintRect.y - paintRect.height / 2 - 50), cv::Scalar(0, 255, 0), 50);
|
||||
// fanZheResult = false;
|
||||
//}
|
||||
}
|
||||
}
|
||||
halconResult halconAlgoProcess(cv::Mat& img, cv::Mat& Paint, handdleAI::pSegmentation* seg_hanYinZhuaQu, cv::Mat& segResult){//算法先画
|
||||
halconResult result;
|
||||
cv::Mat forSeg;
|
||||
cv::resize(img, forSeg, cv::Size(), 0.2, 0.2);
|
||||
segResult = seg_hanYinZhuaQu->Evaluate(forSeg);
|
||||
cv::resize(segResult, segResult, cv::Size(), 5, 5);
|
||||
HObject in_Image1 = MatToHObject(img), in_Image2 = MatToHObject(segResult);
|
||||
HTuple in_Resolution(0.013682);
|
||||
|
||||
HDevEngineCpp::HDevProcedure proc("_1_Cal_JE_Distance");
|
||||
HDevEngineCpp::HDevProcedureCall procedureCall(proc);
|
||||
procedureCall.SetInputIconicParamObject("in_Image1", in_Image1);
|
||||
procedureCall.SetInputIconicParamObject("in_Image2", in_Image2);
|
||||
procedureCall.SetInputCtrlParamTuple("in_Resolution", in_Resolution);
|
||||
procedureCall.Execute();
|
||||
HTuple out_LinePoint, out_Distance, out_Flag;
|
||||
out_LinePoint = procedureCall.GetOutputCtrlParamTuple("out_LinePoint");//获取输出控制类变量
|
||||
out_Distance = procedureCall.GetOutputCtrlParamTuple("out_Distance");//获取输出控制类变量
|
||||
out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出控制类变量
|
||||
if (out_Flag.D() == 1)
|
||||
{
|
||||
for (auto i = 0; i < out_LinePoint.Length(); i += 4)
|
||||
{
|
||||
cv::line(Paint,
|
||||
cv::Point(out_LinePoint[i + 1].D(), out_LinePoint[i].D()),
|
||||
cv::Point(out_LinePoint[i + 3].D(), out_LinePoint[i + 2].D()),
|
||||
cv::Scalar(0, 255, 0), 5);
|
||||
}
|
||||
|
||||
double value1 = out_Distance[0].D();
|
||||
double value2 = out_Distance[1].D();
|
||||
double value3 = out_Distance[2].D();
|
||||
|
||||
result.jiErWidth = value1;
|
||||
result.jiErHeight = value2;
|
||||
result.hanYin1 = value3;
|
||||
}
|
||||
else
|
||||
{
|
||||
//putTextHusky(Paint, utf8_to_gbk("算法异常").c_str(), cv::Point(0, 500), cv::Scalar(0, 255, 0), 300);
|
||||
//putTextHusky(Paint, utf8_to_gbk("NG").c_str(), cv::Point(0, 0), cv::Scalar(0, 0, 255), 300);
|
||||
result.result = false;
|
||||
return result;
|
||||
}
|
||||
result.result = true;
|
||||
return result;
|
||||
}
|
||||
bool hanHouCeLiang(std::shared_ptr <detData> data, yuHanHanHouParams* _detParams, sx_581_address address) {
|
||||
QByteArray plcResult = "2";
|
||||
try {
|
||||
#if 0
|
||||
/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓调试用↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
|
||||
QString resultTag = "OK";
|
||||
Mat srcImage;
|
||||
srcImage = img2D.clone();
|
||||
cv::Mat dstImage;
|
||||
srcImage.copyTo(dstImage);
|
||||
cv::resize(dstImage, dstImage, cv::Size(), 0.5, 0.5);
|
||||
putTextHusky(dstImage, utf8_to_gbk("AI_OK").c_str(), cv::Point(1800, 50), cv::Scalar(0, 255, 0), 200);
|
||||
putTextHusky(dstImage, utf8_to_gbk("ALGO_OK").c_str(), cv::Point(1800, 250), cv::Scalar(0, 255, 0), 200);
|
||||
cv::resize(dstImage, dstImage, cv::Size(), 0.5, 0.5);
|
||||
resMat.push_back(dstImage);
|
||||
addImgToSaveStruct(resMat[0], "0", getResSaveFormat(SN, resultTag));
|
||||
addImgToSaveStruct(HikMat[0], "0", getOriSaveFormat(SN, resultTag));
|
||||
return true;
|
||||
/*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑调试用↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/
|
||||
#else
|
||||
cv::Mat sourceImg = data->oriImgs[0];
|
||||
cv::Mat Paint;
|
||||
data->oriImgs[0].copyTo(Paint);
|
||||
|
||||
if (Paint.channels() == 1)
|
||||
cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR);
|
||||
|
||||
//HALCON异步处理
|
||||
cv::Mat hySegResult;
|
||||
auto futrue = std::async(std::launch::async, halconAlgoProcess, sourceImg, Paint, _detParams->segHanYinZhuaQu, std::ref(hySegResult));//异步执行
|
||||
|
||||
//handleAI主线程处理 定位极耳
|
||||
float resizeRate = 5.0;
|
||||
cv::Mat matForDingWei;
|
||||
cv::resize(sourceImg, matForDingWei, cv::Size(), 1 / resizeRate, 1 / resizeRate);
|
||||
cv::Mat dingWeiResultMat = ~_detParams->segYuHanDingWei->Evaluate(matForDingWei);
|
||||
cv::Mat structreElement = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
|
||||
dilate(dingWeiResultMat, dingWeiResultMat, structreElement, cv::Point(-1, -1), 1);
|
||||
cv::Rect rect = findMaxAreaContour(dingWeiResultMat);
|
||||
cv::Mat matDet;
|
||||
cv::Rect rectCutJier(rect.x * resizeRate - 25,
|
||||
rect.y * resizeRate - 25,
|
||||
rect.width * resizeRate + 50,
|
||||
rect.height * resizeRate + 50);
|
||||
sourceImg(rectCutJier & (cv::Rect(0, 0, sourceImg.cols, sourceImg.rows))).copyTo(matDet);
|
||||
|
||||
//SEG缺陷检测
|
||||
cv::Mat SegRes = ~_detParams->segHanHou->Evaluate(matDet);
|
||||
bool silieOk = true, fanZheOk = true;
|
||||
std::vector<cv::Mat> clsImgs;
|
||||
handleAiProcess(sourceImg, SegRes, Paint, silieOk, fanZheOk, cv::Point(rect.x * resizeRate, rect.y * resizeRate), _detParams->clsHanHou, clsImgs);
|
||||
|
||||
//等待halcon算法完成
|
||||
futrue.wait();
|
||||
halconResult halconResult = futrue.get();
|
||||
//结果处理
|
||||
QString okNgSaveText = "OK";
|
||||
QByteArray silieResultText = silieOk == true ? "1" : "2";
|
||||
QByteArray fanzheResultText = fanZheOk == true ? "1" : "2";
|
||||
TextRendererZH textPainter(Paint.cols, Paint.rows, 300);
|
||||
if (silieOk == true && fanZheOk == true) {//OK
|
||||
textPainter.putText(Paint, "缺陷检测OK", cv::Point(4000, 50), cv::Scalar(0, 255, 0));
|
||||
}
|
||||
else {
|
||||
textPainter.putText(Paint, "撕裂/翻折NG", cv::Point(4000, 50), cv::Scalar(0, 255, 0));
|
||||
plcResult = "2";
|
||||
data->aiDetOK = false;
|
||||
}
|
||||
if (halconResult.result == true) {
|
||||
textPainter.putText(Paint, "算法OK", cv::Point(4000, 350), cv::Scalar(0, 255, 0));
|
||||
}
|
||||
else {
|
||||
textPainter.putText(Paint, "算法NG", cv::Point(4000, 350), cv::Scalar(0, 255, 0));
|
||||
plcResult = "2";
|
||||
data->halconOK = false;
|
||||
}
|
||||
|
||||
plcResult = "1"; silieResultText = "1"; fanzheResultText = "1";
|
||||
data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈
|
||||
data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr) + "_" + silieResultText);//发送数据-撕裂OKNG
|
||||
data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr + 1) + "_" + fanzheResultText);//发送数据-翻折OKNG
|
||||
data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(halconResult.jiErWidth));//发送数据-极耳宽
|
||||
data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 4) + "_" + QByteArray::number(halconResult.jiErHeight));//发送数据-极耳高
|
||||
data->service->_triggerManager->writeShort("D" + QByteArray::number(address.valueOffsetAddr + 6) + "_1");//发送数据-焊印位置判定结果
|
||||
data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 8) + "_" + QByteArray::number(halconResult.hanYin1));//发送数据-芯包顶部到焊印的距离
|
||||
|
||||
textPainter.putText(Paint, "极耳宽度" + std::to_string(halconResult.jiErWidth), cv::Point(100, 50), cv::Scalar(0, 255, 0));
|
||||
textPainter.putText(Paint, "极耳高度" + std::to_string(halconResult.jiErHeight), cv::Point(100, 300), cv::Scalar(0, 255, 0));
|
||||
textPainter.putText(Paint, "焊印上边缘到极耳上边缘高度" + std::to_string(halconResult.hanYin1), cv::Point(100, 550), cv::Scalar(0, 255, 0));
|
||||
|
||||
cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5);
|
||||
data->resultImgs.push_back(Paint);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
CATCH_EXCEPTIONS
|
||||
|
||||
qDebug() << "[Error] " << QString::fromUtf8("检测失败!");
|
||||
cv::Mat Paint;
|
||||
data->oriImgs[0].copyTo(Paint);
|
||||
if (Paint.channels() == 1)
|
||||
cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR);
|
||||
TextRendererZH textPainter(Paint.cols, Paint.rows, 300);
|
||||
textPainter.putText(Paint, "NG", cv::Point(100, 50), cv::Scalar(0, 255, 0));
|
||||
cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5);
|
||||
data->resultImgs.push_back(Paint);
|
||||
data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hanHouDown(std::shared_ptr <detData> data, yuHanHanHouParams* _detParams, sx_581_address address) {
|
||||
QByteArray plcResult = "2";
|
||||
try{
|
||||
#if 0
|
||||
/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓调试用↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
|
||||
QString resultTag = "OK";
|
||||
Mat srcImage;
|
||||
srcImage = img2D.clone();
|
||||
cv::Mat dstImage;
|
||||
srcImage.copyTo(dstImage);
|
||||
cv::resize(dstImage, dstImage, cv::Size(), 0.5, 0.5);
|
||||
putTextHusky(dstImage, utf8_to_gbk("AI_OK").c_str(), cv::Point(1800, 50), cv::Scalar(0, 255, 0), 200);
|
||||
cv::resize(dstImage, dstImage, cv::Size(), 0.5, 0.5);
|
||||
resMat.push_back(dstImage);
|
||||
addImgToSaveStruct(resMat[0], "0", getResSaveFormat(SN, resultTag));
|
||||
addImgToSaveStruct(HikMat[0], "0", getOriSaveFormat(SN, resultTag));
|
||||
return true;
|
||||
/*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑调试用↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/
|
||||
|
||||
#else
|
||||
//存图数据加保存队列,加锁,避免数据访问冲突
|
||||
cv::Mat sourceImg = data->oriImgs[0];
|
||||
cv::Mat Paint;
|
||||
sourceImg.copyTo(Paint);
|
||||
|
||||
if (Paint.channels() == 1)
|
||||
cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR);
|
||||
|
||||
//jier定位
|
||||
float resizeRate = 5.0;
|
||||
cv::Mat matForDingWei;
|
||||
cv::resize(sourceImg, matForDingWei, cv::Size(), 1 / resizeRate, 1 / resizeRate);
|
||||
cv::Mat dingWeiResultMat = ~_detParams->segYuHanDingWei->Evaluate(matForDingWei);
|
||||
cv::Mat structreElement = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
|
||||
dilate(dingWeiResultMat, dingWeiResultMat, structreElement, cv::Point(-1, -1), 1);
|
||||
cv::Rect rect = findMaxAreaContour(dingWeiResultMat);
|
||||
cv::Mat matDet;
|
||||
cv::Rect rectCutJier(rect.x * resizeRate - 25,
|
||||
rect.y * resizeRate - 25,
|
||||
rect.width * resizeRate + 50,
|
||||
rect.height * resizeRate + 50);
|
||||
sourceImg(rectCutJier & (cv::Rect(0, 0, sourceImg.cols, sourceImg.rows))).copyTo(matDet);
|
||||
|
||||
//SEG缺陷检测
|
||||
cv::Mat SegRes = ~_detParams->segHanHou->Evaluate(matDet);
|
||||
bool silieOk = true, fanZheOk = true;
|
||||
std::vector<cv::Mat> clsImgs;
|
||||
handleAiProcess(sourceImg, SegRes, Paint, silieOk, fanZheOk, cv::Point(rect.x * resizeRate, rect.y * resizeRate), _detParams->clsHanHou, clsImgs);
|
||||
QString okNgSaveText = "OK";
|
||||
QByteArray silieResultText = silieOk == true ? "1" : "2";
|
||||
QByteArray fanzheResultText = fanZheOk == true ? "1" : "2";
|
||||
plcResult = "1";
|
||||
TextRendererZH textPainter(Paint.cols, Paint.rows, 200);
|
||||
if (silieOk == true && fanZheOk == true) {//OK
|
||||
textPainter.putText(Paint, "OK", cv::Point(3000, 50), cv::Scalar(0, 255, 0));
|
||||
}
|
||||
else {
|
||||
textPainter.putText(Paint, "撕裂/翻折NG", cv::Point(3000, 50), cv::Scalar(0, 255, 0));
|
||||
plcResult = "2";
|
||||
data->aiDetOK = false;
|
||||
}
|
||||
plcResult = "1";
|
||||
data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈
|
||||
|
||||
cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5);
|
||||
data->resultImgs.push_back(Paint);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
CATCH_EXCEPTIONS
|
||||
|
||||
qDebug() << "[Error] " << QString::fromUtf8("检测失败!");
|
||||
cv::Mat Paint;
|
||||
data->oriImgs[0].copyTo(Paint);
|
||||
if (Paint.channels() == 1)
|
||||
cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR);
|
||||
TextRendererZH textPainter(Paint.cols, Paint.rows, 300);
|
||||
textPainter.putText(Paint, "NG", cv::Point(100, 50), cv::Scalar(0, 255, 0));
|
||||
cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5);
|
||||
data->resultImgs.push_back(Paint);
|
||||
data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
mission* createMission() {
|
||||
return new _581_YuHan_hanqian();
|
||||
}
|
||||
void destroyMission(mission* _mission) {
|
||||
delete _mission;
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
#include <missionBase.hpp>
|
||||
#include <sxGlobal.h>
|
||||
#pragma region 算法
|
||||
#include <simpleAlgo.h>
|
||||
#include <hdevengine/HDevEngineCpp.h>
|
||||
#include <opencvPaintAlgo.hpp>
|
||||
using namespace HDevEngineCpp;
|
||||
#pragma endregion
|
||||
class yuHanHanHouParams {
|
||||
public:
|
||||
handdleAI::pSegmentation* segHanYinZhuaQu = nullptr;
|
||||
handdleAI::pSegmentation* segYuHanDingWei = nullptr;
|
||||
handdleAI::pSegmentation* segHanHou = nullptr;
|
||||
handdleAI::pClassification* clsHanHou = nullptr;
|
||||
bool isTong = true;
|
||||
};
|
||||
struct halconResult {
|
||||
bool result = true;
|
||||
double jiErWidth = -1;
|
||||
double jiErHeight = -1;
|
||||
double hanYin1 = -1;
|
||||
};
|
||||
void handleAiProcess(cv::Mat& src, cv::Mat& segRes, cv::Mat& Paint,
|
||||
bool& silieResult, bool& fanZheResult,
|
||||
cv::Point offset, handdleAI::pClassification* clsPtr, std::vector<cv::Mat>& clsImgs);
|
||||
halconResult halconAlgoProcess(cv::Mat& img, cv::Mat& Paint, handdleAI::pSegmentation* seg_hanYinZhuaQu, cv::Mat& segResult);
|
||||
bool hanHouCeLiang(std::shared_ptr <detData> data, yuHanHanHouParams* _detParams, sx_581_address address);
|
||||
bool hanHouDown(std::shared_ptr <detData> data, yuHanHanHouParams* _detParams, sx_581_address address);
|
||||
|
||||
namespace hanhou45{
|
||||
|
||||
}
|
||||
class _581_YuHan_hanqian : public mission {
|
||||
public:
|
||||
_581_SX_Single_triggerTemplate< yuHanHanHouParams> lv_top90_1;
|
||||
_581_SX_Single_triggerTemplate< yuHanHanHouParams> lv_down90_2;
|
||||
_581_SX_Single_triggerTemplate< yuHanHanHouParams> tong_top90_3;
|
||||
_581_SX_Single_triggerTemplate< yuHanHanHouParams> tong_down90_4;
|
||||
|
||||
_581_SX_Single_triggerTemplate< yuHanHanHouParams> lv_top45_5;
|
||||
_581_SX_Single_triggerTemplate< yuHanHanHouParams> lv_down45_6;
|
||||
_581_SX_Single_triggerTemplate< yuHanHanHouParams> tong_top45_7;
|
||||
_581_SX_Single_triggerTemplate< yuHanHanHouParams> tong_down45_8;
|
||||
std::vector < yuHanHanHouParams> tongDetParams;
|
||||
std::vector < yuHanHanHouParams> lvDetParams;
|
||||
bool initOnce = false;
|
||||
void onConfigReloaded() {
|
||||
HDevEngineCpp::HDevEngine myEngine;
|
||||
myEngine.SetProcedurePath("./halconAlgoFiles/AlgoLibrary_602.hdpl");
|
||||
|
||||
/*tongDetParams.segHanYinZhuaQu = _serviceManager->_handleAiModelManager->getSegModel("segTongHanYinZhuaQu_GPU1");
|
||||
tongDetParams.segYuHanDingWei = _serviceManager->_handleAiModelManager->getSegModel("segTongYuHanDingWei_GPU1");
|
||||
tongDetParams.segHanHou = _serviceManager->_handleAiModelManager->getSegModel("segTongHanHou_GPU1");
|
||||
tongDetParams.clsHanHou = _serviceManager->_handleAiModelManager->getClsModel("clsTongHanHou_GPU1");
|
||||
|
||||
|
||||
lvDetParams.segHanYinZhuaQu = _serviceManager->_handleAiModelManager->getSegModel("segLvHanYinZhuaQu_GPU0");
|
||||
lvDetParams.segYuHanDingWei = _serviceManager->_handleAiModelManager->getSegModel("segLvYuHanDingWei_GPU0");
|
||||
lvDetParams.segHanHou = _serviceManager->_handleAiModelManager->getSegModel("segLvHanHou_GPU0");
|
||||
lvDetParams.clsHanHou = _serviceManager->_handleAiModelManager->getClsModel("clsLvHanHou_GPU0");*/
|
||||
if (initOnce == false) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
yuHanHanHouParams tong;
|
||||
tong.segHanYinZhuaQu = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-hanYinZhuaQu-T.BHD", 64, 0);
|
||||
tong.segYuHanDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-yuHanDingWei-T.BHD", 64, 0);
|
||||
tong.segHanHou = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-yuHanhanHou-T.BHD", 64, 0);
|
||||
tong.clsHanHou = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanhou/cls-yuHanhanHou-T.BHD", 0, 1);
|
||||
tongDetParams.push_back(tong);
|
||||
|
||||
yuHanHanHouParams lv;
|
||||
lv.segHanYinZhuaQu = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-hanYinZhuaQu-L.BHD", 64, 1);
|
||||
lv.segYuHanDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-yuHanDingWei-L.BHD", 64, 1);
|
||||
lv.segHanHou = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanhou/seg-yuHanhanHou-L.BHD", 64, 1);
|
||||
lv.clsHanHou = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanhou/cls-yuHanhanHou-L.BHD", 1, 1);
|
||||
lv.isTong = false;
|
||||
lvDetParams.push_back(lv);
|
||||
}
|
||||
initOnce = true;
|
||||
}
|
||||
}
|
||||
bool initCustom() {
|
||||
#pragma region 注册触发器回调
|
||||
if (_configMap["hanhou"] == "OUT") {
|
||||
lv_top90_1.init("Camera1", "极耳尺寸-外-铝-相机1(顶部90°)", { { 522, 1,540,"523","530",820} }, 1, lvDetParams[0], _serviceManager, bridge, hanHouCeLiang);
|
||||
lv_down90_2.init("Camera2", "极耳尺寸-外-铝-相机2(底部90°)", { { 524, 1,540,"525","532",-1} }, 1, lvDetParams[1], _serviceManager, bridge, hanHouDown);
|
||||
tong_top90_3.init("Camera3", "极耳尺寸-外-铜-相机3(顶部90°)", { { 526,1,540,"527","534",800} }, 1, tongDetParams[0], _serviceManager, bridge, hanHouCeLiang);
|
||||
tong_down90_4.init("Camera4", "极耳尺寸-外-铜-相机4(底部90°)", { { 528, 1,540,"529","536",-1} }, 1, tongDetParams[1], _serviceManager, bridge, hanHouDown);
|
||||
|
||||
lv_top45_5.init("Camera5", "底部撕裂-外-铝-相机5(顶部45°)", { { 562,1,540,"563","570",-1} }, 1, lvDetParams[2], _serviceManager, bridge, hanHouDown);
|
||||
lv_down45_6.init("Camera6", "底部撕裂-外-铝-相机6(底部45°)", { { 564, 1,540,"565","572",-1} }, 1, lvDetParams[3], _serviceManager, bridge, hanHouDown);
|
||||
tong_top45_7.init("Camera7", "底部撕裂-外-铜-相机7(顶部45°)", { { 566, 1,540,"567","574",-1} }, 1, tongDetParams[2], _serviceManager, bridge, hanHouDown);
|
||||
tong_down45_8.init("Camera8", "底部撕裂-外-铜-相机8(底部45°)", { { 568, 1,540,"569","576",-1} }, 1, tongDetParams[3], _serviceManager, bridge, hanHouDown);
|
||||
}
|
||||
else {
|
||||
lv_top90_1.init("Camera1", "极耳尺寸-内-铝-相机1(顶部90°)", { { 602, 1,580,"603","610",860} }, 1, lvDetParams[0], _serviceManager, bridge, hanHouCeLiang);
|
||||
lv_down90_2.init("Camera2", "极耳尺寸-内-铝-相机2(底部90°)", { { 604, 1,580,"605","612",-1} }, 1, lvDetParams[1], _serviceManager, bridge, hanHouDown);
|
||||
tong_top90_3.init("Camera3", "极耳尺寸-内-铜-相机3(顶部90°)", { { 606,1,580,"607","614",840} }, 1, tongDetParams[0], _serviceManager, bridge, hanHouCeLiang);
|
||||
tong_down90_4.init("Camera4", "极耳尺寸-内-铜-相机4(底部90°)", { { 608, 1,580,"609","616",-1} }, 1, tongDetParams[1], _serviceManager, bridge, hanHouDown);
|
||||
|
||||
lv_top45_5.init("Camera5", "底部撕裂-内-铝-相机5(顶部45°)", { { 642,1,580,"643","650",-1} }, 1, lvDetParams[2], _serviceManager, bridge, hanHouDown);
|
||||
lv_down45_6.init("Camera6", "底部撕裂-内-铝-相机6(底部45°)", { { 644, 1,580,"645","652",-1} }, 1, lvDetParams[3], _serviceManager, bridge, hanHouDown);
|
||||
tong_top45_7.init("Camera7", "底部撕裂-内-铜-相机7(顶部45°)", { { 646, 1,580,"647","654",-1} }, 1, tongDetParams[2], _serviceManager, bridge, hanHouDown);
|
||||
tong_down45_8.init("Camera8", "底部撕裂-内-铜-相机8(底部45°)", { { 648, 1,580,"649","656",-1} }, 1, tongDetParams[3], _serviceManager, bridge, hanHouDown);
|
||||
}
|
||||
#pragma endregion
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
@@ -0,0 +1,78 @@
|
||||
# 获取获取当前目录名
|
||||
get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
string(TIMESTAMP RUN_TIME)
|
||||
message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME})
|
||||
|
||||
set(DLL_NAMES "opencv" "halcon" "handdleAI")
|
||||
foreach(child ${DLL_NAMES})
|
||||
LIST(APPEND ENV_INCLUDE ${${child}_include})
|
||||
LIST(APPEND ENV_LIB ${${child}_lib})
|
||||
LIST(APPEND ENV_TARGET ${${child}_target_link})
|
||||
endforeach()
|
||||
message(" ENV_INCLUDE : " ${ENV_INCLUDE} )
|
||||
message(" ENV_LIB : " ${ENV_LIB} )
|
||||
message(" ENV_TARGET : " ${ENV_TARGET} )
|
||||
include_directories(
|
||||
${PROJECT_ROOT_PATH}/src/core
|
||||
${PROJECT_ROOT_PATH}/src/core/handleAi
|
||||
${PROJECT_ROOT_PATH}/src/core/back
|
||||
${PROJECT_ROOT_PATH}/src/core/sql
|
||||
${ENV_INCLUDE}
|
||||
)
|
||||
|
||||
link_directories (
|
||||
${ENV_LIB}
|
||||
|
||||
)
|
||||
add_compile_options(/utf-8)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
SET(CMAKE_CXX_STANDARD 11)
|
||||
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
SET(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
FILE(GLOB HEAD_FILES "*.h" )
|
||||
FILE(GLOB SRC_FILES "./*.cpp")
|
||||
FILE(GLOB UI_FILES "./*.ui")
|
||||
|
||||
|
||||
#find_package(Qt5 COMPONENTS Core REQUIRED)
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Gui Network Sql REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Sql REQUIRED)
|
||||
|
||||
add_library(${CURRENT_FOLDER} SHARED
|
||||
${HEAD_FILES}
|
||||
${SRC_FILES}
|
||||
${UI_FILES}
|
||||
${PROJECT_ROOT_PATH}/include/qtBridge.h
|
||||
)
|
||||
|
||||
|
||||
|
||||
set_target_properties(${CURRENT_FOLDER} PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
|
||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}
|
||||
)
|
||||
|
||||
|
||||
target_link_libraries(${CURRENT_FOLDER} PRIVATE
|
||||
${ENV_TARGET}
|
||||
Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt${QT_VERSION_MAJOR}::Network
|
||||
Qt${QT_VERSION_MAJOR}::Sql
|
||||
)
|
||||
|
||||
|
||||
# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY)
|
||||
|
||||
|
||||
|
||||
|
||||
string(TIMESTAMP RUN_TIME)
|
||||
message( " modelx end : " ${CURRENT_FOLDER}:${RUN_TIME})
|
||||
message( " header files "${HEAD_FILES})
|
||||
@@ -8,10 +8,11 @@ using namespace HDevEngineCpp;
|
||||
#pragma endregion
|
||||
class yuHanHanQianParams {
|
||||
public:
|
||||
handleAiModelSeg* segDingWei = nullptr;
|
||||
handdleAI::pSegmentation* segDingWei = nullptr;
|
||||
|
||||
handleAiModelSeg* segJiErFanZhe = nullptr;
|
||||
handleAiModelCls* clsJiErFanZhe = nullptr;
|
||||
handdleAI::pSegmentation* segJiErFanZhe = nullptr;
|
||||
handdleAI::pClassification* clsJiErFanZhe = nullptr;
|
||||
bool isTong = true;
|
||||
};
|
||||
void halconProcess(cv::Mat& sourceImg, cv::Mat& Paint) {
|
||||
try {
|
||||
@@ -158,14 +159,14 @@ bool jiErFanZhe(std::shared_ptr <detData> data, yuHanHanQianParams* _detParams,
|
||||
sourceImg.copyTo(Paint);
|
||||
if (Paint.channels() == 1)
|
||||
cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR);
|
||||
halconProcess(sourceImg, Paint);
|
||||
//halconProcess(sourceImg, Paint);
|
||||
float resizeRate = 5.0;
|
||||
auto rect = getImageLocateRect(sourceImg, _detParams->segDingWei->segPtr, 1.0 / resizeRate);//定位
|
||||
auto rect = getImageLocateRect(sourceImg, _detParams->segDingWei, 1.0 / resizeRate);//定位
|
||||
rect = rect & (cv::Rect(0, 0, sourceImg.cols, sourceImg.rows));//防止越界
|
||||
bool isNG = false;
|
||||
cv::Mat seg_saveImg;
|
||||
if (rect.width > 500 || rect.height > 500) {
|
||||
isNG = handleAiProcess(sourceImg(rect), Paint(rect), _detParams->segJiErFanZhe->segPtr, _detParams->clsJiErFanZhe->clsPtr, data->clsOriginImgs);
|
||||
isNG = handleAiProcess(sourceImg(rect), Paint(rect), _detParams->segJiErFanZhe, _detParams->clsJiErFanZhe, data->clsOriginImgs);
|
||||
cv::rectangle(Paint, rect, cv::Scalar(0, 255, 255), 3);
|
||||
cv::resize(sourceImg(rect), seg_saveImg, cv::Size(), 0.5, 0.5);
|
||||
}
|
||||
@@ -173,15 +174,15 @@ bool jiErFanZhe(std::shared_ptr <detData> data, yuHanHanQianParams* _detParams,
|
||||
isNG = true;
|
||||
}
|
||||
QString okNgSaveText = "NG";
|
||||
TextRendererZH textPainter(Paint.cols, Paint.rows, 15);
|
||||
TextRendererZH textPainter(Paint.cols, Paint.rows, 300);
|
||||
if (isNG == false)//OK
|
||||
{
|
||||
textPainter.putText(Paint, "OK", cv::Point(1000, 50), cv::Scalar(0, 255, 0));
|
||||
textPainter.putText(Paint, "OK", cv::Point(100, 50), cv::Scalar(0, 255, 0));
|
||||
okNgSaveText = "OK";
|
||||
}
|
||||
else
|
||||
{
|
||||
textPainter.putText(Paint, "NG", cv::Point(1000, 50), cv::Scalar(0, 255, 0));
|
||||
textPainter.putText(Paint, "NG", cv::Point(100, 50), cv::Scalar(0, 255, 0));
|
||||
data->aiDetOK = false;
|
||||
plcResult = "2";
|
||||
}
|
||||
@@ -189,11 +190,12 @@ bool jiErFanZhe(std::shared_ptr <detData> data, yuHanHanQianParams* _detParams,
|
||||
data->resultImgs.push_back(Paint);
|
||||
sourceImg.release();
|
||||
data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
CATCH_EXCEPTIONS
|
||||
|
||||
qDebug() << "[Error] " << QString::fromUtf8("检测失败!");
|
||||
|
||||
qDebug() << "[Error] " << QString::fromUtf8("检测失败!") << data->uuid << QString::fromStdString(data->SNcode);
|
||||
cv::Mat Paint;
|
||||
data->oriImgs[0].copyTo(Paint);
|
||||
if (Paint.channels() == 1)
|
||||
@@ -216,33 +218,39 @@ public:
|
||||
_581_SX_Single_triggerTemplate< yuHanHanQianParams> out_lv_down_6;
|
||||
_581_SX_Single_triggerTemplate< yuHanHanQianParams> out_tong_top_7;
|
||||
_581_SX_Single_triggerTemplate< yuHanHanQianParams> out_tong_down_8;
|
||||
yuHanHanQianParams tongDetParams;
|
||||
yuHanHanQianParams lvDetParams;
|
||||
std::vector < yuHanHanQianParams> tongDetParams = std::vector < yuHanHanQianParams>(4);
|
||||
std::vector < yuHanHanQianParams> lvDetParams = std::vector < yuHanHanQianParams>(4);
|
||||
bool initOnce = false;
|
||||
void onConfigReloaded() {
|
||||
HDevEngineCpp::HDevEngine myEngine;
|
||||
myEngine.SetProcedurePath("./halconAlgoFiles/AlgoLibrary_602.hdpl");
|
||||
|
||||
tongDetParams.segDingWei = _serviceManager->_handleAiModelManager->getSegModel("segDingWei_GPU0");
|
||||
tongDetParams.segJiErFanZhe = _serviceManager->_handleAiModelManager->getSegModel("segTongJiErFanZhe_GPU0");
|
||||
tongDetParams.clsJiErFanZhe = _serviceManager->_handleAiModelManager->getClsModel("clsTongJiErFanZhe_GPU0");
|
||||
|
||||
|
||||
lvDetParams.segDingWei = _serviceManager->_handleAiModelManager->getSegModel("clsLvJiErFanZhe_GPU1");
|
||||
lvDetParams.segJiErFanZhe = _serviceManager->_handleAiModelManager->getSegModel("segLvJiErFanZhe_GPU1");
|
||||
lvDetParams.clsJiErFanZhe = _serviceManager->_handleAiModelManager->getClsModel("clsLvJiErFanZhe_GPU1");
|
||||
myEngine.SetProcedurePath("./halconAlgoFiles/AlgoLibrary_628_1.hdpl");
|
||||
|
||||
if (initOnce == false) {
|
||||
for (auto& params : tongDetParams) {
|
||||
params.segDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanqian/60_2_hanqian_dingwei_seg.BHD", 64, 0);
|
||||
params.segJiErFanZhe = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanqian/60_2_hanqian_segT.BHD", 64, 0);
|
||||
params.clsJiErFanZhe = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanqian/60_2_hanqian_clsT.BHD", 0, 1);
|
||||
}
|
||||
for (auto& params : lvDetParams) {
|
||||
params.segDingWei = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanqian/60_2_hanqian_dingwei_seg.BHD", 64, 1);
|
||||
params.segJiErFanZhe = handdleAI::CreateSegObjS("./handleaiModels/yuhan_hanqian/60_2_hanqian_segL.BHD", 64, 1);
|
||||
params.clsJiErFanZhe = handdleAI::CreateClsObjV3("./handleaiModels/yuhan_hanqian/60_2_hanqian_clsL.BHD", 1, 1);
|
||||
params.isTong = false;
|
||||
}
|
||||
initOnce = true;
|
||||
}
|
||||
}
|
||||
bool initCustom() {
|
||||
#pragma region 注册触发器回调
|
||||
in_lv_top_1.init("Camera1", "极耳翻折-铝-内-相机1(顶部)", { { 522, 1,540,"523","530",-1} }, 1, tongDetParams, _serviceManager, bridge, jiErFanZhe);
|
||||
in_lv_down_2.init("Camera2", "极耳翻折-铝-内-相机2(底部)", { { 524, 1,620,"525","532",-1} }, 1, tongDetParams, _serviceManager, bridge, jiErFanZhe);
|
||||
in_tong_top_3.init("Camera3", "极耳翻折-铜-内-相机3(顶部)", { { 526,1,540,"527","534",-1} }, 1, tongDetParams, _serviceManager, bridge, jiErFanZhe);
|
||||
in_tong_down_4.init("Camera4", "极耳翻折-铜-内-相机4(底部)", { { 528, 1,620,"529","536",-1} }, 1, tongDetParams, _serviceManager, bridge, jiErFanZhe);
|
||||
in_lv_top_1.init("Camera1", "极耳翻折-铝-内-相机1(顶部)", { { 682, 1,760,"683","670",-1} }, 1, lvDetParams[0], _serviceManager, bridge, jiErFanZhe);
|
||||
in_lv_down_2.init("Camera2", "极耳翻折-铝-内-相机2(底部)", { { 684, 1,760,"685","672",-1} }, 1, lvDetParams[1], _serviceManager, bridge, jiErFanZhe);
|
||||
in_tong_top_3.init("Camera3", "极耳翻折-铜-内-相机3(顶部)", { { 686,1,760,"687","674",-1} }, 1, tongDetParams[0], _serviceManager, bridge, jiErFanZhe);
|
||||
in_tong_down_4.init("Camera4", "极耳翻折-铜-内-相机4(底部)", { { 688, 1,760,"689","676",-1} }, 1, tongDetParams[1], _serviceManager, bridge, jiErFanZhe);
|
||||
|
||||
out_lv_top_5.init("Camera5", "极耳翻折-铝-外-相机5(顶部)", { { 562,1,580,"563","570",-1} }, 1, lvDetParams, _serviceManager, bridge, jiErFanZhe);
|
||||
out_lv_down_6.init("Camera6", "极耳翻折-铝-外-相机6(底部)", { { 564, 1,660,"565","572",-1} }, 1, lvDetParams, _serviceManager, bridge, jiErFanZhe);
|
||||
out_tong_top_7.init("Camera7", "极耳翻折-铜-外-相机7(顶部)", { { 566, 1,580,"567","574",-1} }, 1, lvDetParams, _serviceManager, bridge, jiErFanZhe);
|
||||
out_tong_down_8.init("Camera8", "极耳翻折-铜-外-相机8(底部)", { { 568, 1,660,"569","576",-1} }, 1, lvDetParams, _serviceManager, bridge, jiErFanZhe);
|
||||
out_lv_top_5.init("Camera5", "极耳翻折-铝-外-相机5(顶部)", { { 702,1,720,"703","710",-1} }, 1, lvDetParams[2], _serviceManager, bridge, jiErFanZhe);
|
||||
out_lv_down_6.init("Camera6", "极耳翻折-铝-外-相机6(底部)", { { 704, 1,720,"705","712",-1} }, 1, lvDetParams[3], _serviceManager, bridge, jiErFanZhe);
|
||||
out_tong_top_7.init("Camera7", "极耳翻折-铜-外-相机7(顶部)", { { 706, 1,720,"707","714",-1} }, 1, tongDetParams[2], _serviceManager, bridge, jiErFanZhe);
|
||||
out_tong_down_8.init("Camera8", "极耳翻折-铜-外-相机8(底部)", { { 708, 1,720,"709","716",-1} }, 1, tongDetParams[3], _serviceManager, bridge, jiErFanZhe);
|
||||
#pragma endregion
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user