Files
eUi/include/sxGlobal.h
2025-11-12 00:59:22 +08:00

161 lines
7.4 KiB
C++

#pragma once
#include <missionBase.hpp>
#include <detCallbackChain.hpp>
#include <share.h>
#include <QObject>
#include <opencvPaintAlgo.hpp>
#pragma region 基础函数
#define CATCH_EXCEPTIONS \
catch (HDevEngineCpp::HDevEngineException& ex) { \
std::cout << "HDevEngineException: " << ex.Message() << std::endl; \
qDebug() << "HDevEngineException: " << ex.Message(); \
} \
catch (HalconCpp::HException& ex) { \
std::cout << "Halcon Exception Caught!" << std::endl; \
std::cout << "Error Code: " << ex.ErrorCode() << std::endl; \
std::cout << "Error Message: " << ex.ErrorMessage() << std::endl; \
qDebug() << "Halcon Exception Caught!"; \
qDebug() << "Error Code: " << ex.ErrorCode(); \
qDebug() << "Error Message: " << ex.ErrorMessage(); \
} \
catch (const std::exception& e) { \
std::cout << "Caught exception: " << e.what() << std::endl; \
qDebug() << "Caught exception: " << e.what(); \
}
struct sx_581_address {
int triggerAddr = -1;
int triggerValue = -1;
std::vector<int> snAddr;
QByteArray completeAddr = "-1";
QByteArray resultAddr = "-1";
int valueOffsetAddr = -1;
};
class detParams {
public:
};
#pragma endregion
//算法回调函数需要包含完整的算法流程以及发送信号,发送ui图表,捕获异常,处理异常等操作
//并且注意 异常可能会导致运行不到发送信号的函数,请在处理异常时发送异常结果
static bool generalAlgoTest(std::shared_ptr <detData> data, detParams* _detParams, sx_581_address address) {
try {
qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start";
std::vector < std::string> defects = {"测试"};
///////////////////取图//处理//////////////////
if (data->oriImgs.size() < 1)
{
qCritical() << "图片数量不满足要求:" << data->oriImgs.size();
return false;
}
if (data->oriImgs[0].rows == 100) {
cv::Mat Paint;
data->oriImgs[0].copyTo(Paint);
cv::putText(Paint, "time out", cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255), 2);
return false;
}
cv::Mat Paint;
QMutex paintMutex;
clock_t start, finish;
start = clock();
cv::Mat src1 = data->oriImgs[0];
if (src1.channels() != 3)
cv::cvtColor(src1, Paint, cv::COLOR_GRAY2BGR);
else
src1.copyTo(Paint);
TextRendererZH textPainter(Paint.cols, Paint.rows, 15);
textPainter.putText(Paint, "划伤", cv::Point(10,10), cv::Scalar(0, 255, 0));
cv::putText(Paint, "pos:" + data->additional["触发地址"].toString().toStdString(), cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255, 0, 0), 2);
data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果
data->service->_missionResultHandle->toBarChart(data->SNcode, !defects.size() > 0, defects);//发送图标操作
data->resultImgs.push_back(Paint);
return true;
}
CATCH_EXCEPTIONS
data->service->_triggerManager->writeShort("D" + address.resultAddr + "_2");//发送异常结果
return false;
}
template <typename paramTemplte>
//此类适用于单相机多触发地址单次判断的情况,比如密封钉,三协机台
//例触发地址有4个,输入信号为 1 0 0 1 则按顺序触发1和4的地址拍照检测,2和3不做处理
class _581_SX_Single_triggerTemplate {
public:
paramTemplte* _detParams;
detCallbackChain<paramTemplte, sx_581_address>* generalDet;
std::string cameraName;
QString viewerName;
std::vector<sx_581_address>address;
int oneTriggerCaptrueTimes = 1;
/// <summary>
/// 初始化
/// </summary>
/// <param name="cameraNameIn">相机名</param>
/// <param name="viewerNameIN">窗口名</param>
/// <param name="startAddr">开始地址</param>
/// <param name="triggerCount">触发信号数</param>
/// <param name="oneTriggerCaptrueTimes">单次触发调用几次相机模块</param>
/// <param name="detParamsIn">参数输入</param>
/// <param name="_serviceManagerIn">默认</param>
/// <param name="bridgeIn">默认</param>
/// <param name="_processAlgoCallback">算法函数</param>
/// <param name="resultHandlerIn"></param>
void init(std::string cameraNameIn, QString viewerNameIN, std::vector<sx_581_address> addressIN, int oneTriggerCaptrueTimesIN,
paramTemplte* detParamsIn, ServiceManager* _serviceManagerIn, bSignalHub* bridgeIn,
typename detCallbackChain<paramTemplte, sx_581_address>::processAlgoCallback _processAlgoCallback,
QString saveObjectNameIN = "") {
viewerName = viewerNameIN;
cameraName = cameraNameIn;
_serviceManager = _serviceManagerIn;
_detParams = detParamsIn;
bridge = bridgeIn;
address = addressIN;
saveObjectName = saveObjectNameIN;
oneTriggerCaptrueTimes = oneTriggerCaptrueTimesIN;
generalDet = new detCallbackChain<paramTemplte, sx_581_address>(_serviceManager, _detParams, bridge);
generalDet->registerProcessAlgoCallback(_processAlgoCallback);
//单次触发器条件
for (int i = 0; i < addressIN.size(); i++) {
//注册单触发器 触发地址置1时触发
_serviceManager->_triggerManager->registerCallback(address[i].triggerAddr, address[i].triggerValue, [this, i](int triggerPos, int triggerValue, QByteArray& byteArray) {
evaluate(i, byteArray);}, "");
}
for (int i = 0; i < address.size(); i++) {
_serviceManager->_triggerManager->registerPlcValueViewer(viewerNameIN + "_" + QString::number(i),
{ {"触发",address[i].triggerAddr },
{"反馈",address[i].completeAddr.toInt()},
{"结果",address[i].resultAddr.toInt()},
{"数值1",address[i].valueOffsetAddr},
{"数值2",address[i].valueOffsetAddr + 2},
{"数值3",address[i].valueOffsetAddr + 4} });
}
}
//获取图片并进行检测
void evaluate(int batteryOffset, QByteArray& byteArray) {
_serviceManager->_triggerManager->writeShort("D" + QByteArray::number(address[0].triggerAddr) + "_0");//触发信号清零
std::string sn;
for (auto& snAddr : address[batteryOffset].snAddr) {
sn.append(_serviceManager->_triggerManager->readSnFromQByteArray(byteArray, snAddr, true, false, -1));
if (snAddr != address[batteryOffset].snAddr.back()) {
sn.append("_");
}
}
auto camera = _serviceManager->_cameraManager->getCamera(cameraName);//获取相机
camera->clearCache();//清除缓存
std::shared_ptr <detData> data = _serviceManager->_detDataManager->createDetData(
QString::fromStdString(cameraName), sn, oneTriggerCaptrueTimes, camera->config.oriSaveFormat);//创建数据包
QString saveObjectName = "";
data->saveObjectName = saveObjectName;
camera->captureImage(data);//拍照
generalDet->ansyncProcess(data, address[batteryOffset], ("D" + address[0].completeAddr + "_1"));//处理算法 并在取到图片后发送完成信号
data->resultImgShowSet.push_back(showImgPack(viewerName, "结果图"));
}
private:
QString saveObjectName = "";
bSignalHub* bridge;
ServiceManager* _serviceManager = nullptr;
};