#include "Hd_FangDing_module.h" #include #include #include #include #include "nlohmannJson.hpp" #include "generalJsonParsing.hpp" #include ////逻辑UI头文件 // //#include "CPPTaskLoader/pbloadtask.h" // //#include "io.h" //#include //#include //#include //#include //628算法 #include #pragma execution_character_set("utf-8") using namespace cv; using namespace std; using namespace handdleAI; //using namespace HalconCpp; //总保存文件夹 QString AllImgSaveDir = "D:/CCD/"; //检测线程锁 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";//返回给PLC的结果 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(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 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 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 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 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 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 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(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 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 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_FangDing_module* create() { qDebug() << "[INFO] " << " Hd_FangDing_module create success!" ; return new Hd_FangDing_module; } void destory(Hd_FangDing_module* ptr) { qDebug() << "[INFO] " << "Hd_FangDing_module destory success!"; if(ptr) { delete ptr; ptr = nullptr; } } Hd_FangDing_module::Hd_FangDing_module() { detect_mutex = new QMutex; saveStruct_mutex = new QMutex; ifdetectThread = false; } Hd_FangDing_module::~Hd_FangDing_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_FangDing_module::readData(std::vector&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_FangDing_module::encodeResultValue(QVector 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_FangDing_module::writeData(std::vector& 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(','); 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_FangDing_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 future1 = QtConcurrent::run(this, &Hd_FangDing_module::detectThread); //运行存图线程 QFuture future2 = QtConcurrent::run(this, &Hd_FangDing_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_FangDing_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_FangDing_module::decodeAiValue(QByteArray byte,QVector &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; } //存图加入队列 void Hd_FangDing_module::addImgToSaveStruct(cv::Mat img2D, QString mysaveKey, std::pair 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_FangDing_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_FangDing_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 Hd_FangDing_module::run() { try { shortData_result = "0"; floatData_offsetX = "0"; floatData_offsetY = "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; } 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; // } // 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]); //* Function Name : _9_shangding < / c> // * Author : < / c> // *Description : < / c> // < / c> // *Input(HObject) : in_Image, 图像(bmp), < / c> // < / c> // *output(HObject) : < / c> // *Input(HTuple) : in_ProductionType, 生产类别 : 0, 生产模式: 1, 标定模式 < / c> // * in_CameraNumber, 相机序列号 < / c> // * in_FilePath1, 模板文件路径; 示例:'./模板文件/' < / 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(); // *output(HTuple) : < / c> // *out_Circle, 圆心坐标(y, x, radius) < / c > // * out_Flag, 算法执行成功标志位, 0 : 算法执行失败 1 : 算法执行成功< / c> // *out_OffsetX : 模组X轴的补偿量(mm) < / 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(); 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) { 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));//保存结果图 putTextZH(img_dst, "OK", cv::Point(50, 500), cv::Scalar(0, 255, 0), 150, "微软雅黑"); } 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(); //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_FangDing_module::checkStatus() { status = moduleStatus; return status; }