diff --git a/BaseModules/Hd_AI_algo_3_1_hanQianDingWei/CMakeLists.txt b/BaseModules/Hd_AI_algo_3_1_hanQianDingWei/CMakeLists.txt new file mode 100644 index 0000000..be2265d --- /dev/null +++ b/BaseModules/Hd_AI_algo_3_1_hanQianDingWei/CMakeLists.txt @@ -0,0 +1,71 @@ +# 获取获取当前目录名 +get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +string(TIMESTAMP RUN_TIME) +message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) + +set(DLL_NAMES "opencv" "halcon" "halconAlgo" "myTools" "handdleAI") +foreach(child ${DLL_NAMES}) + LIST(APPEND ENV_INCLUDE ${${child}_include}) + LIST(APPEND ENV_LIB ${${child}_lib}) + LIST(APPEND ENV_TARGET ${${child}_target_link}) +endforeach() +message(" ENV_INCLUDE : " ${ENV_INCLUDE} ) +message(" ENV_LIB : " ${ENV_LIB} ) +message(" ENV_TARGET : " ${ENV_TARGET} ) +include_directories( + + ${ENV_INCLUDE} + ) + +link_directories ( + ${ENV_LIB} + + ) + + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_AUTOMOC ON) +SET(CMAKE_AUTOUIC ON) +set(CMAKE_AUTORCC ON) + +FILE(GLOB HEAD_FILES "./*.h" ) +FILE(GLOB SRC_FILES "./*.cpp") +FILE(GLOB UI_FILES "./*.ui") + + +#find_package(Qt5 COMPONENTS Core REQUIRED) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS network REQUIRED) +add_library(${CURRENT_FOLDER} SHARED + ${HEAD_FILES} + ${SRC_FILES} + ${UI_FILES} + ) + + + +set_target_properties(${CURRENT_FOLDER} PROPERTIES LINKER_LANGUAGE C + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + ) + + +target_link_libraries(${CURRENT_FOLDER} PRIVATE + ${ENV_TARGET} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Network + ) + + +# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY) + + + + +string(TIMESTAMP RUN_TIME) +message( " model end : " ${CURRENT_FOLDER}:${RUN_TIME}) diff --git a/BaseModules/Hd_AI_algo_3_1_hanQianDingWei/Hd_AI_algo_3_1_hanQianDingWei.cpp b/BaseModules/Hd_AI_algo_3_1_hanQianDingWei/Hd_AI_algo_3_1_hanQianDingWei.cpp new file mode 100644 index 0000000..3508687 --- /dev/null +++ b/BaseModules/Hd_AI_algo_3_1_hanQianDingWei/Hd_AI_algo_3_1_hanQianDingWei.cpp @@ -0,0 +1,1070 @@ +#include "Hd_AI_algo_3_1_hanQianDingWei.h" +#include + +#include +#include +#include +#include +#include +#include +using namespace cv; +//原图保存文件夹s + QString oriImgSaveDir = "D:/601线/软连接CCD/焊前定位CCD/相机1/原图/"; +//原图class图保存文件夹 + QString classImgSaveDir = "D:/601线/软连接CCD/焊前定位CCD/相机1/class图/"; +//结果保存文件夹 + QString resImgSaveDir = "D:/601线/软连接CCD/焊前定位CCD/相机1/结果图/"; + int algoResult = 0;//0 OK 1 NG +//切图的class的width,根据项目实际设置! + int sizeW = 150; +//切图的class的height,根据项目实际设置! + int sizeH = 150; +//切图的class的width,根据项目实际设置!0为黑,255为白; + int fillColour = 0; + + +//检测线程锁 + QMutex* detect_mutex; +//保存线程锁 + QMutex* saveStruct_mutex; +//检测线程运行标志 + bool ifdetectThread = false; + + QString cameraKey_index = ""; + + //初始化参数列表 + QByteArrayList initValueList; + + 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"; + } + 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; + } + static cv::Rect findMaxAreaContour(cv::Mat src) + { + int maxIndex = 0, maxArea = 0; + std::vector>contours; + cv::findContours(src, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); + if (contours.size() == 0) + return cv::Rect(0, 0, 0, 0); + for (int i = 0; i < contours.size(); i++) + { + int Area = cv::contourArea(contours[i]); + if (Area > maxArea) + { + maxArea = Area; + maxIndex = i; + } + } + if (contours.size() != 0) + return cv::boundingRect(contours[maxIndex]); + return cv::Rect(0, 0, 0, 0); + } + inline std::string utf8_to_gbk(const std::string& str) + { + std::wstring_convert> conv; + std::wstring tmp_wstr = conv.from_bytes(str); + //GBK locale name in windows + const char* GBK_LOCALE_NAME = ".936"; + std::wstring_convert> convert(new std::codecvt_byname(GBK_LOCALE_NAME)); + return convert.to_bytes(tmp_wstr); + } + void getAllFiles(std::string path, std::vector& files, std::string format) + { + intptr_t hFile = 0;//文件句柄 + struct _finddata_t fileinfo;//文件信息 + std::string p; + if ((hFile = _findfirst(p.assign(path).append("\\*" + format).c_str(), &fileinfo)) != -1) //文件存在 + { + do + { + if ((fileinfo.attrib & _A_SUBDIR))//判断是否为文件夹 + { + if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)//文件夹名中不含"."和".." + { + files.push_back(p.assign(path).append("\\").append(fileinfo.name)); //保存文件夹名 + getAllFiles(p.assign(path).append("\\").append(fileinfo.name), files, format); //递归遍历文件夹 + } + } + else + { + files.push_back(p.assign(path).append("\\").append(fileinfo.name));//如果不是文件夹,储存文件名 + } + } while (_findnext(hFile, &fileinfo) == 0); + _findclose(hFile); + } + } + QString geteOriSaveFromat() + { + return oriImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//" + + "ORI_" + cameraKey_index + "_" + QString::fromStdString(getCurrentTime()) + ".bmp"; + } + QString getResSaveFromat() + { + return resImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//" + + "RES_" + cameraKey_index + "_" + QString::fromStdString(getCurrentTime()) + ".png"; + } +// 缺陷信息结构体 +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; + +//Mat转Halcon图像 +void 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;*/ + + } + 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; + + } + +} + +//判断文件是否存在,不存在则创建 +bool isFileExist(QString fullFileName) +{ + QFileInfo fileInfo(fullFileName); + if (fileInfo.isFile()) + { + return true; + } + return false; +} + +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)); + + + 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, "微软雅黑"); + } +} + + + +//判断文件夹是否存在,不存在则创建 +void Hd_AI_algo_3_1_hanQianDingWei::isDirExist(QString fullDirName) +{ + QDir* photo = new QDir; + bool exist = photo->exists(fullDirName); + if (exist) + { + //qDebug() << fullDirName << "::已存在"; + } + else + { + //创建photo文件夹 + //qDebug() << fullDirName << "::不存在,创建"; + photo->mkdir(fullDirName); + } + delete photo; + photo = nullptr; +} + +Hd_AI_algo_3_1_hanQianDingWei* create() +{ + qDebug() << "[INFO] " << " Hd_AI_algo_3_1_hanQianDingWei create success!" ; + return new Hd_AI_algo_3_1_hanQianDingWei; +} + +void destory(Hd_AI_algo_3_1_hanQianDingWei* ptr) +{ + qDebug() << "[INFO] " << "Hd_AI_algo_3_1_hanQianDingWei destory success!"; + if(ptr) + { + delete ptr; + ptr = nullptr; + } +} + +Hd_AI_algo_3_1_hanQianDingWei::Hd_AI_algo_3_1_hanQianDingWei() +{ + detect_mutex = new QMutex; + saveStruct_mutex = new QMutex; + ifdetectThread = false; + for (int i = 0; i < 4; i++) + { + QString DirPath = "E:/testImg/source" + QString::number(i); + QStringList imgFilters; + imgFilters << "*.jpg" << "*.png" << "*.PNG" << "*.gif" << "*.tif" << "*.jpeg" << "*.bmp"; + QDir qdir(DirPath); + //返回文件名列表 + QStringList localSourceImgsName = qdir.entryList(imgFilters, QDir::Files | QDir::Readable, QDir::Name); + for (int j = 0; j < localSourceImgsName.size(); j++) + { + QString imgPath = DirPath + "/" + localSourceImgsName[j]; + QFile myf(imgPath); + if (myf.exists()) + myf.remove(); + //Sleep(1); + } + } +} + +Hd_AI_algo_3_1_hanQianDingWei::~Hd_AI_algo_3_1_hanQianDingWei() +{ + 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);*/ +} +//从类中读数据到实例对象 +bool Hd_AI_algo_3_1_hanQianDingWei::readData(std::vector&vec_mat,QByteArray &data) +{ + detect_mutex->lock(); + //qDebug() << __FUNCTION__ << " line:" <<__LINE__ << " data len:" << data.length(); + if (resMat.size()>0) + { + vec_mat.push_back(resMat[0]); + resMat.clear(); + } + else + { + if(HikMat.size()>0) + vec_mat.push_back(HikMat[0]); + //qDebug() << __FUNCTION__ << " line:" << __LINE__ << " resMat.data err:"; + } + //if (allNum++ % 2 == 0) + // data = "2*3*2";// resByte.dequeue(); + //else + data = "1*" + QByteArray::number(algoResult) + "&+" + QByteArray::number(algoResult);//1OK,2NG + resByte.clear(); + ////之后根据结果类修改 + //if(resIfNg == true) + // data = "NG"; + //else data = "OK"; + detect_mutex->unlock(); + /*if(cameraKey_index.contains('_')) + qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getDetectData--CameraName:" + << cameraKey_index.split("_")[0] << " imgIndex:" << cameraKey_index.split("_")[1]; + else + qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getDetectData--CameraName imgIndex:" << cameraKey_index;*/ + return true; +} +//从类中读数据到实例对象 +bool Hd_AI_algo_3_1_hanQianDingWei::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; +} + +int myallNum[4] = {0}; +QMap lastImgMap; +//接收数据 +bool Hd_AI_algo_3_1_hanQianDingWei::writeData(std::vector& vec_mat, QByteArray &data) +{ + //qDebug() << __FUNCTION__ << "line:"<< __LINE__ << " data len" << data.length() ; + if(vec_mat.empty()) + { + qCritical() << "[Error] " << " vec_mat is null !"; + return false; + } + detect_mutex->lock(); + HikMat.clear(); + for (int i = 0; i < vec_mat.size(); i++) + HikMat.enqueue(vec_mat[i]); + + QByteArray source_savePath; + QByteArray sData = data; + QByteArrayList splitDataList = sData.split(','); + if (splitDataList.size() >= 4) + { + if (splitDataList[2].contains('_')) + cameraKey_index = splitDataList[2]; + QByteArray saveDir = splitDataList[0] + "/" + splitDataList[1] + "/"; + isDirExist(byteArrayToUnicode(saveDir)); //不存在,创建 + QString sdataTime= QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz"); + source_savePath = splitDataList[0] + "/" + splitDataList[1] + "/" + sdataTime.toLocal8Bit() + "-" + splitDataList[2] + "-" + splitDataList[3];// +".bmp"; + } + //int index = -1; + /*if (sData.contains("offline-camera0")) + { + index = 0; + savePath = "E:\\testImg\\source0\\"+QString::number(myallNum[0]++) + ".bmp"; + } + else if (sData.contains("offline-camera1")) + { + index = 1; + savePath = "E:\\testImg\\source1\\" + QString::number(myallNum[1]++) + ".bmp"; + } + else if (sData.contains("offline-camera2")) + { + index = 2; + savePath = "E:\\testImg\\source2\\" + QString::number(myallNum[2]++) + ".bmp"; + } + else if (sData.contains("offline-camera3")) + { + index = 3; + savePath = "E:\\testImg\\source3\\" + QString::number(myallNum[3]++) + ".bmp"; + }*/ + + + createDirectoryIfNotExists(oriImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//"); + addImgToSaveStruct(HikMat[0], "0", geteOriSaveFromat());//保存原图 + //if (!source_savePath.isEmpty()) + //{ + // //std::cout << "try savePath::" << savePath.toStdString() << std::endl; + // //测试相机的, + // //while (HikMat[0].cols > 2000)cv::resize(HikMat[0], HikMat[0], cv::Size(), 0.08, 0.08);' + // for (int i = 0; i < initValueList.size(); i++) + // { + // QString minit = byteArrayToUnicode(initValueList[i]); + // if (initValueList[i].contains(data.split(',')[2].split('_')[0])) + // if (initValueList[i].contains(QString("原图_保存").toLocal8Bit())) + // { + // addImgToSaveStruct(HikMat[0], "0", byteArrayToUnicode(source_savePath + ".bmp"));//保存原图 + // if (HikMat.size() == 2)//3D + // addImgToSaveStruct(HikMat[1], "0", byteArrayToUnicode(source_savePath + ".tif")); + // } + // } + //} + + //if (myallNum[index] == 1) + //{ + // cv::Mat img; + // lastImgMap.insert(index, img); + //} + //else + //{ + // //判断和上一张图,是否重复 + // int dataLength = HikMat[0].total() * HikMat[0].elemSize(); + // bool res = false; + // if (myallNum[index] > 0) + // { + // cv::Mat img = lastImgMap.value(index); + // if (img.total() * img.elemSize() == dataLength) + // { + // res = memcmp(img.data, HikMat[0].data, dataLength) == 0; + // if (res == true) + // std::cout << "res ==true ====!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + // } + // } + //} + //lastImgMap.insert(index, HikMat[0]); + + //or检测:保存路径,拍照面描述,相机key_第几张图,SN_时间戳 + //and检测:保存路径,拍照面描述,相机key_第几张图,相机key_第几张图,SN_时间戳,SN_时间戳 + //汇总:保存路径,拍照面描述,触发信号_序号列表0,SN_时间戳 + QString qstring_data = data; + QStringList datalist = qstring_data.split(','); + + + /*saveKey.enqueue("datalist[0]"); + Dir2D.enqueue("datalist[1]"); + QStringList SN_dataTime; + SN_dataTime = datalist[3].split('_'); + DateTime1 = "SN_dataTime[1]"; + SN.enqueue("SN_dataTime[0]");*/ + //qCritical() << __FUNCTION__ << " line: " << __LINE__ << " data:" << qstring_data; + detect_mutex->unlock(); + + //qDebug() << __FUNCTION__ << "line:" << __LINE__ << "[INFO] " << " data: " << data << " run end"; + //cv::Mat resultDstImg = vec_mat[0].clone();// = pSeg->Evaluate(sourceImg); //返回单通道二值图 图片错误输出Image Error!但不报错。。 + //resultDstImg = pSeg->Evaluate(resultDstImg); + //resultDstImg.release(); + + return true; +} + +//传入initParas函数,格式为:相机key+参数名1#参数值1#参数值2+参数名2#参数值1... +//初始化 +bool Hd_AI_algo_3_1_hanQianDingWei::initParas(QByteArray& byte) +{ + initValueList = byte.split('+'); + QStringList valueiList; + + 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; + } + + + if (initValueList.size() > 1) + for (int i = 1; i < initValueList.size(); i++) + { + QString valuei = byteArrayToUnicode(initValueList[i]); + valueiList.append(valuei); + } + + /*pSeg = CreateSegObjS(pSeg_modulePath, 128, gpuId); + pCls = CreateClsObjV3(pCls_modulePath, gpuId, 1);*/ + + + //StationNo = vec_ret.at(0).toInt(); + //InitThreads(StationNo, img2D); + //InitModels(StationNo, img2D); + + //运行检测线程 + ifdetectThread = true; + + //线程检测:结果类完成时,使用 + //ifThreadRunDetect = true; + //QFuture future1 = QtConcurrent::run(this, &Hd_AI_algo_3_1_hanQianDingWei::detectThread); + //运行存图线程 + QFuture future2 = QtConcurrent::run(this, &Hd_AI_algo_3_1_hanQianDingWei::saveImgThread); + //detectThread(); + //seg_hanHouDingWei = handdleAI::CreateSegObjS("./model/seg-hanHouDingWei.BHD",32,0); + //原图总文件夹 + isDirExist(oriImgSaveDir); + //原图class总文件夹 + isDirExist(classImgSaveDir); + //结果图总文件夹 + isDirExist(resImgSaveDir); + + //qDebug() << "[INFO] " << " StationNo:" << StationNo << " img2D:" << img2D ; + return true; +} +// 解码 +bool Hd_AI_algo_3_1_hanQianDingWei::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; +} +//---------检测流程,根据实际项目修改--------- +bool Hd_AI_algo_3_1_hanQianDingWei::AIdetect(cv::Mat img2D, QString mysaveKey, QString myDir2D, QString mySN, QString myDataTime) +{ + try + { + //存图数据加保存队列,加锁,避免数据访问冲突 + saveStruct_mutex->lock(); + saveImgStruct mySave; + Mat sourceImg; + 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(); + //} + //sourceImg = cv::imread("D:\\mySN15-46-33-86.bmp",-1); + //sourceImg = cv::imread("D:/CCD/Image_20241017202132775.bmp", -1); + //sourceImg = cv::imread("D:/1/ruanLianJie/fbf/Image_20240816162604747.bmp",-1); + cv::Mat Paint; + sourceImg.copyTo(Paint); + if(Paint.channels() == 1) + cvtColor(Paint, Paint, COLOR_GRAY2BGR); + + HObject ho_Image; + HTuple hv_Pix(0.02); + HTuple hv_Distances; + HTuple hv_Out_line; + HTuple hv_Make; + MatToHObject(sourceImg,&ho_Image); + _628_3_ExplosionProofValves(ho_Image,hv_Pix, + &hv_Distances, + &hv_Out_line,&hv_Make); + if(hv_Make.D() == 1) + { + double ditance = hv_Distances.D(); + cv::Point p1x = hv_Out_line[1].D(), p1y = hv_Out_line[0].D(), p2x = hv_Out_line[3].D(), p2y = hv_Out_line[2].D(); + putTextHusky(Paint, utf8_to_gbk("间距"+std::to_string(ditance)).c_str(), cv::Point(0, 50), cv::Scalar(0, 255, 0), 500); + } + else + putTextHusky(Paint, utf8_to_gbk("算法错误").c_str(), cv::Point(0, 50), cv::Scalar(0, 255, 0), 500); + + + QQueue defectInfoList; + + + detect_mutex->lock(); + + + + + + resMat.push_back(Paint); + 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(); + + //往主界面发 + //emit sendResultData(resMat, resQbyte); + //resQbyte.clear(); + + //isDirExist(resImgSaveDir + mysaveKey1 + "/"); + QString qimgsavePath = resImgSaveDir + mysaveKey1 + "/" + mySN + myDataTime + ".png"; + //存图数据入队,按需 + if (resMat.size() > 0 ) + { + createDirectoryIfNotExists(resImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//"); + addImgToSaveStruct(resMat[0], "0", getResSaveFromat());//保存原图 + } + detect_mutex->unlock(); + + obj.insert("detaillists", detaillists); + obj.insert("qimgsavePath", qimgsavePath); + document.setObject(obj); + //resByte.clear(); + QByteArray qa = document.toJson(); + //resByte .enqueue(qa); + + + //resMat.release(); + sourceImg.release(); + + mySave.out_Mat.resize(0); + mysaveKey1.clear(); + qApp->processEvents(); + + + ////原图和结果都往主界面发? + //std::vector resMat; + //resMat.push_back(img2D); + //resMat.push_back(sourceRectangles); + //QByteArray resByte = mysaveKey.toLocal8Bit(); + //resByte.append(myDir2D.toLocal8Bit()); + //resByte.append(mySN.toLocal8Bit()); + //resByte.append(myDataTime.toLocal8Bit()); + + ////往主界面发送图片和数据 + ////emit writeData(resMat, resByte); + //resMat.resize(0); + //resByte.resize(0); + } + catch (...) + { + qDebug() << "[Error] " << QString::fromUtf8("检测失败!"); + return false; + } + return true; + +} + +//存图加入队列 +void Hd_AI_algo_3_1_hanQianDingWei::addImgToSaveStruct(cv::Mat img2D, QString mysaveKey, 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.toLocal8Bit().toStdString(); + saveStruct.enqueue(mySave); + saveStruct_mutex->unlock(); +} +void Hd_AI_algo_3_1_hanQianDingWei::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(); + 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_AI_algo_3_1_hanQianDingWei::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); + +} + +static int runNum = 0; +bool Hd_AI_algo_3_1_hanQianDingWei::run() +{ + clock_t start, stop; + start = clock(); + + //Sleep(1000); + detectThread(); + stop = clock(); + qDebug() << __FUNCTION__ << "line:" << __LINE__ << " run start ::runNum::" << runNum++<<" cutTime::"< +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "imgproc/imgproc_c.h" +#include "base.h" +#include "handleAI.h" +#pragma execution_character_set("utf-8") + + + +//保存图片的结构体 +struct saveImgStruct; +//{ +// cv::Mat out_Mat; +// std::string saveKey; //关键字,用于LOG日志 +// std::string savePath; //保存路径 +//}; + +//初始化流程(一次):Hd_AI_algo_3_1_hanQianDingWei,initParas +//运行流程:writeData主线程把数据传过来,run,readData此线程把数据传主线程 +class Hd_AI_algo_3_1_hanQianDingWei :public Base +{ + Q_OBJECT +public: + Hd_AI_algo_3_1_hanQianDingWei(); + virtual ~Hd_AI_algo_3_1_hanQianDingWei(); + //从类中读数据到实例对象 + bool readData(std::vector&,QByteArray&); + //实例对象把数据写入到类 + bool writeData(std::vector&, QByteArray&); + bool initParas(QByteArray&); + //运行(Logic_taskthread.cpp) + bool run(); + //线程状态 + bool checkStatus();// { return true; }; + + bool encodeResultValue(QVector append_value,QByteArray &resultByte); + bool decodeAiValue(QByteArray byte,QVector &vec_ret); + //---------检测流程,根据实际项目修改--------- + bool AIdetect(cv::Mat img2D, QString saveKey, QString Dir2D, QString SN, QString DataTime); + //handdleAI::pSegmentation* seg_hanHouDingWei; +private: + int allNum = 0; + int StationNo=0; + int img2D = 2; + + bool moduleStatus = true; + + //输入图片队列 + QQueue HikMat; + //输入关键字队列 + QString saveKey="saveKey"; + //结果路径文件夹队列 + QString Dir2D="Dir2D"; + //产品SN队列 + QString SN="SN"; + //产品时间戳队列 + QString DateTime1="DateTime1"; + + int paramNum; + + //是否使用线程检测方式 + bool ifThreadRunDetect = false; + //检测结果图 + std::vector resMat; + //检测结果 + bool resIfNg = false; + + QQueue resByte; + + //检测线程 + void detectThread(); + //存图线程 + void saveImgThread(); + + //保存图片队列 + QQueue saveStruct; + + //判断文件夹是否存在,不存在则创建 + void isDirExist(QString fullDirName); + + //存图加入队列 + void addImgToSaveStruct(cv::Mat img2D, QString saveKey, QString savePath); +}; + +extern "C" +{ + Q_DECL_EXPORT Hd_AI_algo_3_1_hanQianDingWei * create(); + Q_DECL_EXPORT void destory(Hd_AI_algo_3_1_hanQianDingWei * ptr); +} +//保存图片的结构体 +struct saveImgStruct +{ + cv::Mat out_Mat; + std::string saveKey; //关键字,用于LOG日志 + std::string savePath; //保存路径 +}; +#endif // Hd_AI_927_2D_module_H diff --git a/BaseModules/Hd_AI_algo_3_1_hanQianDingWei/base.h b/BaseModules/Hd_AI_algo_3_1_hanQianDingWei/base.h new file mode 100644 index 0000000..00bd6b2 --- /dev/null +++ b/BaseModules/Hd_AI_algo_3_1_hanQianDingWei/base.h @@ -0,0 +1,69 @@ +#ifndef __BASECLASS_H__ +#define __BASECLASS_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class Base :public QObject +{ + Q_OBJECT +public: + bool init_flag; //是否初始化,false,true + bool status = true; //相机状态(判断相机是否断开连接) + std::string paras; //传输数据 + std::vector m_mat; //传输图片 + std::string moduleName; //模块名称 +public: + Base(){} + virtual ~Base(){} + virtual bool readData(std::vector&,QByteArray&){return true;} + virtual bool writeData(std::vector&,QByteArray&){return true;} + virtual bool initParas(QByteArray&){return true;} + virtual bool run() {return true;} + virtual bool checkStatus() { return true; } + +//signals: + //QByteArrayList,根据实际项目进行解析;因不确定每个参数的长度,固用队列的方式。每个QByteArray表示一个值,使用时先转换为QString + //参数,例:返回结果图;相机关键字(SN或userID)+保存路径+缺陷信息列表(缺陷名称,缺陷位置int(x,y,w,h),画框颜色Scalar(a,b,c),缺陷面积double) + //void sendResultData(cv::Mat resMat, QJsonObject resQbj); +}; + +/* +//QJsonObject 转QByteArray +{ + QJsonDocument document; + QJsonObject obj; + obj.insert(password, "pwd"); + obj.insert(userName, "usr"); + document.setObject(obj); + QByteArray abyte = document.toJson(QJsonDocument::Compact); +} + +//QByteArray转QJsonObject +{ + QByteArray ba = reply->readAll(); + QJsonDocument doc = QJsonDocument::fromJson(ba); + QJsonObject obj = doc.object(); +} +*/ +/* +//从类中读数据到实例对象 +virtual bool readData(std::vector&,QByteArray&){return true;} + + + + + + + + +*/ + +#endif diff --git a/BaseModules/Hd_AI_tmp_module_savImg/CMakeLists.txt b/BaseModules/Hd_AI_tmp_module_savImg/CMakeLists.txt index 06f29aa..d6e2eaa 100644 --- a/BaseModules/Hd_AI_tmp_module_savImg/CMakeLists.txt +++ b/BaseModules/Hd_AI_tmp_module_savImg/CMakeLists.txt @@ -3,7 +3,7 @@ get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) string(TIMESTAMP RUN_TIME) message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) -set(DLL_NAMES "opencv" "halcon") +set(DLL_NAMES "opencv" "halcon" "myTools" ) foreach(child ${DLL_NAMES}) LIST(APPEND ENV_INCLUDE ${${child}_include}) LIST(APPEND ENV_LIB ${${child}_lib}) diff --git a/BaseModules/Hd_AI_tmp_module_savImg/Hd_AI_tmp_module_savImg.cpp b/BaseModules/Hd_AI_tmp_module_savImg/Hd_AI_tmp_module_savImg.cpp index 75b15c9..f5d52ed 100644 --- a/BaseModules/Hd_AI_tmp_module_savImg/Hd_AI_tmp_module_savImg.cpp +++ b/BaseModules/Hd_AI_tmp_module_savImg/Hd_AI_tmp_module_savImg.cpp @@ -3,54 +3,148 @@ #include #include - #include +#include +#include using namespace cv; - -//原图保存文件夹 需要手动设置 - QString oriImgSaveDir = "D:/601线/超声波终焊01号机/极性检测/"; -//原图class图保存文件夹 需要手动设置 - QString classImgSaveDir = "F:/ORIclass/"; -//结果保存文件夹 需要手动设置 - QString resImgSaveDir = "F:/res/"; - +//原图保存文件夹s +QString oriImgSaveDir = "D:/601线/软连接CCD/临时存图CCD/相机1/原图/"; +//原图class图保存文件夹 +QString classImgSaveDir = "D:/601线/软连接CCD/临时存图CCD/相机1/class图/"; +//结果保存文件夹 +QString resImgSaveDir = "D:/601线/软连接CCD/临时存图位CCD/相机1/结果图/"; +int algoResult = 0;//0 OK 1 NG //切图的class的width,根据项目实际设置! - int sizeW = 150; +int sizeW = 150; //切图的class的height,根据项目实际设置! - int sizeH = 150; +int sizeH = 150; //切图的class的width,根据项目实际设置!0为黑,255为白; - int fillColour = 0; +int fillColour = 0; //检测线程锁 - QMutex* detect_mutex; +QMutex* detect_mutex; //保存线程锁 - QMutex* saveStruct_mutex; +QMutex* saveStruct_mutex; //检测线程运行标志 - bool ifdetectThread = false; +bool ifdetectThread = false; - QString cameraKey_index = ""; +QString cameraKey_index = ""; - //初始化参数列表 - QByteArrayList initValueList; +//初始化参数列表 +QByteArrayList initValueList; - QString byteArrayToUnicode(const QByteArray array) { +static void createDirectoryIfNotExists(const QString& path) { + QDir dir; + dir.mkpath(path); +} +static std::string getCurrentTime() { - // 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; - } + // 获取当前时间点 + 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"; +} +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; +} +static cv::Rect findMaxAreaContour(cv::Mat src) +{ + int maxIndex = 0, maxArea = 0; + std::vector>contours; + cv::findContours(src, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); + if (contours.size() == 0) + return cv::Rect(0, 0, 0, 0); + for (int i = 0; i < contours.size(); i++) + { + int Area = cv::contourArea(contours[i]); + if (Area > maxArea) + { + maxArea = Area; + maxIndex = i; + } + } + if (contours.size() != 0) + return cv::boundingRect(contours[maxIndex]); + return cv::Rect(0, 0, 0, 0); +} +inline std::string utf8_to_gbk(const std::string& str) +{ + std::wstring_convert> conv; + std::wstring tmp_wstr = conv.from_bytes(str); + //GBK locale name in windows + const char* GBK_LOCALE_NAME = ".936"; + std::wstring_convert> convert(new std::codecvt_byname(GBK_LOCALE_NAME)); + return convert.to_bytes(tmp_wstr); +} +void getAllFiles(std::string path, std::vector& files, std::string format) +{ + intptr_t hFile = 0;//文件句柄 + struct _finddata_t fileinfo;//文件信息 + std::string p; + if ((hFile = _findfirst(p.assign(path).append("\\*" + format).c_str(), &fileinfo)) != -1) //文件存在 + { + do + { + if ((fileinfo.attrib & _A_SUBDIR))//判断是否为文件夹 + { + if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)//文件夹名中不含"."和".." + { + files.push_back(p.assign(path).append("\\").append(fileinfo.name)); //保存文件夹名 + getAllFiles(p.assign(path).append("\\").append(fileinfo.name), files, format); //递归遍历文件夹 + } + } + else + { + files.push_back(p.assign(path).append("\\").append(fileinfo.name));//如果不是文件夹,储存文件名 + } + } while (_findnext(hFile, &fileinfo) == 0); + _findclose(hFile); + } +} +QString geteOriSaveFromat() +{ + return oriImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//" + + "ORI_" + cameraKey_index + "_" + QString::fromStdString(getCurrentTime()) + ".bmp"; +} +QString geteOriSaveFromat2() +{ + return oriImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//" + + "ORI2_" + cameraKey_index + "_" + QString::fromStdString(getCurrentTime()) + ".bmp"; +} +QString getResSaveFromat() +{ + return resImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//" + + "RES_" + cameraKey_index + "_" + QString::fromStdString(getCurrentTime()) + ".png"; +} // 缺陷信息结构体 typedef struct { QString defectName = "";//缺陷名称 @@ -60,7 +154,111 @@ typedef struct { double defectDepth = 0;//缺陷深度/高度,3D信息 }defectInfo; +//Mat转Halcon图像 +void 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;*/ + + } + 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; + + } + +} //判断文件是否存在,不存在则创建 bool isFileExist(QString fullFileName) @@ -81,6 +279,8 @@ void GetStringSize(HDC hdc, const char* str, int* w, int* h) 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) { @@ -266,14 +466,14 @@ void Hd_AI_tmp_module_savImg::isDirExist(QString fullDirName) Hd_AI_tmp_module_savImg* create() { - qDebug() << "[INFO] " << " Hd_AI_tmp_module_savImg create success!" ; + qDebug() << "[INFO] " << " Hd_AI_tmp_module_savImg create success!"; return new Hd_AI_tmp_module_savImg; } void destory(Hd_AI_tmp_module_savImg* ptr) { qDebug() << "[INFO] " << "Hd_AI_tmp_module_savImg destory success!"; - if(ptr) + if (ptr) { delete ptr; ptr = nullptr; @@ -285,7 +485,6 @@ Hd_AI_tmp_module_savImg::Hd_AI_tmp_module_savImg() detect_mutex = new QMutex; saveStruct_mutex = new QMutex; ifdetectThread = false; - for (int i = 0; i < 4; i++) { QString DirPath = "E:/testImg/source" + QString::number(i); @@ -319,29 +518,30 @@ Hd_AI_tmp_module_savImg::~Hd_AI_tmp_module_savImg() delete saveStruct_mutex; saveStruct_mutex = nullptr; } + /*DestroySegObj(pSeg); DestroyClsObj(pCls);*/ } //从类中读数据到实例对象 -bool Hd_AI_tmp_module_savImg::readData(std::vector&vec_mat,QByteArray &data) +bool Hd_AI_tmp_module_savImg::readData(std::vector& vec_mat, QByteArray& data) { detect_mutex->lock(); //qDebug() << __FUNCTION__ << " line:" <<__LINE__ << " data len:" << data.length(); - if (resMat.size()>0) + if (resMat.size() > 0) { vec_mat.push_back(resMat[0]); resMat.clear(); } else { - if(HikMat.size()>0) + if (HikMat.size() > 0) vec_mat.push_back(HikMat[0]); //qDebug() << __FUNCTION__ << " line:" << __LINE__ << " resMat.data err:"; } //if (allNum++ % 2 == 0) // data = "2*3*2";// resByte.dequeue(); //else - data = "1*1*1*1+1234+123666";//1OK,2NG + data = "1*" + QByteArray::number(algoResult) + "&+" + QByteArray::number(algoResult);//1OK,2NG resByte.clear(); ////之后根据结果类修改 //if(resIfNg == true) @@ -349,40 +549,41 @@ bool Hd_AI_tmp_module_savImg::readData(std::vector&vec_mat,QByteArray & //else data = "OK"; detect_mutex->unlock(); /*if(cameraKey_index.contains('_')) - qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getDetectData--CameraName:" + qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getDetectData--CameraName:" << cameraKey_index.split("_")[0] << " imgIndex:" << cameraKey_index.split("_")[1]; else qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getDetectData--CameraName imgIndex:" << cameraKey_index;*/ return true; } //从类中读数据到实例对象 -bool Hd_AI_tmp_module_savImg::encodeResultValue(QVector append_value,QByteArray &resultByte) +bool Hd_AI_tmp_module_savImg::encodeResultValue(QVector append_value, QByteArray& resultByte) { try { std::string sendMsg; - for(int i = 0 ; i < append_value.size();i++) + 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 ); + 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 ); + 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) + } + catch (QString ev) { qCritical() << "[Error] " << " ev:" << ev; return false; @@ -390,13 +591,13 @@ bool Hd_AI_tmp_module_savImg::encodeResultValue(QVector append_valu return true; } -int myallNum[4] = {0}; +int myallNum[4] = { 0 }; QMap lastImgMap; //接收数据 -bool Hd_AI_tmp_module_savImg::writeData(std::vector& vec_mat, QByteArray &data) +bool Hd_AI_tmp_module_savImg::writeData(std::vector& vec_mat, QByteArray& data) { //qDebug() << __FUNCTION__ << "line:"<< __LINE__ << " data len" << data.length() ; - if(vec_mat.empty()) + if (vec_mat.empty()) { qCritical() << "[Error] " << " vec_mat is null !"; return false; @@ -404,7 +605,7 @@ bool Hd_AI_tmp_module_savImg::writeData(std::vector& vec_mat, QByteArra detect_mutex->lock(); HikMat.clear(); for (int i = 0; i < vec_mat.size(); i++) - HikMat.enqueue(vec_mat[i]); + HikMat.enqueue(vec_mat[i]); QByteArray source_savePath; QByteArray sData = data; @@ -415,7 +616,7 @@ bool Hd_AI_tmp_module_savImg::writeData(std::vector& vec_mat, QByteArra cameraKey_index = splitDataList[2]; QByteArray saveDir = splitDataList[0] + "/" + splitDataList[1] + "/"; isDirExist(byteArrayToUnicode(saveDir)); //不存在,创建 - QString sdataTime= QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz"); + QString sdataTime = QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz"); source_savePath = splitDataList[0] + "/" + splitDataList[1] + "/" + sdataTime.toLocal8Bit() + "-" + splitDataList[2] + "-" + splitDataList[3];// +".bmp"; } //int index = -1; @@ -441,25 +642,27 @@ bool Hd_AI_tmp_module_savImg::writeData(std::vector& vec_mat, QByteArra }*/ - - - if (!source_savePath.isEmpty()) - { - //std::cout << "try savePath::" << savePath.toStdString() << std::endl; - //测试相机的, - //while (HikMat[0].cols > 2000)cv::resize(HikMat[0], HikMat[0], cv::Size(), 0.08, 0.08);' - for (int i = 0; i < initValueList.size(); i++) - { - QString minit = byteArrayToUnicode(initValueList[i]); - if (initValueList[i].contains(data.split(',')[2].split('_')[0])) - if (initValueList[i].contains(QString("原图_保存").toLocal8Bit())) - { - addImgToSaveStruct(HikMat[0], "0", byteArrayToUnicode(source_savePath + ".bmp"));//保存原图 - if (HikMat.size() == 2)//3D - addImgToSaveStruct(HikMat[1], "0", byteArrayToUnicode(source_savePath + ".tif")); - } - } - } + createDirectoryIfNotExists(oriImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//"); + addImgToSaveStruct(HikMat[0], "0", geteOriSaveFromat());//保存原图 + if(HikMat.size()>0) + addImgToSaveStruct(HikMat[1], "0", geteOriSaveFromat2());//保存原图 + //if (!source_savePath.isEmpty()) + //{ + // //std::cout << "try savePath::" << savePath.toStdString() << std::endl; + // //测试相机的, + // //while (HikMat[0].cols > 2000)cv::resize(HikMat[0], HikMat[0], cv::Size(), 0.08, 0.08);' + // for (int i = 0; i < initValueList.size(); i++) + // { + // QString minit = byteArrayToUnicode(initValueList[i]); + // if (initValueList[i].contains(data.split(',')[2].split('_')[0])) + // if (initValueList[i].contains(QString("原图_保存").toLocal8Bit())) + // { + // addImgToSaveStruct(HikMat[0], "0", byteArrayToUnicode(source_savePath + ".bmp"));//保存原图 + // if (HikMat.size() == 2)//3D + // addImgToSaveStruct(HikMat[1], "0", byteArrayToUnicode(source_savePath + ".tif")); + // } + // } + //} //if (myallNum[index] == 1) //{ @@ -493,7 +696,7 @@ bool Hd_AI_tmp_module_savImg::writeData(std::vector& vec_mat, QByteArra /*saveKey.enqueue("datalist[0]"); Dir2D.enqueue("datalist[1]"); - QStringList SN_dataTime; + QStringList SN_dataTime; SN_dataTime = datalist[3].split('_'); DateTime1 = "SN_dataTime[1]"; SN.enqueue("SN_dataTime[0]");*/ @@ -535,13 +738,11 @@ bool Hd_AI_tmp_module_savImg::initParas(QByteArray& byte) valueiList.append(valuei); } - /*pSeg = CreateSegObjS(pSeg_modulePath, 128, gpuId); pCls = CreateClsObjV3(pCls_modulePath, gpuId, 1);*/ //StationNo = vec_ret.at(0).toInt(); - //InitThreads(StationNo, img2D); //InitModels(StationNo, img2D); @@ -554,7 +755,7 @@ bool Hd_AI_tmp_module_savImg::initParas(QByteArray& byte) //运行存图线程 QFuture future2 = QtConcurrent::run(this, &Hd_AI_tmp_module_savImg::saveImgThread); //detectThread(); - + //seg_hanHouDingWei = handdleAI::CreateSegObjS("./model/seg-hanHouDingWei.BHD",32,0); //原图总文件夹 isDirExist(oriImgSaveDir); //原图class总文件夹 @@ -562,46 +763,44 @@ bool Hd_AI_tmp_module_savImg::initParas(QByteArray& byte) //结果图总文件夹 isDirExist(resImgSaveDir); - //qDebug() << "[INFO] " << " StationNo:" << StationNo << " img2D:" << img2D ; return true; } // 解码 -bool Hd_AI_tmp_module_savImg::decodeAiValue(QByteArray byte,QVector &vec_ret) +bool Hd_AI_tmp_module_savImg::decodeAiValue(QByteArray byte, QVector& vec_ret) { - if(byte.isEmpty()) + 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); + 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); + 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); + 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 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); + QByteArray mm_data = byte.mid(0, len); vec_ret.append(mm_data); - byte.remove(0,len); + byte.remove(0, len); } return true; } - //---------检测流程,根据实际项目修改--------- bool Hd_AI_tmp_module_savImg::AIdetect(cv::Mat img2D, QString mysaveKey, QString myDir2D, QString mySN, QString myDataTime) { @@ -633,178 +832,43 @@ bool Hd_AI_tmp_module_savImg::AIdetect(cv::Mat img2D, QString mysaveKey, QString // csvName.write(lines[i].toStdString().c_str()); // csvName.close(); //} + //sourceImg = cv::imread("D:\\mySN15-46-33-86.bmp",-1); + //sourceImg = cv::imread("D:/CCD/Image_20241017202132775.bmp", -1); + //sourceImg = cv::imread("D:/1/ruanLianJie/fbf/Image_20240816162604747.bmp",-1); + //cv::Mat Paint; + //sourceImg.copyTo(Paint); + //if (Paint.channels() == 1) + // cvtColor(Paint, Paint, COLOR_GRAY2BGR); + + //HObject ho_Image; + //HTuple hv_Pix(0.02); + //HTuple hv_Distances; + //HTuple hv_Out_line; + //HTuple hv_Make; + //MatToHObject(sourceImg, &ho_Image); + //_628_3_ExplosionProofValves(ho_Image, hv_Pix, + // &hv_Distances, + // &hv_Out_line, &hv_Make); + //if (hv_Make.D() == 1) + //{ + // double ditance = hv_Distances.D(); + // cv::Point p1x = hv_Out_line[1].D(), p1y = hv_Out_line[0].D(), p2x = hv_Out_line[3].D(), p2y = hv_Out_line[2].D(); + // putTextHusky(Paint, utf8_to_gbk("间距" + std::to_string(ditance)).c_str(), cv::Point(0, 50), cv::Scalar(0, 255, 0), 500); + //} + //else + // putTextHusky(Paint, utf8_to_gbk("算法错误").c_str(), cv::Point(0, 50), cv::Scalar(0, 255, 0), 500); + QQueue defectInfoList; - //seg后class检测逻辑 - /*if (0) { - Mat sourceRectangles;// 在原图缺陷位置,边界矩形框出 - sourceRectangles = sourceImg.clone(); - //sourceImg.copyTo(sourceRectangles); - vector> contours; - - //seg检测 - Mat resultDstImg;// = sourceImg.clone();// = pSeg->Evaluate(sourceImg); //返回单通道二值图 图片错误输出Image Error!但不报错。。 - resultDstImg = pSeg->Evaluate(sourceImg); - //int resultClass = pCls->Evaluate(sourceImg); //类别id - - //opencv对二值图进行处理 - //GaussianBlur(resultDstImg, resultDstImg, Size(3, 3), 1); //缺陷过滤值较大时,可以减少检出数;缺陷较小时,漏检较多 - threshold(resultDstImg, resultDstImg, pSeg->m_classes, 255, THRESH_BINARY_INV);//大于部分设为0,小于部分设为255 - //findContours(resultDstImg, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); //不识别内部轮廓,有些情况抓到的图像外框? - findContours(resultDstImg, contours, cv::noArray(), cv::RETR_TREE, cv::CHAIN_APPROX_NONE); //需要内部轮廓的写法 - - if (contours.size() == 0) - { - //printf("Notlabeled\n"); - } - else - { - for (int j = 0; j < contours.size(); j++) - { - Rect rect1 = boundingRect(Mat(contours[j])); - - //最小缺陷过滤参数,根据项目实际设置! - int filterNum = 10; - float w = rect1.width * 1.0; - float h = rect1.height * 1.0; - if ((w / sourceImg.cols > 0.98) || (h / sourceImg.rows > 0.98)) - { - //抓到图像外框了 - //qDebug() << "NG is too big..."; - continue; - } - //且逻辑,有的项目需要或逻辑!! - if ((w > filterNum && h > filterNum))//||rect1.area> filterNum*filterNum*1.5) - { - //class检测mat - Mat imgCls; - - //此段为切图逻辑为: - //缺陷外扩5像素; - //判断最大边,大于class建网大小的,按照最大边尺寸比例切大图,然后resize为建网大小;最大边小于等于建网大小的,按照建网大小切图; - //越界填充 - { - int startX = rect1.x - 5; - int startY = rect1.y - 5; - int endX = rect1.x + rect1.width + 5; - int endY = rect1.y + rect1.height + 5; - - //尺寸比例 - double maxscaler, scalerX, scalerY; - maxscaler = 1.0; - scalerX = (endX - startX) * 1.0 / sizeW;//*1.0转为float,避免被取整了 - scalerY = (endY - startY) * 1.0 / sizeH; - - maxscaler = max(maxscaler, max(scalerX, scalerY)); - - int avgX = (rect1.x + rect1.x + rect1.width) / 2; //中点X位置 - int avgY = (rect1.y + rect1.y + rect1.height) / 2;//中点Y位置 - - startX = avgX - int(maxscaler * sizeW / 2);//强转为int - endX = startX + int(maxscaler * sizeW); - startY = avgY - int(maxscaler * sizeH / 2); - endY = startY + int(maxscaler * sizeH); - - //判断是否越界,越界要填充的像素个数 - int copyTop = max(0, 0 - startY); - int copyButton = max(0, endY - sourceImg.rows); - int copyLeft = max(0, 0 - startX); - int copyRight = max(0, endX - sourceImg.cols); - - //切图不要越界,会崩溃 - Mat imgCut = sourceImg(Range(max(0, startY - copyTop), min(sourceImg.rows, endY - copyButton)), - Range(max(0, startX - copyLeft), min(sourceImg.cols, endX - copyRight))); //起始行,终止行;起始列,终止列 - - //图像扩充 - if (sourceImg.channels() == 1) - { - copyMakeBorder(imgCut, imgCut, copyTop, copyButton, copyLeft, copyRight, BORDER_CONSTANT, fillColour); - } - else - { - copyMakeBorder(imgCut, imgCut, copyTop, copyButton, copyLeft, copyRight, BORDER_CONSTANT, Scalar(fillColour, fillColour, fillColour)); - } - //resize为建网大小 - cv::resize(imgCut, imgCls, cv::Size(sizeW, sizeH)); - imgCut.release(); - } - - - int resultClass = 0; - float prob = 1.0; - - resultClass = pCls->Evaluate(imgCls); //类别id - prob = pCls->getProbability(); //可能性 - - //切图保存,按需 - { - isDirExist(classImgSaveDir + mysaveKey1 + "/class_" + QString::number(resultClass)); - //存图数据入队,按需 - addImgToSaveStruct(imgCls, mysaveKey1, classImgSaveDir + mysaveKey1 + "/class_" + QString::number(resultClass) + "/" + mySN + myDataTime + QString::number(j) + ".bmp"); - } - - //此处应添加缺陷计数逻辑 - - if (resultClass == 0)//OK - { - ; - } - else if (resultClass == 1)//划伤Scratch - { - resIfNg = true; - //rectangle(sourceRectangles, rect1.tl(), rect1.br(), Scalar(0, 0, 255), 3, 8); - ////可行,必须转一下格式 - //{ - // QString pathQstr = "划伤"; - // QByteArray path_arr = pathQstr.toLocal8Bit(); - // const char* path = path_arr.data(); - // putTextZH(sourceRectangles, path, cv::Point(rect1.tl().x, rect1.tl().y - 5), Scalar(255, 0, 0), 50, "微软雅黑"); - //} - - defectInfo mdefectInfo; - mdefectInfo.defectName = "划伤"; - mdefectInfo.defectRect = rect1; - mdefectInfo.defectArea = contourArea(contours[j]); - mdefectInfo.defectScalar = cv::Scalar(0, 0, 255); - defectInfoList.enqueue(mdefectInfo); - } - else if (resultClass == 2)//碰伤 - { - resIfNg = true; - defectInfo mdefectInfo; - mdefectInfo.defectName = "碰伤"; - mdefectInfo.defectRect = rect1; - mdefectInfo.defectArea = contourArea(contours[j]); - mdefectInfo.defectScalar = cv::Scalar(0, 255, 255); - defectInfoList.enqueue(mdefectInfo); - } - imgCls.release(); - } - else { - //cout << "ng is too small<" << filterNum << endl; - continue; - } - } - } - //cv::Mat resMat = img2D.clone(); - sourceRectangles.release(); - contours.resize(0); - resultDstImg.release(); - } - */ detect_mutex->lock(); - //resMat = sourceImg.clone(); - //sourceImg.copyTo(resMat); - resMat.push_back(sourceImg); - //结果图画框和缺陷,在resMat上绘制 - if (resMat.size() > 0) - drawDefects(resMat[0], defectInfoList); - //QByteArray,根据实际项目进行解析 - //参数,例:返回结果图;相机关键字(SN或userID)+保存路径+缺陷信息列表(缺陷名称,缺陷位置int(x,y,w,h),画框颜色Scalar(a,b,c),缺陷面积double) + + + + //resMat.push_back(Paint); QJsonArray detaillists; //QByteArrayList resQbyte; for (int i = 0; i < defectInfoList.size(); i++) @@ -829,7 +893,7 @@ bool Hd_AI_tmp_module_savImg::AIdetect(cv::Mat img2D, QString mysaveKey, QString 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))); + detailObj.insert("defectLength", QString::number(sqrt(mdefect.defectRect.width * mdefect.defectRect.width + mdefect.defectRect.height * mdefect.defectRect.height))); detaillists.append(detailObj); } @@ -842,11 +906,14 @@ bool Hd_AI_tmp_module_savImg::AIdetect(cv::Mat img2D, QString mysaveKey, QString //emit sendResultData(resMat, resQbyte); //resQbyte.clear(); - isDirExist(resImgSaveDir + mysaveKey1 + "/"); + //isDirExist(resImgSaveDir + mysaveKey1 + "/"); QString qimgsavePath = resImgSaveDir + mysaveKey1 + "/" + mySN + myDataTime + ".png"; //存图数据入队,按需 - if (resMat.size() > 0 ) - addImgToSaveStruct(resMat[0], mysaveKey1, resImgSaveDir + mysaveKey1 + "/" + mySN + myDataTime + ".png"); + if (resMat.size() > 0) + { + createDirectoryIfNotExists(resImgSaveDir + getCurrentDate() + "//" + getCurrentHour() + "//"); + addImgToSaveStruct(resMat[0], "0", getResSaveFromat());//保存原图 + } detect_mutex->unlock(); obj.insert("detaillists", detaillists); @@ -889,7 +956,7 @@ bool Hd_AI_tmp_module_savImg::AIdetect(cv::Mat img2D, QString mysaveKey, QString } //存图加入队列 -void Hd_AI_tmp_module_savImg::addImgToSaveStruct(cv::Mat img2D, QString mysaveKey, QString savePath) +void Hd_AI_tmp_module_savImg::addImgToSaveStruct(cv::Mat img2D, QString mysaveKey, QString savePath) { //存图数据加保存队列,加锁,避免数据访问冲突 saveStruct_mutex->lock(); @@ -917,7 +984,7 @@ void Hd_AI_tmp_module_savImg::saveImgThread() saveImgStruct mysaveStruct = saveStruct.dequeue(); saveStruct_mutex->unlock(); stop = clock(); - if(stop-start >1000) + if (stop - start > 1000) std::cout << "lock stop-start >1000::************************" << stop - start << std::endl; start = clock(); if (mysaveStruct.out_Mat.data) @@ -925,7 +992,7 @@ void Hd_AI_tmp_module_savImg::saveImgThread() //std::cout << "savePath::" << mysaveStruct.savePath << std::endl; stop = clock(); if (stop - start > 1000) - std::cout << "imwrite stop-start >1000::--------------------------"<< stop - start << std::endl; + std::cout << "imwrite stop-start >1000::--------------------------" << stop - start << std::endl; _sleep(1); } } @@ -935,7 +1002,7 @@ void Hd_AI_tmp_module_savImg::detectThread() { do { - if (!ifdetectThread)return; + if (!ifdetectThread)return; //此两行代码,避免程序卡死;_sleep的时间根据实际项目调整 _sleep(2); @@ -965,9 +1032,9 @@ void Hd_AI_tmp_module_savImg::detectThread() isDirExist(resImgSaveDir + mysaveKey); } - + //测试相机的, - while (sourceImg1.cols > 2000)cv::resize(sourceImg1, sourceImg1, cv::Size(), 0.5, 0.5); + // while (sourceImg1.cols > 2000)cv::resize(sourceImg1, sourceImg1, cv::Size(), 0.5, 0.5); //存图数据入队 //addImgToSaveStruct(sourceImg1, mysaveKey, oriImgSaveDir + mysaveKey + "/" + mySN + myDataTime + ".bmp"); @@ -980,24 +1047,12 @@ void Hd_AI_tmp_module_savImg::detectThread() myDir2D.clear(); mySN.clear(); myDataTime.clear(); - qApp->processEvents(); + qApp->processEvents(); } while (ifThreadRunDetect); - -} -static std::string getCurrentDateTime() { - // 获取当前时间点 - 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 int runNum = 0; bool Hd_AI_tmp_module_savImg::run() { @@ -1005,11 +1060,11 @@ bool Hd_AI_tmp_module_savImg::run() start = clock(); //Sleep(1000); - //detectThread(); - //stop = clock(); - //qDebug() << __FUNCTION__ << "line:" << __LINE__ << " run start ::runNum::" << runNum++<<" cutTime::"< #include #include - #include #include #include "imgproc/imgproc_c.h" - #include "base.h" - #pragma execution_character_set("utf-8") @@ -43,7 +40,7 @@ public: Hd_AI_tmp_module_savImg(); virtual ~Hd_AI_tmp_module_savImg(); //从类中读数据到实例对象 - bool readData(std::vector&,QByteArray&); + bool readData(std::vector&, QByteArray&); //实例对象把数据写入到类 bool writeData(std::vector&, QByteArray&); bool initParas(QByteArray&); @@ -52,17 +49,14 @@ public: //线程状态 bool checkStatus();// { return true; }; - bool encodeResultValue(QVector append_value,QByteArray &resultByte); - bool decodeAiValue(QByteArray byte,QVector &vec_ret); + bool encodeResultValue(QVector append_value, QByteArray& resultByte); + bool decodeAiValue(QByteArray byte, QVector& vec_ret); //---------检测流程,根据实际项目修改--------- bool AIdetect(cv::Mat img2D, QString saveKey, QString Dir2D, QString SN, QString DataTime); - - - + //handdleAI::pSegmentation* seg_hanHouDingWei; private: - int allNum = 0; - int StationNo=0; + int StationNo = 0; int img2D = 2; bool moduleStatus = true; @@ -70,13 +64,13 @@ private: //输入图片队列 QQueue HikMat; //输入关键字队列 - QString saveKey="saveKey"; + QString saveKey = "saveKey"; //结果路径文件夹队列 - QString Dir2D="Dir2D"; + QString Dir2D = "Dir2D"; //产品SN队列 - QString SN="SN"; + QString SN = "SN"; //产品时间戳队列 - QString DateTime1="DateTime1"; + QString DateTime1 = "DateTime1"; int paramNum; @@ -93,7 +87,7 @@ private: void detectThread(); //存图线程 void saveImgThread(); - + //保存图片队列 QQueue saveStruct; @@ -106,8 +100,8 @@ private: extern "C" { - Q_DECL_EXPORT Hd_AI_tmp_module_savImg * create(); - Q_DECL_EXPORT void destory(Hd_AI_tmp_module_savImg * ptr); + Q_DECL_EXPORT Hd_AI_tmp_module_savImg* create(); + Q_DECL_EXPORT void destory(Hd_AI_tmp_module_savImg* ptr); } //保存图片的结构体 struct saveImgStruct diff --git a/BaseModules/Hd_LogicDll_module/CMakeLists.txt b/BaseModules/Hd_LogicDll_module/CMakeLists.txt index 9f697ac..b935737 100644 --- a/BaseModules/Hd_LogicDll_module/CMakeLists.txt +++ b/BaseModules/Hd_LogicDll_module/CMakeLists.txt @@ -4,7 +4,7 @@ string(TIMESTAMP RUN_TIME) message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) -set(DLL_NAMES "opencv" "qt5") +set(DLL_NAMES "opencv" "qt5" "myTools") foreach(child ${DLL_NAMES}) LIST(APPEND ENV_INCLUDE ${${child}_include}) LIST(APPEND ENV_LIB ${${child}_lib}) diff --git a/BaseModules/Hd_LogicDll_module/Logic_hdataprocess.cpp b/BaseModules/Hd_LogicDll_module/Logic_hdataprocess.cpp index ab2d8ac..24a420c 100644 --- a/BaseModules/Hd_LogicDll_module/Logic_hdataprocess.cpp +++ b/BaseModules/Hd_LogicDll_module/Logic_hdataprocess.cpp @@ -18,10 +18,10 @@ void HSnData::addSnVector(QVector snVec) QVector vec_str = queue_vector_sn.last(); if (!vec_str.isEmpty()) { - //if (!vec_str[0].contains(snVec[0])) //demo流程重入检查也可以 - //{ - // queue_vector_sn.append(snVec); - //} + if (!vec_str[0].contains(snVec[0])) //demo流程重入检查也可以 + { + queue_vector_sn.append(snVec); + } /*else std::cout << "HSnData::addSnVector err" << std::endl;*/ } diff --git a/BaseModules/Hd_LogicDll_module/Logic_taskthread.cpp b/BaseModules/Hd_LogicDll_module/Logic_taskthread.cpp index 55023b0..42bed7e 100644 --- a/BaseModules/Hd_LogicDll_module/Logic_taskthread.cpp +++ b/BaseModules/Hd_LogicDll_module/Logic_taskthread.cpp @@ -1,5 +1,5 @@ #include "Logic_taskthread.h" - +#include //图像锁、通信指令锁 void Logic_taskthread::setMutex(QMutex* image_lock, QMutex* write_mutex) { if (m_image_lock == nullptr) @@ -810,7 +810,13 @@ bool Logic_taskthread::deleteSnData ( QByteArray byteArray, QVector& sn // 算法结果 写入plc bool Logic_taskthread::writeAiCommond ( QString cameraName,QString camera_name_index,QByteArray byteArray ) { - QByteArrayList PLCvec_ret= byteArray.split('*'); // 存储结果的 + std::string str = byteArray.toStdString(); + int start = str.find(resultCmdSplitStart) + std::size(resultCmdSplitStart)-1; + int end = str.find(resultCmdSplitEnd)- start; + if (end > 0 && start > 0) + str = str.substr(start,end); + //char split = *generalSplit; + QByteArrayList PLCvec_ret= QByteArray::fromStdString(str).split(*generalSplit); // 存储结果的 if (PLCvec_ret.isEmpty() ) { diff --git a/HanddleAI/CMakeLists.txt b/HanddleAI/CMakeLists.txt index 7e139b4..dcc066f 100644 --- a/HanddleAI/CMakeLists.txt +++ b/HanddleAI/CMakeLists.txt @@ -13,7 +13,7 @@ foreach(dll ${OUR_LIBS}) endforeach(dll ${}) -set(DLL_NAMES "halcon" "opencv" "json" "handdleAI") +set(DLL_NAMES "halcon" "opencv" "json" "handdleAI" "myTools") foreach(child ${DLL_NAMES}) LIST(APPEND ENV_INCLUDE ${${child}_include}) LIST(APPEND ENV_LIB ${${child}_lib}) diff --git a/HanddleAI/QtSendPLC.cpp b/HanddleAI/QtSendPLC.cpp index 4bcd9a3..192dc2f 100644 --- a/HanddleAI/QtSendPLC.cpp +++ b/HanddleAI/QtSendPLC.cpp @@ -264,7 +264,7 @@ void QtSendPLC::setData(QJsonArray qjsonArray) ////sizePolicy1.setHeightForWidth(ui.widget_image->sizePolicy().hasHeightForWidth()); ////this->setStyleSheet(QString::fromUtf8("background-color: rgb(101, 103, 100);")); //this->setSizePolicy(sizePolicy1); - this->setMinimumSize(QSize(300, 200)); + this->setMinimumSize(QSize(800, 800)); pressStart = clock(); //this->show(); diff --git a/HanddleAI/QtSendPLC.h b/HanddleAI/QtSendPLC.h index 8f48002..5c2a38c 100644 --- a/HanddleAI/QtSendPLC.h +++ b/HanddleAI/QtSendPLC.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include #include "ui_QtSendPLC.h" @@ -48,11 +48,11 @@ private: public: enum MousePoss { LeftUp = 0, Up, RightUp, Right, RightDown, Down, LeftDown, Left, Middle }; private: - MousePoss mp_curPos; //¼Ç¼Êó±굱ǰËùÔÚÇøÓòµıäÁ¿ - //¸ı䴰¿ڵĴóС + MousePoss mp_curPos; //记录鼠标当前所在区域的变量 + //改变窗口的大小 void changeWindowSize(MousePoss type, QRect& wid, QPoint ptemp, int minWidth, int minHeight); - //Ð޸ÄÊó±êÑùʽ + //修改鼠标样式 void setCursorType(MousePoss type); - //¼ÆËãÊó±êλÖà + //计算鼠标位置 MousePoss calcmouseposs(QPoint p); }; diff --git a/HanddleAI/Qt_epWindow.cpp b/HanddleAI/Qt_epWindow.cpp index c7745e9..31a3921 100644 --- a/HanddleAI/Qt_epWindow.cpp +++ b/HanddleAI/Qt_epWindow.cpp @@ -1,6 +1,7 @@ #include "Qt_epWindow.h" #include "qapplication.h" #include +#include #pragma execution_character_set("utf-8") clock_t pressStart, pressStop; @@ -1803,6 +1804,24 @@ void Qt_epWindow::getTransferData(QString key, QString cameraName, QString snInf int mm = nowTime.split(" ")[1].split(":")[1].toInt(); if ((hh > 8 && hh < 20) || (hh == 8 && mm >= 30) || (hh == 20 && mm < 30)) ifNight = false; + + std::string str = byteArray.toStdString(); + std::string chartData, csvData, defectData; + //CHART表格数据 + int startChart = str.find(chartSplitStart) + std::size(chartSplitStart) - 1; + int endChart = str.find(chartSplitEnd) - startChart; + if (startChart > 0 && endChart > 0) + chartData = str.substr(startChart, endChart); + //CSV表格数据 + int startCSV = str.find(csvSplitStart) + std::size(csvSplitStart) - 1; + int endCSV = str.find(csvSplitEnd) - startCSV; + if (startCSV > 0 && endCSV > 0) + csvData = str.substr(startCSV, endCSV); + //缺陷直方图 + int startDefect = str.find(csvSplitStart) + std::size(csvSplitStart) - 1; + int endDefect = str.find(csvSplitEnd) - startDefect; + if (startDefect > 0 && endDefect > 0) + defectData = str.substr(startDefect, endDefect); if (key.contains("程序号")) { cName_surface_defectNums.clear(); @@ -1843,10 +1862,12 @@ void Qt_epWindow::getTransferData(QString key, QString cameraName, QString snInf set_tabQPushButton(0); //waiteBox-> close(); } - else if (myByte.contains("*") )//|| CommunicationProcessLevel==1) //简单流程每张图就是结果 + if (chartData.size() > 0)//|| CommunicationProcessLevel==1) //简单流程每张图就是结果 { + int result = stoi(chartData); + QPieSeriesData_ALL.allNum++; - if (myByte.contains("1*") || (CommunicationProcessLevel==1 && myByte=='1')) + if (result == 1) { myByte = "OK"; setInsertTextColor(ui.plainTextEdit_history, QColor("green")); @@ -1869,13 +1890,12 @@ void Qt_epWindow::getTransferData(QString key, QString cameraName, QString snInf if (historyLogList.size() > 100000) historyLogList.dequeue(); ui.plainTextEdit_history->appendPlainText(historyLogList.last()); - //实时信息 { ui.label_result->setText(myByte); ui.label_SN->setText(snInfo); ui.label_allNum->setText(QString::number(QPieSeriesData_ALL.allNum)); - ui.label_OKPercent->setText(QString::number(int(QPieSeriesData_ALL.okNum*1.0000 / QPieSeriesData_ALL.allNum * 10000) / 100.00) + "%"); + ui.label_OKPercent->setText(QString::number(int(QPieSeriesData_ALL.okNum * 1.0000 / QPieSeriesData_ALL.allNum * 10000) / 100.00) + "%"); ui.label_OKNum->setText(QString::number(QPieSeriesData_ALL.okNum)); ui.label_NGnum->setText(QString::number(QPieSeriesData_ALL.ngNum));; //百万级变负数?? if (QPieSeriesData_ALL.allNum > 1) @@ -1888,12 +1908,11 @@ void Qt_epWindow::getTransferData(QString key, QString cameraName, QString snInf } start = clock(); } - //饼图更新 { //ALL饼图;slices()[0] ok;slices()[1] ng; QPieSeriesData_ALL.series->slices()[0]->setValue(int(QPieSeriesData_ALL.okNum * 1.0000 / QPieSeriesData_ALL.allNum * 10000) / 100.00); - QPieSeriesData_ALL.series->slices()[1]->setValue(100.00- int(QPieSeriesData_ALL.okNum * 1.0000 / QPieSeriesData_ALL.allNum * 10000) / 100.00); + QPieSeriesData_ALL.series->slices()[1]->setValue(100.00 - int(QPieSeriesData_ALL.okNum * 1.0000 / QPieSeriesData_ALL.allNum * 10000) / 100.00); //换班判断 if (ifLastNight != ifNight) @@ -1925,7 +1944,7 @@ void Qt_epWindow::getTransferData(QString key, QString cameraName, QString snInf if (ifNight) { QPieSeriesData_night.allNum++; - if(myByte=="OK") + if (myByte == "OK") QPieSeriesData_night.okNum++; else if (myByte == "NG") QPieSeriesData_night.ngNum++; @@ -1975,11 +1994,10 @@ void Qt_epWindow::getTransferData(QString key, QString cameraName, QString snInf rowNumn++; } } - //更新缺陷统计表图 - if (myByteCpy.contains("&")) //格式为:忽略段&缺陷类型1的是否有缺陷标志&缺陷类型2的是否有缺陷标志... + if(defectData.size() > 0) { - QStringList myByteList = myByteCpy.split("&"); + QStringList myByteList = myByteCpy.split(*generalSplit); if (myByteList.size() > 1) for (int i = 1; i < myByteList.size(); i++) { @@ -2089,11 +2107,11 @@ void Qt_epWindow::getTransferData(QString key, QString cameraName, QString snInf } //写表格CSV - if (myByteCpy.contains("+")) + if (csvData.size()>0) { QString ymd = QDateTime::currentDateTime().toString("yyyy-MM-dd"); QString hms = QDateTime::currentDateTime().toString("hh:mm:ss"); - QStringList outDataList = myByteCpy.split("+"); + QStringList outDataList = myByteCpy.split(*generalSplit); std::vector strList; strList.push_back(hms.toStdString());// 时间 strList.push_back(snInfo.toStdString());//SN diff --git a/HanddleAI/modules/Hd_AI_empty_module/CMakeLists.txt b/HanddleAI/modules/Hd_AI_empty_module/CMakeLists.txt index 06f29aa..20d718b 100644 --- a/HanddleAI/modules/Hd_AI_empty_module/CMakeLists.txt +++ b/HanddleAI/modules/Hd_AI_empty_module/CMakeLists.txt @@ -3,7 +3,7 @@ get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) string(TIMESTAMP RUN_TIME) message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME}) -set(DLL_NAMES "opencv" "halcon") +set(DLL_NAMES "opencv" "halcon" "Myalgo") foreach(child ${DLL_NAMES}) LIST(APPEND ENV_INCLUDE ${${child}_include}) LIST(APPEND ENV_LIB ${${child}_lib}) diff --git a/HanddleAI/modules/Hd_AI_empty_module/Hd_AI_empty_module.cpp b/HanddleAI/modules/Hd_AI_empty_module/Hd_AI_empty_module.cpp index 3827322..96f6c21 100644 --- a/HanddleAI/modules/Hd_AI_empty_module/Hd_AI_empty_module.cpp +++ b/HanddleAI/modules/Hd_AI_empty_module/Hd_AI_empty_module.cpp @@ -3,16 +3,16 @@ #include #include - #include +#include "Myalgo.h" using namespace cv; //原图保存文件夹 - QString oriImgSaveDir = "F:/ORI/"; + QString oriImgSaveDir = "D:/D601线/超声波预焊02机/极性检测CCD/原图/"; //原图class图保存文件夹 - QString classImgSaveDir = "F:/ORIclass/"; + QString classImgSaveDir = "D:/D601线/超声波预焊02机/极性检测CCD/class图/"; //结果保存文件夹 - QString resImgSaveDir = "F:/res/"; + QString resImgSaveDir = "D:/D601线/超声波预焊02机/极性检测CCD/结果图/"; //切图的class的width,根据项目实际设置! int sizeW = 150; @@ -31,6 +31,9 @@ using namespace cv; QString cameraKey_index = ""; + //初始化参数列表 + QByteArrayList initValueList; + QString byteArrayToUnicode(const QByteArray array) { // state用于保存转换状态,它的成员invalidChars,可用来判断是否转换成功 @@ -57,7 +60,111 @@ typedef struct { double defectDepth = 0;//缺陷深度/高度,3D信息 }defectInfo; +//Mat转Halcon图像 +void 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;*/ + + } + 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; + + } + +} //判断文件是否存在,不存在则创建 bool isFileExist(QString fullFileName) @@ -331,13 +438,14 @@ bool Hd_AI_empty_module::readData(std::vector&vec_mat,QByteArray &data) } else { - vec_mat.push_back(HikMat[0]); + if(HikMat.size()>0) + vec_mat.push_back(HikMat[0]); //qDebug() << __FUNCTION__ << " line:" << __LINE__ << " resMat.data err:"; } - if (allNum++ % 21 == 20) - data = "2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2";// resByte.dequeue(); - else - data = "1";//1OK,2NG + //if (allNum++ % 2 == 0) + // data = "2*3*2";// resByte.dequeue(); + //else + data = "1*0*0";//1OK,2NG resByte.clear(); ////之后根据结果类修改 //if(resIfNg == true) @@ -399,16 +507,23 @@ bool Hd_AI_empty_module::writeData(std::vector& vec_mat, QByteArray &da } detect_mutex->lock(); HikMat.clear(); - HikMat.enqueue(vec_mat[0]); + for (int i = 0; i < vec_mat.size(); i++) + HikMat.enqueue(vec_mat[i]); - QString savePath; - QString sData = data; - QStringList splitDataList = sData.split(","); - if(splitDataList.size()>=4) - if(splitDataList[2].contains('_')) + QByteArray source_savePath; + QByteArray sData = data; + QByteArrayList splitDataList = sData.split(','); + if (splitDataList.size() >= 4) + { + if (splitDataList[2].contains('_')) cameraKey_index = splitDataList[2]; - int index = -1; - if (sData.contains("offline-camera0")) + QByteArray saveDir = splitDataList[0] + "/" + splitDataList[1] + "/"; + isDirExist(byteArrayToUnicode(saveDir)); //不存在,创建 + QString sdataTime= QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz"); + source_savePath = splitDataList[0] + "/" + splitDataList[1] + "/" + sdataTime.toLocal8Bit() + "-" + splitDataList[2] + "-" + splitDataList[3];// +".bmp"; + } + //int index = -1; + /*if (sData.contains("offline-camera0")) { index = 0; savePath = "E:\\testImg\\source0\\"+QString::number(myallNum[0]++) + ".bmp"; @@ -427,14 +542,27 @@ bool Hd_AI_empty_module::writeData(std::vector& vec_mat, QByteArray &da { index = 3; savePath = "E:\\testImg\\source3\\" + QString::number(myallNum[3]++) + ".bmp"; - } + }*/ - if (!savePath.isEmpty()) + + + + if (!source_savePath.isEmpty()) { //std::cout << "try savePath::" << savePath.toStdString() << std::endl; //测试相机的, - while (HikMat[0].cols > 2000)cv::resize(HikMat[0], HikMat[0], cv::Size(), 0.08, 0.08); - addImgToSaveStruct(HikMat[0], "0", savePath);// + //while (HikMat[0].cols > 2000)cv::resize(HikMat[0], HikMat[0], cv::Size(), 0.08, 0.08);' + for (int i = 0; i < initValueList.size(); i++) + { + QString minit = byteArrayToUnicode(initValueList[i]); + if (initValueList[i].contains(data.split(',')[2].split('_')[0])) + if (initValueList[i].contains(QString("原图_保存").toLocal8Bit())) + { + addImgToSaveStruct(HikMat[0], "0", byteArrayToUnicode(source_savePath + ".bmp"));//保存原图 + if (HikMat.size() == 2)//3D + addImgToSaveStruct(HikMat[1], "0", byteArrayToUnicode(source_savePath + ".tif")); + } + } } //if (myallNum[index] == 1) @@ -486,28 +614,28 @@ bool Hd_AI_empty_module::writeData(std::vector& vec_mat, QByteArray &da //传入initParas函数,格式为:相机key+参数名1#参数值1#参数值2+参数名2#参数值1... //初始化 -bool Hd_AI_empty_module::initParas(QByteArray& byteArray) +bool Hd_AI_empty_module::initParas(QByteArray& byte) { - QByteArrayList valueList = byteArray.split('+'); + initValueList = byte.split('+'); QStringList valueiList; - if (byteArray.contains("onlySetParameter")) + if (byte.contains("onlySetParameter")) { - qDebug() << __FUNCTION__ << " line:" << __LINE__ << "onlySetParameter,valueList[0]:" << valueList[0]; - if (valueList.size() > 1) - for (int i = 1; i < valueList.size(); i++) + qDebug() << __FUNCTION__ << " line:" << __LINE__ << "onlySetParameter,valueList[0]:" << initValueList[0]; + if (initValueList.size() > 1) + for (int i = 1; i < initValueList.size(); i++) { - QString valuei = byteArrayToUnicode(valueList[i]); - qDebug() << __FUNCTION__ << " line:" << __LINE__ << "onlySetParameter,lastName:" << valueList[0] << " ,valuei:" << valuei; + QString valuei = byteArrayToUnicode(initValueList[i]); + qDebug() << __FUNCTION__ << " line:" << __LINE__ << "onlySetParameter,lastName:" << initValueList[0] << " ,valuei:" << valuei; } return true; } - if (valueList.size() > 1) - for (int i = 1; i < valueList.size(); i++) + if (initValueList.size() > 1) + for (int i = 1; i < initValueList.size(); i++) { - QString valuei = byteArrayToUnicode(valueList[i]); + QString valuei = byteArrayToUnicode(initValueList[i]); valueiList.append(valuei); } @@ -543,37 +671,37 @@ bool Hd_AI_empty_module::initParas(QByteArray& byteArray) return true; } // 解码 -bool Hd_AI_empty_module::decodeAiValue(QByteArray byteArray,QVector &vec_ret) +bool Hd_AI_empty_module::decodeAiValue(QByteArray byte,QVector &vec_ret) { - if(byteArray.isEmpty()) + if(byte.isEmpty()) { - qCritical() << "[Error] " << " byteArray is null!"; + qCritical() << "[Error] " << " byte is null!"; return false; } /*******************************************/ - byteArray.remove(0,8); - QByteArray mm_data = byteArray.mid(0,4); + byte.remove(0,8); + QByteArray mm_data = byte.mid(0,4); memcpy((void*)¶mNum,(void*)mm_data.data(), 4); qDebug() << "[INFO] " << " paramNum:" << paramNum; - byteArray.remove(0,4); + byte.remove(0,4); /*******************************************/ - while (!byteArray.isEmpty()) + while (!byte.isEmpty()) { int type = 0; - QByteArray m_type = byteArray.mid(0,4); + QByteArray m_type = byte.mid(0,4); memcpy((void*)&type,(void*)m_type.data(), 4); - byteArray.remove(0,4); + byte.remove(0,4); int len = 0; - QByteArray m_len = byteArray.mid(0,4); + QByteArray m_len = byte.mid(0,4); memcpy((void*)&len,(void*)m_len.data(), 4); - byteArray.remove(0,4); + byte.remove(0,4); - QByteArray mm_data = byteArray.mid(0,len); + QByteArray mm_data = byte.mid(0,len); vec_ret.append(mm_data); - byteArray.remove(0,len); + byte.remove(0,len); } return true; } @@ -612,163 +740,40 @@ bool Hd_AI_empty_module::AIdetect(cv::Mat img2D, QString mysaveKey, QString myDi QQueue defectInfoList; - //seg后class检测逻辑 - /*if (0) { - Mat sourceRectangles;// 在原图缺陷位置,边界矩形框出 - sourceRectangles = sourceImg.clone(); - //sourceImg.copyTo(sourceRectangles); - vector> contours; - - //seg检测 - Mat resultDstImg;// = sourceImg.clone();// = pSeg->Evaluate(sourceImg); //返回单通道二值图 图片错误输出Image Error!但不报错。。 - resultDstImg = pSeg->Evaluate(sourceImg); - //int resultClass = pCls->Evaluate(sourceImg); //类别id - - //opencv对二值图进行处理 - //GaussianBlur(resultDstImg, resultDstImg, Size(3, 3), 1); //缺陷过滤值较大时,可以减少检出数;缺陷较小时,漏检较多 - threshold(resultDstImg, resultDstImg, pSeg->m_classes, 255, THRESH_BINARY_INV);//大于部分设为0,小于部分设为255 - //findContours(resultDstImg, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); //不识别内部轮廓,有些情况抓到的图像外框? - findContours(resultDstImg, contours, cv::noArray(), cv::RETR_TREE, cv::CHAIN_APPROX_NONE); //需要内部轮廓的写法 - - if (contours.size() == 0) + //极性检测 + HObject ho_Image; + HTuple hv_out_Value; + HTuple hv_Make; + MatToHObject(sourceImg, &ho_Image); + _628_1_Polarity_detection(ho_Image, &hv_out_Value, &hv_Make); + if (hv_Make.D() != -1) + { + if (hv_out_Value.D() == 1)//铝 { - //printf("Notlabeled\n"); + cv::putText(sourceImg, "Aluminium", cv::Point(0, 240), 2, 10, cv::Scalar(0, 255, 0), 10); + //Result = 1 ? 2; + //Result = 1; + } + else if (hv_out_Value.D() == 2)//铜 + { + cv::putText(sourceImg, "Copper", cv::Point(0, 240), 2, 10, cv::Scalar(0, 255, 0), 10); } else { - for (int j = 0; j < contours.size(); j++) - { - Rect rect1 = boundingRect(Mat(contours[j])); - - //最小缺陷过滤参数,根据项目实际设置! - int filterNum = 10; - float w = rect1.width * 1.0; - float h = rect1.height * 1.0; - if ((w / sourceImg.cols > 0.98) || (h / sourceImg.rows > 0.98)) - { - //抓到图像外框了 - //qDebug() << "NG is too big..."; - continue; - } - //且逻辑,有的项目需要或逻辑!! - if ((w > filterNum && h > filterNum))//||rect1.area> filterNum*filterNum*1.5) - { - //class检测mat - Mat imgCls; - - //此段为切图逻辑为: - //缺陷外扩5像素; - //判断最大边,大于class建网大小的,按照最大边尺寸比例切大图,然后resize为建网大小;最大边小于等于建网大小的,按照建网大小切图; - //越界填充 - { - int startX = rect1.x - 5; - int startY = rect1.y - 5; - int endX = rect1.x + rect1.width + 5; - int endY = rect1.y + rect1.height + 5; - - //尺寸比例 - double maxscaler, scalerX, scalerY; - maxscaler = 1.0; - scalerX = (endX - startX) * 1.0 / sizeW;//*1.0转为float,避免被取整了 - scalerY = (endY - startY) * 1.0 / sizeH; - - maxscaler = max(maxscaler, max(scalerX, scalerY)); - - int avgX = (rect1.x + rect1.x + rect1.width) / 2; //中点X位置 - int avgY = (rect1.y + rect1.y + rect1.height) / 2;//中点Y位置 - - startX = avgX - int(maxscaler * sizeW / 2);//强转为int - endX = startX + int(maxscaler * sizeW); - startY = avgY - int(maxscaler * sizeH / 2); - endY = startY + int(maxscaler * sizeH); - - //判断是否越界,越界要填充的像素个数 - int copyTop = max(0, 0 - startY); - int copyButton = max(0, endY - sourceImg.rows); - int copyLeft = max(0, 0 - startX); - int copyRight = max(0, endX - sourceImg.cols); - - //切图不要越界,会崩溃 - Mat imgCut = sourceImg(Range(max(0, startY - copyTop), min(sourceImg.rows, endY - copyButton)), - Range(max(0, startX - copyLeft), min(sourceImg.cols, endX - copyRight))); //起始行,终止行;起始列,终止列 - - //图像扩充 - if (sourceImg.channels() == 1) - { - copyMakeBorder(imgCut, imgCut, copyTop, copyButton, copyLeft, copyRight, BORDER_CONSTANT, fillColour); - } - else - { - copyMakeBorder(imgCut, imgCut, copyTop, copyButton, copyLeft, copyRight, BORDER_CONSTANT, Scalar(fillColour, fillColour, fillColour)); - } - //resize为建网大小 - cv::resize(imgCut, imgCls, cv::Size(sizeW, sizeH)); - imgCut.release(); - } - - - int resultClass = 0; - float prob = 1.0; - - resultClass = pCls->Evaluate(imgCls); //类别id - prob = pCls->getProbability(); //可能性 - - //切图保存,按需 - { - isDirExist(classImgSaveDir + mysaveKey1 + "/class_" + QString::number(resultClass)); - //存图数据入队,按需 - addImgToSaveStruct(imgCls, mysaveKey1, classImgSaveDir + mysaveKey1 + "/class_" + QString::number(resultClass) + "/" + mySN + myDataTime + QString::number(j) + ".bmp"); - } - - //此处应添加缺陷计数逻辑 - - if (resultClass == 0)//OK - { - ; - } - else if (resultClass == 1)//划伤Scratch - { - resIfNg = true; - //rectangle(sourceRectangles, rect1.tl(), rect1.br(), Scalar(0, 0, 255), 3, 8); - ////可行,必须转一下格式 - //{ - // QString pathQstr = "划伤"; - // QByteArray path_arr = pathQstr.toLocal8Bit(); - // const char* path = path_arr.data(); - // putTextZH(sourceRectangles, path, cv::Point(rect1.tl().x, rect1.tl().y - 5), Scalar(255, 0, 0), 50, "微软雅黑"); - //} - - defectInfo mdefectInfo; - mdefectInfo.defectName = "划伤"; - mdefectInfo.defectRect = rect1; - mdefectInfo.defectArea = contourArea(contours[j]); - mdefectInfo.defectScalar = cv::Scalar(0, 0, 255); - defectInfoList.enqueue(mdefectInfo); - } - else if (resultClass == 2)//碰伤 - { - resIfNg = true; - defectInfo mdefectInfo; - mdefectInfo.defectName = "碰伤"; - mdefectInfo.defectRect = rect1; - mdefectInfo.defectArea = contourArea(contours[j]); - mdefectInfo.defectScalar = cv::Scalar(0, 255, 255); - defectInfoList.enqueue(mdefectInfo); - } - imgCls.release(); - } - else { - //cout << "ng is too small<" << filterNum << endl; - continue; - } - } + cv::putText(sourceImg, "Algo error1", cv::Point(0, 240), 2, 10, cv::Scalar(0, 0, 255), 10); + //Result = 2; } - //cv::Mat resMat = img2D.clone(); - sourceRectangles.release(); - contours.resize(0); - resultDstImg.release(); } - */ + else + { + cv::putText(sourceImg, "Algo error2", cv::Point(0, 240), 2, 10, cv::Scalar(0, 0, 255), 10); + + + } + + ho_Image.Clear(); + hv_out_Value.Clear(); + hv_Make.Clear(); detect_mutex->lock(); //resMat = sourceImg.clone(); @@ -872,8 +877,8 @@ void Hd_AI_empty_module::addImgToSaveStruct(cv::Mat img2D, QString mysaveKey, QS saveImgStruct mySave; mySave.out_Mat = img2D.clone(); //img2D.copyTo(mySave.out_Mat); - mySave.saveKey = (mysaveKey).toStdString(); - mySave.savePath = (savePath).toStdString(); + mySave.saveKey = mysaveKey.toLocal8Bit().toStdString(); + mySave.savePath = savePath.toLocal8Bit().toStdString(); saveStruct.enqueue(mySave); saveStruct_mutex->unlock(); } @@ -882,7 +887,7 @@ void Hd_AI_empty_module::saveImgThread() while (1) { if (!ifdetectThread)return; - _sleep(1); + _sleep(5); qApp->processEvents(); if (saveStruct.size() < 1)continue; for (int i = 0; i < saveStruct.size(); i++) @@ -896,7 +901,8 @@ void Hd_AI_empty_module::saveImgThread() 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); + if (mysaveStruct.out_Mat.data) + imwrite(mysaveStruct.savePath, mysaveStruct.out_Mat); //std::cout << "savePath::" << mysaveStruct.savePath << std::endl; stop = clock(); if (stop - start > 1000) @@ -968,9 +974,9 @@ bool Hd_AI_empty_module::run() start = clock(); //Sleep(1000); - //detectThread(); - //stop = clock(); - //qDebug() << __FUNCTION__ << "line:" << __LINE__ << " run start ::runNum::" << runNum++<<" cutTime::"< diff --git a/HanddleAI/modules/Hd_AI_seg_module/Hd_AI_seg_module.cpp b/HanddleAI/modules/Hd_AI_seg_module/Hd_AI_seg_module.cpp index 9c104e0..8107e99 100644 --- a/HanddleAI/modules/Hd_AI_seg_module/Hd_AI_seg_module.cpp +++ b/HanddleAI/modules/Hd_AI_seg_module/Hd_AI_seg_module.cpp @@ -299,16 +299,17 @@ bool Hd_AI_seg_module::readData(std::vector&vec_mat,QByteArray &data) } else { - vec_mat.push_back(HikMat[0]); + if(HikMat.size()) + vec_mat.push_back(HikMat[0]); //qDebug() << __FUNCTION__ << " line:" << __LINE__ << " resMat.data err:"; } //if (allNum++ % 21 == 20) // data = "2";// resByte.dequeue(); //else - if (defectNums == 0) - data = "1";//1OK,2NG - else - data = "2"; + //if (allNum++ % 2 == 0) + // data = "0*2*3*2";// resByte.dequeue(); + //else + data = "1*0*0";//1OK,2NG resByte.clear(); ////之后根据结果类修改 //if(resIfNg == true) @@ -882,7 +883,7 @@ bool Hd_AI_seg_module::run() float prob = 0; if (HikMat.isEmpty()) - return false; + return true; srcMats.push_back(HikMat[0]); start = clock(); @@ -903,7 +904,7 @@ bool Hd_AI_seg_module::run() //Sleep(50); //detectThread(); //stop = clock(); - //qDebug() << __FUNCTION__ << "line:" << __LINE__ << " run start ::runNum::" << runNum++<<" cutTime::"< Îü×ì±àºÅ,x¾ø¶Ô×ø±꣬y¾ø¶Ô×ø±ê * hv_Out_Roboot2£ºÎü×ì2->Îü×ì±àºţ¬x¾ø¶Ô×ø±꣬y¾ø¶Ô×ø±ê * hv_Out_Roboot3£ºÎü×ì3->Îü×ì±àºţ¬x¾ø¶Ô×ø±꣬y¾ø¶Ô×ø±ê +* hv_StartRun: 1Æô¶¯Õñ¶¯Ạ̊¬2²»Æô¶¯Õñ¶¯ÅÌ * »úÆ÷ÈËÒýµ¼º¯Êý * ÈýЭ»ų́ */ extern "C" __declspec(dllexport) void _stdcall _628_BootTheMachine(HObject ho_Image, HTuple hv_NinePointDocument, HTuple hv_SetNumber, - HTuple* hv_Circle_Point, HTuple* hv_Make, HTuple* hv_Out_Roboot1, HTuple* hv_Out_Roboot2,HTuple* hv_Out_Roboot3, HTuple* hv_StartRun); + HTuple* hv_Circle_Point, HTuple* hv_Make, HTuple* hv_Out_Roboot1, HTuple* hv_Out_Roboot2, + HTuple* hv_Out_Roboot3, HTuple* hv_StartRun); /* *ho_Image£ºÊäÈëͼƬ£¨ԭͼ£© @@ -87,7 +89,7 @@ extern "C" __declspec(dllexport) void _stdcall _628_NailingPosition(HObject ho_I /* ho_Image:ÊäÈëԭͼ - hv_out_Value£ºÊä³ö¼ì²â½á¹û[1,1] .1ΪÂÁ£¬[2,2] 2Ϊͭ + hv_out_Value£ºÊä³ö¼ì²â½á¹û[1,1] .1ΪÂÁ£¬[2,2] 2Ϊͭ ,0ΪÎÞÁÏ hv_Make£ºË㷨ִÐÐ״̬-1ΪË㷨NG£¬1ΪË㷨ok ¼«ÐԼì²⺯Êý Öպ¸ÈýЭ»ų́ @@ -203,6 +205,20 @@ extern "C" __declspec(dllexport) void _stdcall _628_3_PoleDetections(HObject ho_ extern "C" __declspec(dllexport) void _stdcall _628_3_ExplosionProofValves(HObject ho_Image, HTuple hv_Pix, HTuple* hv_Distance_Value, HTuple* hv_Out_Point, HTuple* hv_Make); +/* +* ho_Image £ºÊäÈëͼƬ +* hv_Pix £ºÏà»úÏñËؾ«¶È +* hv_Distances £º¼ä¾à²âÁ¿ֵÁ½¸öֵ +* hv_Out_line £ºÊä³ö²âÁ¿Ï߶εĶ˵ã×ø±꣨Åжϳ¤¶ȣ© +* hv_Makes£ºÊä³ö-1ΪË㷨´íÎó£¬Êä³ö1ΪË㷨Õý³£ִÐÐ +*ÈíÁ¬½Ó3-1º¸ǰ¶¨λ +* ÈýЭµĻų́ +*/ +extern "C" __declspec(dllexport) void _stdcall _628_3_PreWeldMeasurement(HObject ho_Image, HTuple hv_Pix, HTuple* hv_Distances, + HTuple* hv_Out_line, HTuple* hv_Make); + + + @@ -315,6 +331,46 @@ extern "C" __declspec(dllexport) void _stdcall Cal_Defect_Height(HObject ho_in_ HTuple hv_in_FilePath, HTuple hv_in_OffsetValue, HTuple hv_in_HoffsetValue, HTuple* hv_out_Height, HTuple* hv_out_Angle, HTuple* hv_out_Flag); +//********************************************************************** +//Function Name: Cal_Long_Coatingcover_Dist_Left +//Author: +//Description: ¼ÆËãĤµ½¶˸ǵľàÀë, +//Input(HObject): in_Image,Â˲¨´¦ÀíºóµÄץ±ßͼÏñ +//Input(HTuple): in_Resolution, Ïà»ú¾«¶È(mm/pix) +//output(HTuple): out_Maxdistance, Ĥµ½¶˸ǵÄ×î´ó¾àÀë(mm) +// out_Mindistance, Ĥµ½¶˸ǵÄ×îС¾àÀë(mm) +// out_Line, »ù׼ÏßλÖÃ(x1,y1,x2,y2) +// out_X, ĤµÄxµã×ø±꼯 +// out_Y, ĤµÄyµã×ø±꼯 +// out_Flag: ִÐгɹ¦λ±êʶ 1, Ë㷨ִÐгɹ¦ 2, Ë㷨ִÐÐng +// out_NgTails: NGµÄÃ÷ϸ +//verion change log: ºúºº±ø 2024-07-11 V1.1 Create new function . +//********************************************************************** + +extern "C" __declspec(dllexport) void _stdcall Cal_Long_Coatingcover_Dist_Left(HObject ho_in_Image, HTuple hv_in_Resolution, + HTuple* hv_out_Maxdistance, HTuple* hv_out_Mindistance, HTuple* hv_out_Line, + HTuple* hv_out_X, HTuple* hv_out_Y, HTuple* hv_out_Flag, HTuple* hv_out_Ngtails); + +//********************************************************************** + //Function Name: Cal_Long_Coatingcover_Dist_Right + //Author: + //Description: ¼ÆËãĤµ½¶˸ǵľàÀë, + //Input(HObject): in_Image,Â˲¨´¦ÀíºóµÄץ±ßͼÏñ + //Input(HTuple): in_Resolution, Ïà»ú¾«¶È(mm/pix) + //output(HTuple): out_Maxdistance, Ĥµ½¶˸ǵÄ×î´ó¾àÀë(mm) + // out_Mindistance, Ĥµ½¶˸ǵÄ×îС¾àÀë(mm) + // out_Line, »ù׼ÏßλÖÃ(x1,y1,x2,y2) + // out_X, ĤµÄxµã×ø±꼯 + // out_Y, ĤµÄyµã×ø±꼯 + // out_Flag: ִÐгɹ¦λ±êʶ 1, Ë㷨ִÐгɹ¦ 2, Ë㷨ִÐÐng + // out_NgTails: NGµÄÃ÷ϸ + //verion change log: ºúºº±ø 2024-10-26 V1.1 Create new function . + //********************************************************************** + +extern "C" __declspec(dllexport) void _stdcall Cal_Long_Coatingcover_Dist_Right(HObject ho_in_Image, HTuple hv_in_Resolution, + HTuple* hv_out_Maxdistance, HTuple* hv_out_Mindistance, HTuple* hv_out_Line, + HTuple* hv_out_X, HTuple* hv_out_Y, HTuple* hv_out_Flag, HTuple* hv_out_Ngtails); + @@ -366,6 +422,18 @@ void cs_628_PoleDetection(HObject ho_Image, HTuple hv_Pix, HTuple* hv_Distances, HTuple* hv_UP_Down_Point, HTuple* hv_life_Ren_Point, HTuple* hv_Point, HTuple* hv_Chamfering, HTuple* hv_Make); +void Get_Rectangle2_Corner(HObject ho_Rectangle, HTuple* hv_out_Row, HTuple* hv_out_Col); + +void Get_LineParameters(HObject ho_in_Image, HObject* ho_out_Contour, HTuple hv_in_Parameters, + HTuple* hv_out_Parameters, HTuple* hv_out_Flag, HTuple* hv_out_NgTails); + +void rake1(HObject ho_Image, HObject * ho_Regions, HTuple hv_InParameters, HTuple * hv_ResultRow, + HTuple * hv_ResultColumn); + +void Get_CircleParameters(HObject ho_in_Image, HObject* ho_out_Contour, HTuple hv_in_Parameters, + HTuple* hv_out_Flag, HTuple* hv_out_NgTails, HTuple* hv_out_Parameters); + + #endif diff --git a/env/halconAlgo/lib/Inspection.lib b/env/halconAlgo/lib/Inspection.lib index 5a0e12a..5cf1f53 100644 Binary files a/env/halconAlgo/lib/Inspection.lib and b/env/halconAlgo/lib/Inspection.lib differ diff --git a/env/myTools/include/global.h b/env/myTools/include/global.h new file mode 100644 index 0000000..4bcd134 --- /dev/null +++ b/env/myTools/include/global.h @@ -0,0 +1,10 @@ +#define resultCmdSplitStart "[resultCmdSplitStart]" +#define resultCmdSplitEnd "[resultCmdSplitEnd]" +#define defectSplitStart "[defectSplitStart]" +#define defectSplitEnd "[defectSplitEnd]" +#define chartSplitStart "[chartSplitStart]" +#define chartSplitEnd "[chartSplitEnd]" +#define csvSplitStart "[csvSplitStart]" +#define csvSplitEnd "[csvSplitEnd]" +#define generalSplit "|" +//SAMPLE \ No newline at end of file