This commit is contained in:
RCi
2025-07-29 11:59:42 +08:00
parent 64e5d663ca
commit aa74dfcd15
13 changed files with 747 additions and 261 deletions
@@ -1,4 +1,4 @@
#include "Hd_YuHang_module.h"
#include "Hd_ShangDing_module.h"
#include <QDateTime>
#include <global.h>
#include <QtConcurrent/QtConcurrent>
@@ -27,6 +27,20 @@ using namespace handdleAI;
//总保存文件夹
QString AllImgSaveDir = "D:/CCD/";
//切图的class的width,根据项目实际设置!
static int sizeW = 150;
//切图的class的height,根据项目实际设置!
static int sizeH = 150;
//切图的class的width,根据项目实际设置!0为黑,255为白;
static int fillColour = 0;
pDetection* det_DJY;
pClassification* cls_DJY;
std::string modelPath_det_DJY = "../bin/model/det_DJY.BHD";
std::string modelPath_cls_DJY = "../bin/model/cls_DJY.BHD";
//检测线程锁
QMutex* detect_mutex;
//保存线程锁
@@ -42,8 +56,8 @@ QStringList splitDataList;
QByteArrayList initValueList;
QString sdataTime; //产品名里的时间戳
QString okngText = "OK";
QString shortData_result = "1";//返回给PLC的结果
QString floatData_offsetX = "-1.1", floatData_offsetY = "-1.1";//偏移值
QString shortData_result = "1";
QString floatData_offsetX = "-1.1", floatData_offsetY = "-1.1";
// 缺陷信息结构体
typedef struct {
QString defectName = "";//缺陷名称
@@ -462,15 +476,15 @@ void drawDefects(cv::Mat& sourceMat, QQueue<defectInfo> defectInfoList)
}
}
Hd_YuHang_module* create()
Hd_ShangDing_module* create()
{
qDebug() << "[INFO] " << " Hd_YuHang_module create success!" ;
return new Hd_YuHang_module;
qDebug() << "[INFO] " << " Hd_ShangDing_module create success!" ;
return new Hd_ShangDing_module;
}
void destory(Hd_YuHang_module* ptr)
void destory(Hd_ShangDing_module* ptr)
{
qDebug() << "[INFO] " << "Hd_YuHang_module destory success!";
qDebug() << "[INFO] " << "Hd_ShangDing_module destory success!";
if(ptr)
{
delete ptr;
@@ -478,14 +492,14 @@ void destory(Hd_YuHang_module* ptr)
}
}
Hd_YuHang_module::Hd_YuHang_module()
Hd_ShangDing_module::Hd_ShangDing_module()
{
detect_mutex = new QMutex;
saveStruct_mutex = new QMutex;
ifdetectThread = false;
}
Hd_YuHang_module::~Hd_YuHang_module()
Hd_ShangDing_module::~Hd_ShangDing_module()
{
ifdetectThread = false;
Sleep(10);
@@ -505,7 +519,7 @@ Hd_YuHang_module::~Hd_YuHang_module()
static int defectNums = 0;
//static cv::Mat resMat;
//从类中读数据到实例对象
bool Hd_YuHang_module::readData(std::vector<cv::Mat>&vec_mat,QByteArray &data)
bool Hd_ShangDing_module::readData(std::vector<cv::Mat>&vec_mat,QByteArray &data)
{
if (HikMat[0].cols == 200)
return true;
@@ -555,7 +569,7 @@ bool Hd_YuHang_module::readData(std::vector<cv::Mat>&vec_mat,QByteArray &data)
return true;
}
//从类中读数据到实例对象
bool Hd_YuHang_module::encodeResultValue(QVector<std::string> append_value,QByteArray &resultByte)
bool Hd_ShangDing_module::encodeResultValue(QVector<std::string> append_value,QByteArray &resultByte)
{
try
{
@@ -591,7 +605,7 @@ bool Hd_YuHang_module::encodeResultValue(QVector<std::string> append_value,QByte
//接收数据
bool Hd_YuHang_module::writeData(std::vector<cv::Mat>& vec_mat, QByteArray &data)
bool Hd_ShangDing_module::writeData(std::vector<cv::Mat>& vec_mat, QByteArray &data)
{
qDebug() << __FUNCTION__ << "line:" << __LINE__ << " data:" << data;
if (vec_mat.empty())
@@ -614,6 +628,7 @@ bool Hd_YuHang_module::writeData(std::vector<cv::Mat>& vec_mat, QByteArray &data
//QByteArray source_savePath;
sData = byteArrayToUnicode(data);
splitDataList = sData.split(',');
singal_sign = splitDataList[1];
SN = splitDataList[3];
cameraKey_index = splitDataList[2];
sdataTime = QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz");
@@ -623,7 +638,7 @@ bool Hd_YuHang_module::writeData(std::vector<cv::Mat>& vec_mat, QByteArray &data
return true;
}
//初始化
bool Hd_YuHang_module::initParas(QByteArray& byte)
bool Hd_ShangDing_module::initParas(QByteArray& byte)
{
initValueList = byte.split('+');
@@ -658,9 +673,9 @@ bool Hd_YuHang_module::initParas(QByteArray& byte)
////线程检测:结果类完成时,使用
////ifThreadRunDetect = true;
////QFuture<void> future1 = QtConcurrent::run(this, &Hd_YuHang_module::detectThread);
////QFuture<void> future1 = QtConcurrent::run(this, &Hd_ShangDing_module::detectThread);
//运行存图线程
QFuture<void> future2 = QtConcurrent::run(this, &Hd_YuHang_module::saveImgThread);
QFuture<void> future2 = QtConcurrent::run(this, &Hd_ShangDing_module::saveImgThread);
//cv::Mat initimg = cv::imread("../bin/initimg.bmp");
//if (initimg.channels() == 3)
@@ -673,7 +688,7 @@ bool Hd_YuHang_module::initParas(QByteArray& byte)
return true;
}
bool Hd_YuHang_module::InitModels()
bool Hd_ShangDing_module::InitModels()
{
int flag = 0;
//seg_aokeng = CreateSegObjS((char*)modelPath_seg_aokeng.c_str(), 1, 0); if (seg_aokeng->getStatus() != SegStatus::Seg_Success)flag++;
@@ -687,7 +702,7 @@ bool Hd_YuHang_module::InitModels()
return (flag == 0);
}
// 解码
bool Hd_YuHang_module::decodeAiValue(QByteArray byte,QVector<QByteArray> &vec_ret)
bool Hd_ShangDing_module::decodeAiValue(QByteArray byte,QVector<QByteArray> &vec_ret)
{
if(byte.isEmpty())
{
@@ -722,8 +737,113 @@ bool Hd_YuHang_module::decodeAiValue(QByteArray byte,QVector<QByteArray> &vec_re
return true;
}
//---------检测流程,根据实际项目修改---------
bool Hd_ShangDing_module::AIdetect(cv::Mat img2D, QString mysaveKey, QString myDir2D, QString mySN, QString myDataTime)
{
/*try
{*/
//存图数据加保存队列,加锁,避免数据访问冲突
saveStruct_mutex->lock();
saveImgStruct mySave;
Mat sourceImg, sourceImg1, sourceImg2;
sourceImg = img2D.clone();
//img2D.copyTo(sourceImg);
//img2D.release();
QString mysaveKey1 = mysaveKey; //"offlineStation1_off_1"
saveStruct_mutex->unlock();
QJsonDocument document;
QJsonObject obj;
obj.insert("result_key", "mysaveKey");
obj.insert("SN", "mySN");
obj.insert("DataTime", "myDataTime");
//QFile csvName("test.csv");
//QStringList lines;
//lines << "class,name\n" << "3,4,5,6,7\n" << "a,b,c,d\n";
//if (csvName.open(QIODevice::WriteOnly)) //若文件不存在,会自动创建
//{
// for (int i = 0; i < lines.size(); i++)
// csvName.write(lines[i].toStdString().c_str());
// csvName.close();
//}
QQueue<defectInfo> defectInfoList;
detect_mutex->lock();
//结果图画框和缺陷,在resMat上绘制
/*if (resMat.size() > 0)
drawDefects(resMat[0], defectInfoList);*/
//QByteArray,根据实际项目进行解析
//参数,例:返回结果图;相机关键字(SN或userID)+保存路径+缺陷信息列表(缺陷名称,缺陷位置int(x,y,w,h),画框颜色Scalar(a,b,c),缺陷面积double)
QJsonArray detaillists;
//QByteArrayList resQbyte;
for (int i = 0; i < defectInfoList.size(); i++)
{
defectInfo mdefect = defectInfoList[i];
//resQbyte.push_back(mdefect.defectName.toLocal8Bit()); //中文也可以QString::number(1.1).toUtf8()
//resQbyte.push_back(QString::number(mdefect.defectRect.x).toUtf8());
//resQbyte.push_back(QString::number(mdefect.defectRect.y).toUtf8());
//resQbyte.push_back(QString::number(mdefect.defectRect.width).toUtf8());
//resQbyte.push_back(QString::number(mdefect.defectRect.height).toUtf8());
//resQbyte.push_back(QString::number(mdefect.defectScalar[0]).toUtf8());
//resQbyte.push_back(QString::number(mdefect.defectScalar[1]).toUtf8());
//resQbyte.push_back(QString::number(mdefect.defectScalar[2]).toUtf8());
//resQbyte.push_back(QString::number(mdefect.defectArea).toUtf8());
QJsonObject detailObj;
detailObj.insert("defectName", "mdefect.defectName");
detailObj.insert("defectRect.x", QString::number(mdefect.defectRect.x));
detailObj.insert("defectRect.y", QString::number(mdefect.defectRect.y));
detailObj.insert("defectRect.width", QString::number(mdefect.defectRect.width));
detailObj.insert("defectRect.height", QString::number(mdefect.defectRect.height));
detailObj.insert("defectScalar0", QString::number(mdefect.defectScalar[0]));
detailObj.insert("defectScalar1", QString::number(mdefect.defectScalar[1]));
detailObj.insert("defectScalar2", QString::number(mdefect.defectScalar[2]));
detailObj.insert("defectArea", QString::number(mdefect.defectArea));
detailObj.insert("defectLength", QString::number(sqrt(mdefect.defectRect.width* mdefect.defectRect.width+ mdefect.defectRect.height* mdefect.defectRect.height)));
detaillists.append(detailObj);
}
//使用完删除
defectInfoList.clear();
/* isDirExist(resImgSaveDir + mysaveKey1 + "/");
QString qimgsavePath = resImgSaveDir + mysaveKey1 + "/" + mySN + myDataTime + ".jpg";*/
//存图数据入队,按需
/*if (resMat.size() > 0 )
addImgToSaveStruct(resMat[0], mysaveKey1, resImgSaveDir + mysaveKey1 + "/" + mySN + myDataTime + ".jpg");*/
detect_mutex->unlock();
obj.insert("detaillists", detaillists);
//obj.insert("qimgsavePath", qimgsavePath);
document.setObject(obj);
QByteArray qa = document.toJson();
mySave.out_Mat.resize(0);
mysaveKey1.clear();
qApp->processEvents();
/* }
catch (...)
{
qDebug() << "[Error] " << QString::fromUtf8("检测失败!");
hv_Image.clear();
number = 0;
return false;
}*/
return true;
}
//存图加入队列
void Hd_YuHang_module::addImgToSaveStruct(cv::Mat img2D, QString mysaveKey, std::pair<QString, QString> savePath)
void Hd_ShangDing_module::addImgToSaveStruct(cv::Mat img2D, QString mysaveKey, std::pair<QString, QString> savePath)
{
//存图数据加保存队列,加锁,避免数据访问冲突
saveStruct_mutex->lock();
@@ -736,7 +856,7 @@ void Hd_YuHang_module::addImgToSaveStruct(cv::Mat img2D, QString mysaveKey, std:
saveStruct.enqueue(mySave);
saveStruct_mutex->unlock();
}
void Hd_YuHang_module::saveImgThread()
void Hd_ShangDing_module::saveImgThread()
{
while (1)
{
@@ -767,7 +887,7 @@ void Hd_YuHang_module::saveImgThread()
}
}
//检测线程,应当只运行一次
void Hd_YuHang_module::detectThread()
void Hd_ShangDing_module::detectThread()
{
do
{
@@ -822,13 +942,31 @@ void Hd_YuHang_module::detectThread()
}
bool Hd_YuHang_module::run()
bool myMath(double a, double b)
{
return a > b;
}
static int runNum = 0;
QQueue<double> timeAll_A;
QQueue<double> timeAll_B;
bool Hd_ShangDing_module::run()
{
try
{
shortData_result = "0";
floatData_offsetX = "0";
floatData_offsetY = "0";
if (HikMat[0].cols == 200) {
std::cout << "skip";
return true;
}
defectNums = 0;
cv::Mat resImg1, resImg2;
//cv::Mat mat;
float prob = 0;
if (HikMat.isEmpty())
{
shortData_result = "2";
@@ -837,7 +975,7 @@ bool Hd_YuHang_module::run()
return true;
}
if (HikMat.isEmpty() || HikMat[0].rows < 200 || HikMat[0].cols < 200)//超时补图
if (HikMat.isEmpty() || HikMat[0].rows < 200 || HikMat[0].cols < 200)
{
shortData_result = "2";
cv::Mat null_mat = cv::Mat::zeros(cv::Size(100, 100), CV_8UC3);
@@ -845,109 +983,202 @@ bool Hd_YuHang_module::run()
return true;
}
cv::Mat srcImg;
if (HikMat[0].channels() == 3)// && (qstring_data.contains("jizu") || qstring_data.contains("fangbaofa")))
cv::cvtColor(HikMat[0], srcImg, COLOR_BGR2GRAY);
else
srcImg = HikMat[0];
cv::Mat img_dst;
cvtColor(HikMat[0], img_dst, cv::COLOR_GRAY2BGR);
//hv_model.Append(m_hv_model); //后续开放参数窗口
//try {
// auto jsonConfig = readJsonFromPath("./config/editableConfig.json");
// BiaoDingFlag = jsonConfig["上钉标定"];
// YiWuFlag = jsonConfig["上钉异物检测"];
// if (BiaoDingFlag != 1)
// {
// hv_model = 0;
// }
//if (splitDataList[1].contains("20400_2") || splitDataList[1].contains("20600_2") ||
// splitDataList[1].contains("20800_2") || splitDataList[1].contains("21000_2"))
//{
// cv::Mat srcImg;
// if (HikMat[0].channels() == 3)// && (qstring_data.contains("jizu") || qstring_data.contains("fangbaofa")))
// cv::cvtColor(HikMat[0], srcImg, COLOR_BGR2GRAY);
// else
// {
// hv_model = 1;
// }
// srcImg = HikMat[0];
// cv::Mat img_dst;
// cvtColor(HikMat[0], img_dst, cv::COLOR_GRAY2BGR);
// resMat.push_back(img_dst);
// //qDebug() << __FUNCTION__ << " line:" << __LINE__ << "camera::放钉" << "_SN::" << SN << splitDataList[1].split("_")[0] << "_" << stop - start << "ms";
// //return true;
//}
//catch (...) {
// qDebug() << __FUNCTION__ << " line:" << __LINE__ << "getJsonError";
//}
//qDebug() << __FUNCTION__ << " line:" << __LINE__ << "放钉标定::" << BiaoDingFlag;
////hv_model = 1;
//qDebug() << __FUNCTION__ << " line:" << __LINE__ << "放钉标定::" << hv_model.I();
/*<c>* Input(HObject) : in_Image, 图像(bmp), < / c>
<c>*output(HObject) : < / c>
<c>*Input(HTuple) : in_ProductionType, 生产类别 : 0, 生产模式: 1, 标定模式 < / c>
<c>* in_CameraNumber, 相机序列号 < / c>
<c>* in_FilePath1, 模板文件路径; 示例:'./模板文件/' < / c >
<c>*in_FilePath2, 基准文件路径; < / c>*/
HalconCpp::HObject in_Image = MatToHObject(HikMat[0]);
std::string cameraNumberStr = "1";
if (cameraKey_index == "DA494077x0_0")
cameraNumberStr = "2";
HDevEngineCpp::HDevProcedure proc("_9_yuhan");
HDevProcedureCall procedureCall(proc);
procedureCall.SetInputIconicParamObject("in_Image", in_Image);
procedureCall.SetInputCtrlParamTuple("in_ProductionType", 0);
procedureCall.SetInputCtrlParamTuple("in_CameraNumber", HTuple(cameraNumberStr.c_str()));
procedureCall.SetInputCtrlParamTuple("in_FilePath1", HTuple("./halconFiles/template/"));
procedureCall.SetInputCtrlParamTuple("in_FilePath2", HTuple("./halconFiles/base/"));
procedureCall.Execute();
//<c>* out_Circle, 密封钉的圆心坐标(y, x, radius) < / c >
//<c>*out_Flag, 算法执行成功标志位, 0: 算法执行失败 1 : 算法执行成功< / c>
//<c>*out_OffsetX : 模组X轴的补偿量(mm) < / c >
//<c>*out_OffsetY : 模组Y轴的补偿量(mm) < / c >
HTuple out_Circle = procedureCall.GetOutputCtrlParamTuple("out_Circle");
HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");
HTuple out_OffsetX = procedureCall.GetOutputCtrlParamTuple("out_OffsetX");
HTuple out_OffsetY = procedureCall.GetOutputCtrlParamTuple("out_OffsetY");
int outFlag = out_Flag.D();
qDebug() << __FUNCTION__ << " line:" << __LINE__ << "camera::放钉" << "_SN::" << SN << ",放钉算法结果;" << out_Flag[0].D();
if (outFlag == 1){ //-1为失败,无结果
//圆及十字
cv::circle(img_dst, cv::Point(out_Circle[1].D(), out_Circle[0].D()), out_Circle[2].D(), cv::Scalar(0, 255, 0), 20);
cv::line(img_dst, cv::Point(out_Circle[1].D() - 300, out_Circle[0].D()), cv::Point(out_Circle[1].D() + 300, out_Circle[0].D()), cv::Scalar(0, 255, 0), 15);
cv::line(img_dst, cv::Point(out_Circle[1].D(), out_Circle[0].D() - 300), cv::Point(out_Circle[1].D(), out_Circle[0].D() + 300), cv::Scalar(0, 255, 0), 15);
//if (splitDataList[1].contains("放钉"))
{
cv::Mat srcImg;
if (HikMat[0].channels() == 3)// && (qstring_data.contains("jizu") || qstring_data.contains("fangbaofa")))
cv::cvtColor(HikMat[0], srcImg, COLOR_BGR2GRAY);
else
srcImg = HikMat[0];
cv::Mat img_dst;
cvtColor(HikMat[0], img_dst, cv::COLOR_GRAY2BGR);
/* HalconCpp::HTuple hv_BenchmarkFile;
hv_BenchmarkFile.Append("C:\\Hd_Mifengding-1\\env\\628\\FD\\");
HalconCpp::HTuple hv_NinePointDocument;
if (qstring_data.contains("放钉1"))
hv_NinePointDocument.Append("C:\\Hd_Mifengding-1\\env\\628\\FD\\jiudian1.tup");
if (qstring_data.contains("放钉2"))
hv_NinePointDocument.Append("C:\\Hd_Mifengding-1\\env\\628\\FD\\jiudian2.tup");
if (qstring_data.contains("放钉3"))
hv_NinePointDocument.Append("C:\\Hd_Mifengding-1\\env\\628\\FD\\jiudian3.tup");
if (qstring_data.contains("放钉4"))
hv_NinePointDocument.Append("C:\\Hd_Mifengding-1\\env\\628\\FD\\jiudian4.tup");
HalconCpp::HTuple hv_CameraNumber;
if (qstring_data.contains("放钉1"))
hv_CameraNumber.Append(1);
if (qstring_data.contains("放钉2"))
hv_CameraNumber.Append(2);
if (qstring_data.contains("放钉3"))
hv_CameraNumber.Append(3);
if (qstring_data.contains("放钉4"))
hv_CameraNumber.Append(4);*/
//HalconCpp::HTuple hv_model = 1;
//int BiaoDingFlag = 2;
//int YiWuFlag = 2;
//hv_model.Append(m_hv_model); //后续开放参数窗口
//try {
// auto jsonConfig = readJsonFromPath("./config/editableConfig.json");
// BiaoDingFlag = jsonConfig["上钉标定"];
// YiWuFlag = jsonConfig["上钉异物检测"];
// if (BiaoDingFlag != 1)
// {
// hv_model = 0;
// }
// else
// {
// hv_model = 1;
// }
//}
//catch (...) {
// qDebug() << __FUNCTION__ << " line:" << __LINE__ << "getJsonError";
//}
//qDebug() << __FUNCTION__ << " line:" << __LINE__ << "放钉标定::" << BiaoDingFlag;
////hv_model = 1;
//qDebug() << __FUNCTION__ << " line:" << __LINE__ << "放钉标定::" << hv_model.I();
HalconCpp::HObject in_Image = MatToHObject(HikMat[0]);
//<c>* Function Name : _9_shangding < / c>
// <c>* Author : < / c>
// <c>*Description : < / c>
// <c>< / c>
// <c>*Input(HObject) : in_Image, 图像(bmp), < / c>
// <c> < / c>
// <c>*output(HObject) : < / c>
// <c>*Input(HTuple) : in_ProductionType, 生产
// 类别 : 0, 生产模式: 1, 标定模式 < / c>
// <c>* in_CameraNumber, 相机序列号 < / c>
// <c>* in_FilePath1, 模板文件路径; 示例:'./模板文件/' < / c >
// <c>*in_FilePath2, 基准文件路径; < / c>
std::string cameraNumberStr = "1";
if (singal_sign.contains("D19000"))
cameraNumberStr = "2";
else if(singal_sign.contains("D19200"))
cameraNumberStr = "3";
else if (singal_sign.contains("D19400"))
cameraNumberStr = "4";
HDevEngineCpp::HDevProcedure proc("_9_shangding");
HDevProcedureCall procedureCall(proc);
procedureCall.SetInputIconicParamObject("in_Image", in_Image);
procedureCall.SetInputCtrlParamTuple("in_ProductionType", 0);
procedureCall.SetInputCtrlParamTuple("in_CameraNumber", HTuple(cameraNumberStr.c_str()));
procedureCall.SetInputCtrlParamTuple("in_FilePath1", HTuple("./halconFiles/template/"));
procedureCall.SetInputCtrlParamTuple("in_FilePath2", HTuple("./halconFiles/base/"));
procedureCall.Execute();
// <c>*output(HTuple) : < / c>
// <c>*out_Circle, 圆心坐标(y, x, radius) < / c >
// <c>* out_Flag, 算法执行成功标志位, 0 : 算法执行失败 1 : 算法执行成功< / c>
// <c>*out_OffsetX : 模组X轴的补偿量(mm) < / c >
// <c>*out_OffsetY : 模组Y轴的补偿量(mm) < / c >
HTuple out_Circle = procedureCall.GetOutputCtrlParamTuple("out_Circle");
HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");
HTuple out_OffsetX = procedureCall.GetOutputCtrlParamTuple("out_OffsetX");
HTuple out_OffsetY = procedureCall.GetOutputCtrlParamTuple("out_OffsetY");
int outFlag = out_Flag.D();
qDebug() << __FUNCTION__ << " line:" << __LINE__ << "camera::放钉" << "_SN::" << SN << ",放钉算法结果;" << out_Flag[0].D();
if (outFlag == 1){ //-1为失败,无结果
//圆及十字
cv::circle(img_dst, cv::Point(out_Circle[1].D(), out_Circle[0].D()), out_Circle[2].D(), cv::Scalar(0, 255, 0), 20);
cv::line(img_dst, cv::Point(out_Circle[1].D() - 300, out_Circle[0].D()), cv::Point(out_Circle[1].D() + 300, out_Circle[0].D()), cv::Scalar(0, 255, 0), 15);
cv::line(img_dst, cv::Point(out_Circle[1].D(), out_Circle[0].D() - 300), cv::Point(out_Circle[1].D(), out_Circle[0].D() + 300), cv::Scalar(0, 255, 0), 15);
double offsetX = 0 - out_OffsetX.D();
double offsetY = 0 - out_OffsetY.D();
double offsetX;
double offsetY;
//if (cameraKey_index.contains("DA4940802") || cameraKey_index.contains("DA4940782")) {//B Part Camera
// offsetX = out_OffsetX.D();
// offsetY = out_OffsetY.D();
//}
//else {
// offsetX = 0 - out_OffsetX.D();
// offsetY = 0 - out_OffsetY.D();
//}
offsetX = 0 - out_OffsetX.D();
offsetY = 0 - out_OffsetY.D();
QString UP_Down = "X偏移:" + QString::number(offsetX);
QByteArray path_arr = UP_Down.toLocal8Bit();
const char* path = path_arr.data();
putTextZH(img_dst, path, cv::Point(50, 150), cv::Scalar(0, 255, 0), 150, "微软雅黑");
UP_Down = "Y偏移:" + QString::number(offsetY);
path_arr = UP_Down.toLocal8Bit();
path = path_arr.data();
putTextZH(img_dst, path, cv::Point(50, 350), cv::Scalar(0, 255, 0), 150, "微软雅黑");
QString UP_Down = "X偏移:" + QString::number(offsetX);
QByteArray path_arr = UP_Down.toLocal8Bit();
const char* path = path_arr.data();
putTextZH(img_dst, path, cv::Point(50, 100), cv::Scalar(0, 255, 0), 150, "微软雅黑");
UP_Down = "Y偏移:" + QString::number(offsetY);
path_arr = UP_Down.toLocal8Bit();
path = path_arr.data();
putTextZH(img_dst, path, cv::Point(50, 300), cv::Scalar(0, 255, 0), 150, "微软雅黑");
if (abs(offsetX) >= 6000 || abs(offsetY) >= 6000)
UP_Down = "相机:" + QString::fromStdString(cameraNumberStr);
path_arr = UP_Down.toLocal8Bit();
path = path_arr.data();
putTextZH(img_dst, path, cv::Point(50, 0), cv::Scalar(0, 255, 0), 150, "微软雅黑");
if (abs(offsetX) >= 6000 || abs(offsetY) >= 6000)
{
shortData_result = "2";
floatData_offsetX = "-1.1";
floatData_offsetY = "-1.1";
qDebug() << __FUNCTION__ << " line:" << __LINE__ << " 放钉X偏移abs(resultData[0]) >= 6000,may err,set 0";
}
else {
shortData_result = "1";
floatData_offsetX = QString::number(offsetX);
floatData_offsetY = QString::number(offsetY);
}
addImgToSaveStruct(img_dst, "0", getResSaveFormat(SN, okngText));//保存结果图
}
else
{
//resultOKNG = 2;
//resultData[0] = 0;
//resultData[1] = 0;
//QString s;
//if (hv_Make[0].D() == -1)
//{
// s = "算法异常";
//}
//else if (hv_model == 1)
//{
// s = "基准标定";
// cv::circle(img_dst, cv::Point(hv_out_circle[1].D(), hv_out_circle[0].D()), hv_out_circle[2].D(), cv::Scalar(0, 0, 255), 20);
// cv::line(img_dst, cv::Point(hv_out_circle[1].D() - 300, hv_out_circle[0].D()), cv::Point(hv_out_circle[1].D() + 300, hv_out_circle[0].D()), cv::Scalar(0, 0, 255), 15);
// cv::line(img_dst, cv::Point(hv_out_circle[1].D(), hv_out_circle[0].D() - 300), cv::Point(hv_out_circle[1].D(), hv_out_circle[0].D() + 300), cv::Scalar(0, 0, 255), 15);
//}
shortData_result = "2";
floatData_offsetX = "-1.1";
floatData_offsetY = "-1.1";
qDebug() << __FUNCTION__ << " line:" << __LINE__ << " 放钉X偏移abs(resultData[0]) >= 6000,may err,set 0";
putTextZH(img_dst, "算法异常", cv::Point(50, 300), cv::Scalar(0, 0, 255), 150, "微软雅黑");
}
else {
shortData_result = "1";
floatData_offsetX = QString::number(offsetX);
floatData_offsetY = QString::number(offsetY);
if (shortData_result == "1")
{
putTextZH(img_dst, "OK", cv::Point(50, 550), cv::Scalar(0, 255, 0), 150, "微软雅黑");
}
addImgToSaveStruct(img_dst, "0", getResSaveFormat(SN, okngText));//保存结果图
putTextZH(img_dst, "OK", cv::Point(50, 500), cv::Scalar(0, 255, 0), 150, "微软雅黑");
else
{
putTextZH(img_dst, "NG", cv::Point(50, 500), cv::Scalar(0, 0, 255), 150, "微软雅黑");
}
resMat.push_back(img_dst);
//qDebug() << __FUNCTION__ << " line:" << __LINE__ << "camera::放钉:" << hv_CameraNumber.D() << "_SN::" << SN << ",放钉算法结果;" << out_Flag.D();
}
else
{
shortData_result = "2";
floatData_offsetX = "-0.123";
floatData_offsetY = "-0.123";
putTextZH(img_dst, "算法异常", cv::Point(50, 300), cv::Scalar(0, 0, 255), 150, "微软雅黑");
putTextZH(img_dst, "NG", cv::Point(50, 500), cv::Scalar(0, 0, 255), 150, "微软雅黑");
}
resMat.push_back(img_dst);
//qDebug() << __FUNCTION__ << " line:" << __LINE__ << "camera::放钉:" << hv_CameraNumber.D() << "_SN::" << SN << ",放钉算法结果;" << out_Flag.D();
runNum++;
//HikMat.clear();
//qDebug() << __FUNCTION__ << " line:" << __LINE__ << "Mat_name: run end" << "model uesd time::" << stop - start << "ms";
return true;
}
@@ -976,7 +1207,7 @@ bool Hd_YuHang_module::run()
return true;
}
bool Hd_YuHang_module::checkStatus()
bool Hd_ShangDing_module::checkStatus()
{
status = moduleStatus;
return status;
@@ -1,5 +1,5 @@
#ifndef Hd_YuHang_module_H
#define Hd_YuHang_module_H
#ifndef Hd_ShangDing_module_H
#define Hd_ShangDing_module_H
#include <assert.h>
#include <atlstr.h>
@@ -37,14 +37,14 @@ struct saveImgStruct;
// std::string savePath; //保存路径
//};
//初始化流程(一次):Hd_YuHang_module,initParas
//初始化流程(一次):Hd_ShangDing_module,initParas
//运行流程:writeData主线程把数据传过来,run,readData此线程把数据传主线程
class Hd_YuHang_module :public Base
class Hd_ShangDing_module :public Base
{
Q_OBJECT
public:
Hd_YuHang_module();
virtual ~Hd_YuHang_module();
Hd_ShangDing_module();
virtual ~Hd_ShangDing_module();
//从类中读数据到实例对象
bool readData(std::vector<cv::Mat>&,QByteArray&);
//实例对象把数据写入到类
@@ -59,6 +59,13 @@ public:
bool encodeResultValue(QVector<std::string> append_value,QByteArray &resultByte);
bool decodeAiValue(QByteArray byte,QVector<QByteArray> &vec_ret);
//---------检测流程,根据实际项目修改---------
bool AIdetect(cv::Mat img2D, QString saveKey, QString Dir2D, QString SN, QString DataTime);
cv::Mat srcImg1;//电解液图片
cv::Mat srcImg2;
cv::Mat srcImg3;
cv::Mat srcImg4;
cv::Mat workImg;
private:
HDevEngine myEngine;
int allNum = 0;
@@ -78,6 +85,7 @@ private:
//结果路径文件夹队列
QString Dir2D="Dir2D";
//产品SN队列
QString singal_sign = "";
QString SN="SN";
//产品时间戳队列
QString DateTime1="DateTime1";
@@ -126,8 +134,8 @@ private:
extern "C"
{
Q_DECL_EXPORT Hd_YuHang_module * create();
Q_DECL_EXPORT void destory(Hd_YuHang_module * ptr);
Q_DECL_EXPORT Hd_ShangDing_module * create();
Q_DECL_EXPORT void destory(Hd_ShangDing_module * ptr);
}
//保存图片的结构体
struct saveImgStruct
@@ -1,4 +1,4 @@
#include "Hd_FangDing_module.h"
#include "Hd_YuHan_module.h"
#include <QDateTime>
#include <global.h>
#include <QtConcurrent/QtConcurrent>
@@ -27,6 +27,20 @@ using namespace handdleAI;
//总保存文件夹
QString AllImgSaveDir = "D:/CCD/";
//切图的class的width,根据项目实际设置!
static int sizeW = 150;
//切图的class的height,根据项目实际设置!
static int sizeH = 150;
//切图的class的width,根据项目实际设置!0为黑,255为白;
static int fillColour = 0;
pDetection* det_DJY;
pClassification* cls_DJY;
std::string modelPath_det_DJY = "../bin/model/det_DJY.BHD";
std::string modelPath_cls_DJY = "../bin/model/cls_DJY.BHD";
//检测线程锁
QMutex* detect_mutex;
//保存线程锁
@@ -42,8 +56,8 @@ QStringList splitDataList;
QByteArrayList initValueList;
QString sdataTime; //产品名里的时间戳
QString okngText = "OK";
QString shortData_result = "1";//返回给PLC的结果
QString floatData_offsetX = "-1.1", floatData_offsetY = "-1.1";//偏移值
QString shortData_result = "1";
QString floatData_offsetX = "-1.1", floatData_offsetY = "-1.1";
// 缺陷信息结构体
typedef struct {
QString defectName = "";//缺陷名称
@@ -462,15 +476,15 @@ void drawDefects(cv::Mat& sourceMat, QQueue<defectInfo> defectInfoList)
}
}
Hd_FangDing_module* create()
Hd_YuHan_module* create()
{
qDebug() << "[INFO] " << " Hd_FangDing_module create success!" ;
return new Hd_FangDing_module;
qDebug() << "[INFO] " << " Hd_YuHan_module create success!" ;
return new Hd_YuHan_module;
}
void destory(Hd_FangDing_module* ptr)
void destory(Hd_YuHan_module* ptr)
{
qDebug() << "[INFO] " << "Hd_FangDing_module destory success!";
qDebug() << "[INFO] " << "Hd_YuHan_module destory success!";
if(ptr)
{
delete ptr;
@@ -478,14 +492,14 @@ void destory(Hd_FangDing_module* ptr)
}
}
Hd_FangDing_module::Hd_FangDing_module()
Hd_YuHan_module::Hd_YuHan_module()
{
detect_mutex = new QMutex;
saveStruct_mutex = new QMutex;
ifdetectThread = false;
}
Hd_FangDing_module::~Hd_FangDing_module()
Hd_YuHan_module::~Hd_YuHan_module()
{
ifdetectThread = false;
Sleep(10);
@@ -505,10 +519,8 @@ Hd_FangDing_module::~Hd_FangDing_module()
static int defectNums = 0;
//static cv::Mat resMat;
//从类中读数据到实例对象
bool Hd_FangDing_module::readData(std::vector<cv::Mat>&vec_mat,QByteArray &data)
bool Hd_YuHan_module::readData(std::vector<cv::Mat>&vec_mat,QByteArray &data)
{
if (HikMat[0].cols == 200)
return true;
detect_mutex->lock();
//qDebug() << __FUNCTION__ << " line:" <<__LINE__ << " data len:" << data.length();
if (resMat.size() > 0)
@@ -522,7 +534,13 @@ bool Hd_FangDing_module::readData(std::vector<cv::Mat>&vec_mat,QByteArray &data)
qDebug() << __FUNCTION__ << " line:" << __LINE__ << " resMat.data err:";
}
data = logicUiTransport::encodeAllData(SN, {floatData_offsetX,floatData_offsetY,shortData_result }, {});
if (singal_sign.contains("D19600") || singal_sign.contains("D19800")) {
data = logicUiTransport::encodeAllData(SN, { floatData_offsetX,floatData_offsetY,shortData_result,0,0,0 }, {});
}
else {
data = logicUiTransport::encodeAllData(SN, {0,0,0,floatData_offsetX,floatData_offsetY,shortData_result }, {});
}
resByte.clear();
addImgToSaveStruct(HikMat[0], "0", getOriSaveFormat(SN, okngText));//保存原图
//{
@@ -555,7 +573,7 @@ bool Hd_FangDing_module::readData(std::vector<cv::Mat>&vec_mat,QByteArray &data)
return true;
}
//从类中读数据到实例对象
bool Hd_FangDing_module::encodeResultValue(QVector<std::string> append_value,QByteArray &resultByte)
bool Hd_YuHan_module::encodeResultValue(QVector<std::string> append_value,QByteArray &resultByte)
{
try
{
@@ -591,7 +609,7 @@ bool Hd_FangDing_module::encodeResultValue(QVector<std::string> append_value,QBy
//接收数据
bool Hd_FangDing_module::writeData(std::vector<cv::Mat>& vec_mat, QByteArray &data)
bool Hd_YuHan_module::writeData(std::vector<cv::Mat>& vec_mat, QByteArray &data)
{
qDebug() << __FUNCTION__ << "line:" << __LINE__ << " data:" << data;
if (vec_mat.empty())
@@ -614,6 +632,7 @@ bool Hd_FangDing_module::writeData(std::vector<cv::Mat>& vec_mat, QByteArray &da
//QByteArray source_savePath;
sData = byteArrayToUnicode(data);
splitDataList = sData.split(',');
singal_sign = splitDataList[1];
SN = splitDataList[3];
cameraKey_index = splitDataList[2];
sdataTime = QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz");
@@ -623,7 +642,7 @@ bool Hd_FangDing_module::writeData(std::vector<cv::Mat>& vec_mat, QByteArray &da
return true;
}
//初始化
bool Hd_FangDing_module::initParas(QByteArray& byte)
bool Hd_YuHan_module::initParas(QByteArray& byte)
{
initValueList = byte.split('+');
@@ -658,9 +677,9 @@ bool Hd_FangDing_module::initParas(QByteArray& byte)
////线程检测:结果类完成时,使用
////ifThreadRunDetect = true;
////QFuture<void> future1 = QtConcurrent::run(this, &Hd_FangDing_module::detectThread);
////QFuture<void> future1 = QtConcurrent::run(this, &Hd_YuHan_module::detectThread);
//运行存图线程
QFuture<void> future2 = QtConcurrent::run(this, &Hd_FangDing_module::saveImgThread);
QFuture<void> future2 = QtConcurrent::run(this, &Hd_YuHan_module::saveImgThread);
//cv::Mat initimg = cv::imread("../bin/initimg.bmp");
//if (initimg.channels() == 3)
@@ -673,7 +692,7 @@ bool Hd_FangDing_module::initParas(QByteArray& byte)
return true;
}
bool Hd_FangDing_module::InitModels()
bool Hd_YuHan_module::InitModels()
{
int flag = 0;
//seg_aokeng = CreateSegObjS((char*)modelPath_seg_aokeng.c_str(), 1, 0); if (seg_aokeng->getStatus() != SegStatus::Seg_Success)flag++;
@@ -687,7 +706,7 @@ bool Hd_FangDing_module::InitModels()
return (flag == 0);
}
// 解码
bool Hd_FangDing_module::decodeAiValue(QByteArray byte,QVector<QByteArray> &vec_ret)
bool Hd_YuHan_module::decodeAiValue(QByteArray byte,QVector<QByteArray> &vec_ret)
{
if(byte.isEmpty())
{
@@ -722,8 +741,113 @@ bool Hd_FangDing_module::decodeAiValue(QByteArray byte,QVector<QByteArray> &vec_
return true;
}
//---------检测流程,根据实际项目修改---------
bool Hd_YuHan_module::AIdetect(cv::Mat img2D, QString mysaveKey, QString myDir2D, QString mySN, QString myDataTime)
{
/*try
{*/
//存图数据加保存队列,加锁,避免数据访问冲突
saveStruct_mutex->lock();
saveImgStruct mySave;
Mat sourceImg, sourceImg1, sourceImg2;
sourceImg = img2D.clone();
//img2D.copyTo(sourceImg);
//img2D.release();
QString mysaveKey1 = mysaveKey; //"offlineStation1_off_1"
saveStruct_mutex->unlock();
QJsonDocument document;
QJsonObject obj;
obj.insert("result_key", "mysaveKey");
obj.insert("SN", "mySN");
obj.insert("DataTime", "myDataTime");
//QFile csvName("test.csv");
//QStringList lines;
//lines << "class,name\n" << "3,4,5,6,7\n" << "a,b,c,d\n";
//if (csvName.open(QIODevice::WriteOnly)) //若文件不存在,会自动创建
//{
// for (int i = 0; i < lines.size(); i++)
// csvName.write(lines[i].toStdString().c_str());
// csvName.close();
//}
QQueue<defectInfo> defectInfoList;
detect_mutex->lock();
//结果图画框和缺陷,在resMat上绘制
/*if (resMat.size() > 0)
drawDefects(resMat[0], defectInfoList);*/
//QByteArray,根据实际项目进行解析
//参数,例:返回结果图;相机关键字(SN或userID)+保存路径+缺陷信息列表(缺陷名称,缺陷位置int(x,y,w,h),画框颜色Scalar(a,b,c),缺陷面积double)
QJsonArray detaillists;
//QByteArrayList resQbyte;
for (int i = 0; i < defectInfoList.size(); i++)
{
defectInfo mdefect = defectInfoList[i];
//resQbyte.push_back(mdefect.defectName.toLocal8Bit()); //中文也可以QString::number(1.1).toUtf8()
//resQbyte.push_back(QString::number(mdefect.defectRect.x).toUtf8());
//resQbyte.push_back(QString::number(mdefect.defectRect.y).toUtf8());
//resQbyte.push_back(QString::number(mdefect.defectRect.width).toUtf8());
//resQbyte.push_back(QString::number(mdefect.defectRect.height).toUtf8());
//resQbyte.push_back(QString::number(mdefect.defectScalar[0]).toUtf8());
//resQbyte.push_back(QString::number(mdefect.defectScalar[1]).toUtf8());
//resQbyte.push_back(QString::number(mdefect.defectScalar[2]).toUtf8());
//resQbyte.push_back(QString::number(mdefect.defectArea).toUtf8());
QJsonObject detailObj;
detailObj.insert("defectName", "mdefect.defectName");
detailObj.insert("defectRect.x", QString::number(mdefect.defectRect.x));
detailObj.insert("defectRect.y", QString::number(mdefect.defectRect.y));
detailObj.insert("defectRect.width", QString::number(mdefect.defectRect.width));
detailObj.insert("defectRect.height", QString::number(mdefect.defectRect.height));
detailObj.insert("defectScalar0", QString::number(mdefect.defectScalar[0]));
detailObj.insert("defectScalar1", QString::number(mdefect.defectScalar[1]));
detailObj.insert("defectScalar2", QString::number(mdefect.defectScalar[2]));
detailObj.insert("defectArea", QString::number(mdefect.defectArea));
detailObj.insert("defectLength", QString::number(sqrt(mdefect.defectRect.width* mdefect.defectRect.width+ mdefect.defectRect.height* mdefect.defectRect.height)));
detaillists.append(detailObj);
}
//使用完删除
defectInfoList.clear();
/* isDirExist(resImgSaveDir + mysaveKey1 + "/");
QString qimgsavePath = resImgSaveDir + mysaveKey1 + "/" + mySN + myDataTime + ".jpg";*/
//存图数据入队,按需
/*if (resMat.size() > 0 )
addImgToSaveStruct(resMat[0], mysaveKey1, resImgSaveDir + mysaveKey1 + "/" + mySN + myDataTime + ".jpg");*/
detect_mutex->unlock();
obj.insert("detaillists", detaillists);
//obj.insert("qimgsavePath", qimgsavePath);
document.setObject(obj);
QByteArray qa = document.toJson();
mySave.out_Mat.resize(0);
mysaveKey1.clear();
qApp->processEvents();
/* }
catch (...)
{
qDebug() << "[Error] " << QString::fromUtf8("检测失败!");
hv_Image.clear();
number = 0;
return false;
}*/
return true;
}
//存图加入队列
void Hd_FangDing_module::addImgToSaveStruct(cv::Mat img2D, QString mysaveKey, std::pair<QString, QString> savePath)
void Hd_YuHan_module::addImgToSaveStruct(cv::Mat img2D, QString mysaveKey, std::pair<QString, QString> savePath)
{
//存图数据加保存队列,加锁,避免数据访问冲突
saveStruct_mutex->lock();
@@ -736,7 +860,7 @@ void Hd_FangDing_module::addImgToSaveStruct(cv::Mat img2D, QString mysaveKey, st
saveStruct.enqueue(mySave);
saveStruct_mutex->unlock();
}
void Hd_FangDing_module::saveImgThread()
void Hd_YuHan_module::saveImgThread()
{
while (1)
{
@@ -767,7 +891,7 @@ void Hd_FangDing_module::saveImgThread()
}
}
//检测线程,应当只运行一次
void Hd_FangDing_module::detectThread()
void Hd_YuHan_module::detectThread()
{
do
{
@@ -822,13 +946,27 @@ void Hd_FangDing_module::detectThread()
}
bool Hd_FangDing_module::run()
bool myMath(double a, double b)
{
return a > b;
}
static int runNum = 0;
QQueue<double> timeAll_A;
QQueue<double> timeAll_B;
bool Hd_YuHan_module::run()
{
try
{
shortData_result = "0";
floatData_offsetX = "0";
floatData_offsetY = "0";
defectNums = 0;
cv::Mat resImg1, resImg2;
//cv::Mat mat;
float prob = 0;
if (HikMat.isEmpty())
{
shortData_result = "2";
@@ -837,7 +975,7 @@ bool Hd_FangDing_module::run()
return true;
}
if (HikMat.isEmpty() || HikMat[0].rows < 200 || HikMat[0].cols < 200)//超时补图
if (HikMat.isEmpty() || HikMat[0].rows < 200 || HikMat[0].cols < 200)
{
shortData_result = "2";
cv::Mat null_mat = cv::Mat::zeros(cv::Size(100, 100), CV_8UC3);
@@ -845,114 +983,214 @@ bool Hd_FangDing_module::run()
return true;
}
cv::Mat srcImg;
if (HikMat[0].channels() == 3)// && (qstring_data.contains("jizu") || qstring_data.contains("fangbaofa")))
cv::cvtColor(HikMat[0], srcImg, COLOR_BGR2GRAY);
else
srcImg = HikMat[0];
cv::Mat img_dst;
cvtColor(HikMat[0], img_dst, cv::COLOR_GRAY2BGR);
//hv_model.Append(m_hv_model); //后续开放参数窗口
//try {
// auto jsonConfig = readJsonFromPath("./config/editableConfig.json");
// BiaoDingFlag = jsonConfig["上钉标定"];
// YiWuFlag = jsonConfig["上钉异物检测"];
// if (BiaoDingFlag != 1)
// {
// hv_model = 0;
// }
//if (splitDataList[1].contains("20400_2") || splitDataList[1].contains("20600_2") ||
// splitDataList[1].contains("20800_2") || splitDataList[1].contains("21000_2"))
//{
// cv::Mat srcImg;
// if (HikMat[0].channels() == 3)// && (qstring_data.contains("jizu") || qstring_data.contains("fangbaofa")))
// cv::cvtColor(HikMat[0], srcImg, COLOR_BGR2GRAY);
// else
// {
// hv_model = 1;
// }
// srcImg = HikMat[0];
// cv::Mat img_dst;
// cvtColor(HikMat[0], img_dst, cv::COLOR_GRAY2BGR);
// resMat.push_back(img_dst);
// //qDebug() << __FUNCTION__ << " line:" << __LINE__ << "camera::放钉" << "_SN::" << SN << splitDataList[1].split("_")[0] << "_" << stop - start << "ms";
// //return true;
//}
//catch (...) {
// qDebug() << __FUNCTION__ << " line:" << __LINE__ << "getJsonError";
//}
//qDebug() << __FUNCTION__ << " line:" << __LINE__ << "放钉标定::" << BiaoDingFlag;
////hv_model = 1;
//qDebug() << __FUNCTION__ << " line:" << __LINE__ << "放钉标定::" << hv_model.I();
HalconCpp::HObject in_Image = MatToHObject(HikMat[0]);
//<c>* Function Name : _9_shangding < / c>
// <c>* Author : < / c>
// <c>*Description : < / c>
// <c>< / c>
// <c>*Input(HObject) : in_Image, 图像(bmp), < / c>
// <c> < / c>
// <c>*output(HObject) : < / c>
// <c>*Input(HTuple) : in_ProductionType, 生产类别 : 0, 生产模式: 1, 标定模式 < / c>
// <c>* in_CameraNumber, 相机序列号 < / c>
// <c>* in_FilePath1, 模板文件路径; 示例:'./模板文件/' < / c >
// <c>*in_FilePath2, 基准文件路径; < / c>
std::string cameraNumberStr = "1";
if (cameraKey_index == "DA4940770_0")
cameraNumberStr = "2";
HDevEngineCpp::HDevProcedure proc("_9_shangding");
HDevProcedureCall procedureCall(proc);
procedureCall.SetInputIconicParamObject("in_Image", in_Image);
procedureCall.SetInputCtrlParamTuple("in_ProductionType", 0);
procedureCall.SetInputCtrlParamTuple("in_CameraNumber", HTuple(cameraNumberStr.c_str()));
procedureCall.SetInputCtrlParamTuple("in_FilePath1", HTuple("./halconFiles/template/"));
procedureCall.SetInputCtrlParamTuple("in_FilePath2", HTuple("./halconFiles/base/"));
procedureCall.Execute();
// <c>*output(HTuple) : < / c>
// <c>*out_Circle, 圆心坐标(y, x, radius) < / c >
// <c>* out_Flag, 算法执行成功标志位, 0 : 算法执行失败 1 : 算法执行成功< / c>
// <c>*out_OffsetX : 模组X轴的补偿量(mm) < / c >
// <c>*out_OffsetY : 模组Y轴的补偿量(mm) < / c >
HTuple out_Circle = procedureCall.GetOutputCtrlParamTuple("out_Circle");
HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");
HTuple out_OffsetX = procedureCall.GetOutputCtrlParamTuple("out_OffsetX");
HTuple out_OffsetY = procedureCall.GetOutputCtrlParamTuple("out_OffsetY");
int outFlag = out_Flag.D();
qDebug() << __FUNCTION__ << " line:" << __LINE__ << "camera::放钉" << "_SN::" << SN << ",放钉算法结果;" << out_Flag[0].D();
if (outFlag == 1){ //-1为失败,无结果
//圆及十字
cv::circle(img_dst, cv::Point(out_Circle[1].D(), out_Circle[0].D()), out_Circle[2].D(), cv::Scalar(0, 255, 0), 20);
cv::line(img_dst, cv::Point(out_Circle[1].D() - 300, out_Circle[0].D()), cv::Point(out_Circle[1].D() + 300, out_Circle[0].D()), cv::Scalar(0, 255, 0), 15);
cv::line(img_dst, cv::Point(out_Circle[1].D(), out_Circle[0].D() - 300), cv::Point(out_Circle[1].D(), out_Circle[0].D() + 300), cv::Scalar(0, 255, 0), 15);
//if (splitDataList[1].contains("放钉"))
{
cv::Mat srcImg;
if (HikMat[0].channels() == 3)// && (qstring_data.contains("jizu") || qstring_data.contains("fangbaofa")))
cv::cvtColor(HikMat[0], srcImg, COLOR_BGR2GRAY);
else
srcImg = HikMat[0];
cv::Mat img_dst;
cvtColor(HikMat[0], img_dst, cv::COLOR_GRAY2BGR);
/* HalconCpp::HTuple hv_BenchmarkFile;
hv_BenchmarkFile.Append("C:\\Hd_Mifengding-1\\env\\628\\FD\\");
HalconCpp::HTuple hv_NinePointDocument;
if (qstring_data.contains("放钉1"))
hv_NinePointDocument.Append("C:\\Hd_Mifengding-1\\env\\628\\FD\\jiudian1.tup");
if (qstring_data.contains("放钉2"))
hv_NinePointDocument.Append("C:\\Hd_Mifengding-1\\env\\628\\FD\\jiudian2.tup");
if (qstring_data.contains("放钉3"))
hv_NinePointDocument.Append("C:\\Hd_Mifengding-1\\env\\628\\FD\\jiudian3.tup");
if (qstring_data.contains("放钉4"))
hv_NinePointDocument.Append("C:\\Hd_Mifengding-1\\env\\628\\FD\\jiudian4.tup");
HalconCpp::HTuple hv_CameraNumber;
if (qstring_data.contains("放钉1"))
hv_CameraNumber.Append(1);
if (qstring_data.contains("放钉2"))
hv_CameraNumber.Append(2);
if (qstring_data.contains("放钉3"))
hv_CameraNumber.Append(3);
if (qstring_data.contains("放钉4"))
hv_CameraNumber.Append(4);*/
//HalconCpp::HTuple hv_model = 1;
//int BiaoDingFlag = 2;
//int YiWuFlag = 2;
//hv_model.Append(m_hv_model); //后续开放参数窗口
//try {
// auto jsonConfig = readJsonFromPath("./config/editableConfig.json");
// BiaoDingFlag = jsonConfig["上钉标定"];
// YiWuFlag = jsonConfig["上钉异物检测"];
// if (BiaoDingFlag != 1)
// {
// hv_model = 0;
// }
// else
// {
// hv_model = 1;
// }
//}
//catch (...) {
// qDebug() << __FUNCTION__ << " line:" << __LINE__ << "getJsonError";
//}
//qDebug() << __FUNCTION__ << " line:" << __LINE__ << "放钉标定::" << BiaoDingFlag;
////hv_model = 1;
//qDebug() << __FUNCTION__ << " line:" << __LINE__ << "放钉标定::" << hv_model.I();
HalconCpp::HObject in_Image = MatToHObject(HikMat[0]);
//<c>* Function Name : _9_shangding < / c>
// <c>* Author : < / c>
// <c>*Description : < / c>
// <c>< / c>
// <c>*Input(HObject) : in_Image, 图像(bmp), < / c>
// <c> < / c>
// <c>*output(HObject) : < / c>
// <c>*Input(HTuple) : in_ProductionType, 生产
// 类别 : 0, 生产模式: 1, 标定模式 < / c>
// <c>* in_CameraNumber, 相机序列号 < / c>
// <c>* in_FilePath1, 模板文件路径; 示例:'./模板文件/' < / c >
// <c>*in_FilePath2, 基准文件路径; < / c>
std::string cameraNumberStr = "1", FixtureNumber = "1";
if (singal_sign.contains("D19600")) {
cameraNumberStr = "1";
FixtureNumber = "1";
}
else if(singal_sign.contains("D19602")) {
cameraNumberStr = "1";
FixtureNumber = "2";
}
else if (singal_sign.contains("D19800")) {
cameraNumberStr = "2";
FixtureNumber = "1";
}
else if (singal_sign.contains("D19802")) {
cameraNumberStr = "2";
FixtureNumber = "2";
}
HDevEngineCpp::HDevProcedure proc("_9_yuhan");
HDevProcedureCall procedureCall(proc);
procedureCall.SetInputIconicParamObject("in_Image", in_Image);
procedureCall.SetInputCtrlParamTuple("in_ProductionType", 0);
procedureCall.SetInputCtrlParamTuple("in_CameraNumber", HTuple(cameraNumberStr.c_str()));
procedureCall.SetInputCtrlParamTuple("in_FixtureNumber", HTuple(FixtureNumber.c_str()));
procedureCall.SetInputCtrlParamTuple("in_FilePath1", HTuple("./halconFiles/template/"));
procedureCall.SetInputCtrlParamTuple("in_FilePath2", HTuple("./halconFiles/base/"));
procedureCall.Execute();
// <c>*output(HTuple) : < / c>
// <c>*out_Circle, 圆心坐标(y, x, radius) < / c >
// <c>* out_Flag, 算法执行成功标志位, 0 : 算法执行失败 1 : 算法执行成功< / c>
// <c>*out_OffsetX : 模组X轴的补偿量(mm) < / c >
// <c>*out_OffsetY : 模组Y轴的补偿量(mm) < / c >
HTuple out_Circle = procedureCall.GetOutputCtrlParamTuple("out_Circle");
HTuple out_Flag = procedureCall.GetOutputCtrlParamTuple("out_Flag");
HTuple out_OffsetX = procedureCall.GetOutputCtrlParamTuple("out_OffsetX");
HTuple out_OffsetY = procedureCall.GetOutputCtrlParamTuple("out_OffsetY");
int outFlag = out_Flag.D();
qDebug() << __FUNCTION__ << " line:" << __LINE__ << "camera::放钉" << "_SN::" << SN << ",放钉算法结果;" << out_Flag[0].D();
if (outFlag == 1){ //-1为失败,无结果
//圆及十字
cv::circle(img_dst, cv::Point(out_Circle[1].D(), out_Circle[0].D()), out_Circle[2].D(), cv::Scalar(0, 255, 0), 20);
cv::line(img_dst, cv::Point(out_Circle[1].D() - 300, out_Circle[0].D()), cv::Point(out_Circle[1].D() + 300, out_Circle[0].D()), cv::Scalar(0, 255, 0), 15);
cv::line(img_dst, cv::Point(out_Circle[1].D(), out_Circle[0].D() - 300), cv::Point(out_Circle[1].D(), out_Circle[0].D() + 300), cv::Scalar(0, 255, 0), 15);
double offsetX = 0 - out_OffsetX.D();
double offsetY = 0 - out_OffsetY.D();
double offsetX;
double offsetY;
//if (cameraKey_index.contains("DA4940802") || cameraKey_index.contains("DA4940782")) {//B Part Camera
// offsetX = out_OffsetX.D();
// offsetY = out_OffsetY.D();
//}
//else {
// offsetX = 0 - out_OffsetX.D();
// offsetY = 0 - out_OffsetY.D();
//}
offsetX = 0 - out_OffsetX.D();
offsetY = 0 - out_OffsetY.D();
QString UP_Down = "X偏移:" + QString::number(offsetX);
QByteArray path_arr = UP_Down.toLocal8Bit();
const char* path = path_arr.data();
putTextZH(img_dst, path, cv::Point(50, 150), cv::Scalar(0, 255, 0), 150, "微软雅黑");
UP_Down = "Y偏移:" + QString::number(offsetY);
path_arr = UP_Down.toLocal8Bit();
path = path_arr.data();
putTextZH(img_dst, path, cv::Point(50, 350), cv::Scalar(0, 255, 0), 150, "微软雅黑");
QString UP_Down = "X偏移:" + QString::number(offsetX);
QByteArray path_arr = UP_Down.toLocal8Bit();
const char* path = path_arr.data();
putTextZH(img_dst, path, cv::Point(50, 100), cv::Scalar(0, 255, 0), 150, "微软雅黑");
UP_Down = "Y偏移:" + QString::number(offsetY);
path_arr = UP_Down.toLocal8Bit();
path = path_arr.data();
putTextZH(img_dst, path, cv::Point(50, 300), cv::Scalar(0, 255, 0), 150, "微软雅黑");
if (abs(offsetX) >= 6000 || abs(offsetY) >= 6000)
UP_Down = "相机:" + QString::fromStdString(cameraNumberStr);
path_arr = UP_Down.toLocal8Bit();
path = path_arr.data();
putTextZH(img_dst, path, cv::Point(50, 0), cv::Scalar(0, 255, 0), 150, "微软雅黑");
if (abs(offsetX) >= 6000 || abs(offsetY) >= 6000)
{
shortData_result = "2";
floatData_offsetX = "-1.1";
floatData_offsetY = "-1.1";
qDebug() << __FUNCTION__ << " line:" << __LINE__ << " 放钉X偏移abs(resultData[0]) >= 6000,may err,set 0";
}
else {
shortData_result = "1";
floatData_offsetX = QString::number(offsetX);
floatData_offsetY = QString::number(offsetY);
}
addImgToSaveStruct(img_dst, "0", getResSaveFormat(SN, okngText));//保存结果图
}
else
{
//resultOKNG = 2;
//resultData[0] = 0;
//resultData[1] = 0;
//QString s;
//if (hv_Make[0].D() == -1)
//{
// s = "算法异常";
//}
//else if (hv_model == 1)
//{
// s = "基准标定";
// cv::circle(img_dst, cv::Point(hv_out_circle[1].D(), hv_out_circle[0].D()), hv_out_circle[2].D(), cv::Scalar(0, 0, 255), 20);
// cv::line(img_dst, cv::Point(hv_out_circle[1].D() - 300, hv_out_circle[0].D()), cv::Point(hv_out_circle[1].D() + 300, hv_out_circle[0].D()), cv::Scalar(0, 0, 255), 15);
// cv::line(img_dst, cv::Point(hv_out_circle[1].D(), hv_out_circle[0].D() - 300), cv::Point(hv_out_circle[1].D(), hv_out_circle[0].D() + 300), cv::Scalar(0, 0, 255), 15);
//}
shortData_result = "2";
floatData_offsetX = "-1.1";
floatData_offsetY = "-1.1";
qDebug() << __FUNCTION__ << " line:" << __LINE__ << " 放钉X偏移abs(resultData[0]) >= 6000,may err,set 0";
putTextZH(img_dst, "算法异常", cv::Point(50, 300), cv::Scalar(0, 0, 255), 150, "微软雅黑");
}
else {
shortData_result = "1";
floatData_offsetX = QString::number(offsetX);
floatData_offsetY = QString::number(offsetY);
if (shortData_result == "1")
{
putTextZH(img_dst, "OK", cv::Point(50, 550), cv::Scalar(0, 255, 0), 150, "微软雅黑");
}
addImgToSaveStruct(img_dst, "0", getResSaveFormat(SN, okngText));//保存结果图
putTextZH(img_dst, "OK", cv::Point(50, 500), cv::Scalar(0, 255, 0), 150, "微软雅黑");
else
{
putTextZH(img_dst, "NG", cv::Point(50, 500), cv::Scalar(0, 0, 255), 150, "微软雅黑");
}
resMat.push_back(img_dst);
//qDebug() << __FUNCTION__ << " line:" << __LINE__ << "camera::放钉:" << hv_CameraNumber.D() << "_SN::" << SN << ",放钉算法结果;" << out_Flag.D();
}
else
{
shortData_result = "2";
floatData_offsetX = "-0.123";
floatData_offsetY = "-0.123";
putTextZH(img_dst, "算法异常", cv::Point(50, 300), cv::Scalar(0, 0, 255), 150, "微软雅黑");
putTextZH(img_dst, "NG", cv::Point(50, 500), cv::Scalar(0, 0, 255), 150, "微软雅黑");
}
resMat.push_back(img_dst);
//qDebug() << __FUNCTION__ << " line:" << __LINE__ << "camera::放钉:" << hv_CameraNumber.D() << "_SN::" << SN << ",放钉算法结果;" << out_Flag.D();
runNum++;
//HikMat.clear();
//qDebug() << __FUNCTION__ << " line:" << __LINE__ << "Mat_name: run end" << "model uesd time::" << stop - start << "ms";
return true;
}
@@ -981,7 +1219,7 @@ bool Hd_FangDing_module::run()
return true;
}
bool Hd_FangDing_module::checkStatus()
bool Hd_YuHan_module::checkStatus()
{
status = moduleStatus;
return status;
@@ -1,5 +1,5 @@
#ifndef Hd_FangDing_module_H
#define Hd_FangDing_module_H
#ifndef Hd_YuHan_module_H
#define Hd_YuHan_module_H
#include <assert.h>
#include <atlstr.h>
@@ -37,14 +37,14 @@ struct saveImgStruct;
// std::string savePath; //保存路径
//};
//初始化流程(一次):Hd_FangDing_module,initParas
//初始化流程(一次):Hd_YuHan_module,initParas
//运行流程:writeData主线程把数据传过来,run,readData此线程把数据传主线程
class Hd_FangDing_module :public Base
class Hd_YuHan_module :public Base
{
Q_OBJECT
public:
Hd_FangDing_module();
virtual ~Hd_FangDing_module();
Hd_YuHan_module();
virtual ~Hd_YuHan_module();
//从类中读数据到实例对象
bool readData(std::vector<cv::Mat>&,QByteArray&);
//实例对象把数据写入到类
@@ -59,6 +59,13 @@ public:
bool encodeResultValue(QVector<std::string> append_value,QByteArray &resultByte);
bool decodeAiValue(QByteArray byte,QVector<QByteArray> &vec_ret);
//---------检测流程,根据实际项目修改---------
bool AIdetect(cv::Mat img2D, QString saveKey, QString Dir2D, QString SN, QString DataTime);
cv::Mat srcImg1;//电解液图片
cv::Mat srcImg2;
cv::Mat srcImg3;
cv::Mat srcImg4;
cv::Mat workImg;
private:
HDevEngine myEngine;
int allNum = 0;
@@ -78,6 +85,7 @@ private:
//结果路径文件夹队列
QString Dir2D="Dir2D";
//产品SN队列
QString singal_sign = "";
QString SN="SN";
//产品时间戳队列
QString DateTime1="DateTime1";
@@ -126,8 +134,8 @@ private:
extern "C"
{
Q_DECL_EXPORT Hd_FangDing_module * create();
Q_DECL_EXPORT void destory(Hd_FangDing_module * ptr);
Q_DECL_EXPORT Hd_YuHan_module * create();
Q_DECL_EXPORT void destory(Hd_YuHan_module * ptr);
}
//保存图片的结构体
struct saveImgStruct
@@ -134,8 +134,8 @@ bool connectDevice()
MV_CC_CreateHandle(&handle, m_stDevList.pDeviceInfo[index]);
int nRet = MV_CC_OpenDevice(handle);
////触发模式
MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_LINE0);
MV_CC_SetEnumValue(handle, "TriggerMode", MV_TRIGGER_MODE_ON);
MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_SOFTWARE);
// //加载用户集,相机设置应当UserSet1
nRet = MV_CC_SetEnumValueByString(handle, "UserSetSelector", "UserSet1");
if (MV_OK != nRet)
@@ -311,11 +311,10 @@ Hd_CameraModule_HIK_hard_PCIE::Hd_CameraModule_HIK_hard_PCIE()
//关闭设备
void CloseDevice()
{
unsigned int nRet = MV_CC_StopGrabbing(handle);
CloseHandle(handle);
//nRet = MV_CC_CloseDevice(handle);
//nRet = MV_CC_DestroyHandle(handle);
MV_CC_StopGrabbing(handle);
MV_CC_CloseDevice(handle);
MV_CC_DestroyHandle(handle);
handle = nullptr; //此处注释掉的话,软件断开再连接,回调函数不出图
}
Hd_CameraModule_HIK_hard_PCIE::~Hd_CameraModule_HIK_hard_PCIE()
{
@@ -483,7 +482,7 @@ bool Hd_CameraModule_HIK_hard_PCIE::run()
bool result = false;
ifRunning = true;
ifBreak = false;
//MV_CC_SetCommandValue(handle, "TriggerSoftware");
try
{
m_flag = false;
@@ -497,6 +496,8 @@ bool Hd_CameraModule_HIK_hard_PCIE::run()
imgShouldGetIndex++;
return true;
}
else
MV_CC_SetCommandValue(handle, "TriggerSoftware");
imgShouldGetIndex++;
}
int cnt = 0;