#include #include "FrontendBackendBridge.h" #include #include #include #include #include #include bool showOk = true;//显示ok缺陷的框 std::string fileSavePath("D://CCD//"); ////////////////////// std::vector rotateRect(const cv::Rect& rect, const cv::Point2f& center, double angle) { // 构建矩形的四个角点 std::vector corners(4); corners[0] = cv::Point2f(rect.x, rect.y); corners[1] = cv::Point2f(rect.x + rect.width, rect.y); corners[2] = cv::Point2f(rect.x + rect.width, rect.y + rect.height); corners[3] = cv::Point2f(rect.x, rect.y + rect.height); // 创建旋转矩阵 cv::Mat rotationMatrix = cv::getRotationMatrix2D(center, angle, 1.0); // 对每个角点应用旋转变换 std::vector rotatedCorners(4); for (int i = 0; i < 4; ++i) { cv::Mat pointMat = (cv::Mat_(3, 1) << corners[i].x, corners[i].y, 1); cv::Mat rotatedPoint = rotationMatrix * pointMat; rotatedCorners[i] = cv::Point2f(rotatedPoint.at(0, 0), rotatedPoint.at(1, 0)); } return rotatedCorners; } double calculateAngleWithXAxis(const cv::Point& p1, const cv::Point& p2) { // 计算两点的坐标差异 double dx = p2.x - p1.x; double dy = p2.y - p1.y; // 使用反正切函数计算角度 double angle = std::atan2(dy, dx) * 180 / CV_PI; // 确保角度在 0 到 360 度之间 if (angle < 0) { angle += 360; } return angle; } void rotateImage(const cv::Mat& src, double angle, cv::Mat& dst) { // 图像中心作为旋转中心 cv::Point2f center(static_cast(src.cols / 2), static_cast(src.rows / 2)); // 计算旋转矩阵 cv::Mat rot = cv::getRotationMatrix2D(center, angle, 1.0); // 应用旋转 cv::warpAffine(src, dst, rot, src.size()); } double calculateDistance(const cv::Point& p1, const cv::Point& p2) { // 计算距离 double distance = std::sqrt(std::pow(p2.x - p1.x, 2) + std::pow(p2.y - p1.y, 2)); return distance; } //std::vector> fitLines(const std::vector& points, double length) { // // 进行多边形拟合 // std::vector approxCurve; // cv::approxPolyDP(points, approxCurve, length, true); // // std::vector> lines; // // // 从拟合后的多边形中提取直线段 // for (size_t i = 0; i < approxCurve.size(); ++i) { // cv::Point p1 = approxCurve[i]; // cv::Point p2 = approxCurve[(i + 1) % approxCurve.size()]; // // lines.push_back(std::make_pair(p1, p2)); // } // // return lines; //} std::vector> fitLines(const std::vector& points, double length) { // 进行多边形拟合 std::vector approxCurve; cv::approxPolyDP(points, approxCurve, length, true); std::vector> lines; // 构建凸包 std::vector convexHull; cv::convexHull(approxCurve, convexHull); // 计算凸包的几何中心 cv::Point2f center(0, 0); for (const auto& point : convexHull) { center.x += point.x; center.y += point.y; } center *= (1.0 / convexHull.size()); // 从拟合后的多边形中提取直线段,并排除方向向内的线段 for (size_t i = 0; i < approxCurve.size(); ++i) { cv::Point p1 = approxCurve[i]; cv::Point p2 = approxCurve[(i + 1) % approxCurve.size()]; // 计算线段的中点 cv::Point midPoint = (p1 + p2) * 0.5; // 计算线段中点到多边形几何中心的向量 cv::Point2f centerToMid = cv::Point2f(midPoint) - center; // 计算线段方向向量 cv::Point2f lineDirection = cv::Point2f(p2) - cv::Point2f(p1); // 计算凸包法线 cv::Point2f normal = cv::Point2f(-centerToMid.y, centerToMid.x); // 检查线段方向是否朝向凸包内部(与凸包法线方向相反) if (lineDirection.dot(normal) < 0) { lines.push_back(std::make_pair(p1, p2)); } } return lines; } void writeToData_xxxCsvOkNgNew(detData* rdata, QString OKNG, ngNoteCls* note) { QDateTime currentDateTime = QDateTime::currentDateTime(); std::string ymd = currentDateTime.toString("yyyy-MM-dd").toStdString(); QString filePath = QString::fromStdString(fileSavePath + "//result//" + ymd + "//Data_" + ymd + ".csv"); /* QString searchString = QString::fromStdString(rdata->getSN() + "_" + to_string(rdata->snCountIndex));*/ QString searchString = QString::fromStdString(rdata->SNcode); QFile file(filePath); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qDebug() << "Error opening file."; } QStringList headers; QList data; QTextStream in(&file); while (!in.atEnd()) { QString line = in.readLine(); QStringList fields = line.split(','); if (headers.isEmpty()) { // 如果headers为空,则当前行为标题行 headers = fields; } else { data.append(fields); } } file.close(); // 在data中进行字符串检索并修改匹配的行 int modifiedRowCount = 0; for (int i = data.size() - 1; i > 0; --i) { QStringList& row = data[i]; //if (row.size()<3||row.isEmpty()) //{ // break; //} // 在当前行中检索字符串 try { if (row.size() >= 6) if (row[1].contains(searchString, Qt::CaseInsensitive)) { // 匹配到字符串,进行修改 row[3] = OKNG; row[4] += note->getNgSummaryStr(); row[5] += note->getOkSummaryStr(); modifiedRowCount++; } } catch (...) { break; } } // 将修改后的数据写回文件 QFile writeFile(filePath); if (!writeFile.open(QIODevice::WriteOnly | QIODevice::Text)) { qDebug() << "Error opening file for writing."; } QTextStream out(&writeFile); // 写入标题行 out << headers.join(",") << "\n"; // 写入修改后的数据行 for (const auto& row : data) { out << row.join(",") << "\n"; } writeFile.close(); qDebug() << "Modified rows:" << modifiedRowCount; qDebug() << "Data modified and saved to data_modified.csv"; //return 0; } void writeToData_xxxCSVNew(detData* resData, string OKNG, ngNoteCls* note) { QDateTime currentDateTime = QDateTime::currentDateTime(); std::string ymd = currentDateTime.toString("yyyy-MM-dd").toStdString(); int hour = currentDateTime.time().hour(); QString filePath = QString::fromStdString(fileSavePath + "//result//" + ymd + "//Data_" + ymd + ".csv"); //string sn(resData->SNcode + "-" + to_string(resData->snCountIndex)); string sn(resData->SNcode); /*std::string str(to_string(hour) + "H//" + sn + "-" + to_string(resData->snCountIndex) + "//" + ymd + "-" + to_string(hour) + "_" + resData->getSN() + "-" + to_string(resData->snCountIndex));*/ std::string str(to_string(hour) + "H//" + sn + "//" + ymd + "-" + to_string(hour) + "_" + sn); bool fileExist = false; QStringList dataList; if (hour < 10) dataList.append("0" + QString::number(hour) + "H"); else dataList.append(QString::number(hour) + "H"); dataList.append(QString::fromStdString(sn)); dataList.append(QString::fromStdString(str)); dataList.append(QString::fromStdString(OKNG)); dataList.append(note->getNgSummaryStr()); dataList.append(note->getOkSummaryStr()); // 创建CSV文件 QFile file(filePath); if (!file.exists()) { // 创建目录(如果不存在) QDir dir; if (!dir.mkpath(QFileInfo(filePath).absolutePath())) { //qWarning() << "无法创建目录:" << QFileInfo(filePath).absolutePath(); return; } fileExist = true; } // 打开CSV文件并写入数据 if (file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) { QTextStream stream(&file); if (fileExist == true) { stream << "Time,"; stream << "SN,"; stream << "Path,"; stream << "Result,"; stream << "summuryResult,"; stream << "\n"; } // 将数据写入CSV文件 for (const QString& data : dataList) { stream << data << ","; } stream << "\n"; file.close(); qDebug() << "CSV文件写入成功"; } //else // qWarning() << "无法打开CSV文件:" << filePath; } void algoThread::getAllFiles(string path, vector& files, string format) { intptr_t hFile = 0;//恅璃曆梟 struct _finddata_t fileinfo;//恅璃陓洘 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); } } void drawContoursOverlap(cv::Mat& image, const std::vector>& contours) { cv::Mat mask = cv::Mat::zeros(image.size(), CV_8U); // 绘制轮廓在掩码上 cv::drawContours(mask, contours, -1, cv::Scalar(255), cv::FILLED); // 将图像中与掩码不重叠的区域涂黑 cv::Mat result; image.copyTo(result, mask); image.setTo(cv::Scalar(0, 0, 0), ~mask); } void drawContourOnImage(Mat seg, cv::Mat& imgInput, Size offset = Size(0, 0)) { if (seg.empty() || imgInput.empty()) { std::cerr << "Empty contour or input image." << std::endl; return; } cv::Mat imgWithAlpha; cv::cvtColor(imgInput, imgWithAlpha, cv::COLOR_BGR2BGRA); std::vector>contours; if (offset.width != 0 && offset.height != 0) { Mat offsetImg(offset.width + seg.rows, offset.height + seg.cols, CV_8UC1, Scalar(0)); seg.copyTo(offsetImg(Rect(offset.width, offset.height, seg.rows, seg.cols))); offsetImg.copyTo(seg); } cv::findContours(seg, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); for (auto& contour : contours) { cv::Scalar color(0, 255, 0, 128); cv::polylines(imgWithAlpha, contour, true, color); cv::cvtColor(imgWithAlpha, imgInput, cv::COLOR_BGRA2BGR); } } /////Specified function//////////////// void writeSpecificStatement(Mat& Paint, const wchar_t* Text, rectAndData& data, int amount, int limit, Scalar& color) { wstring MM(to_wstring(max(data.defectHeight, data.defectWidth))); MM = MM.substr(0, MM.find_first_of(L".") + 2); putTextHusky(Paint, (WString2String(Text + to_wstring(amount) + L"/" + to_wstring(limit) + L"|" + MM + L"mm")).c_str(), cv::Point(data.rect.x, data.rect.y - 20), color, 20); } int getMaxAreaIndex(std::vector>& pts) { int maxVal = 0, maxI = -1; for (int i =0;i maxVal) { maxI = i; maxVal = areaSize; } } return maxI; } std::vector < std::vector>> splitLinesByCenterAndAngle(const std::vector>& lines, const cv::Point& center) { std::vector> topLines, bottomLines, leftLines, rightLines; for (const auto& line : lines) { const cv::Point& p1 = line.first; const cv::Point& p2 = line.second; // 计算线段的方向向量 cv::Point2f lineDirection = cv::Point2f(p2) - cv::Point2f(p1); // 计算线段与 x 轴和 y 轴的夹角 double angleWithX = std::atan2(lineDirection.y, lineDirection.x) * 180 / CV_PI; double angleWithY = std::atan2(lineDirection.x, lineDirection.y) * 180 / CV_PI; angleWithX = (angleWithX < 0) ? 180 + angleWithX : angleWithX; angleWithY = (angleWithY < 0) ? 180 + angleWithY : angleWithY; // 根据线段方向和中心点位置将线段分组 if (p1.y <= center.y && p2.y <= center.y && (angleWithX < 10 || angleWithX > 170)) { std::cout << "A" << to_string(angleWithX) << "A" << to_string(angleWithY) << std::endl; topLines.push_back(line); } else if (p1.y >= center.y && p2.y >= center.y && (angleWithX < 10 || angleWithX > 170)) { bottomLines.push_back(line); } else if (p1.x <= center.x && p2.x <= center.x && (angleWithY < 10 || angleWithY > 170)) { leftLines.push_back(line); } else if (p1.x >= center.x && p2.x >= center.x && (angleWithY < 10 || angleWithY > 170)) { rightLines.push_back(line); } } // 返回四个方向的线段结果 return { topLines, bottomLines, leftLines, rightLines }; } std::vector> filterLinesByAngle(const std::vector>& lines) { std::vector> filteredLines; for (const auto& line : lines) { const cv::Point& p1 = line.first; const cv::Point& p2 = line.second; // 计算线段的方向向量 cv::Point2f lineDirection = cv::Point2f(p2) - cv::Point2f(p1); // 计算线段与 x 轴和 y 轴的夹角 double angleWithX = std::abs(std::atan2(lineDirection.y, lineDirection.x) * 180 / CV_PI); double angleWithY = std::abs(std::atan2(lineDirection.x, lineDirection.y) * 180 / CV_PI); // 如果与 x 轴或 y 轴的夹角在正负30度内,则保留该线段 if ((angleWithX < 10 || angleWithX > 170) || (angleWithY < 10 || angleWithY > 170)) { filteredLines.push_back(line); } } return filteredLines; } double pointLineSegmentDistance(const cv::Point& p, const cv::Point& q, const cv::Point& a, const cv::Point& b) { cv::Point pq = q - p; cv::Point ab = b - a; cv::Point pa = a - p; double t = static_cast(pq.dot(ab)) / pq.dot(pq); if (t >= 0 && t <= 1) { cv::Point pt = p + pq * t; return cv::norm(pt - a); } else { double dist1 = cv::norm(p - a); double dist2 = cv::norm(q - b); return std::min(dist1, dist2); } } double calculateLineSegmentDistance(const std::pair& line1, const std::pair& line2) { cv::Point p1 = line1.first; cv::Point p2 = line1.second; cv::Point p3 = line2.first; cv::Point p4 = line2.second; double distance1 = pointLineSegmentDistance(p1, p2, p3, p4); double distance2 = pointLineSegmentDistance(p2, p1, p3, p4); double distance3 = pointLineSegmentDistance(p3, p4, p1, p2); double distance4 = pointLineSegmentDistance(p4, p3, p1, p2); //return std::min({distance1, distance2, distance3, distance4 }); return (distance1 + distance2 + distance3 + distance4) / 4; } void calculateLineSegmentDistances(const std::vector>& lines1, const std::vector>& lines2) { double minDistance = std::numeric_limits::max(); double maxDistance = std::numeric_limits::min(); double sumDistance = 0.0; size_t count = 0; for (const auto& line1 : lines1) { for (const auto& line2 : lines2) { double distance = calculateLineSegmentDistance(line1, line2); if (distance >= 0) { sumDistance += distance; std::cout << "Minimum dist ssdce: " << distance * 0.014744 << std::endl; if (distance < minDistance) { minDistance = distance; } if (distance > maxDistance) { maxDistance = distance; } ++count; } } } std::cout << "Minimum distance: " << minDistance* 0.014744 << std::endl; std::cout << "Maximum distance: " << maxDistance* 0.014744 << std::endl; std::cout << "Average distance: " << (sumDistance / count)* 0.014744 << std::endl; } /////////////////////ALGOTHREAD///////////////////////// bool algoThread::addDetTask(std::shared_ptr data) { detQueueMutex.lock(); detQueue.append(data); detQueueMutex.unlock(); this->start(); return false; } bool algoThread::waitForImg(std::shared_ptr data,int timeOutSet=10000) { int timeOut = 0; int sleepMs = 100; while (1) { int imgSize = data->imgs.size(); int imgAmountMin = data->imgAmountMin; if (imgSize >= imgAmountMin) return true; timeOut+= sleepMs; if (timeOut > timeOutSet) return false; QThread::msleep(sleepMs); } } void algoThread::run() { while (m_runFlag == true) { while (detQueue.size() > 0) { detQueueMutex.lock(); std::shared_ptr data = detQueue.dequeue();//取出数据 detQueueMutex.unlock(); int threadId = data->algoThreadIndex;//获取线程id if (waitForImg(data) == false) { qDebug() << "取图失败"; cout << "get img err" << endl; detDataManager* dManager = data->dManager; data->dManager->deleteDetData(data->timeCode); break; } detDataManager* dManager = data->dManager; data->dManager->deleteDetData(data->timeCode); continue; if (threadId == 0) { int timeOut = 0; int sleepMs = 100; while (data->correctionData==nullptr) { if (timeOut > 10000)break; timeOut += sleepMs; QThread::msleep(sleepMs); } ALGO_Correction(data); } else { if (waitForImg(data) == false) { qDebug() << "取图失败"; cout << "get img err" << endl; break; } bridge.front.showImg("Camera", data->imgs[0], threadId);//显示原图 auto start = std::chrono::high_resolution_clock::now(); switch (threadId) { case 0: Camera1_Algo(data); break; case 1: Camera1_Algo(data); break; } //oriSaveThread->saveOriImg(data);//保存原图 auto end = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast(end - start); std::cout << "Time taken by function: " << duration.count() << " milliseconds" << std::endl; //if (!data->SNcode.compare(snDatas->snErrorsnError))//无sn阻塞 // data->SNcode = snDatas->waitForSn(data->timeCode); if (data->resultImgs.size() > 0) { //resSaveThread->saveResImg(data);//保存结果图 bridge.front.showImg("Algorithm", data->resultImgs[0], threadId);//显示原图 //cout << "algoEnd" << data->algoThreadIndex; } std::vector sqlDatas;//定义sql数据 for (auto sqlData : data->sqlVec)//将算法中的数据导入到数据结构中 sqlDatas.push_back({ sqlData.first, std::to_string(sqlData.second) }); sql->addData(data->SNcode, sqlDatas);//将数据插入数据库 std::vectorstrVec({ QString::fromStdString(data->SNcode),QString::number(data->camera1Width) + "x" + QString::number(data->camera1Height) }); bridge.front.tableViewPtr->addRowDataValue(strVec);//将数据插入界面表格 detDataManager* dManager = data->dManager; data->dManager->deleteDetData(data->timeCode); } } QThread::msleep(10); } } void matsToMat(cv::Mat& mat1, cv::Mat& mat2, cv::Mat* Paint) { auto start_time = std::chrono::high_resolution_clock::now(); *Paint = cv::Mat(mat1.rows + mat2.rows, mat1.cols, CV_8UC1); memcpy(Paint->data, mat1.data, mat1.rows * mat1.cols); memcpy(mat1.rows * mat1.cols + Paint->data, mat2.data, mat2.rows * mat2.cols); if (Paint->channels() == 1) cv::cvtColor(*Paint, *Paint, cv::COLOR_GRAY2BGR); auto end_time = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast(end_time - start_time); std::cout << "matsToMat: " << duration.count() << " microseconds" << std::endl; } void algoThread::ALGO_Correction(std::shared_ptr data) { ALGO_Inspection(data); int pValueBounus = 100; if (data->correctionData == nullptr) return; #pragma region XOY_DEFINE HTuple hv_in_X_X0Y; for (auto rangeData : data->correctionData->in_X_X0Y) hv_in_X_X0Y.Append(rangeData); HTuple hv_in_Y_X0Y; for (auto rangeData : data->correctionData->in_Y_X0Y) hv_in_Y_X0Y.Append(rangeData); HTuple hv_in_Z_X0Y; for (auto rangeData : data->correctionData->in_Z_X0Y) hv_in_Z_X0Y.Append(rangeData); HTuple hv_in_Z_X0Y_Value; for (auto rangeData : data->correctionData->in_Z_X0Y_Value) hv_in_Z_X0Y_Value.Append(rangeData); #pragma endregion #pragma region XOZ_DEFINE HTuple hv_in_X_X0Z; for (auto rangeData : data->correctionData->in_X_X0Z) hv_in_X_X0Z.Append(rangeData); HTuple hv_in_Y_X0Z; for (auto rangeData : data->correctionData->in_Y_X0Z) hv_in_Y_X0Z.Append(rangeData); HTuple hv_in_Z_X0Z; for (auto rangeData : data->correctionData->in_Z_X0Z) hv_in_Z_X0Z.Append(rangeData); HTuple hv_in_Y_X0Z_Value; for (auto rangeData : data->correctionData->in_Y_X0Z_Value) hv_in_Y_X0Z_Value.Append(rangeData); #pragma endregion #pragma region YOZ_DEFINE HTuple hv_in_X_Y0Z; for (auto rangeData : data->correctionData->in_X_Y0Z) hv_in_X_Y0Z.Append(rangeData); HTuple hv_in_Y_Y0Z; for (auto rangeData : data->correctionData->in_Y_Y0Z) hv_in_Y_Y0Z.Append(rangeData); HTuple hv_in_Z_Y0Z; for (auto rangeData : data->correctionData->in_Z_Y0Z) hv_in_Z_Y0Z.Append(rangeData); HTuple hv_in_X_Y0Z_Value; for (auto rangeData : data->correctionData->in_X_Y0Z_Value) hv_in_X_Y0Z_Value.Append(rangeData); #pragma endregion HTuple hv_out_Origin; HTuple hv_out_Result_X; HTuple hv_out_Result_Y; HTuple hv_out_Result_Z; HTuple hv_out_AngleZX; HTuple hv_out_AngleYZ; HTuple hv_out_AngleXY; HTuple hv_out_Flag; halcon_Correction( hv_in_X_X0Y, hv_in_Y_X0Y, hv_in_Z_X0Y, hv_in_Z_X0Y_Value, hv_in_X_X0Z, hv_in_Y_X0Z, hv_in_Z_X0Z, hv_in_Y_X0Z_Value, hv_in_X_Y0Z, hv_in_Y_Y0Z, hv_in_Z_Y0Z, hv_in_X_Y0Z_Value, &hv_out_Origin,&hv_out_Result_X,&hv_out_Result_Y,&hv_out_Result_Z, &hv_out_AngleZX,&hv_out_AngleYZ,&hv_out_AngleXY,&hv_out_Flag); int ok_Flag = 0; vectorout_Origin; vectorout_Result_X; vectorout_Result_Y; vectorout_Result_Z; double out_AngleZX; double out_AngleYZ; double out_AngleXY; if(hv_out_Flag.Length()==1) if (hv_out_Flag[0].D()== 1) { if (hv_out_Origin.Length() == 3) { out_Origin = { hv_out_Origin[0].D(),hv_out_Origin[1].D(), hv_out_Origin[2].D() }; ok_Flag++; } if (hv_out_Result_X.Length() == 3) { out_Result_X = { hv_out_Result_X[0].D(),hv_out_Result_X[1].D(), hv_out_Result_X[2].D() }; ok_Flag++; } if (hv_out_Result_Y.Length() == 3) { out_Result_Y = { hv_out_Result_Y[0].D(),hv_out_Result_Y[1].D(), hv_out_Result_Y[2].D() }; ok_Flag++; } if (hv_out_Result_Z.Length() == 3) { out_Result_Z = { hv_out_Result_Z[0].D(),hv_out_Result_Z[1].D(), hv_out_Result_Z[2].D() }; ok_Flag++; } if (hv_out_AngleZX.Length() == 1) { out_AngleZX = hv_out_AngleZX[0].D(); ok_Flag++; } if (hv_out_AngleYZ.Length() == 1) { out_AngleYZ = hv_out_AngleYZ[0].D(); ok_Flag++; } if (hv_out_AngleXY.Length() == 1) { out_AngleXY = hv_out_AngleXY[0].D(); ok_Flag++; } } else { std::cout << "error"; } if (ok_Flag != 7) { //qDebug() return; } //originX _triggerManager->sendFinsMsg("write_short_310_" + QString::number(out_Origin[0] < 0 ? 2 : 1)); _triggerManager->sendFinsMsg("write_short_311_" + QString::number(abs(static_cast(out_Origin[0])))); double pvalue = out_Origin[0] - static_cast(out_Origin[0]); _triggerManager->sendFinsMsg("write_short_312_" + QString::number(abs(pvalue* pValueBounus))); //originY _triggerManager->sendFinsMsg("write_short_313_" + QString::number(out_Origin[1] < 0 ? 2 : 1)); _triggerManager->sendFinsMsg("write_short_314_" + QString::number(abs(static_cast(out_Origin[1])))); pvalue = out_Origin[1] - static_cast(out_Origin[1]); _triggerManager->sendFinsMsg("write_short_315_" + QString::number(abs(pvalue * pValueBounus))); //originZ _triggerManager->sendFinsMsg("write_short_316_" + QString::number(out_Origin[2] < 0 ? 2 : 1)); _triggerManager->sendFinsMsg("write_short_317_" + QString::number(abs(static_cast(out_Origin[2])))); pvalue = out_Origin[2] - static_cast(out_Origin[2]); _triggerManager->sendFinsMsg("write_short_318_" + QString::number(abs(pvalue * pValueBounus))); //ResultX1 _triggerManager->sendFinsMsg("write_short_319_" + QString::number(out_Result_X[0] < 0 ? 2 : 1)); _triggerManager->sendFinsMsg("write_short_320_" + QString::number(abs(static_cast(out_Result_X[0])))); pvalue = out_Result_X[0] - static_cast(out_Result_X[0]); _triggerManager->sendFinsMsg("write_short_321_" + QString::number(abs(pvalue * pValueBounus))); //ResultX2 _triggerManager->sendFinsMsg("write_short_322_" + QString::number(out_Result_X[1] < 0 ? 2 : 1)); _triggerManager->sendFinsMsg("write_short_323_" + QString::number(abs(static_cast(out_Result_X[1])))); pvalue = out_Result_X[1] - static_cast(out_Result_X[1]); _triggerManager->sendFinsMsg("write_short_324_" + QString::number(abs(pvalue * pValueBounus))); //ResultX3 _triggerManager->sendFinsMsg("write_short_325_" + QString::number(out_Result_X[2] < 0 ? 2 : 1)); _triggerManager->sendFinsMsg("write_short_326_" + QString::number(abs(static_cast(out_Result_X[2])))); pvalue = out_Result_X[2] - static_cast(out_Result_X[2]); _triggerManager->sendFinsMsg("write_short_327_" + QString::number(abs(pvalue * pValueBounus))); //ResultY1 _triggerManager->sendFinsMsg("write_short_328_" + QString::number(out_Result_Y[0] < 0 ? 2 : 1)); _triggerManager->sendFinsMsg("write_short_329_" + QString::number(abs(static_cast(out_Result_Y[0])))); pvalue = out_Result_Y[0] - static_cast(out_Result_Y[0]); _triggerManager->sendFinsMsg("write_short_330_" + QString::number(abs(pvalue * pValueBounus))); //ResultY2 _triggerManager->sendFinsMsg("write_short_331_" + QString::number(out_Result_Y[1] < 0 ? 2 : 1)); _triggerManager->sendFinsMsg("write_short_332_" + QString::number(abs(static_cast(out_Result_Y[1])))); pvalue = out_Result_Y[1] - static_cast(out_Result_Y[1]); _triggerManager->sendFinsMsg("write_short_333_" + QString::number(abs(pvalue * pValueBounus))); //ResultY3 _triggerManager->sendFinsMsg("write_short_334_" + QString::number(out_Result_Y[2] < 0 ? 2 : 1)); _triggerManager->sendFinsMsg("write_short_335_" + QString::number(abs(static_cast(out_Result_Y[2])))); pvalue = out_Result_Y[2] - static_cast(out_Result_Y[2]); _triggerManager->sendFinsMsg("write_short_336_" + QString::number(abs(pvalue * pValueBounus))); } void algoThread::ALGO_Inspection(std::shared_ptr data) { if (data->imgs.size() < 1) { qDebug() << __FUNCDNAME__ << __LINE__ << "camera Mat size is Error!"; return; } //hv_in_Parameter //[0]-产品种类; 1A正面 2A反面 3B正面 4C正面 //[1]-图像序号第一位; //[2]-图像序号第二位; //[3]-3d相机精度(mm); //[4]-ping针偏移判NG阈值(mm); //[5]-切图存图开关 #pragma region halcon变量定义 //测量 HObject ho_in_Image; HTuple hv_in_ShapePath; HTuple hv_in_Parameter; HTuple hv_out_Pings_X; HTuple hv_out_Pings_Y; HTuple hv_out_NG_Pings_X; HTuple hv_out_NG_Pings_Y; HTuple hv_out_Pings_Num; HTuple hv_out_NG_Pings_Num; HTuple hv_out_Flag_INS; //ROI HTuple hv_out_ROI_Value; HTuple hv_out_Flag_ROI; #pragma endregion cv::Mat mat = cv::imread("C://NHMJDHNN78474-5_1-ASR1006X20240320-150822.BMP", -1); ho_in_Image=simpleAlgo::MatToHObject(mat); hv_in_Parameter.Append(3); hv_in_Parameter.Append(5); hv_in_Parameter.Append(1); hv_in_Parameter.Append(0.0135); hv_in_Parameter.Append(0.2); hv_in_Parameter.Append(2); hv_in_ShapePath = "./halconModel"; Pings_Inspection(ho_in_Image, hv_in_ShapePath, hv_in_Parameter, &hv_out_Pings_X, &hv_out_Pings_Y, &hv_out_NG_Pings_X, &hv_out_NG_Pings_Y, &hv_out_Pings_Num, &hv_out_NG_Pings_Num, &hv_out_Flag_INS); Pings_ROI(ho_in_Image, hv_in_ShapePath, hv_in_Parameter, &hv_out_ROI_Value, &hv_out_Flag_ROI); vectorResult; for (int i = 0; i < hv_out_ROI_Value.Length()/4;i++) { Result.push_back( cv::Rect( hv_out_ROI_Value[i * 4 +1].D(), hv_out_ROI_Value[i * 4].D(), hv_out_ROI_Value[i * 4 +3].D() - hv_out_ROI_Value[i * 4 + 1].D(), hv_out_ROI_Value[i * 4 +2].D() - hv_out_ROI_Value[i * 4].D() )); } cv::Mat Paint; cvtColor(mat, Paint, COLOR_GRAY2BGR); rectangle(Paint, Result[0], cv::Scalar(0, 0, 255), 4); _sleep(100); } void algoThread::Camera1_Algo(std::shared_ptr data) { auto start_time = std::chrono::high_resolution_clock::now(); if (data->imgs.size() < 1) { qDebug() << __FUNCDNAME__ << __LINE__ << "camera Mat size is Error!"; return; } ///////////////////取图///声明///////////////////// ngNoteCls Note; cv::Mat src; cv::Mat Paint; int CCD1OK = 1; double CCD1height = -1; double dmCodeWidth = 0, dmCodeHeight = 0; double pixAccX = 0.013502052, pixAccY = 0.014005423575; double camera1Width = 1, camera1Height = 2; QFuture future1; if (data->imgs.size() == 1) { src = data->imgs[0]; if (Paint.channels() == 1) cv::cvtColor(src, Paint, cv::COLOR_GRAY2BGR); else src.copyTo(Paint); } //} if (CCD1OK == 2) cv::putText(Paint, "NG", cv::Point(150, 600), 1, 10, cv::Scalar(0, 0, 255), 30); else cv::putText(Paint, "OK", cv::Point(150, 600), 1, 10, cv::Scalar(0, 255, 0), 30); ///////////////////无SN阻塞/////////////////////// //if (!data->SNcode.compare(snDatas->snErrorsnError)) // data->SNcode = snDatas->waitForSn(data->timeCode); cv::putText(Paint, data->SNcode, cv::Point(150, 800), 1, 10, cv::Scalar(0, 255, 0), 10); /////////////////////SQL//////////////////////// data->sqlVec.push_back({ "Camera1Result", CCD1OK }); data->sqlVec.push_back({ "Camera1_Width", camera1Width }); data->sqlVec.push_back({ "Camera1_Height", camera1Height }); ////////////////////结果保存////////////////// cv::resize(Paint, Paint, cv::Size(Paint.cols / 2, Paint.rows / 2)); data->resultImgs.push_back(Paint); //////////////CSV///////////////////////////// string OKNG("OK"); if (CCD1OK == 2)OKNG = "NG"; qDebug() << "[Debug]algo1 end:" << QString::fromStdString(data->SNcode); std::cout << "algo1 end:" << QString::fromStdString(data->SNcode).toStdString() << endl; }