V20260105-2.3.4
进一步优化rpcFIns的boost模块性能(测试)。 对赢合取图丢弃的逻辑进行了更改。
This commit is contained in:
+2
-2
@@ -2,7 +2,7 @@
|
||||
#include <qpixmap.h>
|
||||
#include <opencv.hpp>
|
||||
#include <qdebug.h>
|
||||
#include <memory>
|
||||
#include <memory>,。
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <QDir>
|
||||
|
||||
#pragma execution_character_set("utf-8")
|
||||
const std::string softwareVersion = "20251231-2.3.3";
|
||||
const std::string softwareVersion = "20260105-2.3.4";
|
||||
const std::string euiJsonVersion = "1.0.6";
|
||||
#define savePathToDataBase true
|
||||
#define GigaByte 1073741824
|
||||
|
||||
+16
-12
@@ -7,19 +7,23 @@
|
||||
#define CATCH_EXCEPTIONS \
|
||||
catch (HDevEngineCpp::HDevEngineException& ex) { \
|
||||
std::cout << "HDevEngineException: " << ex.Message() << std::endl; \
|
||||
qDebug() << "HDevEngineException: " << ex.Message(); \
|
||||
qCritical() << "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(); \
|
||||
qCritical() << "Halcon Exception Caught!"; \
|
||||
qCritical() << "Error Code: " << ex.ErrorCode(); \
|
||||
qCritical() << "Error Message: " << ex.ErrorMessage(); \
|
||||
} \
|
||||
catch (const std::exception& e) { \
|
||||
std::cout << "Caught exception: " << e.what() << std::endl; \
|
||||
qDebug() << "Caught exception: " << e.what(); \
|
||||
qCritical() << "Caught exception: " << e.what(); \
|
||||
}\
|
||||
catch (...) {\
|
||||
std::cout << "Caught exception: unexcepted"; \
|
||||
qCritical() << "Caught exception: unexcepted"; \
|
||||
}
|
||||
struct sx_581_address {
|
||||
int triggerAddr = -1;
|
||||
@@ -112,7 +116,7 @@ public:
|
||||
address = addressIN;
|
||||
saveObjectName = saveObjectNameIN;
|
||||
oneTriggerCaptrueTimes = oneTriggerCaptrueTimesIN;
|
||||
generalDet = new detCallbackChain<paramTemplte, sx_581_address>(_serviceManager, _detParams, bridge, &_serviceManagerIn->_chainWatcher);
|
||||
generalDet = new detCallbackChain<paramTemplte, sx_581_address>(_serviceManager, _detParams, bridge);
|
||||
generalDet->registerProcessAlgoCallback(_processAlgoCallback);
|
||||
//单次触发器条件
|
||||
for (int i = 0; i < addressIN.size(); i++) {
|
||||
@@ -122,12 +126,12 @@ public:
|
||||
}
|
||||
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} });
|
||||
{ {QString::number(address[i].triggerAddr) + "触发",address[i].triggerAddr },
|
||||
{address[i].completeAddr + "反馈",address[i].completeAddr.toInt()},
|
||||
{address[i].resultAddr + "结果",address[i].resultAddr.toInt()},
|
||||
{QString::number(address[i].valueOffsetAddr) + "数值1",address[i].valueOffsetAddr},
|
||||
{QString::number(address[i].valueOffsetAddr + 2) + "数值2",address[i].valueOffsetAddr + 2},
|
||||
{QString::number(address[i].valueOffsetAddr + 4) + "数值3",address[i].valueOffsetAddr + 4} });
|
||||
}
|
||||
}
|
||||
//获取图片并进行检测
|
||||
|
||||
+33
-26
@@ -8,19 +8,23 @@
|
||||
#define CATCH_EXCEPTIONS \
|
||||
catch (HDevEngineCpp::HDevEngineException& ex) { \
|
||||
std::cout << "HDevEngineException: " << ex.Message() << std::endl; \
|
||||
qDebug() << "HDevEngineException: " << ex.Message(); \
|
||||
qCritical() << "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(); \
|
||||
qCritical() << "Halcon Exception Caught!"; \
|
||||
qCritical() << "Error Code: " << ex.ErrorCode(); \
|
||||
qCritical() << "Error Message: " << ex.ErrorMessage(); \
|
||||
} \
|
||||
catch (const std::exception& e) { \
|
||||
std::cout << "Caught exception: " << e.what() << std::endl; \
|
||||
qDebug() << "Caught exception: " << e.what(); \
|
||||
qCritical() << "Caught exception: " << e.what(); \
|
||||
}\
|
||||
catch (...) {\
|
||||
std::cout << "Caught exception: unexcepted"; \
|
||||
qCritical() << "Caught exception: unexcepted"; \
|
||||
}
|
||||
struct yh_581_address {
|
||||
int triggerAddr = -1;
|
||||
@@ -153,7 +157,7 @@ public:
|
||||
oneTriggerCaptrueTimes = oneTriggerCaptrueTimesIN;
|
||||
|
||||
saveObjectName = saveObjectNameIN;
|
||||
generalDet = new detCallbackChain<paramTemplte, yh_581_address>(_serviceManager, _detParams, bridge, &_serviceManagerIn->_chainWatcher);
|
||||
generalDet = new detCallbackChain<paramTemplte, yh_581_address>(_serviceManager, _detParams, bridge);
|
||||
generalDet->registerProcessAlgoCallback(_processAlgoCallback);
|
||||
address = generateYh581AddressMap(startAddr, triggerCount);
|
||||
//联合触发器条件
|
||||
@@ -171,23 +175,22 @@ public:
|
||||
if (val.second == 1)
|
||||
evaluate(cnt, byteArray);
|
||||
else
|
||||
captrueAndDiscard(cnt);
|
||||
captrueAndDiscard(cnt, byteArray);
|
||||
cnt++;
|
||||
}
|
||||
}, "");
|
||||
for (int i = 0; i < address.size(); i++) {
|
||||
_serviceManager->_triggerManager->registerPlcValueViewer(viewerNameIN + "_" + QString::number(i),
|
||||
{ {"触发",address[i].triggerAddr,finsShort },
|
||||
{"反馈",address[i].completeAddr.toInt(),finsShort},
|
||||
{"结果",address[i].resultAddr.toInt(),finsShort},
|
||||
{"数值1",address[i].valueOffsetAddr,finsFloat},
|
||||
{"数值2",address[i].valueOffsetAddr + 2,finsFloat},
|
||||
{"数值3",address[i].valueOffsetAddr + 4,finsFloat} });
|
||||
{ {QString::number(address[i].triggerAddr) + "触发",address[i].triggerAddr,finsShort },
|
||||
{address[i].completeAddr + "反馈",address[i].completeAddr.toInt(),finsShort},
|
||||
{address[i].resultAddr + "结果",address[i].resultAddr.toInt(),finsShort},
|
||||
{QString::number(address[i].valueOffsetAddr) + "数值1",address[i].valueOffsetAddr,finsFloat},
|
||||
{QString::number(address[i].valueOffsetAddr + 2) + "数值2",address[i].valueOffsetAddr + 2,finsFloat},
|
||||
{QString::number(address[i].valueOffsetAddr + 4) + "数值3",address[i].valueOffsetAddr + 4,finsFloat} });
|
||||
}
|
||||
}
|
||||
//获取图片并进行检测
|
||||
void evaluate(int batteryOffset, QByteArray& byteArray) {
|
||||
_serviceManager->_triggerManager->writeShort("D" + address[0].completeAddr + "_1");//完成信号 固定只发在第0位
|
||||
std::string sn = _serviceManager->_triggerManager->readSnFromQByteArray(byteArray, address[batteryOffset].snAddr, false, false, -1);
|
||||
auto camera = _serviceManager->_cameraManager->getCamera(cameraName);
|
||||
camera->clearCache();
|
||||
@@ -199,15 +202,18 @@ public:
|
||||
|
||||
generalDet->asyncProcess(data, address[batteryOffset]);//处理算法
|
||||
data->resultImgShowSet.push_back(showImgPack(viewerName, "结果图"));
|
||||
_serviceManager->_triggerManager->writeShort("D" + address[0].completeAddr + "_1");//完成信号 固定只发在第0位
|
||||
}
|
||||
//获取图片然后废弃
|
||||
void captrueAndDiscard(int index) {
|
||||
_serviceManager->_triggerManager->writeShort("D" + address[index].resultAddr + "_4");//发个4防止报警
|
||||
void captrueAndDiscard(int batteryOffset, QByteArray& byteArray) {
|
||||
std::string sn = _serviceManager->_triggerManager->readSnFromQByteArray(byteArray, address[batteryOffset].snAddr, false, false, -1);
|
||||
auto camera = _serviceManager->_cameraManager->getCamera(cameraName);
|
||||
std::shared_ptr <detData> data = _serviceManager->_detDataManager->createDetData();//创建数据包
|
||||
std::shared_ptr <detData> data = _serviceManager->_detDataManager->createDetData(QString::fromStdString(cameraName), sn, oneTriggerCaptrueTimes, camera->config.oriSaveFormat);//创建数据包
|
||||
camera->captureImage(data);//拍照
|
||||
qDebug() << "uuid" << data->uuid << "将取图并丢弃";
|
||||
qDebug() <<"sn" << QString::fromStdString(sn) << "uuid" << data->uuid << "将取图并丢弃";
|
||||
_serviceManager->_detDataManager->deleteDetDataLater(data->uuid);
|
||||
_serviceManager->_triggerManager->writeShort("D" + address[0].completeAddr + "_1");//完成信号 固定只发在第0位
|
||||
_serviceManager->_triggerManager->writeShort("D" + address[batteryOffset].resultAddr + "_4");//发个4防止报警
|
||||
}
|
||||
private:
|
||||
QString saveObjectName = "";
|
||||
@@ -251,7 +257,7 @@ public:
|
||||
oneTriggerCaptrueTimes = oneTriggerCaptrueTimesIN;
|
||||
|
||||
saveObjectName = saveObjectNameIN;
|
||||
generalDet = new detCallbackChain<paramTemplte2, yh_581_address>(_serviceManager, _detParams, bridge, &_serviceManagerIn->_chainWatcher);
|
||||
generalDet = new detCallbackChain<paramTemplte2, yh_581_address>(_serviceManager, _detParams, bridge);
|
||||
generalDet->registerProcessAlgoCallback(_processAlgoCallback);
|
||||
address = generateYh581AddressMap(startAddr, triggerCount);
|
||||
//单次触发器条件
|
||||
@@ -265,18 +271,18 @@ public:
|
||||
}
|
||||
for (int i = 0; i < address.size(); i++) {
|
||||
_serviceManager->_triggerManager->registerPlcValueViewer(viewerNameIN + "_" + QString::number(i),
|
||||
{ {"触发",address[i].triggerAddr,finsShort },
|
||||
{"反馈",address[i].completeAddr.toInt(),finsShort},
|
||||
{"结果",address[i].resultAddr.toInt(),finsShort},
|
||||
{"数值1",address[i].valueOffsetAddr,finsFloat},
|
||||
{"数值2",address[i].valueOffsetAddr + 2,finsFloat},
|
||||
{"数值3",address[i].valueOffsetAddr + 4,finsFloat} });
|
||||
{ {QString::number(address[i].triggerAddr) + "触发",address[i].triggerAddr,finsShort },
|
||||
{address[i].completeAddr + "反馈",address[i].completeAddr.toInt(),finsShort},
|
||||
{address[i].resultAddr + "结果",address[i].resultAddr.toInt(),finsShort},
|
||||
{QString::number(address[i].valueOffsetAddr) + "数值1",address[i].valueOffsetAddr,finsFloat},
|
||||
{QString::number(address[i].valueOffsetAddr + 2) + "数值2",address[i].valueOffsetAddr + 2,finsFloat},
|
||||
{QString::number(address[i].valueOffsetAddr + 4) + "数值3",address[i].valueOffsetAddr + 4,finsFloat} });
|
||||
}
|
||||
|
||||
}
|
||||
//获取图片并进行检测
|
||||
void evaluate(int batteryOffset, QByteArray& byteArray) {
|
||||
_serviceManager->_triggerManager->writeShort("D" + address[batteryOffset].completeAddr + "_1");//完成信号 根据偏移发送
|
||||
|
||||
std::string sn = _serviceManager->_triggerManager->readSnFromQByteArray(byteArray, address[batteryOffset].snAddr, false, false, -1);
|
||||
auto camera = _serviceManager->_cameraManager->getCamera(cameraName);
|
||||
camera->clearCache();
|
||||
@@ -288,6 +294,7 @@ public:
|
||||
|
||||
generalDet->asyncProcess(data, address[batteryOffset]);//处理算法
|
||||
data->resultImgShowSet.push_back(showImgPack(viewerName, "结果图"));
|
||||
_serviceManager->_triggerManager->writeShort("D" + address[batteryOffset].completeAddr + "_1");//完成信号 根据偏移发送
|
||||
}
|
||||
private:
|
||||
QString saveObjectName = "";
|
||||
|
||||
BIN
Binary file not shown.
@@ -114,6 +114,7 @@ bool rpc_finsTcp::readData(std::vector<cv::Mat>& vec_mat, QByteArray& data){
|
||||
JsonRpcClient* ptr = read_JsonRpcClient[data];
|
||||
if(ptr == nullptr) {
|
||||
ptr = new JsonRpcClient("127.0.0.1", 9000);
|
||||
ptr->writeCall("init", QJsonArray{ m_IP,m_port }, "finstcp");
|
||||
read_JsonRpcClient[data] = ptr;
|
||||
}
|
||||
QByteArray resp = ptr->finsReadCall("excuteCli", QString(data), "finstcp");
|
||||
@@ -264,7 +265,7 @@ void rpc_finsTcp::initHearBeatThread() {
|
||||
}
|
||||
|
||||
bool rpc_finsTcp::initParas(QByteArray& data){
|
||||
startProcess("./json_rpc_server_1_1_0.exe");
|
||||
startProcess("./json_rpc_server_1_1_1.exe");
|
||||
QThread::msleep(500);
|
||||
write_JsonRpcClients = std::vector<std::pair<QThread*, JsonRpcClientWorker*>>(threadCount);
|
||||
for (int i = 0; i < write_JsonRpcClients.size(); i++) {
|
||||
|
||||
@@ -130,9 +130,6 @@ void cameraManager::run(){
|
||||
MV_CC_DEVICE_INFO_LIST m_stDevList = searchMV_CC_DEVICE_INFO_LIST();
|
||||
QByteArray mvDevices1 = "deviceList" + MV_CC_DeviceInfoListToQByteArray(m_stDevList);
|
||||
|
||||
MV_GENTL_IF_INFO_LIST m_stIFList = searchMV_GENTL_IF_INFO_LIST();
|
||||
QByteArray mvDevices2 = "deviceList" + MV_GENTL_IF_INFO_LISTToQByteArray(m_stIFList);
|
||||
|
||||
for (auto i = 0; i < _cameraStructs.size(); i++) {
|
||||
auto& m_module = _cameraStructs[i];
|
||||
QString dllPath = QString::fromStdString(m_module.dllPath);
|
||||
@@ -161,14 +158,6 @@ void cameraManager::run(){
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < m_stIFList.nInterfaceNum; i++) {
|
||||
std::string serialNumber = static_cast<std::string>((LPCSTR)m_stIFList.pIFInfo[i]->chInterfaceID);
|
||||
std::string userDefineName = static_cast<std::string>((LPCSTR)m_stIFList.pIFInfo[i]->chInterfaceID);
|
||||
if (m_module.connectionName.find(serialNumber) != std::string::npos || m_module.connectionName.find(userDefineName) != std::string::npos) {
|
||||
m_module.module_ptr->writeData(vec_mat, mvDevices1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
status = NotInit;
|
||||
|
||||
@@ -94,9 +94,6 @@ public:
|
||||
inline void setExposureTime(float value){
|
||||
writeData("exposure_" + std::to_string(value));
|
||||
}
|
||||
inline void setUserSet(int value){
|
||||
writeData("userset_" + std::to_string(value));
|
||||
}
|
||||
inline void clearCache() {
|
||||
writeData("clearCache");
|
||||
}
|
||||
|
||||
@@ -14,16 +14,16 @@ template<typename customTemplate, typename addressTemplate>
|
||||
class detCallbackChain {
|
||||
public:
|
||||
using processAlgoCallback = std::function<bool(std::shared_ptr <detData>, customTemplate*, addressTemplate)>;
|
||||
|
||||
detCallbackChain(ServiceManager* _ServiceManagerIn, customTemplate* _customTemplateIn, bSignalHub* bridgeIn, detCallbackChainWatcher* _chainWatcherIn = nullptr)
|
||||
detCallbackChain(ServiceManager* _ServiceManagerIn, customTemplate* _customTemplateIn, bSignalHub* bridgeIn)
|
||||
: _imgSaveThreadManager(_ServiceManagerIn->_imgSaveThreadManager),
|
||||
_handleAiModels(_customTemplateIn),
|
||||
_triggerManager(_ServiceManagerIn->_triggerManager),
|
||||
bridge(bridgeIn), _serviceManager(_ServiceManagerIn)
|
||||
{
|
||||
int threadCount = 4 * QThread::idealThreadCount();
|
||||
|
||||
int threadCount = 10 * QThread::idealThreadCount();
|
||||
QThreadPool::globalInstance()->setMaxThreadCount(threadCount);
|
||||
_chainWatcher = _chainWatcherIn;
|
||||
|
||||
}
|
||||
//异步启动检测
|
||||
void asyncProcess(std::shared_ptr <detData> data, addressTemplate address, QByteArray completeSignal = "") {
|
||||
@@ -34,15 +34,6 @@ public:
|
||||
QFuture<void> future = QtConcurrent::run([this, data, address, completeSignal]() {
|
||||
process(data, address, completeSignal);
|
||||
});
|
||||
if (_chainWatcher != nullptr) {
|
||||
// 构建任务名称:包含 UUID 和 SN 码便于追踪
|
||||
QString taskName = QString("DetTask_UUID[%1]_SN[%2]")
|
||||
.arg(data->uuid)
|
||||
.arg(QString::fromStdString(data->SNcode));
|
||||
|
||||
// 将任务添加到监控器
|
||||
int watcherId = _chainWatcher->addFeature(future, taskName);
|
||||
}
|
||||
}
|
||||
//阻塞启动检测
|
||||
void process(std::shared_ptr <detData> data, addressTemplate address, QByteArray completeSignal = "") {
|
||||
@@ -83,17 +74,20 @@ public:
|
||||
}
|
||||
catch (HDevEngineCpp::HDevEngineException& ex) {
|
||||
|
||||
qDebug() << "detChain catched->HDevEngineException: " << ex.Message();
|
||||
qCritical() << "detChain catched->HDevEngineException: " << ex.Message();
|
||||
}
|
||||
catch (HalconCpp::HException& ex) {
|
||||
|
||||
qDebug() << "detChain catched->Halcon Exception Caught!";
|
||||
qDebug() << "detChain catched->Error Code: " << ex.ErrorCode();
|
||||
qDebug() << "detChain catched->Error Message: " << ex.ErrorMessage();
|
||||
qCritical() << "detChain catched->Halcon Exception Caught!";
|
||||
qCritical() << "detChain catched->Error Code: " << ex.ErrorCode();
|
||||
qCritical() << "detChain catched->Error Message: " << ex.ErrorMessage();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
|
||||
qDebug() << "detChain catched->Caught exception: " << e.what();
|
||||
qCritical() << "detChain catched->Caught exception: " << e.what();
|
||||
}
|
||||
catch (...) {
|
||||
qCritical() << "detChain catched->Caught exception: unexcepted";
|
||||
}
|
||||
std::chrono::steady_clock::time_point algoEndTime = std::chrono::steady_clock::now();
|
||||
data->algoTime = std::chrono::duration_cast<std::chrono::milliseconds>(algoEndTime - algoStartTime).count();
|
||||
@@ -124,14 +118,13 @@ public:
|
||||
// 异步保存检测图像
|
||||
std::thread([this,data] {_imgSaveThreadManager->saveImage(data); }).detach();
|
||||
}
|
||||
#pragma region 注册回调函数
|
||||
|
||||
void registerProcessAlgoCallback(processAlgoCallback func) {
|
||||
_processAlgoCallback = func;
|
||||
}
|
||||
|
||||
|
||||
#pragma endregion
|
||||
|
||||
|
||||
private:
|
||||
int uiShowImgCompressThreshold = 5000; // 超过该宽或高就压缩
|
||||
imgSaveThreadManager* _imgSaveThreadManager = nullptr;
|
||||
@@ -139,7 +132,6 @@ private:
|
||||
triggerManager* _triggerManager = nullptr;
|
||||
processAlgoCallback _processAlgoCallback;
|
||||
bSignalHub* bridge = nullptr;
|
||||
detCallbackChainWatcher* _chainWatcher = nullptr;
|
||||
ServiceManager* _serviceManager = nullptr;
|
||||
};
|
||||
|
||||
|
||||
@@ -32,20 +32,19 @@ triggerManager::triggerManager(ServiceManager* _serviceManager, bSignalHub* brid
|
||||
void triggerManager::run(){
|
||||
if(connectHost() == false)
|
||||
return;
|
||||
QThread::msleep(1000);
|
||||
QThread::msleep(500);
|
||||
QElapsedTimer heartTimer, loopCounterCollectTimer,loopIntervalTimer;
|
||||
int loopCounter = 0,maxIntervalLog = 0,interval = 0;
|
||||
loopIntervalTimer.start();
|
||||
while (runFlag){
|
||||
reciveCommond();
|
||||
//心跳
|
||||
if (heartTimer.elapsed()> heartBeatIntervalMS) {
|
||||
if (heartTimer.elapsed()> heartBeatIntervalMS) {//心跳
|
||||
sendFinsMsg(heartBeatCmds[heartBeatCmdCnt++]);
|
||||
if(heartBeatCmdCnt >= heartBeatCmds.size())
|
||||
heartBeatCmdCnt = 0;
|
||||
heartTimer.start();
|
||||
}
|
||||
if (loopCounterCollectTimer.elapsed() > 3000) {
|
||||
if (loopCounterCollectTimer.elapsed() > 3000) {//发送性能数据
|
||||
emit bridge->sendTriggerManagerLoopData(loopCounter / 3, maxIntervalLog);
|
||||
maxIntervalLog = 0;
|
||||
loopCounter = 0;
|
||||
|
||||
@@ -137,18 +137,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
//直接发送数据到模块的方法
|
||||
bool sendFinsMsg(const char* cmdx){
|
||||
QString str = cmdx;
|
||||
if (trigger == nullptr)
|
||||
return false;
|
||||
if (!trigger->writeData(vec_mat, str.toUtf8()))
|
||||
{
|
||||
qCritical() << "[TCP Error] " << QString::fromUtf8("Fins数据发送失败!") << cmdx;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//直接发送数据到模块的方法
|
||||
bool sendFinsMsg(const QByteArray& write_byte){
|
||||
if (trigger == nullptr)
|
||||
return false;
|
||||
@@ -414,7 +402,7 @@ public:
|
||||
}
|
||||
std::map<QByteArray, std::vector<unionTriggerCallbackStruct>> unionTriggerCallbackFuncs;
|
||||
|
||||
//SUB
|
||||
//监控指定地址的数值
|
||||
void registerPlcValueViewer(const QString& groupName, const std::vector<PlcValueViewerStruct>& viewerDatas) {
|
||||
QMutexLocker locer(&mutex);
|
||||
for (auto& data : viewerDatas) {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#include <581-Dgh-CB-1.h>
|
||||
|
||||
mission* createMission() {
|
||||
return new _581_Dgh();
|
||||
}
|
||||
void destroyMission(mission* _mission) {
|
||||
delete _mission;
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
#include <missionBase.hpp>
|
||||
#include <simpleAlgo.h>
|
||||
#include <hdevengine/HDevEngineCpp.h>
|
||||
#include <opencvPaintAlgo.hpp>
|
||||
#include <yhGlobal.h>
|
||||
#include <qregularexpression.h>
|
||||
QByteArray getCameraIndex(QString cameraStr) {
|
||||
QRegularExpression re("\\d+");
|
||||
auto match = re.match(cameraStr);
|
||||
if (match.hasMatch()) {
|
||||
return "_" + match.captured(0).toLocal8Bit();
|
||||
}
|
||||
return "_-2";
|
||||
}
|
||||
#pragma region 算法
|
||||
|
||||
using namespace HDevEngineCpp;
|
||||
|
||||
#pragma endregion
|
||||
void exceptionResume(std::shared_ptr<detData> data, detParams* _detParams, yh_581_address address, QString why = "") {
|
||||
qDebug() << "[Error] " << QString::fromUtf8("检测失败!") << data->uuid << QString::fromStdString(data->SNcode) << why;
|
||||
cv::Mat Paint;
|
||||
data->getOriImg(0).copyTo(Paint);
|
||||
if (Paint.channels() == 1)
|
||||
cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR);
|
||||
|
||||
TextRendererZH textPainter(Paint.cols, Paint.rows, 300);
|
||||
textPainter.putText(Paint, why.toStdString(), cv::Point(50, 50), cv::Scalar(0, 255, 0));
|
||||
cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5);
|
||||
data->insertResultImg(Paint);
|
||||
data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_1,1,1,1,1,1,1,1,1,1,1,1,1,1");
|
||||
data->service->_triggerManager->writeShort("D" + address.resultAddr + "_3");//结果反馈//原来是异常发送NG-2,改成异常发送3,表示取图失败
|
||||
}
|
||||
static bool yuHanQian3D(std::shared_ptr <detData> data, detParams* _detParams, yh_581_address address) {
|
||||
try {
|
||||
std::vector<std::string> defects;
|
||||
auto CameraIndex = getCameraIndex(QString::fromStdString(data->cameraKeyName));
|
||||
QDateTime createTime = QDateTime::currentDateTime();
|
||||
double heightThreshold = data->service->_paramSyncManager->get("预焊前检测", "高度/台阶差最大阈值", 0.3).toDouble();
|
||||
double widthThreshold = data->service->_paramSyncManager->get("预焊前检测", "缝隙值最大阈值", 0.1).toDouble();
|
||||
double MeasureNumber = data->service->_paramSyncManager->get("预焊前检测", "焊点的测量数量", 4).toDouble();
|
||||
/* data->oriImgs.clear();
|
||||
data->oriImgs.push_back(cv::imread("D:\\testimg\\04QCB82602000JFBN00063BN_45_Camera1_0.tiff", -1));
|
||||
data->oriImgs.push_back(cv::imread("D:\\testimg\\04QCB82602000JFBN00063BN_45_Camera1_1.tiff", -1));*/
|
||||
if (data->getOriImgSize() < 2) {
|
||||
exceptionResume(data, _detParams, address, "NG");
|
||||
return true;
|
||||
}
|
||||
if (data->getOriImg(0).cols == 1000) {
|
||||
exceptionResume(data, _detParams, address, "取图超时");
|
||||
return true;
|
||||
}
|
||||
cv::Mat heightImg = data->getOriImg(1);
|
||||
cv::Mat lumImg = data->getOriImg(0);
|
||||
cv::Mat Paint;
|
||||
|
||||
HalconCpp::HObject in_imageH = MatToHObject(heightImg);
|
||||
HalconCpp::HObject in_imageLum = MatToHObject(lumImg);
|
||||
HDevEngineCpp::HDevProcedure proc("_6_detect_gap_width_height");
|
||||
HDevProcedureCall procedureCall(proc);
|
||||
procedureCall.SetInputIconicParamObject("in_imageH", in_imageH);
|
||||
procedureCall.SetInputIconicParamObject("in_imageLum", in_imageLum);
|
||||
procedureCall.SetInputCtrlParamTuple("in_MeasureNumber", MeasureNumber);
|
||||
|
||||
procedureCall.SetInputCtrlParamTuple("in_xResolution", 0.0025);
|
||||
procedureCall.SetInputCtrlParamTuple("in_yResolution", data->service->_paramSyncManager->get("预焊前检测", "3D相机Y方向精度",0.177).toFloat());
|
||||
procedureCall.SetInputCtrlParamTuple("in_zResolution", 0.0004);
|
||||
if(address.triggerAddr == 18000 || address.triggerAddr == 18002 || address.triggerAddr == 18400 || address.triggerAddr == 18402)
|
||||
procedureCall.SetInputCtrlParamTuple("in_Location", "Right");
|
||||
else
|
||||
procedureCall.SetInputCtrlParamTuple("in_Location", "Left");
|
||||
procedureCall.Execute();
|
||||
HObject out_DisplayImage = procedureCall.GetOutputIconicParamObject("out_DisplayImage");
|
||||
|
||||
HTuple out_MaxHeight = procedureCall.GetOutputCtrlParamTuple("out_MaxHeight");
|
||||
HTuple out_MaxWidth = procedureCall.GetOutputCtrlParamTuple("out_MaxWidth");
|
||||
HTuple out_ResultRow = procedureCall.GetOutputCtrlParamTuple("out_ResultRow");
|
||||
HTuple out_ResultColumn = procedureCall.GetOutputCtrlParamTuple("out_ResultColumn");
|
||||
HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");
|
||||
HTuple out_NgTails = procedureCall.GetOutputCtrlParamTuple("out_NgTails");
|
||||
HTuple out_DisplayRows = procedureCall.GetOutputCtrlParamTuple("out_DisplayRows");
|
||||
HTuple out_DisplayCols = procedureCall.GetOutputCtrlParamTuple("out_DisplayCols");
|
||||
int flag = out_Flag.D();
|
||||
TextRendererZH textPainter(Paint.cols, Paint.rows, 75);
|
||||
|
||||
textPainter.appendPaintJob(data->SNcode, cv::Point(1600,0), cv::Scalar(0, 255, 0));
|
||||
textPainter.appendPaintJob(data->cameraKeyName, cv::Point(1600, 50), cv::Scalar(0, 255, 0));
|
||||
if (address.triggerAddr == 18000 || address.triggerAddr == 18200 || address.triggerAddr == 18400 || address.triggerAddr == 18600)
|
||||
textPainter.appendPaintJob("电池1", cv::Point(1600, 100), cv::Scalar(0, 255, 0));
|
||||
else
|
||||
textPainter.appendPaintJob("电池2", cv::Point(1600, 100), cv::Scalar(0, 255, 0));
|
||||
bool isOK = true;
|
||||
bool WidthOpen = data->service->_paramSyncManager->get("预焊前检测", "缝隙值检测开启", true).toBool();
|
||||
bool HeightOpen = data->service->_paramSyncManager->get("预焊前检测", "台阶差检测开启", true).toBool();
|
||||
QByteArray gaoDuChaSendText, fengXiSendText;
|
||||
QByteArray extraDataSend;
|
||||
if (flag == 1) {
|
||||
int yStart = -25;
|
||||
for (int i = 0; i < out_DisplayRows.Length(); i++) {
|
||||
double MaxHeight = out_MaxHeight[i].D();
|
||||
double MaxWidth = out_MaxWidth[i].D();
|
||||
|
||||
cv::Point displayPos( 1000, out_DisplayRows[i].D() - 50);
|
||||
textPainter.appendPaintJob("检测区域" + std::to_string(i + 1) + ":", displayPos, cv::Scalar(0, 255, 0));
|
||||
|
||||
displayPos.x += 280;
|
||||
if (std::abs(MaxHeight) > std::abs(heightThreshold)) {
|
||||
textPainter.appendPaintJob("高度/台阶差" + QString::number(MaxHeight, 'f', 3).toStdString() +"mm", displayPos, cv::Scalar(0, 0, 255));
|
||||
if(HeightOpen) isOK = false;
|
||||
}
|
||||
else
|
||||
textPainter.appendPaintJob("高度/台阶差" + QString::number(MaxHeight, 'f', 3).toStdString() + "mm", displayPos, cv::Scalar(0, 255, 0));
|
||||
|
||||
displayPos.x += 600;
|
||||
if (std::abs(MaxWidth) > std::abs(widthThreshold)) {
|
||||
textPainter.appendPaintJob("缝隙值" + QString::number(MaxWidth, 'f', 3).toStdString() + "mm", displayPos, cv::Scalar(0, 0, 255));
|
||||
if(WidthOpen) isOK = false;
|
||||
}
|
||||
else
|
||||
textPainter.appendPaintJob("缝隙值" + QString::number(MaxWidth, 'f', 3).toStdString() + "mm", displayPos, cv::Scalar(0, 255, 0));
|
||||
if (i == 3) {
|
||||
extraDataSend += QByteArray::number(MaxWidth) + "," + QByteArray::number(MaxHeight);
|
||||
}
|
||||
else {
|
||||
gaoDuChaSendText += QByteArray::number(MaxHeight) + ",";
|
||||
fengXiSendText += QByteArray::number(MaxWidth) + ",";
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
gaoDuChaSendText = "-1,-1,-1,";
|
||||
fengXiSendText = "-1,-1,-1,";
|
||||
std::string ngDetailStr = gbkToUtf8(out_NgTails.ToString().Text());
|
||||
ngDetailStr = ngDetailStr.substr(1, ngDetailStr.length() - 2);
|
||||
textPainter.appendPaintJob(ngDetailStr, cv::Point(50, 450), cv::Scalar(0, 0, 255));
|
||||
for (int i = 0; i < out_ResultRow.Length(); i++) {
|
||||
textPainter.appendPaintJob(cv::Point(out_ResultRow[i].D(), out_ResultColumn[i].D()),1, cv::Scalar(0, 0, 255), 1,0);
|
||||
}
|
||||
data->halconOK = false;
|
||||
isOK = false;
|
||||
}
|
||||
QByteArray plcResult = "1";
|
||||
if (isOK == false) {
|
||||
textPainter.appendPaintJob("NG", cv::Point(50, 50), cv::Scalar(0, 0, 255));
|
||||
plcResult = "2";
|
||||
data->halconOK = false;
|
||||
defects.push_back("台阶/间隙不良");
|
||||
}
|
||||
else
|
||||
textPainter.appendPaintJob("OK", cv::Point(50, 50), cv::Scalar(0, 255, 0));
|
||||
if (data->service->_paramSyncManager->get("通用设置", "强制OK", false).toBool())
|
||||
plcResult = "1";
|
||||
|
||||
//发送参数1
|
||||
data->service->_triggerManager->writeFloat("D"
|
||||
+ QByteArray::number(address.valueOffsetAddr) + "_"
|
||||
+ fengXiSendText + "1,1,"
|
||||
+ gaoDuChaSendText + plcResult + "," + plcResult + "," + plcResult + "," + plcResult +"," + plcResult + "," + plcResult + "," + extraDataSend+ CameraIndex);//数值1
|
||||
|
||||
//发送结果
|
||||
data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult + CameraIndex);//结果反馈
|
||||
|
||||
data->service->_missionResultHandle->toBarChart(data->SNcode, defects);
|
||||
Paint = HObject2Mat(out_DisplayImage);
|
||||
textPainter.excusePaintJobs(Paint);
|
||||
int rate = MIN(Paint.rows, Paint.cols) / 20;
|
||||
TextRendererZH textPainter1(Paint.cols, Paint.rows, rate);
|
||||
textPainter1.putText(Paint, "当前条码:" + data->SNcode, cv::Point(50, Paint.rows - (rate * 2)), cv::Scalar(0, 255, 255));
|
||||
textPainter1.putText(Paint, "获取图像时间:" + createTime.toString("yyyy/MM/dd hh:mm:ss").toStdString(), cv::Point(50, Paint.rows - rate), cv::Scalar(0, 255, 255));
|
||||
data->insertResultImg(Paint);
|
||||
return true;
|
||||
}
|
||||
CATCH_EXCEPTIONS
|
||||
exceptionResume(data, _detParams, address, "NG");
|
||||
return true;
|
||||
}
|
||||
class _581_Dgh : public mission {
|
||||
public:
|
||||
using generalTrigger = _581_Union_triggerTemplate<detParams>;
|
||||
generalTrigger dgh_cb_yh_3d_1;
|
||||
generalTrigger dgh_cb_yh_3d_2;
|
||||
generalTrigger dgh_cb_yh_3d_3;
|
||||
generalTrigger dgh_cb_yh_3d_4;
|
||||
|
||||
generalTrigger dgh_cb_mh_3d_1;
|
||||
generalTrigger dgh_cb_mh_3d_2;
|
||||
generalTrigger dgh_cb_mh_3d_3;
|
||||
generalTrigger dgh_cb_mh_3d_4;
|
||||
detParams _params;
|
||||
|
||||
void onConfigReloaded() {
|
||||
HDevEngineCpp::HDevEngine myEngine;
|
||||
myEngine.SetProcedurePath("");
|
||||
myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_602.hdpl");
|
||||
}
|
||||
bool initCustom() {
|
||||
#pragma region 注册触发器回调
|
||||
dgh_cb_yh_3d_1.init("Camera1", "长边预焊前3D-1", 18000,2,1, &_params, _serviceManager, bridge, yuHanQian3D);
|
||||
dgh_cb_yh_3d_1.address[1].valueOffsetAddr += 20;
|
||||
dgh_cb_yh_3d_2.init("Camera2", "长边预焊前3D-2", 18200,2,1, &_params, _serviceManager, bridge, yuHanQian3D);
|
||||
dgh_cb_yh_3d_2.address[1].valueOffsetAddr += 20;
|
||||
dgh_cb_yh_3d_3.init("Camera3", "长边预焊前3D-3", 18400,2,1, &_params, _serviceManager, bridge, yuHanQian3D);
|
||||
dgh_cb_yh_3d_3.address[1].valueOffsetAddr += 20;
|
||||
dgh_cb_yh_3d_4.init("Camera4", "长边预焊前3D-4", 18600,2,1, &_params, _serviceManager, bridge, yuHanQian3D);
|
||||
dgh_cb_yh_3d_4.address[1].valueOffsetAddr += 20;
|
||||
|
||||
dgh_cb_mh_3d_1.init("Camera5", "长边满焊前3D-1", 19600,2,1, &_params, _serviceManager, bridge, generalAlgoTest);
|
||||
dgh_cb_mh_3d_1.address[1].valueOffsetAddr += 20;
|
||||
dgh_cb_mh_3d_2.init("Camera6", "长边满焊前3D-2", 19800,2,1, &_params, _serviceManager, bridge, generalAlgoTest);
|
||||
dgh_cb_mh_3d_2.address[1].valueOffsetAddr += 20;
|
||||
dgh_cb_mh_3d_3.init("Camera7", "长边满焊前3D-3", 20000,2,1, &_params, _serviceManager, bridge, generalAlgoTest);
|
||||
dgh_cb_mh_3d_3.address[1].valueOffsetAddr += 20;
|
||||
dgh_cb_mh_3d_4.init("Camera8", "长边满焊前3D-4", 20200,2,1, &_params, _serviceManager, bridge, generalAlgoTest);
|
||||
dgh_cb_mh_3d_4.address[1].valueOffsetAddr += 20;
|
||||
#pragma endregion
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
@@ -0,0 +1,77 @@
|
||||
# 获取获取当前目录名
|
||||
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/service
|
||||
${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 OFF)
|
||||
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 REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network REQUIRED)
|
||||
|
||||
add_library(${CURRENT_FOLDER} SHARED
|
||||
${HEAD_FILES}
|
||||
${SRC_FILES}
|
||||
${UI_FILES}
|
||||
${PROJECT_ROOT_PATH}/include/interface.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
|
||||
)
|
||||
|
||||
|
||||
# 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})
|
||||
@@ -0,0 +1,552 @@
|
||||
#include <581_Ruanlianjie_hanqian_hanhou.h>
|
||||
#include <qregularexpression.h>
|
||||
#define switchToNew 1
|
||||
QByteArray getCameraIndex(QString cameraStr) {
|
||||
QRegularExpression re("\\d+");
|
||||
auto match = re.match(cameraStr);
|
||||
if (match.hasMatch()) {
|
||||
return "_" + match.captured(0).toLocal8Bit();
|
||||
}
|
||||
return "_-2";
|
||||
}
|
||||
void exceptionResume(std::shared_ptr<detData> data, hanHouJianCe* _detParams, sx_581_address address, QString why = "") {
|
||||
qDebug() << "[Error] " << QString::fromUtf8("检测失败!") << data->uuid << QString::fromStdString(data->SNcode) << why;
|
||||
cv::Mat Paint;
|
||||
data->getOriImg(0).copyTo(Paint);
|
||||
if (Paint.channels() == 1)
|
||||
cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR);
|
||||
|
||||
TextRendererZH textPainter(Paint.cols, Paint.rows, 300);
|
||||
textPainter.putText(Paint, why.toStdString(), cv::Point(500, 50), cv::Scalar(0, 255, 0));
|
||||
cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5);
|
||||
data->insertResultImg(Paint);
|
||||
data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈
|
||||
|
||||
}
|
||||
void exceptionResume(std::shared_ptr<detData> data, hanQianDingWeiParams* _detParams, sx_581_address address, QString why = "") {
|
||||
qDebug() << "[Error] " << QString::fromUtf8("检测失败!") << data->uuid << QString::fromStdString(data->SNcode) << why;
|
||||
cv::Mat Paint;
|
||||
data->getOriImg(0).copyTo(Paint);
|
||||
if (Paint.channels() == 1)
|
||||
cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR);
|
||||
|
||||
TextRendererZH textPainter(Paint.cols, Paint.rows, 300);
|
||||
textPainter.putText(Paint, why.toStdString(), cv::Point(500, 50), cv::Scalar(0, 255, 0));
|
||||
cv::resize(Paint, Paint, cv::Size(), 0.5, 0.5);
|
||||
data->insertResultImg(Paint);
|
||||
data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//结果反馈
|
||||
|
||||
}
|
||||
bool HanQianDingWei(std::shared_ptr <detData> data, hanQianDingWeiParams* _detParams, sx_581_address address){
|
||||
try
|
||||
{
|
||||
auto cameraThreadIndex = getCameraIndex(QString::fromStdString(data->cameraKeyName));
|
||||
bool zuoLJPtoGaiBanEnable = data->service->_paramSyncManager->get("焊前定位", "左侧连接片和盖板距离判定启用", false).toBool();
|
||||
double zuoLJPtoGaiBanMaxThreshold = data->service->_paramSyncManager->get("焊前定位", "左侧连接片和盖板距离(上限)", 1.8).toDouble();
|
||||
double zuoLJPtoGaiBanMinThreshold = data->service->_paramSyncManager->get("焊前定位", "左侧连接片和盖板距离(下限)", 0.0).toDouble();
|
||||
|
||||
bool youLJPtoGaiBanEnable = data->service->_paramSyncManager->get("焊前定位", "右侧连接片和盖板距离判定启用", false).toBool();
|
||||
double youLJPtoGaiBanMaxThreshold = data->service->_paramSyncManager->get("焊前定位", "右侧连接片和盖板距离(上限)", 1.8).toDouble();
|
||||
double youLJPtoGaiBanMinThreshold = data->service->_paramSyncManager->get("焊前定位", "右侧连接片和盖板距离(下限)", 0.0).toDouble();
|
||||
|
||||
bool ljpYuanXinJuEnable = data->service->_paramSyncManager->get("焊前定位", "连接片圆心距离判定启用", false).toBool();
|
||||
double ljpYuanXinJuMaxThreshold = data->service->_paramSyncManager->get("焊前定位", "连接片圆心距离(上限)", 1.8).toDouble();
|
||||
double ljpYuanXinJuMinThreshold = data->service->_paramSyncManager->get("焊前定位", "连接片圆心距离(下限)", 0.0).toDouble();
|
||||
std::vector <std::string>defects;
|
||||
QByteArray plcResult = "1";
|
||||
//data->getOriImg(0) = cv::imread("D://testImage//hqdw.bmp",-1);
|
||||
cv::Mat sourceImg = data->getOriImg(0);
|
||||
cv::Mat Paint;
|
||||
sourceImg.copyTo(Paint);
|
||||
if (Paint.channels() == 1)
|
||||
cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR);
|
||||
HDevEngineCpp::HDevProcedure proc("_3_HQDW_Inspection");
|
||||
HDevEngineCpp::HDevProcedureCall procedureCall(proc);
|
||||
|
||||
HTuple in_Resolution(data->service->_paramSyncManager->get("相机精度", "焊前定位" + QString::fromStdString(data->cameraKeyName) + "精度", 0.0349425).toDouble()), in_FilePath("./halconFiles/");
|
||||
HObject inputImage = MatToHObject(sourceImg);
|
||||
|
||||
procedureCall.SetInputIconicParamObject("in_Image", inputImage);
|
||||
procedureCall.SetInputCtrlParamTuple("in_Resolution", in_Resolution);
|
||||
procedureCall.SetInputCtrlParamTuple("in_FilePath", in_FilePath);
|
||||
procedureCall.Execute();//执行halcon程序
|
||||
HTuple out_ColorType;
|
||||
HTuple out_Distance;
|
||||
HTuple out_CCDistance;
|
||||
HTuple make;
|
||||
HObject out_DisplayImage;
|
||||
out_ColorType = procedureCall.GetOutputCtrlParamTuple("out_ColorType");//获取输出控制类变量
|
||||
out_Distance = procedureCall.GetOutputCtrlParamTuple("out_Distance");//获取输出控制类变量
|
||||
out_CCDistance = procedureCall.GetOutputCtrlParamTuple("out_CCDistance");//获取输出控制类变量
|
||||
make = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出控制类变量
|
||||
out_DisplayImage = procedureCall.GetOutputIconicParamObject("out_DisplayImage");//获取输出控制类变量
|
||||
int flag = make.D();
|
||||
|
||||
// Output(HTuple): out_ColorType, 1, 铜; 2,铝</c>
|
||||
|
||||
//正确的应该左边铝 右边铜
|
||||
double value1_1 = 0, value1_2 = 0, value2_1 = 0, value2_2 = 0;
|
||||
bool jiXingEnable = data->service->_paramSyncManager->get("焊前定位", "焊前极性判定启用", false).toBool();
|
||||
TextRendererZH textPainter(Paint.cols, Paint.rows, 200);
|
||||
TextRendererZH textPainter2(Paint.cols, Paint.rows, 600);
|
||||
TextRendererZH textPainter3(Paint.cols, Paint.rows, 800);
|
||||
if (flag == 1){
|
||||
|
||||
bool isNg = false;
|
||||
|
||||
Paint = HObject2Mat(out_DisplayImage);
|
||||
int l = out_Distance.Length();
|
||||
if (out_Distance.Length() >= 3) {
|
||||
value1_1 = out_Distance[1].D();
|
||||
value1_2 = out_Distance[2].D();
|
||||
textPainter.appendPaintJob("线段夹角:" + std::to_string(out_Distance[3].D()) + "°", cv::Point(0, 10), cv::Scalar(0, 255, 0));
|
||||
|
||||
|
||||
//判断圆心距
|
||||
double yuanXinJu = out_Distance[0].D();
|
||||
if (ljpYuanXinJuMaxThreshold < yuanXinJu || ljpYuanXinJuMinThreshold > yuanXinJu) {//NG
|
||||
textPainter.appendPaintJob("铜极+铝极连接片中心距离:" + std::to_string(yuanXinJu) + "mm", cv::Point(0, sourceImg.rows - 950), cv::Scalar(0, 0, 255));
|
||||
defects.push_back("圆心距NG");
|
||||
if (ljpYuanXinJuEnable == true)
|
||||
isNg = true;
|
||||
}
|
||||
else//OK
|
||||
textPainter.appendPaintJob("铜极+铝极连接片中心距离:" + std::to_string(yuanXinJu) + "mm", cv::Point(0, sourceImg.rows - 950), cv::Scalar(0, 255, 0));
|
||||
|
||||
textPainter.appendPaintJob("电芯上水平边缘和注液孔的中心圆的距离:" + std::to_string(out_Distance[1].D()) + "mm", cv::Point(0, sourceImg.rows - 750), cv::Scalar(0, 255, 0));
|
||||
textPainter.appendPaintJob("电芯下水平边缘和注液孔的中心圆的距离:" + std::to_string(out_Distance[2].D()) + "mm", cv::Point(0, sourceImg.rows - 550), cv::Scalar(0, 255, 0));
|
||||
#if switchToNew
|
||||
data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(out_Distance[0].D()) + cameraThreadIndex);
|
||||
data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr+2) + "_" + QByteArray::number(out_Distance[1].D()) + cameraThreadIndex);
|
||||
#else
|
||||
data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(out_Distance[0].D()));
|
||||
data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(out_Distance[1].D()));
|
||||
#endif
|
||||
|
||||
data->sqlVec.insert({ "电芯上水平边缘和注液孔的中心圆的距离", out_Distance[1].D() });
|
||||
data->sqlVec.insert({ "电芯下水平边缘和注液孔的中心圆的距离", out_Distance[2].D() });
|
||||
}
|
||||
if (out_CCDistance.Length() == 2) {
|
||||
value2_1 = out_CCDistance[0].D();
|
||||
if (zuoLJPtoGaiBanMaxThreshold < value2_1 || zuoLJPtoGaiBanMinThreshold > value2_1) {//NG
|
||||
textPainter.appendPaintJob("左侧连接片圆心和盖板圆心的距离:" + std::to_string(value2_1) + "mm", cv::Point(0, sourceImg.rows - 350), cv::Scalar(0, 0, 255));
|
||||
defects.push_back("左连接片距离NG");
|
||||
if (zuoLJPtoGaiBanEnable == true)
|
||||
isNg = true;
|
||||
}
|
||||
else//OK
|
||||
textPainter.appendPaintJob("左侧连接片圆心和盖板圆心的距离:" + std::to_string(value2_1) + "mm", cv::Point(0, sourceImg.rows - 350), cv::Scalar(0, 255, 0));
|
||||
|
||||
value2_2 = out_CCDistance[1].D();
|
||||
if (youLJPtoGaiBanMaxThreshold < value2_2 || youLJPtoGaiBanMinThreshold > value2_2) {//NG
|
||||
defects.push_back("右连接片距离NG");
|
||||
textPainter.appendPaintJob("右侧连接片圆心和盖板圆心的距离:" + std::to_string(value2_2) + "mm", cv::Point(0, sourceImg.rows - 150), cv::Scalar(0, 0, 255));
|
||||
if(youLJPtoGaiBanEnable == true)
|
||||
isNg = true;
|
||||
}
|
||||
else
|
||||
textPainter.appendPaintJob("右侧连接片圆心和盖板圆心的距离:" + std::to_string(value2_2) + "mm", cv::Point(0, sourceImg.rows - 150), cv::Scalar(0, 255, 0));
|
||||
#if switchToNew
|
||||
data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 4) + "_" + QByteArray::number(out_CCDistance[0].D()) + cameraThreadIndex);
|
||||
data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 6) + "_" + QByteArray::number(out_Distance[1].D()) + cameraThreadIndex);
|
||||
#else
|
||||
data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 4) + "_" + QByteArray::number(out_CCDistance[0].D()));
|
||||
data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 6) + "_" + QByteArray::number(out_Distance[1].D()));
|
||||
#endif
|
||||
|
||||
data->sqlVec.insert({ "左侧连接片圆心和盖板圆心的距离", out_CCDistance[0].D() });
|
||||
data->sqlVec.insert({ "右侧连接片圆心和盖板圆心的距离", out_CCDistance[1].D() });
|
||||
}
|
||||
|
||||
int left = out_ColorType[0].D();
|
||||
//结果判定,铜在左边,铝在右边
|
||||
if (left == 2)
|
||||
textPainter2.appendPaintJob("铜",cv::Point(0, 1500), cv::Scalar(0, 255, 0));
|
||||
else if (left == 1)
|
||||
textPainter2.appendPaintJob("铝",cv::Point(0, 1500), cv::Scalar(0, 0, 255));
|
||||
else
|
||||
textPainter2.appendPaintJob("异常",cv::Point(0, 1500), cv::Scalar(0, 0, 255));
|
||||
|
||||
int right = out_ColorType[1].D();
|
||||
if (right == 2)
|
||||
textPainter2.appendPaintJob("铜",cv::Point(Paint.cols - 600, 1500), cv::Scalar(0, 0, 255));
|
||||
else if (right == 1)
|
||||
textPainter2.appendPaintJob("铝",cv::Point(Paint.cols - 600, 1500), cv::Scalar(0, 255, 0));
|
||||
else
|
||||
textPainter2.appendPaintJob("异常",cv::Point(Paint.cols - 600, 1500), cv::Scalar(0, 0, 255));
|
||||
|
||||
if (left == 1 || right == 2) {
|
||||
defects.push_back("极性NG");
|
||||
if (jiXingEnable)
|
||||
isNg = true;
|
||||
}
|
||||
|
||||
|
||||
if(isNg == true){
|
||||
textPainter3.appendPaintJob("NG", cv::Point(0, 50), cv::Scalar(0, 0, 255));
|
||||
plcResult = "2";
|
||||
data->halconOK = false;
|
||||
}
|
||||
else {
|
||||
textPainter3.appendPaintJob("OK", cv::Point(0, 50), cv::Scalar(0, 255, 0));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TextRendererZH textPainter4(Paint.cols, Paint.rows, 500);
|
||||
textPainter4.putText(Paint, "NG", cv::Point(0, 50), cv::Scalar(0, 0, 255));//调机
|
||||
plcResult = "2";
|
||||
data->halconOK = false;
|
||||
}
|
||||
if (data->service->_paramSyncManager->get("通用设置","强制OK", false).toBool())
|
||||
plcResult = "1";
|
||||
#if switchToNew
|
||||
data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult + cameraThreadIndex);//结果反馈
|
||||
#else
|
||||
data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);//结果反馈
|
||||
#endif
|
||||
data->service->_missionResultHandle->toBarChart(data->SNcode, defects);
|
||||
|
||||
textPainter.excusePaintJobs(Paint);
|
||||
textPainter2.excusePaintJobs(Paint);
|
||||
textPainter3.excusePaintJobs(Paint);
|
||||
data->insertResultImg(Paint);
|
||||
return true;
|
||||
}
|
||||
CATCH_EXCEPTIONS
|
||||
exceptionResume(data, _detParams, address, "检测失败");
|
||||
qDebug() << "[Error] " << QString::fromUtf8("检测失败!");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HanHou2D_halconEvaluate(std::shared_ptr <detData> data, const cv::Mat& sourceImg,const cv::Mat& segImg, TextRendererZH* textPainter, double& hanHouTongXingDu, int times) {
|
||||
double tongXingDuLimitHigh = data->service->_paramSyncManager->get("焊后", "焊后同心度mm(上限)", 1.8).toDouble();
|
||||
double tongXingDuLimitLow = data->service->_paramSyncManager->get("焊后", "焊后同心度mm(下限)", 0).toDouble();
|
||||
bool tongXingDuLimitEnable = data->service->_paramSyncManager->get("焊后", "焊后同心度判定启用", true).toBool();
|
||||
HDevEngineCpp::HDevProcedure proc("_3_Cal_HY_CC_Distance");
|
||||
HDevEngineCpp::HDevProcedureCall procedureCall(proc);
|
||||
|
||||
HObject in_Image = MatToHObject(sourceImg);
|
||||
HObject in_ImageSeg = MatToHObject(segImg);
|
||||
double resolution = 0.013736;
|
||||
HalconCpp::HTuple in_FliePath("./halconFiles/"), in_Resolution(resolution);
|
||||
procedureCall.SetInputIconicParamObject("in_Image", in_Image);
|
||||
procedureCall.SetInputIconicParamObject("in_ImageSeg", in_ImageSeg);
|
||||
procedureCall.SetInputCtrlParamTuple("in_FliePath", in_FliePath);
|
||||
procedureCall.SetInputCtrlParamTuple("in_Resolution", in_Resolution);
|
||||
procedureCall.Execute();//执行halcon程序
|
||||
HalconCpp::HTuple out_CCDistance = procedureCall.GetOutputCtrlParamTuple("out_CCDistance");//获取输出控制类变量
|
||||
HalconCpp::HTuple out_Circle = procedureCall.GetOutputCtrlParamTuple("out_Circle");//获取输出控制类变量
|
||||
HalconCpp::HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");//获取输出控制类变量
|
||||
HalconCpp::HTuple out_NgTails = procedureCall.GetOutputCtrlParamTuple("out_NgTails");//获取输出控制类变量
|
||||
HalconCpp::HTuple InnerCircle_offset = procedureCall.GetOutputCtrlParamTuple("InnerCircle_offset");//获取输出控制类变量
|
||||
HalconCpp::HTuple OuterCircle_offset = procedureCall.GetOutputCtrlParamTuple("OuterCircle_offset");//外圆偏移(X向偏移,Y向偏移)
|
||||
int flag = out_Flag.D();
|
||||
bool isNg = false;
|
||||
if (flag == 1){
|
||||
|
||||
|
||||
double CCDistance = out_CCDistance.D();
|
||||
textPainter->appendPaintJob("焊印同心度:" + std::to_string(CCDistance), cv::Point(0, 50), cv::Scalar(0, 255, 0));
|
||||
|
||||
std::string x1Text = std::to_string(InnerCircle_offset[0].D());
|
||||
x1Text = x1Text.substr(0, x1Text.find(".") + 4);
|
||||
std::string y1Text = std::to_string(InnerCircle_offset[1].D());
|
||||
y1Text = y1Text.substr(0, y1Text.find(".") + 4);
|
||||
std::string txd1Text = std::to_string(std::sqrtf(std::powf(InnerCircle_offset[0].D(), 2) + std::powf(InnerCircle_offset[1].D(), 2)));
|
||||
txd1Text = txd1Text.substr(0, txd1Text.find(".") + 4);
|
||||
textPainter->appendPaintJob("内圆偏移X:" + x1Text + "mm Y:" + y1Text + "mm 同心度" + txd1Text, cv::Point(0, 250), cv::Scalar(0, 255, 0));
|
||||
|
||||
std::string x2Text = std::to_string(OuterCircle_offset[0].D());
|
||||
x2Text = x2Text.substr(0, x2Text.find(".") + 4);
|
||||
std::string y2Text = std::to_string(OuterCircle_offset[1].D());
|
||||
y2Text = y2Text.substr(0, y2Text.find(".") + 4);
|
||||
std::string txd2Text = std::to_string(std::sqrtf(std::powf(OuterCircle_offset[0].D(), 2) + std::powf(OuterCircle_offset[1].D(), 2)));
|
||||
txd2Text = txd2Text.substr(0, txd2Text.find(".") + 4);
|
||||
textPainter->appendPaintJob("外圆偏移X:" + x2Text + "mm Y:" + y2Text + "mm 同心度:" + txd2Text, cv::Point(0, 450), cv::Scalar(0, 255, 0));
|
||||
|
||||
for (int i = 0; i < out_Circle.Length() / 3; i++) {
|
||||
textPainter->appendPaintJob(cv::Point(out_Circle[i * 3 + 1].D(), out_Circle[i * 3].D()), out_Circle[i * 3 + 2].D(), cv::Scalar(0, 255, 0), 15,0);
|
||||
}
|
||||
if (CCDistance > tongXingDuLimitHigh || CCDistance < tongXingDuLimitLow){
|
||||
textPainter->appendPaintJob("同心度NG", cv::Point(10, 650), cv::Scalar(0, 0, 255));
|
||||
data->halconOK = false;
|
||||
if(tongXingDuLimitEnable == true)
|
||||
isNg = true;
|
||||
}
|
||||
}
|
||||
else{
|
||||
textPainter->appendPaintJob("焊印抓取NG", cv::Point(10, 50), cv::Scalar(0, 0, 255));
|
||||
textPainter->appendPaintJob(gbkToUtf8(out_NgTails.ToString().Text()), cv::Point(10, 450), cv::Scalar(0, 0, 255));
|
||||
if (tongXingDuLimitEnable == true)
|
||||
isNg = true;
|
||||
data->halconOK = false;
|
||||
}
|
||||
return isNg;
|
||||
}
|
||||
bool HanHou2D_handleAiEvaluate(std::shared_ptr <detData> data, hanHouJianCe* _detParams,const cv::Mat& sourceImg, TextRendererZH* textPainter,handdleAI::pSegmentation* seg,handdleAI::pClassification* cls) {
|
||||
double hanZhaFillterWidth = data->service->_paramSyncManager->get("焊后", "焊渣过滤值宽mm(上限)", 0.1).toDouble()/ 0.013736;
|
||||
double hanZhaFillterHeight = data->service->_paramSyncManager->get("焊后", "焊渣过滤值高mm(上限)", 0.1).toDouble()/ 0.013736;
|
||||
bool hanZhaEnable = data->service->_paramSyncManager->get("焊后", "焊渣判定启用", false).toBool();
|
||||
|
||||
cv::Mat forSeg;
|
||||
sourceImg.copyTo(forSeg);
|
||||
cv::resize(sourceImg, forSeg, cv::Size(), 0.5, 0.5);
|
||||
|
||||
cv::Mat SegResult = ~seg->Evaluate(forSeg);
|
||||
std::vector<std::vector<cv::Point>> contours;
|
||||
cv::findContours(SegResult, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
|
||||
std::vector<cv::Rect> PaintRects;
|
||||
std::vector<std::pair<std::string, cv::Mat>>clsImgTmp;
|
||||
bool isNg = false;;
|
||||
for (int i = 0; i < contours.size(); i++) {
|
||||
cv::Rect rect = cv::boundingRect(contours[i]);
|
||||
if (rect.width > hanZhaFillterWidth || rect.height > hanZhaFillterHeight) {
|
||||
cv::Mat clsImg;
|
||||
cv::resize(forSeg(rect), clsImg, cv::Size(128, 128));
|
||||
bool clsIsNg = false;
|
||||
int clsRes = cls->Evaluate(clsImg);
|
||||
if (clsRes == 1)
|
||||
clsIsNg = true;
|
||||
if (clsIsNg == true) {
|
||||
rect.x *= 2; rect.y *= 2; rect.width *= 2; rect.height *= 2;
|
||||
PaintRects.push_back(rect);
|
||||
isNg = true;
|
||||
}
|
||||
clsImgTmp.push_back({ clsIsNg == true ? "NG" : "OK",clsImg });
|
||||
}
|
||||
}
|
||||
for (auto& rect : PaintRects) {
|
||||
textPainter->appendPaintJob(cv::Rect(rect.x + rect.width / 2 -64, rect.y + rect.height / 2 -64, 128, 128), cv::Scalar(0, 0, 255), 3);
|
||||
}
|
||||
data->insertClsOriginImg(clsImgTmp);
|
||||
return isNg;
|
||||
}
|
||||
QByteArray getHanHouJianCe2DSendResult(bool isNg1,bool isNg2) {
|
||||
if (isNg1 == false && isNg2 == false) //都OK发1
|
||||
return "1";
|
||||
else if (isNg1 == true && isNg2 == false)//第一次NG发2
|
||||
return "2";
|
||||
else if (isNg1 == false && isNg2 == true)//第二次NG发3
|
||||
return "3";
|
||||
else if (isNg1 == true && isNg2 == true)//两次都NG发4
|
||||
return "4";
|
||||
else//为了DEBUG
|
||||
return "5";
|
||||
}
|
||||
bool HanHouJianCe2D(std::shared_ptr <detData> data, hanHouJianCe* _detParams, sx_581_address address){
|
||||
try
|
||||
{
|
||||
auto cameraThreadIndex = getCameraIndex(QString::fromStdString(data->cameraKeyName));
|
||||
//data->SNcode = "test";
|
||||
//data->oriImgs.clear();
|
||||
//data->oriImgs.push_back(cv::imread("D:\\testImage\\T.bmp",-1));
|
||||
//data->oriImgs.push_back(cv::imread("D:\\testImage\\L_OK.bmp", -1));
|
||||
#pragma region 错误处理
|
||||
|
||||
if (data->getOriImgSize() < 2) {
|
||||
exceptionResume(data, _detParams, address, "图片数量不满足");
|
||||
return true;
|
||||
}
|
||||
if (data->getOriImg(0).cols == 200 || (data->getOriImg(1).cols == 200)) {
|
||||
data->halconOK = false;
|
||||
cv::Mat Paint;
|
||||
data->getOriImg(0).copyTo(Paint);
|
||||
if (Paint.channels() == 1) {
|
||||
cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR);
|
||||
}
|
||||
TextRendererZH textPainter(Paint.cols, Paint.rows, 40);
|
||||
textPainter.putText(Paint, "图片数量不满足", cv::Point(0, 0), cv::Scalar(0, 255, 0));
|
||||
data->insertResultImg(Paint);
|
||||
data->service->_triggerManager->writeShort("D" + address.resultAddr + "_4");//结果反馈
|
||||
return true;
|
||||
}
|
||||
#pragma endregion
|
||||
cv::Mat Paint1, Paint2;
|
||||
data->getOriImg(0).copyTo(Paint1);
|
||||
data->getOriImg(1).copyTo(Paint2);
|
||||
if (Paint1.channels() == 1) {
|
||||
cvtColor(Paint1, Paint1, cv::COLOR_GRAY2BGR);
|
||||
}
|
||||
if (Paint2.channels() == 1) {
|
||||
cvtColor(Paint2, Paint2, cv::COLOR_GRAY2BGR);
|
||||
}
|
||||
std::vector <std::string>defects;
|
||||
QByteArray plcResult = "1";
|
||||
double hanHouTongXingDu1 = -1;
|
||||
double hanHouTongXingDu2 = -1;
|
||||
cv::Mat forSeg1, forSeg2;
|
||||
double resizeRate = 0.25;
|
||||
bool isNg1 = false, isNg2 = false;
|
||||
QMutex mutex1, mutex2;
|
||||
|
||||
cv::resize(data->getOriImg(0), forSeg1, cv::Size(), resizeRate, resizeRate);
|
||||
cv::Mat seg1 = _detParams->seg_rljHanYinZhuaQu->Evaluate(forSeg1);
|
||||
data->insertSegOriginImg(seg1);
|
||||
cv::Rect tongRect = findMaxAreaContour(~seg1);
|
||||
if (tongRect.width < 100 || tongRect.height < 100) {
|
||||
isNg1 = true;
|
||||
}
|
||||
|
||||
cv::resize(data->getOriImg(1), forSeg2, cv::Size(), resizeRate, resizeRate);
|
||||
cv::Mat seg2 = _detParams->seg_rljHanYinZhuaQu->Evaluate(forSeg2);
|
||||
data->insertSegOriginImg(seg2);
|
||||
cv::Rect lvRect = findMaxAreaContour(~seg2);
|
||||
if (lvRect.width < 100 || lvRect.height < 100) {
|
||||
isNg2 = true;
|
||||
}
|
||||
TextRendererZH textPainter1(Paint1.cols, Paint1.rows, 200), textPainter2(Paint2.cols, Paint2.rows, 200);
|
||||
//判斷焊印結果
|
||||
if (isNg1 == true || isNg2 == true) {//判断存图
|
||||
data->halconOK = false;
|
||||
plcResult = getHanHouJianCe2DSendResult(isNg1, isNg2);
|
||||
if (data->service->_paramSyncManager->get("通用设置", "强制OK", false).toBool())
|
||||
plcResult = "1";
|
||||
data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult);
|
||||
if (isNg1 == true) textPainter1.appendPaintJob("焊印抓取失败", cv::Point(0, 0), cv::Scalar(0, 0, 255));
|
||||
if (isNg2 == true) textPainter2.appendPaintJob("焊印抓取失败", cv::Point(0, 0), cv::Scalar(0, 0, 255));
|
||||
cv::Mat PaintSum;
|
||||
cv::vconcat(Paint1, Paint2, PaintSum);
|
||||
data->insertResultImg(PaintSum);
|
||||
return true;
|
||||
}
|
||||
|
||||
auto futrue1 = std::async(std::launch::async, &HanHou2D_halconEvaluate, data, data->getOriImg(0), seg1, &textPainter1, std::ref(hanHouTongXingDu1), 0);
|
||||
auto futrue2 = std::async(std::launch::async, &HanHou2D_halconEvaluate, data, data->getOriImg(1), seg2, &textPainter2, std::ref(hanHouTongXingDu2), 2);
|
||||
auto futrue3 = std::async(std::launch::async, &HanHou2D_handleAiEvaluate, data, _detParams, data->getOriImg(0), &textPainter1, _detParams->seg_rljHanZha1, _detParams->cls_rljHanZha1);
|
||||
auto futrue4 = std::async(std::launch::async, &HanHou2D_handleAiEvaluate, data, _detParams, data->getOriImg(1), &textPainter2, _detParams->seg_rljHanZha2, _detParams->cls_rljHanZha2);
|
||||
|
||||
futrue1.wait();
|
||||
futrue2.wait();
|
||||
isNg1 = futrue1.get();
|
||||
isNg2 = futrue2.get();
|
||||
|
||||
futrue3.wait();
|
||||
futrue4.wait();
|
||||
|
||||
futrue3.get();
|
||||
futrue4.get();
|
||||
|
||||
std::vector<std::pair<std::string, cv::Mat>> hanYinClsImg;
|
||||
|
||||
int tongClsRes = 0, lvClsRes = 0;
|
||||
if (isNg1 == true || isNg2 == true) {//同心度是否NG
|
||||
defects.push_back({ "焊后同心度NG" });
|
||||
}
|
||||
{
|
||||
auto tongClsImg = cutImg2Cls(tongRect, forSeg1, cv::Size(256, 256));
|
||||
tongClsRes = _detParams->cls_hanYinTong->Evaluate(tongClsImg);
|
||||
double prob = _detParams->cls_hanYinTong->getProbability();
|
||||
hanYinClsImg.push_back({ "tongHY_Res" + std::to_string(tongClsRes) + "_prob" + std::to_string(prob),tongClsImg });
|
||||
if (tongClsRes == 1) {
|
||||
defects.push_back({ "铜焊印CLS-NG" });
|
||||
textPainter1.appendPaintJob("焊印CLS-NG(测试)", cv::Point(0, 850), cv::Scalar(0, 0, 255));
|
||||
/* if (data->service->_paramSyncManager->get("焊后", "焊印CLS判定启用", true).toBool()) {
|
||||
isNg1 = true;
|
||||
}*/
|
||||
}
|
||||
else
|
||||
textPainter1.appendPaintJob("焊印CLS-OK(测试)", cv::Point(0, 850), cv::Scalar(0, 255, 0));
|
||||
}
|
||||
|
||||
{
|
||||
auto lvClsImg = cutImg2Cls(lvRect, forSeg2, cv::Size(256, 256));
|
||||
lvClsRes = _detParams->cls_hanYinLv->Evaluate(lvClsImg);
|
||||
double prob = _detParams->cls_hanYinLv->getProbability();
|
||||
hanYinClsImg.push_back({ "lvHY" + std::to_string(tongClsRes) + "_prob" + std::to_string(prob),lvClsImg });
|
||||
if (lvClsRes == 1) {
|
||||
defects.push_back({ "铝焊印CLS-NG" });
|
||||
textPainter2.appendPaintJob("焊印CLS-NG", cv::Point(0, 850), cv::Scalar(0, 0, 255));
|
||||
if (data->service->_paramSyncManager->get("焊后", "焊印CLS判定启用", true).toBool()) {
|
||||
isNg2 = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
textPainter2.appendPaintJob("焊印CLS-OK", cv::Point(0, 850), cv::Scalar(0, 255, 0));
|
||||
}
|
||||
|
||||
|
||||
|
||||
data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(hanHouTongXingDu1) + "," + QByteArray::number(hanHouTongXingDu2) + cameraThreadIndex);
|
||||
|
||||
if (isNg1 == true || isNg2 == true) {//判断存图
|
||||
data->halconOK = false;
|
||||
}
|
||||
|
||||
plcResult = getHanHouJianCe2DSendResult(isNg1, isNg2);
|
||||
if (data->service->_paramSyncManager->get("通用设置", "强制OK", false).toBool())
|
||||
plcResult = "1";
|
||||
data->service->_triggerManager->writeShort("D" + address.resultAddr + "_" + plcResult + cameraThreadIndex);
|
||||
if (data->cameraKeyName == "Camera3")
|
||||
data->service->_triggerManager->writeShort("D5504_1");
|
||||
else
|
||||
data->service->_triggerManager->writeShort("D5704_1");
|
||||
data->insertClsOriginImg(hanYinClsImg);
|
||||
data->service->_missionResultHandle->toBarChart(data->SNcode, defects);
|
||||
|
||||
textPainter1.excusePaintJobs(Paint1);
|
||||
textPainter2.excusePaintJobs(Paint2);
|
||||
//拼装结果图
|
||||
cv::Mat PaintSum;
|
||||
cv::vconcat(Paint1, Paint2, PaintSum);
|
||||
data->insertResultImg(PaintSum);
|
||||
|
||||
return true;
|
||||
}
|
||||
CATCH_EXCEPTIONS
|
||||
exceptionResume(data, _detParams, address, "检测失败");
|
||||
qDebug() << "[Error] " << QString::fromUtf8("检测失败!");
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool HanHouJianCe3D(std::shared_ptr <detData> data, hanHouJianCe* _detParams, sx_581_address address) {
|
||||
try {
|
||||
data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果
|
||||
qDebug() << "SN" << QString::fromStdString(data->SNcode) << "algo start";
|
||||
std::vector < std::string> defects = { };
|
||||
///////////////////取图//处理//////////////////
|
||||
if (data->getOriImgSize() < 1)
|
||||
{
|
||||
qCritical() << "图片数量不满足要求:" << data->getOriImgSize();
|
||||
return false;
|
||||
}
|
||||
if (data->getOriImg(0).rows == 100) {
|
||||
cv::Mat Paint;
|
||||
data->getOriImg(0).copyTo(Paint);
|
||||
cv::putText(Paint, "time out", cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255), 2);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
QMutex paintMutex;
|
||||
clock_t start, finish;
|
||||
start = clock();
|
||||
cv::Mat src1 = data->getOriImg(0);
|
||||
cv::Mat src2 = data->getOriImg(2);
|
||||
cv::Mat Paint;
|
||||
cv::vconcat(src1, src2, Paint);
|
||||
if (src1.channels() != 3)
|
||||
cv::cvtColor(Paint, Paint, cv::COLOR_GRAY2BGR);
|
||||
|
||||
TextRendererZH textPainter(Paint.cols, Paint.rows, 300);
|
||||
textPainter.putText(Paint, "OK", 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->_missionResultHandle->toBarChart(data->SNcode, !defects.size() > 0, defects);//发送图标操作
|
||||
data->insertResultImg(Paint);
|
||||
return true;
|
||||
}
|
||||
CATCH_EXCEPTIONS
|
||||
exceptionResume(data, _detParams, address, "检测失败");
|
||||
return false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
mission* createMission() {
|
||||
return new _581_Ruanlianjie_hanqian_hanhou();
|
||||
}
|
||||
void destroyMission(mission* _mission) {
|
||||
delete _mission;
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
#include <missionBase.hpp>
|
||||
#include <sxGlobal.h>
|
||||
#include <simpleAlgo.h>
|
||||
#include <hdevengine/HDevEngineCpp.h>
|
||||
#include <Halcon.h>
|
||||
#include <HalconCpp.h>
|
||||
#include <qmutex.h>
|
||||
#include <qqueue.h>
|
||||
#include <opencvPaintAlgo.hpp>
|
||||
using namespace HDevEngineCpp;
|
||||
using namespace HalconCpp;
|
||||
class hanQianDingWeiParams {
|
||||
|
||||
};
|
||||
class hanHouJianCe {
|
||||
public:
|
||||
handdleAI::pSegmentation* seg_rljHanYinZhuaQu = nullptr;
|
||||
handdleAI::pSegmentation* seg_rljHanZha1 = nullptr;
|
||||
handdleAI::pClassification* cls_rljHanZha1 = nullptr;
|
||||
handdleAI::pSegmentation* seg_rljHanZha2 = nullptr;
|
||||
handdleAI::pClassification* cls_rljHanZha2 = nullptr;
|
||||
handdleAI::pClassification* cls_hanYinTong = nullptr;
|
||||
handdleAI::pClassification* cls_hanYinLv = nullptr;
|
||||
int ngCnt = 0;
|
||||
};
|
||||
|
||||
bool HanQianDingWei(std::shared_ptr <detData> data, hanQianDingWeiParams* _detParams, sx_581_address address);
|
||||
bool HanHouJianCe2D(std::shared_ptr <detData> data, hanHouJianCe* _detParams, sx_581_address address);
|
||||
bool HanHouJianCe3D(std::shared_ptr <detData> data, hanHouJianCe* _detParams, sx_581_address address);
|
||||
|
||||
class _581_Ruanlianjie_hanqian_hanhou : public mission {
|
||||
public:
|
||||
|
||||
_581_SX_Single_triggerTemplate<hanQianDingWeiParams> dingwei_1;
|
||||
_581_SX_Single_triggerTemplate<hanQianDingWeiParams> dingwei_2;
|
||||
|
||||
_581_SX_Single_triggerTemplate<hanHouJianCe> jiance_2d_1;
|
||||
_581_SX_Single_triggerTemplate<hanHouJianCe> jiance_2d_2;
|
||||
_581_SX_Single_triggerTemplate<hanHouJianCe> jiance_3d_1;
|
||||
_581_SX_Single_triggerTemplate<hanHouJianCe> jiance_3d_2;
|
||||
|
||||
hanQianDingWeiParams hanqiandingweiparams;
|
||||
std::vector<hanHouJianCe>hanhoujiance2dparams = std::vector<hanHouJianCe>(2);
|
||||
hanHouJianCe hanhoujiance3dparams;
|
||||
|
||||
bool initOnce = false;
|
||||
void onConfigReloaded() {
|
||||
HDevEngineCpp::HDevEngine myEngine;
|
||||
myEngine.SetProcedurePath("");
|
||||
myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_602.hdpl");
|
||||
|
||||
if (initOnce == false) {
|
||||
|
||||
hanhoujiance2dparams[0].seg_rljHanYinZhuaQu = handdleAI::CreateSegObjS("./handleAiModels/seg_rljHanYinZhuaQu.BHD", 64, 0);
|
||||
hanhoujiance2dparams[1].seg_rljHanYinZhuaQu = handdleAI::CreateSegObjS("./handleAiModels/seg_rljHanYinZhuaQu.BHD", 64, 1);
|
||||
|
||||
hanhoujiance2dparams[0].seg_rljHanZha1 = handdleAI::CreateSegObjS("./handleAiModels/seg_rljHanZha.BHD", 64, 0);
|
||||
hanhoujiance2dparams[1].seg_rljHanZha1 = handdleAI::CreateSegObjS("./handleAiModels/seg_rljHanZha.BHD", 64, 1);
|
||||
hanhoujiance2dparams[0].seg_rljHanZha2 = handdleAI::CreateSegObjS("./handleAiModels/seg_rljHanZha.BHD", 64, 0);
|
||||
hanhoujiance2dparams[1].seg_rljHanZha2 = handdleAI::CreateSegObjS("./handleAiModels/seg_rljHanZha.BHD", 64, 1);
|
||||
|
||||
hanhoujiance2dparams[0].cls_rljHanZha1 = handdleAI::CreateClsObjV3("./handleAiModels/cls_rljHanZha.BHD", 0, 1);
|
||||
hanhoujiance2dparams[1].cls_rljHanZha1 = handdleAI::CreateClsObjV3("./handleAiModels/cls_rljHanZha.BHD", 1, 1);
|
||||
hanhoujiance2dparams[0].cls_rljHanZha2 = handdleAI::CreateClsObjV3("./handleAiModels/cls_rljHanZha.BHD", 0, 1);
|
||||
hanhoujiance2dparams[1].cls_rljHanZha2 = handdleAI::CreateClsObjV3("./handleAiModels/cls_rljHanZha.BHD", 1, 1);
|
||||
|
||||
hanhoujiance2dparams[0].cls_hanYinTong = handdleAI::CreateClsObjV3("./handleAiModels/cls_hanYinTong.BHD", 0, 1);
|
||||
hanhoujiance2dparams[1].cls_hanYinTong = handdleAI::CreateClsObjV3("./handleAiModels/cls_hanYinTong.BHD", 1, 1);
|
||||
|
||||
hanhoujiance2dparams[0].cls_hanYinLv = handdleAI::CreateClsObjV3("./handleAiModels/cls_hanYinLv.BHD", 0, 1);
|
||||
hanhoujiance2dparams[1].cls_hanYinLv = handdleAI::CreateClsObjV3("./handleAiModels/cls_hanYinLv.BHD", 1, 1);
|
||||
initOnce = true;
|
||||
}
|
||||
}
|
||||
bool initCustom() {
|
||||
#pragma region 注册触发器回调
|
||||
dingwei_1.init("Camera1", "焊前定位-相机1(左)", { { 4900, 1,{4910},"4902","4904",4930} }, 1, &hanqiandingweiparams, _serviceManager, bridge, HanQianDingWei,"焊前定位CCD");
|
||||
dingwei_2.init("Camera2", "焊前定位-相机2(右)", { { 5800, 1,{5810},"5802","5804",5830} }, 1, &hanqiandingweiparams, _serviceManager, bridge, HanQianDingWei,"焊前定位CCD");
|
||||
|
||||
jiance_2d_1.init("Camera3", "焊后检测2D-相机1(前)", { { 5400, 1,{5410},"5402","5404",5430} }, 2, &hanhoujiance2dparams[0], _serviceManager, bridge, HanHouJianCe2D, "焊后检测CCD");
|
||||
jiance_3d_1.init("Camera4", "焊后检测3D-相机1(前)", { { 5500, 1,{5510},"5502","5504",5530} }, 4, &hanhoujiance3dparams, _serviceManager, bridge, HanHouJianCe3D,"焊后检测CCD");
|
||||
jiance_2d_2.init("Camera5", "焊后检测2D-相机2(后)", { { 5600, 1,{5610},"5602","5604",5630} }, 2, &hanhoujiance2dparams[1], _serviceManager, bridge, HanHouJianCe2D, "焊后检测CCD");
|
||||
jiance_3d_2.init("Camera6", "焊后检测3D-相机2(后)", { { 5700, 1,{5710},"5702","5704",5730} }, 4, &hanhoujiance3dparams, _serviceManager, bridge, HanHouJianCe3D,"焊后检测CCD");
|
||||
#pragma endregion
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
@@ -0,0 +1,77 @@
|
||||
# 获取获取当前目录名
|
||||
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/service
|
||||
${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 OFF)
|
||||
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 REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network REQUIRED)
|
||||
|
||||
add_library(${CURRENT_FOLDER} SHARED
|
||||
${HEAD_FILES}
|
||||
${SRC_FILES}
|
||||
${UI_FILES}
|
||||
${PROJECT_ROOT_PATH}/include/interface.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
|
||||
)
|
||||
|
||||
|
||||
# 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})
|
||||
@@ -333,9 +333,16 @@ bool Hd_CameraModule_HIK_General::writeData(std::vector<cv::Mat>& mat, QByteArra
|
||||
return true;
|
||||
}
|
||||
if (data == "clearCache") {
|
||||
QMutexLocker locker(n_mutex);
|
||||
queuepic.clear();
|
||||
return true;
|
||||
}
|
||||
if (data.contains("exposure")){
|
||||
auto commandList = data.split('_');
|
||||
QMutexLocker locker(n_mutex);
|
||||
SetExposureTime(commandList[1].toFloat());
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//传入initParas函数,格式为:相机key+参数名1#参数值1#参数值2+参数名2#参数值1...
|
||||
|
||||
@@ -333,7 +333,7 @@ bool Hd_CameraModule_HIK_General::writeData(std::vector<cv::Mat>& mat, QByteArra
|
||||
auto result = QByteArrayToMV_CC_DeviceInfoList(data.mid(10));
|
||||
if (result.nDeviceNum != 0) {
|
||||
m_stDevList = result;
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (data == "getStatus") {
|
||||
@@ -341,9 +341,16 @@ bool Hd_CameraModule_HIK_General::writeData(std::vector<cv::Mat>& mat, QByteArra
|
||||
return true;
|
||||
}
|
||||
if (data == "clearCache") {
|
||||
QMutexLocker locker(n_mutex);
|
||||
queuepic.clear();
|
||||
return true;
|
||||
}
|
||||
if (data.contains("exposure")) {
|
||||
auto commandList = data.split('_');
|
||||
QMutexLocker locker(n_mutex);
|
||||
SetExposureTime(commandList[1].toFloat());
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//传入initParas函数,格式为:相机key+参数名1#参数值1#参数值2+参数名2#参数值1...
|
||||
|
||||
@@ -317,6 +317,15 @@ bool Hd_CameraModule_HIK_hard_PCIE::writeData(std::vector<cv::Mat>& mat, QByteAr
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (data == "getStatus") {
|
||||
data = lastError.toUtf8();
|
||||
return true;
|
||||
}
|
||||
if (data == "clearCache") {
|
||||
QMutexLocker locker(n_mutex);
|
||||
queuepic.clear();
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user