1216 lines
45 KiB
C++
1216 lines
45 KiB
C++
#include "Hd_ShangDing_module.h"
|
||
#include <QDateTime>
|
||
#include <global.h>
|
||
#include <QtConcurrent/QtConcurrent>
|
||
#include <qfuture.h>
|
||
#include "nlohmannJson.hpp"
|
||
#include "generalJsonParsing.hpp"
|
||
#include <filesystem>
|
||
////逻辑UI头文件
|
||
//
|
||
//#include "CPPTaskLoader/pbloadtask.h"
|
||
//
|
||
//#include "io.h"
|
||
//#include <direct.h>
|
||
//#include <stdio.h>
|
||
//#include <iterator>
|
||
//#include <regex>
|
||
|
||
//628算法
|
||
#include <handleAI.h>
|
||
#pragma execution_character_set("utf-8")
|
||
using namespace cv;
|
||
using namespace std;
|
||
using namespace handdleAI;
|
||
//using namespace HalconCpp;
|
||
|
||
//总保存文件夹
|
||
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;
|
||
//保存线程锁
|
||
QMutex* saveStruct_mutex;
|
||
//检测线程运行标志
|
||
bool ifdetectThread = false;
|
||
//检测标志
|
||
QString qstring_data;
|
||
QString cameraKey_index = "";
|
||
QString sData;
|
||
QStringList splitDataList;
|
||
//初始化参数列表
|
||
QByteArrayList initValueList;
|
||
QString sdataTime; //产品名里的时间戳
|
||
QString okngText = "OK";
|
||
QString shortData_result = "1";
|
||
QString floatData_offsetX = "-1.1", floatData_offsetY = "-1.1";
|
||
// 缺陷信息结构体
|
||
typedef struct {
|
||
QString defectName = "";//缺陷名称
|
||
cv::Rect defectRect = { 0,0,0,0 };//缺陷位置
|
||
cv::Scalar defectScalar = cv::Scalar(0, 0, 0);//画框颜色
|
||
double defectArea = 0;//缺陷真实面积
|
||
double defectDepth = 0;//缺陷深度/高度,3D信息
|
||
}defectInfo;
|
||
|
||
static void createDirectoryIfNotExists(const QString& path) {
|
||
QDir dir;
|
||
dir.mkpath(path);
|
||
}
|
||
|
||
static std::string getCurrentTime() {
|
||
|
||
// 获取当前时间点
|
||
auto now = std::chrono::system_clock::now();
|
||
|
||
// 转换为字符串
|
||
auto currentTime = std::chrono::system_clock::to_time_t(now);
|
||
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 100;
|
||
std::tm* localTime = std::localtime(¤tTime);
|
||
std::stringstream ss;
|
||
ss << std::put_time(localTime, "%H-%M-%S") << "-" << std::setfill('0') << std::setw(2) << ms.count();
|
||
return ss.str();
|
||
}
|
||
static QString getCurrentDate()
|
||
{
|
||
QDateTime currentDateTime = QDateTime::currentDateTime();
|
||
return currentDateTime.toString("yyyy-MM-dd");
|
||
}
|
||
static QString getCurrentHour()
|
||
{
|
||
QDateTime currentDateTime = QDateTime::currentDateTime();
|
||
return QString::number(currentDateTime.time().hour()) + "H";
|
||
}
|
||
|
||
std::pair<QString, QString> getResSaveFormat(QString SN, QString okNgText = "", int count = 0)
|
||
{
|
||
QString path = AllImgSaveDir + "//" + getCurrentDate() + "//结果图//" + splitDataList[1].split("_")[0] + "//" + getCurrentHour() + "//" + okNgText + "//";
|
||
return { path,path + SN + "_" + cameraKey_index + "_" + sdataTime + ".jpg" };
|
||
//QString path = resImgSaveDir + getCurrentDate() + "//结果图//" + getCurrentHour() + "//" + okNgText + "//" + SN + "//";
|
||
//return { path,path + SN + "_" + cameraKey_index + "_" + QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz") + "_" + okNgText + ".jpg" };
|
||
}
|
||
std::pair<QString, QString> getOriSaveFormat(QString SN, QString okNgText = "", int count = 0)
|
||
{
|
||
QString path = AllImgSaveDir + "//" + getCurrentDate() + "//原图//" + splitDataList[1].split("_")[0] + "//" + getCurrentHour() + "//";
|
||
return{ path, path + SN + "_" + cameraKey_index + "_" + okNgText + "_" + sdataTime + ".bmp" };
|
||
//QString path = oriImgSaveDir + getCurrentDate() + "//原图//" + getCurrentHour() + "//" + okNgText + "//" + SN + "//";
|
||
//return{ path, path + SN + "_" + cameraKey_index + "_" + QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz") + ".bmp" };
|
||
}
|
||
std::pair<QString, QString> getSegSaveFormat(QString SN, QString okNgText = "", int count = 0)
|
||
{
|
||
QString path = AllImgSaveDir + "//" + getCurrentDate() + "//seg图//" + splitDataList[1].split("_")[0] + "//" + getCurrentHour() + "//";
|
||
return { path,path + SN + "_" + cameraKey_index + "_" + okNgText + "_" + sdataTime + ".bmp" };
|
||
//QString path = oriImgSaveDir + getCurrentDate() + "//Seg图//" + getCurrentHour() + "//" + okNgText + "//" + SN + "//";
|
||
//return { path,path + SN + "_" + cameraKey_index + "_" + QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz") + ".bmp" };
|
||
}
|
||
std::pair<QString, QString> getClsSaveFormat(QString SN, QString okNgText = "", int count = 0, int clsResult = 99)
|
||
{
|
||
QString path = AllImgSaveDir + "//" + getCurrentDate() + "//cls图//" + splitDataList[1].split("_")[0] + "//" + getCurrentHour() + "//";
|
||
return{ path, path + SN + "_" + cameraKey_index + "_" + okNgText + "_" + QString::number(clsResult) + "_" + QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz") + ".bmp" };
|
||
//QString path = oriImgSaveDir + getCurrentDate() + "//Cls图//" + getCurrentHour() + "//" + okNgText + "//" + SN + "//";
|
||
//return{ path, path + SN + "_" + cameraKey_index + "_" + QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz") + ".bmp" };
|
||
}
|
||
std::pair<QString, QString> getTiffSaveFormat(QString SN, QString okNgText = "", int count = 0)
|
||
{
|
||
QString path = AllImgSaveDir + "//" + getCurrentDate() + "//原图//" + splitDataList[1].split("_")[0] + "//" + getCurrentHour() + "//" + okNgText + "//";
|
||
return { path,path + SN + "_" + cameraKey_index + "_" + sdataTime + ".tiff" };
|
||
//QString path = oriImgSaveDir + getCurrentDate() + "//原图//" + getCurrentHour() + "//" + okNgText + "//" + SN + "//";
|
||
//return { path,path + SN + "_" + cameraKey_index + "_" + QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz") + ".tiff" };
|
||
}
|
||
|
||
QString byteArrayToUnicode(const QByteArray array) {
|
||
|
||
// state用于保存转换状态,它的成员invalidChars,可用来判断是否转换成功
|
||
// 如果转换成功,则值为0,如果值大于0,则说明转换失败
|
||
QTextCodec::ConverterState state;
|
||
// 先尝试使用utf-8的方式把QByteArray转换成QString
|
||
QString text = QTextCodec::codecForName("UTF-8")->toUnicode(array.constData(), array.size(), &state);
|
||
// 如果转换时无效字符数量大于0,说明编码格式不对
|
||
if (state.invalidChars > 0)
|
||
{
|
||
// 再尝试使用GBK的方式进行转换,一般就能转换正确(当然也可能是其它格式,但比较少见了)
|
||
text = QTextCodec::codecForName("GBK")->toUnicode(array);
|
||
}
|
||
return text;
|
||
}
|
||
|
||
HalconCpp::HObject MatToHObject(cv::Mat& image)
|
||
{
|
||
HalconCpp::HObject Hobj;
|
||
int hgt = image.rows;
|
||
int wid = image.cols;
|
||
int i;
|
||
if (image.type() == CV_8UC3)
|
||
{
|
||
HalconCpp::HImage himage = HalconCpp::HImage();
|
||
|
||
std::vector<cv::Mat> imgchannel;
|
||
split(image, imgchannel);
|
||
cv::Mat imgB = imgchannel[0];
|
||
cv::Mat imgG = imgchannel[1];
|
||
cv::Mat imgR = imgchannel[2];
|
||
uchar* dataR = new uchar[hgt * wid];
|
||
uchar* dataG = new uchar[hgt * wid];
|
||
uchar* dataB = new uchar[hgt * wid];
|
||
for (i = 0; i < hgt; i++)
|
||
{
|
||
memcpy(dataR + wid * i, imgR.data + imgR.step * i, wid);
|
||
memcpy(dataG + wid * i, imgG.data + imgG.step * i, wid);
|
||
memcpy(dataB + wid * i, imgB.data + imgB.step * i, wid);
|
||
}
|
||
himage.GenImage3("byte", wid, hgt, dataR, dataG, dataB);
|
||
HalconCpp::HString tmpType;
|
||
Hlong tmpW, tmpH;
|
||
void* hImgPtR, * hImgPtG, * hImgPtB;
|
||
himage.GetImagePointer3(&hImgPtR, &hImgPtG, &hImgPtB, &tmpType, &tmpW, &tmpH);
|
||
|
||
GenImage3(&Hobj, "byte", wid, hgt, (Hlong)hImgPtR, (Hlong)hImgPtG, (Hlong)hImgPtB);
|
||
delete[]dataR;
|
||
delete[]dataG;
|
||
delete[]dataB;
|
||
dataR = NULL;
|
||
dataG = NULL;
|
||
dataB = NULL;
|
||
}
|
||
else if (image.type() == CV_8UC1)
|
||
{
|
||
//HalconCpp::HImage himage = HalconCpp::HImage();
|
||
|
||
////uchar* data = new uchar[hgt * wid];
|
||
////for (i = 0; i < hgt; i++)
|
||
////{
|
||
//// memcpy(data + wid * i, image.data + image.step * i, wid);
|
||
////}
|
||
////gen_image_const
|
||
//himage.GenImage1("byte", wid, hgt, image.data);
|
||
|
||
//HalconCpp::HString tmpType;
|
||
//Hlong tmpW, tmpH;
|
||
//void* hImgPt;
|
||
//hImgPt = himage.GetImagePointer1(&tmpType, &tmpW, &tmpH);
|
||
//GenImage1(&Hobj, "byte", wid, hgt, (Hlong)hImgPt);
|
||
//GenImage1(&Hobj, "byte", wid, hgt, (Hlong)image.data);
|
||
|
||
/* delete[] data;
|
||
data = NULL;*/
|
||
|
||
uchar* data = new uchar[hgt * wid];
|
||
for (i = 0; i < hgt; i++)
|
||
memcpy(data + wid * i, image.data + image.step * i, wid);
|
||
GenImage1(&Hobj, "byte", wid, hgt, (Hlong)data);
|
||
delete[] data;
|
||
data = NULL;
|
||
|
||
}
|
||
else if (image.type() == CV_16UC1)
|
||
{
|
||
HalconCpp::HImage himage = HalconCpp::HImage();
|
||
|
||
ushort* data = new ushort[hgt * wid * 2];
|
||
|
||
memcpy(data, image.data, hgt * wid * 2);
|
||
|
||
|
||
himage.GenImage1("uint2", wid, hgt, data);
|
||
|
||
HalconCpp::HString tmpType;
|
||
Hlong tmpW, tmpH;
|
||
void* hImgPt;
|
||
hImgPt = himage.GetImagePointer1(&tmpType, &tmpW, &tmpH);
|
||
GenImage1(&Hobj, "uint2", wid, hgt, (Hlong)hImgPt);
|
||
|
||
delete[] data;
|
||
data = NULL;
|
||
|
||
}
|
||
else if (image.type() == CV_16SC1)
|
||
{
|
||
HalconCpp::HImage himage = HalconCpp::HImage();
|
||
|
||
short* data = new short[hgt * wid * 2];
|
||
|
||
memcpy(data, image.data, hgt * wid * 2);
|
||
|
||
|
||
himage.GenImage1("int2", wid, hgt, data);
|
||
|
||
HalconCpp::HString tmpType;
|
||
Hlong tmpW, tmpH;
|
||
void* hImgPt;
|
||
hImgPt = himage.GetImagePointer1(&tmpType, &tmpW, &tmpH);
|
||
GenImage1(&Hobj, "int2", wid, hgt, (Hlong)hImgPt);
|
||
|
||
delete[] data;
|
||
data = NULL;
|
||
|
||
}
|
||
|
||
return Hobj;
|
||
}
|
||
cv::Mat HObject2Mat(HalconCpp::HObject& Hobj) //HObject类型转Mat类型
|
||
{
|
||
HalconCpp::HTuple htCh;
|
||
HalconCpp::HString cType;
|
||
cv::Mat Image;
|
||
ConvertImageType(Hobj, &Hobj, "byte");
|
||
CountChannels(Hobj, &htCh);
|
||
Hlong wid = 0;
|
||
Hlong hgt = 0;
|
||
if (htCh[0].I() == 1)
|
||
{
|
||
HImage hImg(Hobj);
|
||
void* ptr = hImg.GetImagePointer1(&cType, &wid, &hgt);//GetImagePointer1(Hobj, &ptr, &cType, &wid, &hgt);
|
||
int W = wid;
|
||
int H = hgt;
|
||
Image.create(H, W, CV_8UC1);
|
||
unsigned char* pdata = static_cast<unsigned char*>(ptr);
|
||
memcpy(Image.data, pdata, W * H);
|
||
}
|
||
else if (htCh[0].I() == 3)
|
||
{
|
||
void* Rptr;
|
||
void* Gptr;
|
||
void* Bptr;
|
||
HImage hImg(Hobj);
|
||
hImg.GetImagePointer3(&Rptr, &Gptr, &Bptr, &cType, &wid, &hgt);
|
||
int W = wid;
|
||
int H = hgt;
|
||
Image.create(H, W, CV_8UC3);
|
||
std::vector<cv::Mat> VecM(3);
|
||
VecM[0].create(H, W, CV_8UC1);
|
||
VecM[1].create(H, W, CV_8UC1);
|
||
VecM[2].create(H, W, CV_8UC1);
|
||
unsigned char* R2 = (unsigned char*)Rptr;
|
||
unsigned char* G = (unsigned char*)Gptr;
|
||
unsigned char* B = (unsigned char*)Bptr;
|
||
memcpy(VecM[2].data, R2, W * H);
|
||
memcpy(VecM[1].data, G, W * H);
|
||
memcpy(VecM[0].data, B, W * H);
|
||
cv::merge(VecM, Image);
|
||
}
|
||
return Image;
|
||
}
|
||
|
||
void GetStringSize(HDC hdc, const char* str, int* w, int* h)
|
||
{
|
||
SIZE size;
|
||
GetTextExtentPoint32A(hdc, str, strlen(str), &size);
|
||
if (w != 0) *w = size.cx;
|
||
if (h != 0) *h = size.cy;
|
||
}
|
||
//在图像写中文,英文也可以写
|
||
void putTextZH(cv::Mat& dst, const char* str, cv::Point org, cv::Scalar color, int fontsize,
|
||
const char* fn = "Arial", bool italic = false, bool underline = false)
|
||
{
|
||
CV_Assert(dst.data != 0 && (dst.channels() == 1 || dst.channels() == 3));
|
||
if (std::string(str).length() == 0)return;
|
||
|
||
int x, y, r, b;
|
||
//坐标点大于图像宽和高直接返回
|
||
if (org.x > dst.cols || org.y > dst.rows) return;
|
||
x = org.x < 0 ? -org.x : 0;
|
||
y = org.y < 0 ? -org.y : 0;
|
||
|
||
|
||
|
||
LOGFONTA lf;
|
||
lf.lfHeight = -fontsize; //字体高度
|
||
lf.lfWidth = 0; //平均宽度
|
||
lf.lfEscapement = 0; //字符排列角度
|
||
lf.lfOrientation = 0; //字符本身旋转的角度
|
||
lf.lfWeight = 5; //设置字体线条的宽度
|
||
lf.lfItalic = italic; //斜体
|
||
lf.lfUnderline = underline; //下划线
|
||
lf.lfStrikeOut = 0; //是否字符中央加横线
|
||
lf.lfCharSet = DEFAULT_CHARSET; //字符集
|
||
lf.lfOutPrecision = 0; //字体的精确度
|
||
lf.lfQuality = PROOF_QUALITY; //字体质量
|
||
lf.lfPitchAndFamily = 0; //选择字体的间距和字体家族
|
||
strcpy_s(lf.lfFaceName, fn); //字体的名称
|
||
|
||
|
||
HFONT hf = CreateFontIndirectA(&lf);
|
||
HDC hdc = CreateCompatibleDC(0);
|
||
HFONT holdfont = (HFONT)SelectObject(hdc, hf);
|
||
|
||
|
||
int strBaseW = 0, strBaseH = 0;
|
||
int singleRow = 0;
|
||
char buf[1 << 12];
|
||
strcpy_s(buf, str);
|
||
char* bufT[1 << 12]; //这个用于分隔字符串后剩余的字符,可能会超出。
|
||
|
||
|
||
//处理多行
|
||
{
|
||
int nnh = 0;
|
||
int cw, ch;
|
||
|
||
|
||
const char* ln = strtok_s(buf, "\n", bufT);
|
||
while (ln != 0)
|
||
{
|
||
GetStringSize(hdc, ln, &cw, &ch);
|
||
strBaseW = max(strBaseW, cw);
|
||
strBaseH = max(strBaseH, ch);
|
||
|
||
|
||
ln = strtok_s(0, "\n", bufT);
|
||
nnh++;
|
||
}
|
||
singleRow = strBaseH;
|
||
strBaseH *= nnh;
|
||
}
|
||
|
||
|
||
if (org.x + strBaseW < 0 || org.y + strBaseH < 0)
|
||
{
|
||
SelectObject(hdc, holdfont);
|
||
DeleteObject(hf);
|
||
DeleteObject(hdc);
|
||
return;
|
||
}
|
||
|
||
|
||
r = org.x + strBaseW > dst.cols ? dst.cols - org.x - 1 : strBaseW - 1;
|
||
b = org.y + strBaseH > dst.rows ? dst.rows - org.y - 1 : strBaseH - 1;
|
||
org.x = org.x < 0 ? 0 : org.x;
|
||
org.y = org.y < 0 ? 0 : org.y;
|
||
|
||
|
||
BITMAPINFO bmp = { 0 };
|
||
BITMAPINFOHEADER& bih = bmp.bmiHeader;
|
||
int strDrawLineStep = strBaseW * 3 % 4 == 0 ? strBaseW * 3 : (strBaseW * 3 + 4 - ((strBaseW * 3) % 4));
|
||
|
||
|
||
bih.biSize = sizeof(BITMAPINFOHEADER);
|
||
bih.biWidth = strBaseW;
|
||
bih.biHeight = strBaseH;
|
||
bih.biPlanes = 1;
|
||
bih.biBitCount = 24;
|
||
bih.biCompression = BI_RGB;
|
||
bih.biSizeImage = strBaseH * strDrawLineStep;
|
||
bih.biClrUsed = 0;
|
||
bih.biClrImportant = 0;
|
||
|
||
|
||
void* pDibData = 0;
|
||
HBITMAP hBmp = CreateDIBSection(hdc, &bmp, DIB_RGB_COLORS, &pDibData, 0, 0);
|
||
|
||
|
||
CV_Assert(pDibData != 0);
|
||
HBITMAP hOldBmp = (HBITMAP)SelectObject(hdc, hBmp);
|
||
|
||
|
||
//color.val[2], color.val[1], color.val[0]
|
||
SetTextColor(hdc, RGB(255, 255, 255));
|
||
SetBkColor(hdc, 0);
|
||
//SetStretchBltMode(hDC, COLORONCOLOR);
|
||
|
||
|
||
strcpy_s(buf, str);
|
||
const char* ln = strtok_s(buf, "\n", bufT);
|
||
int outTextY = 0;
|
||
while (ln != 0)
|
||
{
|
||
TextOutA(hdc, 0, outTextY, ln, strlen(ln));
|
||
outTextY += singleRow;
|
||
ln = strtok_s(0, "\n", bufT);
|
||
}
|
||
uchar* dstData = (uchar*)dst.data;
|
||
int dstStep = dst.step / sizeof(dstData[0]);
|
||
unsigned char* pImg = (unsigned char*)dst.data + org.x * dst.channels() + org.y * dstStep;
|
||
unsigned char* pStr = (unsigned char*)pDibData + x * 3;
|
||
for (int tty = y; tty <= b; ++tty)
|
||
{
|
||
unsigned char* subImg = pImg + (tty - y) * dstStep;
|
||
unsigned char* subStr = pStr + (strBaseH - tty - 1) * strDrawLineStep;
|
||
for (int ttx = x; ttx <= r; ++ttx)
|
||
{
|
||
for (int n = 0; n < dst.channels(); ++n) {
|
||
double vtxt = subStr[n] / 255.0;
|
||
int cvv = vtxt * color.val[n] + (1 - vtxt) * subImg[n];
|
||
subImg[n] = cvv > 255 ? 255 : (cvv < 0 ? 0 : cvv);
|
||
}
|
||
|
||
|
||
subStr += 3;
|
||
subImg += dst.channels();
|
||
}
|
||
}
|
||
|
||
|
||
SelectObject(hdc, hOldBmp);
|
||
SelectObject(hdc, holdfont);
|
||
DeleteObject(hf);
|
||
DeleteObject(hBmp);
|
||
DeleteDC(hdc);
|
||
}
|
||
|
||
void drawDefects(cv::Mat& sourceMat, QQueue<defectInfo> defectInfoList)
|
||
{
|
||
for (int i = 0; i < defectInfoList.size(); i++)
|
||
{
|
||
defectInfo mdefect = defectInfoList[i];
|
||
|
||
cv::rectangle(sourceMat, cv::Point(mdefect.defectRect.x, mdefect.defectRect.y),
|
||
cv::Point(mdefect.defectRect.x + mdefect.defectRect.width, mdefect.defectRect.y + mdefect.defectRect.height), mdefect.defectScalar, 3, 8);
|
||
|
||
QByteArray path_arr = mdefect.defectName.toLocal8Bit();
|
||
const char* path = path_arr.data();
|
||
putTextZH(sourceMat, path, cv::Point(mdefect.defectRect.x, mdefect.defectRect.y - 50), mdefect.defectScalar, 50, "微软雅黑");
|
||
}
|
||
}
|
||
|
||
Hd_ShangDing_module* create()
|
||
{
|
||
qDebug() << "[INFO] " << " Hd_ShangDing_module create success!" ;
|
||
return new Hd_ShangDing_module;
|
||
}
|
||
|
||
void destory(Hd_ShangDing_module* ptr)
|
||
{
|
||
qDebug() << "[INFO] " << "Hd_ShangDing_module destory success!";
|
||
if(ptr)
|
||
{
|
||
delete ptr;
|
||
ptr = nullptr;
|
||
}
|
||
}
|
||
|
||
Hd_ShangDing_module::Hd_ShangDing_module()
|
||
{
|
||
detect_mutex = new QMutex;
|
||
saveStruct_mutex = new QMutex;
|
||
ifdetectThread = false;
|
||
}
|
||
|
||
Hd_ShangDing_module::~Hd_ShangDing_module()
|
||
{
|
||
ifdetectThread = false;
|
||
Sleep(10);
|
||
if (detect_mutex)
|
||
{
|
||
delete detect_mutex;
|
||
detect_mutex = nullptr;
|
||
}
|
||
if (saveStruct_mutex)
|
||
{
|
||
delete saveStruct_mutex;
|
||
saveStruct_mutex = nullptr;
|
||
}
|
||
/*DestroySegObj(pSeg);
|
||
DestroyClsObj(pCls);*/
|
||
}
|
||
static int defectNums = 0;
|
||
//static cv::Mat resMat;
|
||
//从类中读数据到实例对象
|
||
bool Hd_ShangDing_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)
|
||
{
|
||
vec_mat.push_back(resMat[0]);
|
||
resMat.clear();
|
||
}
|
||
else
|
||
{
|
||
vec_mat.push_back(HikMat[0]);
|
||
qDebug() << __FUNCTION__ << " line:" << __LINE__ << " resMat.data err:";
|
||
}
|
||
|
||
data = logicUiTransport::encodeAllData(SN, {floatData_offsetX,floatData_offsetY,shortData_result }, {});
|
||
resByte.clear();
|
||
addImgToSaveStruct(HikMat[0], "0", getOriSaveFormat(SN, okngText));//保存原图
|
||
//{
|
||
// okngText = shortData_result == "1" ? "OK":"NG";
|
||
|
||
// for (int i = 0; i < initValueList.size(); i++)
|
||
// {
|
||
// QString minit = byteArrayToUnicode(initValueList[i]);
|
||
// if (initValueList[i].contains(moduleData.split(',')[2].split('_')[0]))
|
||
// if (initValueList[i].contains(QString("原图_保存").toLocal8Bit()))
|
||
// {
|
||
// addImgToSaveStruct(HikMat[0], "0", getOriSaveFormat(SN, okngText));//保存原图
|
||
// }
|
||
// }
|
||
|
||
// resize(vec_mat[0], vec_mat[0], cv::Size(), 0.5, 0.5);
|
||
|
||
// for (int i = 0; i < initValueList.size(); i++)
|
||
// {
|
||
// QString minit = byteArrayToUnicode(initValueList[i]);
|
||
// if (initValueList[i].contains(moduleData.split(',')[2].split('_')[0]))
|
||
// if (initValueList[i].contains(QString("结果图_保存").toLocal8Bit()))
|
||
// {
|
||
// addImgToSaveStruct(vec_mat[0], "0", getResSaveFormat(SN, okngText));//保存结果图
|
||
// }
|
||
// }
|
||
//}
|
||
|
||
detect_mutex->unlock();
|
||
return true;
|
||
}
|
||
//从类中读数据到实例对象
|
||
bool Hd_ShangDing_module::encodeResultValue(QVector<std::string> append_value,QByteArray &resultByte)
|
||
{
|
||
try
|
||
{
|
||
std::string sendMsg;
|
||
for(int i = 0 ; i < append_value.size();i++)
|
||
{
|
||
std::string value = append_value.at(1);
|
||
//type
|
||
int type = 3;
|
||
std::string m_type;
|
||
m_type.insert(0,4,'1');
|
||
memcpy ( (void*)m_type.c_str(),(void*)&type,4 );
|
||
sendMsg.append(m_type);
|
||
|
||
//len
|
||
int len = value.length();
|
||
std::string m_len;
|
||
m_len.insert(0,4,'1');
|
||
memcpy ( (void*)m_len.c_str(),(void*)&len,4 );
|
||
sendMsg.append(m_len);
|
||
|
||
//data x
|
||
sendMsg.append(value);
|
||
}
|
||
resultByte = QByteArray::fromStdString(sendMsg);
|
||
} catch (QString ev)
|
||
{
|
||
qCritical() << "[Error] " << " ev:" << ev;
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
|
||
//接收数据
|
||
bool Hd_ShangDing_module::writeData(std::vector<cv::Mat>& vec_mat, QByteArray &data)
|
||
{
|
||
qDebug() << __FUNCTION__ << "line:" << __LINE__ << " data:" << data;
|
||
if (vec_mat.empty())
|
||
{
|
||
qCritical() << "[Error] " << " vec_mat is null !";
|
||
return false;
|
||
}
|
||
detect_mutex->lock();
|
||
HikMat.clear();
|
||
qstring_data = byteArrayToUnicode(data);
|
||
for (int i = 0; i < vec_mat.size(); i++)
|
||
{
|
||
if (vec_mat[i].channels() == 3&& qstring_data.contains("放钉"))
|
||
cv::cvtColor(vec_mat[i], vec_mat[i], COLOR_BGR2GRAY);
|
||
HikMat.enqueue(vec_mat[i]);
|
||
}
|
||
|
||
//hv_Image.push_back(MatToHObject(HikMat[0]));
|
||
//std::cout << "vec_mat.size()" << vec_mat.size() << std::endl;
|
||
//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");
|
||
moduleData = data;
|
||
|
||
detect_mutex->unlock();
|
||
return true;
|
||
}
|
||
//初始化
|
||
bool Hd_ShangDing_module::initParas(QByteArray& byte)
|
||
{
|
||
|
||
initValueList = byte.split('+');
|
||
QStringList valueiList;
|
||
|
||
for (int i = 0; i < initValueList.size(); i++)
|
||
{
|
||
QString valuei = byteArrayToUnicode(initValueList[i]);
|
||
if (valuei.contains("hv_model") && valuei.contains("#"))
|
||
{
|
||
m_hv_model = valuei.split("#")[1].toInt();
|
||
{
|
||
qDebug() << __FUNCTION__ << " line:" << __LINE__ << "m_hv_model::" << m_hv_model;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (byte.contains("onlySetParameter")) //只设置参数,不重新初始化
|
||
{
|
||
qDebug() << __FUNCTION__ << " line:" << __LINE__ << "onlySetParameter,valueList[0]:" << initValueList[0];
|
||
if (initValueList.size() > 1)
|
||
for (int i = 1; i < initValueList.size(); i++)
|
||
{
|
||
QString valuei = byteArrayToUnicode(initValueList[i]);
|
||
qDebug() << __FUNCTION__ << " line:" << __LINE__ << "onlySetParameter,lastName:" << initValueList[0] << " ,valuei:" << valuei;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
////运行检测线程
|
||
ifdetectThread = true;
|
||
|
||
////线程检测:结果类完成时,使用
|
||
////ifThreadRunDetect = true;
|
||
////QFuture<void> future1 = QtConcurrent::run(this, &Hd_ShangDing_module::detectThread);
|
||
//运行存图线程
|
||
QFuture<void> future2 = QtConcurrent::run(this, &Hd_ShangDing_module::saveImgThread);
|
||
|
||
//cv::Mat initimg = cv::imread("../bin/initimg.bmp");
|
||
//if (initimg.channels() == 3)
|
||
// cv::cvtColor(initimg, initimg, COLOR_BGR2GRAY);
|
||
myEngine.SetProcedurePath("./halconFilesAlgo/AlgoLibrary_602.hdpl"); //设置hdvp路径
|
||
//MatToHObject(initimg);
|
||
|
||
//InitModels();
|
||
//qDebug() << "[INFO] " << " StationNo:" << StationNo << " img2D:" << img2D ;
|
||
return true;
|
||
}
|
||
|
||
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++;
|
||
//seg_zhenyan = CreateSegObjS((char*)modelPath_seg_zhenyan.c_str(), 1, 0); if (seg_zhenyan->getStatus() != SegStatus::Seg_Success)flag++;
|
||
//seg_pianhan = CreateSegObjS((char*)modelPath_seg_pianhan.c_str(), 1, 0); if (seg_pianhan->getStatus() != SegStatus::Seg_Success)flag++;
|
||
//seg_rongding = CreateSegObjS((char*)modelPath_seg_rongding.c_str(), 1, 0); if (seg_rongding->getStatus() != SegStatus::Seg_Success)flag++;
|
||
|
||
//det_DJY = CreateDetObjS((char*)modelPath_det_DJY.c_str(), 1, 0); if (det_DJY->getStatus() != DetStatus::Det_Success)flag++;
|
||
// det_neiquan = CreateDetObjS((char*)modelPath_det_neiquan.c_str(), 1, 0); if (det_neiquan->getStatus() != DetStatus::Det_Success)flag++;
|
||
//cls_DJY = CreateClsObjV3((char*)modelPath_cls_DJY.c_str(), 0, 1); if (cls_DJY->getStatus() != ClsStatus::Cls_Success)flag++;
|
||
return (flag == 0);
|
||
}
|
||
// 解码
|
||
bool Hd_ShangDing_module::decodeAiValue(QByteArray byte,QVector<QByteArray> &vec_ret)
|
||
{
|
||
if(byte.isEmpty())
|
||
{
|
||
qCritical() << "[Error] " << " byte is null!";
|
||
return false;
|
||
}
|
||
|
||
/*******************************************/
|
||
byte.remove(0,8);
|
||
QByteArray mm_data = byte.mid(0,4);
|
||
memcpy((void*)¶mNum,(void*)mm_data.data(), 4);
|
||
qDebug() << "[INFO] " << " paramNum:" << paramNum;
|
||
byte.remove(0,4);
|
||
/*******************************************/
|
||
|
||
while (!byte.isEmpty())
|
||
{
|
||
int type = 0;
|
||
QByteArray m_type = byte.mid(0,4);
|
||
memcpy((void*)&type,(void*)m_type.data(), 4);
|
||
byte.remove(0,4);
|
||
|
||
int len = 0;
|
||
QByteArray m_len = byte.mid(0,4);
|
||
memcpy((void*)&len,(void*)m_len.data(), 4);
|
||
byte.remove(0,4);
|
||
|
||
QByteArray mm_data = byte.mid(0,len);
|
||
vec_ret.append(mm_data);
|
||
byte.remove(0,len);
|
||
}
|
||
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_ShangDing_module::addImgToSaveStruct(cv::Mat img2D, QString mysaveKey, std::pair<QString, QString> savePath)
|
||
{
|
||
//存图数据加保存队列,加锁,避免数据访问冲突
|
||
saveStruct_mutex->lock();
|
||
saveImgStruct mySave;
|
||
mySave.out_Mat = img2D.clone();
|
||
//img2D.copyTo(mySave.out_Mat);
|
||
mySave.saveKey = mysaveKey.toLocal8Bit().toStdString();
|
||
mySave.savePath = savePath.second.toLocal8Bit().toStdString();
|
||
mySave.createDirPath = savePath.first;
|
||
saveStruct.enqueue(mySave);
|
||
saveStruct_mutex->unlock();
|
||
}
|
||
void Hd_ShangDing_module::saveImgThread()
|
||
{
|
||
while (1)
|
||
{
|
||
if (!ifdetectThread)return;
|
||
_sleep(5);
|
||
qApp->processEvents();
|
||
if (saveStruct.size() < 1)continue;
|
||
for (int i = 0; i < saveStruct.size(); i++)
|
||
{
|
||
clock_t start, stop;
|
||
start = clock();
|
||
saveStruct_mutex->lock();
|
||
saveImgStruct mysaveStruct = saveStruct.dequeue();
|
||
saveStruct_mutex->unlock();
|
||
createDirectoryIfNotExists(mysaveStruct.createDirPath);
|
||
stop = clock();
|
||
if (stop - start > 1000)
|
||
std::cout << "lock stop-start >1000::************************" << stop - start << std::endl;
|
||
start = clock();
|
||
if (mysaveStruct.out_Mat.data)
|
||
imwrite(mysaveStruct.savePath, mysaveStruct.out_Mat);
|
||
//std::cout << "savePath::" << mysaveStruct.savePath << std::endl;
|
||
stop = clock();
|
||
if (stop - start > 1000)
|
||
std::cout << "imwrite stop-start >1000::--------------------------" << stop - start << std::endl;
|
||
_sleep(1);
|
||
}
|
||
}
|
||
}
|
||
//检测线程,应当只运行一次
|
||
void Hd_ShangDing_module::detectThread()
|
||
{
|
||
do
|
||
{
|
||
if (!ifdetectThread)return;
|
||
|
||
//此两行代码,避免程序卡死;_sleep的时间根据实际项目调整
|
||
_sleep(2);
|
||
qApp->processEvents();
|
||
//取数据加锁,避免数据访问冲突
|
||
detect_mutex->lock();
|
||
//if (HikMat.size() < 1 || saveKey.size() < 1 || Dir2D.size() < 1 || SN.size() < 1 )//|| DateTime1.size() < 1)
|
||
//{
|
||
// detect_mutex->unlock();
|
||
// continue;
|
||
//}
|
||
|
||
cv::Mat sourceImg1 = HikMat[0];// .dequeue();
|
||
QString mysaveKey = "saveKey";// .dequeue();
|
||
QString myDir2D = "Dir2D";// .dequeue();
|
||
QString mySN = "SN";// .dequeue();
|
||
QString myDataTime = "DateTime1";
|
||
detect_mutex->unlock();
|
||
|
||
////判断存图文件夹是否存在,不存在则创建
|
||
//{
|
||
// //原图总文件夹
|
||
// isDirExist(oriImgSaveDir + mysaveKey);
|
||
// //原图class总文件夹
|
||
// isDirExist(classImgSaveDir + mysaveKey);
|
||
// //结果图总文件夹
|
||
// isDirExist(resImgSaveDir + mysaveKey);
|
||
|
||
//}
|
||
|
||
//测试相机的,
|
||
//while (sourceImg1.cols > 2000)cv::resize(sourceImg1, sourceImg1, cv::Size(), 0.5, 0.5);
|
||
|
||
//存图数据入队
|
||
//addImgToSaveStruct(sourceImg1, mysaveKey, oriImgSaveDir + mysaveKey + "/" + mySN + myDataTime + ".bmp");
|
||
|
||
//-------检测流程,根据实际项目修改---------
|
||
//AIdetect(sourceImg1, mysaveKey, oriImgSaveDir, mySN, myDataTime);
|
||
//sourceImg1.release();
|
||
|
||
mysaveKey.clear();
|
||
myDir2D.clear();
|
||
mySN.clear();
|
||
myDataTime.clear();
|
||
qApp->processEvents();
|
||
|
||
} while (ifThreadRunDetect);
|
||
|
||
}
|
||
|
||
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";
|
||
cv::Mat null_mat = cv::Mat::zeros(cv::Size(100, 100), CV_8UC3);
|
||
resMat.push_back(null_mat);
|
||
return true;
|
||
}
|
||
|
||
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);
|
||
resMat.push_back(null_mat);
|
||
return true;
|
||
}
|
||
|
||
//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
|
||
// 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;
|
||
//}
|
||
|
||
//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;
|
||
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, "微软雅黑");
|
||
|
||
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";
|
||
putTextZH(img_dst, "算法异常", cv::Point(50, 300), cv::Scalar(0, 0, 255), 150, "微软雅黑");
|
||
}
|
||
|
||
if (shortData_result == "1")
|
||
{
|
||
putTextZH(img_dst, "OK", cv::Point(50, 550), 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();
|
||
}
|
||
|
||
runNum++;
|
||
//HikMat.clear();
|
||
//qDebug() << __FUNCTION__ << " line:" << __LINE__ << "Mat_name: run end" << "model uesd time::" << stop - start << "ms";
|
||
return true;
|
||
}
|
||
catch (HDevEngineCpp::HDevEngineException& ex) {
|
||
std::cerr << "HDevEngineException: " << ex.Message() << std::endl;
|
||
}
|
||
catch (HException& ex) {
|
||
// 捕获Halcon异常
|
||
std::cerr << "Halcon Exception Caught!" << std::endl;
|
||
std::cerr << "Error Code: " << ex.ErrorCode() << std::endl;
|
||
std::cerr << "Error Message: " << ex.ErrorMessage() << std::endl;
|
||
}
|
||
catch (std::exception& ex) {
|
||
// 捕获其他标准异常
|
||
std::cerr << "Standard Exception Caught: " << ex.what() << std::endl;
|
||
}
|
||
catch (...)
|
||
{
|
||
|
||
qDebug() << __FUNCTION__ << " line:" << __LINE__ << cameraKey_index <<"Mat_error: run end";
|
||
|
||
}
|
||
shortData_result = "2";
|
||
cv::Mat null_mat = cv::Mat::zeros(cv::Size(100, 100), CV_8UC3);
|
||
resMat.push_back(null_mat);
|
||
return true;
|
||
}
|
||
|
||
bool Hd_ShangDing_module::checkStatus()
|
||
{
|
||
status = moduleStatus;
|
||
return status;
|
||
}
|
||
|