// gasFillingPortPosition_test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include #include #include #include #include #include "direct.h" #include #include "rodAndBarDetection_Export.h" #include #include #include #include #include typedef struct { int r; int g; int b; }SG_color; typedef struct { int nPointIdx; double x; double y; double z; float r; float g; float b; } SPointXYZRGB; bool fileExists(const char* path) { FILE* f = fopen(path, "r"); if (f != NULL) { fclose(f); return true; } return false; } // 点乘 dot double _dotMultiply(const SVzNL3DPoint& a, const SVzNL3DPoint& b) { return (a.x * b.x + a.y * b.y + a.z * b.z); } // 模长 double _length(const SVzNL3DPoint& a) { return sqrt(a.x * a.x + a.y * a.y + a.z * a.z); } // 计算两个向量夹角(返回 角度) float _computeVecAngle(const SVzNL3DPoint& a, const SVzNL3DPoint& b) { float l = _length(a) * _length(b); if (l < 1e-6f) return 0.0f; // 避免除零 float cosTheta = _dotMultiply(a, b) / l; cosTheta = cosTheta > 1.0 ? 1.0 : cosTheta; cosTheta = cosTheta < -1.0 ? -1.0 : cosTheta; float rad = acosf(cosTheta); float degree = rad * 180.0f / (float)M_PI; return degree; } void _outputCalibPara(char* fileName, SSG_planeCalibPara calibPara) { std::ofstream sw(fileName); char dataStr[250]; //调平矩阵 sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.planeCalib[0], calibPara.planeCalib[1], calibPara.planeCalib[2]); sw << dataStr << std::endl; sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.planeCalib[3], calibPara.planeCalib[4], calibPara.planeCalib[5]); sw << dataStr << std::endl; sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.planeCalib[6], calibPara.planeCalib[7], calibPara.planeCalib[8]); sw << dataStr << std::endl; //地面高度 sprintf_s(dataStr, 250, "%g", calibPara.planeHeight); sw << dataStr << std::endl; //反向旋转矩阵 sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.invRMatrix[0], calibPara.invRMatrix[1], calibPara.invRMatrix[2]); sw << dataStr << std::endl; sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.invRMatrix[3], calibPara.invRMatrix[4], calibPara.invRMatrix[5]); sw << dataStr << std::endl; sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.invRMatrix[6], calibPara.invRMatrix[7], calibPara.invRMatrix[8]); sw << dataStr << std::endl; sw.close(); } SSG_planeCalibPara _readCalibPara(char* fileName) { //设置初始结果 double initCalib[9] = { 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 }; SSG_planeCalibPara planePara; for (int i = 0; i < 9; i++) planePara.planeCalib[i] = initCalib[i]; planePara.planeHeight = -1.0; for (int i = 0; i < 9; i++) planePara.invRMatrix[i] = initCalib[i]; std::ifstream inputFile(fileName); std::string linedata; if (inputFile.is_open() == false) return planePara; //调平矩阵 std::getline(inputFile, linedata); sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.planeCalib[0], &planePara.planeCalib[1], &planePara.planeCalib[2]); std::getline(inputFile, linedata); sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.planeCalib[3], &planePara.planeCalib[4], &planePara.planeCalib[5]); std::getline(inputFile, linedata); sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.planeCalib[6], &planePara.planeCalib[7], &planePara.planeCalib[8]); //地面高度 std::getline(inputFile, linedata); sscanf_s(linedata.c_str(), "%lf", &planePara.planeHeight); //反向旋转矩阵 std::getline(inputFile, linedata); sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.invRMatrix[0], &planePara.invRMatrix[1], &planePara.invRMatrix[2]); std::getline(inputFile, linedata); sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.invRMatrix[3], &planePara.invRMatrix[4], &planePara.invRMatrix[5]); std::getline(inputFile, linedata); sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.invRMatrix[6], &planePara.invRMatrix[7], &planePara.invRMatrix[8]); inputFile.close(); return planePara; } void wdReadLaserScanPointFromFile_XYZ_vector(const char* fileName, std::vector>& scanData) { std::ifstream inputFile(fileName); std::string linedata; if (inputFile.is_open() == false) return; std::vector< SVzNL3DPosition> a_line; int ptIdx = 0; while (getline(inputFile, linedata)) { if (0 == strncmp("Line_", linedata.c_str(), 5)) { int ptSize = (int)a_line.size(); if (ptSize > 0) { scanData.push_back(a_line); } a_line.clear(); ptIdx = 0; } else if (0 == strncmp("{", linedata.c_str(), 1)) { float X, Y, Z; int imageY = 0; float leftX, leftY; float rightX, rightY; sscanf_s(linedata.c_str(), "{%f,%f,%f}-{%f,%f}-{%f,%f}", &X, &Y, &Z, &leftX, &leftY, &rightX, &rightY); SVzNL3DPosition a_pt; a_pt.pt3D.x = X; a_pt.pt3D.y = Y; a_pt.pt3D.z = Z; a_pt.nPointIdx = ptIdx; ptIdx++; a_line.push_back(a_pt); } } //last line int ptSize = (int)a_line.size(); if (ptSize > 0) { scanData.push_back(a_line); a_line.clear(); } inputFile.close(); return; } void wd_gridScan_GetROIData(std::vector>& scanData, SVzNLRangeD roi_y, std::vector>& roiData) { int lineNum = (int)scanData.size(); int linePtNum = (int)scanData[0].size(); int globalPtStart = INT_MAX; int globalPtEnd = 0; int lineStart = INT_MAX; int lineEnd = 0; for (int line = 0; line < lineNum; line++) { std::vector< SVzNL3DPosition >& lineData = scanData[line]; int ptSize = (int)lineData.size(); int vldNum = 0; int ptStart = INT_MAX; int ptEnd = 0; for (int i = 0; i < ptSize; i++) { if (lineData[i].pt3D.z > 1e-4) { if ((lineData[i].pt3D.y < roi_y.min) || (lineData[i].pt3D.y > roi_y.max)) lineData[i].pt3D = { 0.0, 0.0, 0.0 }; } if (lineData[i].pt3D.z > 1e-4) { if (ptStart > i) ptStart = i; ptEnd = i; vldNum++; } } if (vldNum > 0) { if (globalPtStart > ptStart) globalPtStart = ptStart; if (globalPtEnd < ptEnd) globalPtEnd = ptEnd; if (lineStart > line) lineStart = line; lineEnd = line; } } int vldLineNum = lineEnd - lineStart + 1; int vldPtNum = globalPtEnd - globalPtStart + 1; roiData.resize(vldLineNum); for (int line = 0; line < vldLineNum; line++) { roiData[line].resize(vldPtNum); for (int i = 0; i < vldPtNum; i++) roiData[line][i] = scanData[line + lineStart][i + globalPtStart]; } return; } void _outputScanDataFile(char* fileName, std::vector>& scanData, float lineV, int maxTimeStamp, int clockPerSecond) { std::ofstream sw(fileName); int lineNum = (int)scanData.size(); sw << "LineNum:" << lineNum << std::endl; sw << "DataType: 0" << std::endl; sw << "ScanSpeed:" << lineV << std::endl; sw << "PointAdjust: 1" << std::endl; sw << "MaxTimeStamp:" << maxTimeStamp << "_" << clockPerSecond << std::endl; for (int line = 0; line < lineNum; line++) { int nPositionCnt = (int)scanData[line].size(); sw << "Line_" << line << "_0_" << nPositionCnt << std::endl; for (int i = 0; i < nPositionCnt; i++) { SVzNL3DPosition& pt3D = scanData[line][i]; float x = (float)pt3D.pt3D.x; float y = (float)pt3D.pt3D.y; float z = (float)pt3D.pt3D.z; sw << "{ " << x << "," << y << "," << z << " }-"; sw << "{0,0}-{0,0}" << std::endl; } } sw.close(); } void _readRodParas(char* fileName, std::vector& rodParas) { std::ifstream inputFile(fileName); std::string linedata; if (inputFile.is_open() == false) return; std::vector indices; int maxIdx = 0; std::vector< SSX_rodParam> paras; while (getline(inputFile, linedata)) { int idx; float len, dia; sscanf_s(linedata.c_str(), "%d_L_%f_D_%f", &idx, &len, &dia); SSX_rodParam a_para = { dia , len }; indices.push_back(idx); paras.push_back(a_para); maxIdx = maxIdx < idx ? idx : maxIdx; } if (maxIdx == 0) return; rodParas.resize(maxIdx + 1); for (int i = 0; i < (int)indices.size(); i++) { int idx = indices[i]; rodParas[idx] = paras[i]; } return; } void _outputChanneltInfo(char* fileName, std::vector& screwInfo) { std::ofstream sw(fileName); char dataStr[250]; int objNum = (int)screwInfo.size(); for (int i = 0; i < objNum; i++) { sprintf_s(dataStr, 250, "螺杆_%d: center_( %g, %g, %g ), dir_( %g, %g, %g )", i + 1, screwInfo[i].center.x, screwInfo[i].center.y, screwInfo[i].center.z, screwInfo[i].axialDir.x, screwInfo[i].axialDir.y, screwInfo[i].axialDir.z); sw << dataStr << std::endl; } sw.close(); } void _outputPlatePiseInfo(char* fileName, SSX_platePoseInfo& centerInfo) { std::ofstream sw(fileName); char dataStr[250]; sprintf_s(dataStr, 250, "定位盘: \n"); sw << dataStr << std::endl; sprintf_s(dataStr, 250, " holeLT_(% g, % g, % g)\n", centerInfo.holeLT.x, centerInfo.holeLT.y, centerInfo.holeLT.z); sw << dataStr << std::endl; sprintf_s(dataStr, 250, " holeRB_(% g, % g, % g)\n", centerInfo.holeRB.x, centerInfo.holeRB.y, centerInfo.holeRB.z); sw << dataStr << std::endl; sprintf_s(dataStr, 250, " center_(% g, % g, % g)\n", centerInfo.center.x, centerInfo.center.y, centerInfo.center.z); sw << dataStr << std::endl; sprintf_s(dataStr, 250, " normalDir_(% g, % g, % g)\n", centerInfo.normalDir.x, centerInfo.normalDir.y, centerInfo.normalDir.z); sw << dataStr << std::endl; sprintf_s(dataStr, 250, " xDir_(% g, % g, % g)\n", centerInfo.xDir.x, centerInfo.xDir.y, centerInfo.xDir.z); sw << dataStr << std::endl; sprintf_s(dataStr, 250, " yDir_(% g, % g, % g)\n", centerInfo.yDir.x, centerInfo.yDir.y, centerInfo.yDir.z); sw << dataStr << std::endl; sw.close(); } void _outputRodtInfo(char* fileName, std::vector& rodInfo) { std::ofstream sw(fileName); char dataStr[250]; int objNum = (int)rodInfo.size(); for (int i = 0; i < objNum; i++) { sprintf_s(dataStr, 250, "螺杆_%d: center_( %g, %g, %g ), dir_axia( %g, %g, %g ), dir_normal_( %g, %g, %g )", i + 1, rodInfo[i].center.x, rodInfo[i].center.y, rodInfo[i].center.z, rodInfo[i].axialDir.x, rodInfo[i].axialDir.y, rodInfo[i].axialDir.z, rodInfo[i].normalDir.x, rodInfo[i].normalDir.y, rodInfo[i].normalDir.z); sw << dataStr << std::endl; } sw.close(); } void _outputWeldSeamInfo(char* fileName, std::vector& weldSeamInfo) { std::ofstream sw(fileName); char dataStr[250]; int objNum = (int)weldSeamInfo.size(); for (int i = 0; i < objNum; i++) { sprintf_s(dataStr, 250, "螺杆_%d: center_( %g, %g, %g ), dir_normal_( %g, %g, %g ), x_dir_(", i + 1, weldSeamInfo[i].center.x, weldSeamInfo[i].center.y, weldSeamInfo[i].center.z, weldSeamInfo[i].normalDir.x, weldSeamInfo[i].normalDir.y, weldSeamInfo[i].normalDir.z); sw << dataStr << std::endl; } sw.close(); } void _outputRGBDScan_RGBD( char* fileName, std::vector>& scanLines, std::vector& screwInfo ) { int lineNum = (int)scanLines.size(); std::ofstream sw(fileName); int realLines = lineNum; int objNum = (int)screwInfo.size(); if (objNum > 0) realLines += 1; sw << "LineNum:" << realLines << std::endl; sw << "DataType: 0" << std::endl; sw << "ScanSpeed: 0" << std::endl; sw << "PointAdjust: 1" << std::endl; sw << "MaxTimeStamp: 0_0" << std::endl; int maxLineIndex = 0; int max_stamp = 0; SG_color rgb = { 0, 0, 0 }; SG_color objColor[8] = { {245,222,179},//淡黄色 {210,105, 30},//巧克力色 {240,230,140},//黄褐色 {135,206,235},//天蓝色 {250,235,215},//古董白 {189,252,201},//薄荷色 {221,160,221},//梅红色 {188,143,143},//玫瑰红色 }; int size = 1; int lineIdx = 0; for (int line = 0; line < lineNum; line++) { int linePtNum = (int)scanLines[line].size(); if (linePtNum == 0) continue; sw << "Line_" << lineIdx << "_0_" << linePtNum << std::endl; lineIdx++; for (int i = 0; i < linePtNum; i++) { SVzNL3DPosition* pt3D = &scanLines[line][i]; if (pt3D->nPointIdx == 1) { rgb = objColor[pt3D->nPointIdx]; size = 3; } else if (pt3D->nPointIdx == 2) { rgb = { 250, 0, 0 }; size = 3; } else if (pt3D->nPointIdx == 4) { rgb = { 250, 250, 0 }; size = 6; } else //if (pt3D->nPointIdx == 0) { rgb = { 200, 200, 200 }; size = 1; } float x = (float)pt3D->pt3D.x; float y = (float)pt3D->pt3D.y; float z = (float)pt3D->pt3D.z; sw << "{" << x << "," << y << "," << z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl; } } if (objNum > 0) { sw << "Line_" << lineIdx << "_0_" << objNum << std::endl; rgb = { 250, 0, 0 }; size = 8; for (int i = 0; i < objNum; i++) { float x = (float)screwInfo[i].center.x; float y = (float)screwInfo[i].center.y; float z = (float)screwInfo[i].center.z; sw << "{" << x << "," << y << "," << z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl; } //多输出一个,修正显示工具bug float x = (float)screwInfo[0].center.x; float y = (float)screwInfo[0].center.y; float z = (float)screwInfo[0].center.z; sw << "{" << x << "," << y << "," << z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl; //输出法向 size = 1; double len1 = 30; double len2 = 200; lineIdx = 0; for (int i = 0; i < objNum; i++) { SVzNL3DPoint pt0 = { screwInfo[i].center.x - len1 * screwInfo[i].axialDir.x, screwInfo[i].center.y - len1 * screwInfo[i].axialDir.y, screwInfo[i].center.z - len1 * screwInfo[i].axialDir.z }; SVzNL3DPoint pt1 = { screwInfo[i].center.x + len2 * screwInfo[i].axialDir.x, screwInfo[i].center.y + len2 * screwInfo[i].axialDir.y, screwInfo[i].center.z + len2 * screwInfo[i].axialDir.z }; //显示法向量 sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << (float)pt0.x << "," << (float)pt0.y << "," << (float)pt0.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; sw << "{" << pt1.x << "," << pt1.y << "," << pt1.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; } } sw.close(); } void _outputRGBDScan_RGBD_centerPose( char* fileName, std::vector>& scanLines, SSX_platePoseInfo& poseInfo ) { int lineNum = (int)scanLines.size(); std::ofstream sw(fileName); int realLines = lineNum; realLines += 1; sw << "LineNum:" << realLines << std::endl; sw << "DataType: 0" << std::endl; sw << "ScanSpeed: 0" << std::endl; sw << "PointAdjust: 1" << std::endl; sw << "MaxTimeStamp: 0_0" << std::endl; int maxLineIndex = 0; int max_stamp = 0; SG_color rgb = { 0, 0, 0 }; SG_color objColor[8] = { {245,222,179},//淡黄色 {210,105, 30},//巧克力色 {240,230,140},//黄褐色 {135,206,235},//天蓝色 {250,235,215},//古董白 {189,252,201},//薄荷色 {221,160,221},//梅红色 {188,143,143},//玫瑰红色 }; int size = 1; int lineIdx = 0; for (int line = 0; line < lineNum; line++) { int linePtNum = (int)scanLines[line].size(); if (linePtNum == 0) continue; sw << "Line_" << lineIdx << "_0_" << linePtNum << std::endl; lineIdx++; for (int i = 0; i < linePtNum; i++) { SVzNL3DPosition* pt3D = &scanLines[line][i]; if (pt3D->nPointIdx == 2) { rgb = { 135,206,235 }; size = 5; } else if (pt3D->nPointIdx == 3) { rgb = { 250, 0, 0 }; size = 5; } else //if (pt3D->nPointIdx == 0) { rgb = { 200, 200, 200 }; size = 1; } float x = (float)pt3D->pt3D.x; float y = (float)pt3D->pt3D.y; float z = (float)pt3D->pt3D.z; sw << "{" << x << "," << y << "," << z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl; } } { sw << "Line_" << lineIdx << "_0_3" << std::endl; rgb = { 250, 0, 0 }; size = 8; float x = (float)poseInfo.center.x; float y = (float)poseInfo.center.y; float z = (float)poseInfo.center.z; sw << "{" << x << "," << y << "," << z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl; x = (float)poseInfo.holeLT.x; y = (float)poseInfo.holeLT.y; z = (float)poseInfo.holeLT.z; sw << "{" << x << "," << y << "," << z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl; x = (float)poseInfo.holeRB.x; y = (float)poseInfo.holeRB.y; z = (float)poseInfo.holeRB.z; sw << "{" << x << "," << y << "," << z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl; //输出法向 size = 1; double len = 110; lineIdx = 0; { SVzNL3DPoint pt0 = { poseInfo.center.x, // - len * poseInfo.normalDir.x, poseInfo.center.y, // - len * poseInfo.normalDir.y, poseInfo.center.z }; // - len * poseInfo.normalDir.z }; SVzNL3DPoint pt1 = { poseInfo.center.x + len * poseInfo.normalDir.x, poseInfo.center.y + len * poseInfo.normalDir.y, poseInfo.center.z + len * poseInfo.normalDir.z }; SVzNL3DPoint basePt = poseInfo.center; SVzNL3DPoint pt2 = { poseInfo.center.x + len * poseInfo.xDir.x, poseInfo.center.y + len * poseInfo.xDir.y, poseInfo.center.z + len * poseInfo.xDir.z }; SVzNL3DPoint pt3 = { poseInfo.center.x + len * poseInfo.yDir.x, poseInfo.center.y + len * poseInfo.yDir.y, poseInfo.center.z + len * poseInfo.yDir.z }; //显示法向量 sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << (float)pt0.x << "," << (float)pt0.y << "," << (float)pt0.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; sw << "{" << pt1.x << "," << pt1.y << "," << pt1.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; rgb = { 0, 250, 0 }; sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << (float)basePt.x << "," << (float)basePt.y << "," << (float)basePt.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; sw << "{" << pt2.x << "," << pt2.y << "," << pt2.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; rgb = { 0, 0, 250 }; sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << (float)basePt.x << "," << (float)basePt.y << "," << (float)basePt.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; sw << "{" << pt3.x << "," << pt3.y << "," << pt3.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; rgb = { 0, 250, 0 }; basePt = { poseInfo.holeLT.x - len * poseInfo.xDir.x, poseInfo.holeLT.y - len * poseInfo.xDir.y, poseInfo.holeLT.z - len * poseInfo.xDir.z }; pt2 = { poseInfo.holeLT.x + len * poseInfo.xDir.x, poseInfo.holeLT.y + len * poseInfo.xDir.y, poseInfo.holeLT.z + len * poseInfo.xDir.z }; sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << (float)basePt.x << "," << (float)basePt.y << "," << (float)basePt.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; sw << "{" << pt2.x << "," << pt2.y << "," << pt2.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; basePt = { poseInfo.holeRB.x - len * poseInfo.xDir.x, poseInfo.holeRB.y - len * poseInfo.xDir.y, poseInfo.holeRB.z - len * poseInfo.xDir.z }; pt2 = { poseInfo.holeRB.x + len * poseInfo.xDir.x, poseInfo.holeRB.y + len * poseInfo.xDir.y, poseInfo.holeRB.z + len * poseInfo.xDir.z }; sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << (float)basePt.x << "," << (float)basePt.y << "," << (float)basePt.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; sw << "{" << pt2.x << "," << pt2.y << "," << pt2.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; } } sw.close(); } void _outputRGBDScan_RGBD_rodInfo( char* fileName, std::vector>& scanLines, std::vector& rodInfo ) { int lineNum = (int)scanLines.size(); std::ofstream sw(fileName); int realLines = lineNum; int objNum = (int)rodInfo.size(); if (objNum > 0) realLines += 1; sw << "LineNum:" << realLines << std::endl; sw << "DataType: 0" << std::endl; sw << "ScanSpeed: 0" << std::endl; sw << "PointAdjust: 1" << std::endl; sw << "MaxTimeStamp: 0_0" << std::endl; int maxLineIndex = 0; int max_stamp = 0; SG_color rgb = { 0, 0, 0 }; SG_color objColor[8] = { {245,222,179},//淡黄色 {210,105, 30},//巧克力色 {240,230,140},//黄褐色 {135,206,235},//天蓝色 {250,235,215},//古董白 {189,252,201},//薄荷色 {221,160,221},//梅红色 {188,143,143},//玫瑰红色 }; int size = 1; int lineIdx = 0; for (int line = 0; line < lineNum; line++) { int linePtNum = (int)scanLines[line].size(); if (linePtNum == 0) continue; sw << "Line_" << lineIdx << "_0_" << linePtNum << std::endl; lineIdx++; for (int i = 0; i < linePtNum; i++) { SVzNL3DPosition* pt3D = &scanLines[line][i]; if (pt3D->nPointIdx > 0) { int centerFlag = pt3D->nPointIdx >> 4; if (centerFlag > 0) { rgb = { 180, 0, 0 }; size = 2; } else { rgb = objColor[pt3D->nPointIdx % 8]; size = 2; } } else //if (pt3D->nPointIdx == 0) { rgb = { 200, 200, 200 }; size = 1; } float x = (float)pt3D->pt3D.x; float y = (float)pt3D->pt3D.y; float z = (float)pt3D->pt3D.z; sw << "{" << x << "," << y << "," << z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl; } } if (objNum > 0) { sw << "Line_" << lineIdx << "_0_" << objNum << std::endl; size = 12; for (int i = 0; i < objNum; i++) { if(i == 0) rgb = { 250, 255, 0 }; else rgb = { 250, 0, 0 }; float x = (float)rodInfo[i].center.x; float y = (float)rodInfo[i].center.y; float z = (float)rodInfo[i].center.z; sw << "{" << x << "," << y << "," << z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl; } //输出法向 size = 8; double len = 60; lineIdx = 0; for (int i = 0; i < objNum; i++) { if (i == 0) rgb = { 250, 255, 0 }; else rgb = { 250, 0, 0 }; SVzNL3DPoint pt0 = { rodInfo[i].center.x, rodInfo[i].center.y, rodInfo[i].center.z }; SVzNL3DPoint pt1 = { rodInfo[i].center.x + len * rodInfo[i].axialDir.x, rodInfo[i].center.y + len * rodInfo[i].axialDir.y, rodInfo[i].center.z + len * rodInfo[i].axialDir.z }; SVzNL3DPoint pt2 = { rodInfo[i].center.x + len * rodInfo[i].normalDir.x, rodInfo[i].center.y + len * rodInfo[i].normalDir.y, rodInfo[i].center.z + len * rodInfo[i].normalDir.z }; //显示轴向量 sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << (float)rodInfo[i].startPt.x << "," << (float)rodInfo[i].startPt.y << "," << (float)rodInfo[i].startPt.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; sw << "{" << (float)rodInfo[i].endPt.x << "," << (float)rodInfo[i].endPt.y << "," << (float)rodInfo[i].endPt.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; //显示法向量 sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << (float)pt0.x << "," << (float)pt0.y << "," << (float)pt0.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; sw << "{" << (float)pt2.x << "," << (float)pt2.y << "," << (float)pt2.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; } lineIdx++; } sw.close(); } void _outputRGBDScan_RGBD_weldSeam( char* fileName, std::vector>& scanLines, std::vector& weldSeamInfo ) { int lineNum = (int)scanLines.size(); std::ofstream sw(fileName); int realLines = lineNum; int objNum = (int)weldSeamInfo.size(); if (objNum > 0) realLines += 1; sw << "LineNum:" << realLines << std::endl; sw << "DataType: 0" << std::endl; sw << "ScanSpeed: 0" << std::endl; sw << "PointAdjust: 1" << std::endl; sw << "MaxTimeStamp: 0_0" << std::endl; int maxLineIndex = 0; int max_stamp = 0; SG_color rgb = { 0, 0, 0 }; SG_color objColor[8] = { {245,222,179},//淡黄色 {210,105, 30},//巧克力色 {240,230,140},//黄褐色 {135,206,235},//天蓝色 {250,235,215},//古董白 {189,252,201},//薄荷色 {221,160,221},//梅红色 {188,143,143},//玫瑰红色 }; int size = 1; int lineIdx = 0; for (int line = 0; line < lineNum; line++) { int linePtNum = (int)scanLines[line].size(); if (linePtNum == 0) continue; sw << "Line_" << lineIdx << "_0_" << linePtNum << std::endl; lineIdx++; for (int i = 0; i < linePtNum; i++) { SVzNL3DPosition* pt3D = &scanLines[line][i]; if (pt3D->nPointIdx > 0) { int centerFlag = pt3D->nPointIdx >> 4; if (centerFlag > 0) { if (centerFlag <= 2) { rgb = { 180, 0, 0 }; size = 2; } else if(centerFlag == 4) { rgb = { 0, 250, 0 }; size = 4; } } else { rgb = objColor[pt3D->nPointIdx % 8]; size = 2; } } else //if (pt3D->nPointIdx == 0) { rgb = { 200, 200, 200 }; size = 1; } float x = (float)pt3D->pt3D.x; float y = (float)pt3D->pt3D.y; float z = (float)pt3D->pt3D.z; sw << "{" << x << "," << y << "," << z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl; } } if (objNum > 0) { std::vector weldPoints; for (int i = 0; i < objNum; i++) { if (weldSeamInfo[i].weldType == KeWD_WELD_POINT) weldPoints.push_back(weldSeamInfo[i].center); else { weldPoints.push_back(weldSeamInfo[i].startPt); weldPoints.push_back(weldSeamInfo[i].center); weldPoints.push_back(weldSeamInfo[i].endPt); } } sw << "Line_" << lineIdx << "_0_" << (int)weldPoints.size() << std::endl; size = 15; for (int i = 0; i < (int)weldPoints.size(); i++) { rgb = { 250, 0, 0 }; float x = (float)weldPoints[i].x; float y = (float)weldPoints[i].y; float z = (float)weldPoints[i].z; sw << "{" << x << "," << y << "," << z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl; } //输出法向 size = 4; double len1 = 20; double len2 = 20; lineIdx = 0; for (int i = 0; i < objNum; i++) { SVzNL3DPoint pt0, pt1; if (weldSeamInfo[i].weldType == KeWD_WELD_POINT) { pt0 = weldSeamInfo[i].center; pt1 = { weldSeamInfo[i].center.x + len1 * weldSeamInfo[i].axialDir.x, weldSeamInfo[i].center.y + len1 * weldSeamInfo[i].axialDir.y, weldSeamInfo[i].center.z + len1 * weldSeamInfo[i].axialDir.z }; } else { pt0 = weldSeamInfo[i].startPt; pt1 = weldSeamInfo[i].endPt; } SVzNL3DPoint pt2 = { weldSeamInfo[i].center.x, weldSeamInfo[i].center.y, weldSeamInfo[i].center.z }; SVzNL3DPoint pt3 = { weldSeamInfo[i].center.x + len2 * weldSeamInfo[i].normalDir.x, weldSeamInfo[i].center.y + len2 * weldSeamInfo[i].normalDir.y, weldSeamInfo[i].center.z + len2 * weldSeamInfo[i].normalDir.z }; //显示轴向量 rgb = { 0, 0, 250 }; sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << (float)pt0.x << "," << (float)pt0.y << "," << (float)pt0.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; sw << "{" << (float)pt1.x << "," << (float)pt1.y << "," << (float)pt1.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; //显示法向量 rgb = { 250, 0, 0 }; sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << (float)pt2.x << "," << (float)pt2.y << "," << (float)pt2.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; sw << "{" << (float)pt3.x << "," << (float)pt3.y << "," << (float)pt3.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; } lineIdx++; } sw.close(); } #define SCREW_TEST_GROUP 10 void screwTest(void) { const char* dataPath[SCREW_TEST_GROUP] = { "F:/ShangGu/项目/冠钦项目/螺杆测量/数据/模拟数据/", //0 "F:/ShangGu/项目/冠钦项目/螺杆测量/配天现场点云/螺杆点云2/上方两根/", //1 "F:/ShangGu/项目/冠钦项目/螺杆测量/配天现场点云/螺杆点云3/", //2 "F:/ShangGu/项目/冠钦项目/螺杆测量/配天现场点云/螺杆点云4/位置1/", //3 "F:/ShangGu/项目/冠钦项目/螺杆测量/配天现场点云/螺杆点云4/位置2/", //4 "F:/ShangGu/项目/冠钦项目/螺杆测量/配天现场点云/螺杆点云4/位置2未动螺杆拧进去100mm左右/", //5 "F:/ShangGu/项目/冠钦项目/螺杆测量/配天现场点云/螺杆点云4/位置2向前100mm螺杆拧进去100mm左右/", //6 "F:/ShangGu/项目/冠钦项目/螺杆测量/配天现场点云/螺杆点云20260621/另一根螺杆/", //7 "F:/ShangGu/项目/冠钦项目/螺杆测量/配天现场点云/螺杆点云20260621/拍照点1/", //8 "F:/ShangGu/项目/冠钦项目/螺杆测量/配天现场点云/螺杆点云20260621/拍照点1xyz移动10mm/", //9 }; SVzNLRange fileIdx[SCREW_TEST_GROUP] = { {1,4},{1,30},{1,11}, {1,20}, {1,20}, {1,5}, {1,21}, {1,10}, {1,10}, {1,10} }; const char* ver = wd_rodAndBarDetectionVersion(); printf("ver:%s\n", ver); for (int grp = 9; grp < SCREW_TEST_GROUP; grp++) { for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++) { //fidx =3; char _scan_file[256]; if(0 == grp) sprintf_s(_scan_file, "%sLaserData_%d.txt", dataPath[grp], fidx); else if( (grp>= 7)&&(grp <= 9)) sprintf_s(_scan_file, "%sLaserline_%d.txt", dataPath[grp], fidx); else sprintf_s(_scan_file, "%s%d_LaserData_Jl26C299.txt", dataPath[grp], fidx); std::vector> scanLines; wdReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines); //转成plyTxt格式 //sprintf_s(_scan_file, "%s%d_ply_Hi229229.txt", dataPath[grp], fidx); //wdSavePlyTxt(_scan_file, scanLines); long t1 = (long)GetTickCount64();//统计时间 double rodDiameter; if (grp == 0) rodDiameter = 10.0; else rodDiameter = 28.0; //现场螺杆直径28mm //double rodDiameter = 10.0; SSG_cornerParam cornerParam; cornerParam.cornerTh = 30; //45度角 cornerParam.scale = rodDiameter/4; // algoParam.bagParam.bagH / 8; // 15; // algoParam.bagParam.bagH / 8; cornerParam.minEndingGap = 20; // algoParam.bagParam.bagW / 4; cornerParam.minEndingGap_z = 5.0; cornerParam.jumpCornerTh_1 = 15; //水平角度,小于此角度视为水平 cornerParam.jumpCornerTh_2 = 60; SSG_outlierFilterParam filterParam; filterParam.continuityTh = 20.0; //噪声滤除。当相邻点的z跳变大于此门限时,检查是否为噪声。若长度小于outlierLen, 视为噪声 filterParam.outlierTh = 5; SSG_treeGrowParam growParam; growParam.maxLineSkipNum = 30; growParam.yDeviation_max = 5.0; growParam.maxSkipDistance = 30.0; growParam.zDeviation_max = 50;// growParam.minLTypeTreeLen = 50; //mm, 螺杆长度 growParam.minVTypeTreeLen = 50; //mm bool isHorizonScan = true; //true:激光线平行槽道;false:激光线垂直槽道 int errCode = 0; std::vector screwInfo; sx_hexHeadScrewMeasure( scanLines, isHorizonScan, //true:激光线平行槽道;false:激光线垂直槽道 cornerParam, filterParam, growParam, rodDiameter, screwInfo, &errCode); long t2 = (long)GetTickCount64(); //输出测试结果 char _out_file[256]; sprintf_s(_out_file, "%sresult\\%d_result.txt", dataPath[grp], fidx); _outputRGBDScan_RGBD(_out_file, scanLines, screwInfo); sprintf_s(_out_file, "%sresult\\%d_screw_info.txt", dataPath[grp], fidx); _outputChanneltInfo(_out_file, screwInfo); if (screwInfo.size() > 0) { SVzNL3DPoint zAxis = { 0, 0, 1.0 }; float angle = _computeVecAngle(screwInfo[0].axialDir, zAxis); printf("%s: %d(ms), errCode=%d, {%f, %f, %f}, 与Z轴夹角=%f \n", _scan_file, (int)(t2 - t1), errCode, (float)screwInfo[0].center.x, (float)screwInfo[0].center.y, (float)screwInfo[0].center.z, angle); } else printf("%s: %d(ms), errCode=%d\n", _scan_file, (int)(t2 - t1), errCode); } } } #define LOCATING_PALTE_TEST_GROUP 1 void locatingPlateTest(void) { const char* dataPath[LOCATING_PALTE_TEST_GROUP] = { "F:/ShangGu/项目/冠钦项目/螺杆测量/配天现场点云/定位盘点云/", //0 }; SVzNLRange fileIdx[LOCATING_PALTE_TEST_GROUP] = { {1,17}, }; const char* ver = wd_rodAndBarDetectionVersion(); printf("ver:%s\n", ver); for (int grp = 0; grp < LOCATING_PALTE_TEST_GROUP; grp++) { for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++) { //fidx =2; char _scan_file[256]; sprintf_s(_scan_file, "%sLaserData_%d.txt", dataPath[grp], fidx); std::vector> scanLines; wdReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines); //转成plyTxt格式 //sprintf_s(_scan_file, "%s%d_ply_Hi229229.txt", dataPath[grp], fidx); //wdSavePlyTxt(_scan_file, scanLines); long t1 = (long)GetTickCount64();//统计时间 double rodDiameter = 10.0; SSG_cornerParam cornerParam; cornerParam.cornerTh = 60; //45度角 cornerParam.scale = rodDiameter / 4; // algoParam.bagParam.bagH / 8; // 15; // algoParam.bagParam.bagH / 8; cornerParam.minEndingGap = 20; // algoParam.bagParam.bagW / 4; cornerParam.minEndingGap_z = 5.0; cornerParam.jumpCornerTh_1 = 15; //水平角度,小于此角度视为水平 cornerParam.jumpCornerTh_2 = 60; int errCode = 0; SSX_platePoseInfo centerPose = sx_getLocationPlatePose( scanLines, cornerParam, & errCode); long t2 = (long)GetTickCount64(); printf("%s: %d(ms)!\n", _scan_file, (int)(t2 - t1)); //输出测试结果 sprintf_s(_scan_file, "%sresult\\%d_result.txt", dataPath[grp], fidx); _outputRGBDScan_RGBD_centerPose(_scan_file, scanLines, centerPose); sprintf_s(_scan_file, "%sresult\\%d_screw_info.txt", dataPath[grp], fidx); _outputPlatePiseInfo(_scan_file, centerPose); } } } #define NEW_LOCATING_PALTE_TEST_GROUP 1 void newLocatingPlateTest(void) { const char* dataPath[NEW_LOCATING_PALTE_TEST_GROUP] = { "F:/ShangGu/项目/冠钦项目/螺杆测量/配天现场点云/定位盘点云20260621/", //0 }; SVzNLRange fileIdx[NEW_LOCATING_PALTE_TEST_GROUP] = { {12,13}, }; const char* ver = wd_rodAndBarDetectionVersion(); printf("ver:%s\n", ver); for (int grp = 0; grp < NEW_LOCATING_PALTE_TEST_GROUP; grp++) { for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++) { //fidx =2; char _scan_file[256]; sprintf_s(_scan_file, "%sLaserData_%d.txt", dataPath[grp], fidx); std::vector> scanLines; wdReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines); //转成plyTxt格式 //sprintf_s(_scan_file, "%s%d_ply_Hi229229.txt", dataPath[grp], fidx); //wdSavePlyTxt(_scan_file, scanLines); long t1 = (long)GetTickCount64();//统计时间 SSG_cornerParam cornerParam; cornerParam.cornerTh = 45; //45度角 cornerParam.scale = 5.0; // algoParam.bagParam.bagH / 8; // 15; // algoParam.bagParam.bagH / 8; cornerParam.minEndingGap = 20; // algoParam.bagParam.bagW / 4; cornerParam.minEndingGap_z = 5.0; cornerParam.jumpCornerTh_1 = 15; //水平角度,小于此角度视为水平 cornerParam.jumpCornerTh_2 = 60; int errCode = 0; SSX_platePoseInfo centerPose = sx_getLocationPlatePose_new( scanLines, cornerParam, &errCode); long t2 = (long)GetTickCount64(); printf("%s: %d(ms),errCode=%d\n", _scan_file, (int)(t2 - t1), errCode); //输出测试结果 sprintf_s(_scan_file, "%sresult\\%d_result.txt", dataPath[grp], fidx); _outputRGBDScan_RGBD_centerPose(_scan_file, scanLines, centerPose); sprintf_s(_scan_file, "%sresult\\%d_screw_info.txt", dataPath[grp], fidx); _outputPlatePiseInfo(_scan_file, centerPose); } } } ; void _removeNullData(std::vector>& scanLines, double _F, std::vector>& scanData) { std::vector< SVzNLPointXYZRGBA> validPoints; for (int line = 0; line < (int)scanLines.size(); line++) { for (int j = 0; j < (int)scanLines[line].size(); j++) { if (scanLines[line][j].pt3D.z > 1e-4) { SVzNLPointXYZRGBA a_pt; double v = _F * scanLines[line][j].pt3D.y / scanLines[line][j].pt3D.z + 2000; a_pt.nRGB = (int)(v + 0.5); a_pt.x = scanLines[line][j].pt3D.x; a_pt.y = scanLines[line][j].pt3D.y; a_pt.z = scanLines[line][j].pt3D.z; validPoints.push_back(a_pt); } } } std::vector< SVzNLPointXYZRGBA> a_line; SVzNLPointXYZRGBA pre_pt; pre_pt.x = 0; pre_pt.y = 0; pre_pt.z = 0; pre_pt.nRGB = -1; for (int i = 0; i < validPoints.size(); i++) { if (validPoints[i].nRGB < (pre_pt.nRGB - 10)) { if (a_line.size() > 0) scanData.push_back(a_line); a_line.clear(); } a_line.push_back(validPoints[i]); pre_pt = validPoints[i]; } if(a_line.size() > 0) scanData.push_back(a_line); return; } void _convertToGridData_XYZRGB(std::vector>& scanData, double _F, std::vector>& gridData) { int lineNum = (int)scanData.size(); int min_y = 100000000; int max_y = -10000000; int validStartLine = -1; int validEndLine = -1; for (int line = 0; line < lineNum; line++) { if (scanData[line].size() > 0) { if (validStartLine < 0) { validStartLine = line; validEndLine = line; } else validEndLine = line; } for (int i = 0; i < (int)scanData[line].size(); i++) { SVzNLPointXYZRGBA& a_pt = scanData[line][i]; if (a_pt.z > 1e-4) { double v = _F * a_pt.y / a_pt.z + 2000; a_pt.nRGB = (int)(v + 0.5); max_y = max_y < (int)a_pt.nRGB ? (int)a_pt.nRGB : max_y; min_y = min_y > (int)a_pt.nRGB ? (int)a_pt.nRGB : min_y; } } } if (min_y == 100000000) return; int vldLineNum = validEndLine - validStartLine + 1; gridData.resize(vldLineNum); int pt_counter = max_y - min_y + 1; for (int i = 0; i < vldLineNum; i++) { gridData[i].resize(pt_counter); for (int j = 0; j < pt_counter; j++) { gridData[i][j].nPointIdx = j; gridData[i][j].pt3D.x = 0; gridData[i][j].pt3D.y = 0; gridData[i][j].pt3D.z = 0; } } for (int line = validStartLine; line <= validEndLine; line++) { int gridLine = line - validStartLine; for (int i = 0; i < (int)scanData[line].size(); i++) { SVzNLPointXYZRGBA& a_pt = scanData[line][i]; if (a_pt.z > 1e-4) { int pt_id = a_pt.nRGB - min_y; gridData[gridLine][pt_id].pt3D.x = a_pt.x; gridData[gridLine][pt_id].pt3D.y = a_pt.y; gridData[gridLine][pt_id].pt3D.z = a_pt.z; } } } return; } #define ROD_POSITION_TEST_GROUP 5 #define TEST_CONVERT_TO_GRID 0 #define TEST_COMPUTE_CALIB_PARA 0 #define TEST_COMPUTE_ROD_POSITION 1 void rodPositionTest(void) { #if TEST_CONVERT_TO_GRID //将数据转换成栅格格式格式 char _scan_dir[256]; int lineNum = 0; float lineV = 0.0f; int dataCalib = 0; int maxTimeStamp = 0; int clockPerSecond = 0; sprintf_s(_scan_dir, "F:/ShangGu/项目/冠钦项目/矩森棒材抓取/空料框及内剩一根棒材/"); char _scan_src_file[256]; double _F = 1219.15; //f for (int i = 1; i <= 3; i++) { //read ply txt sprintf_s(_scan_src_file, "%sLaserDataRAW_%d.txt", _scan_dir, i); std::vector> scanLines; wdReadLaserScanPointFromFile_XYZ_vector(_scan_src_file, scanLines); std::vector> scanData; _removeNullData(scanLines, _F, scanData); std::vector> gridData; _convertToGridData_XYZRGB(scanData, _F, gridData); char _out_file[256]; sprintf_s(_out_file, "%sLaserData_%d.txt", _scan_dir, i); _outputScanDataFile(_out_file, gridData, 0.0f, 0, 0); printf("%s: convert done!\n", _scan_src_file); } printf("all converted done!\n", _scan_src_file); #endif #if TEST_COMPUTE_CALIB_PARA const char* calibDataPath = "F:/ShangGu/项目/冠钦项目/矩森棒材抓取/空料框及内剩一根棒材/调平/位置1/"; char _calib_datafile[256]; sprintf_s(_calib_datafile, "%sGroundData_1.txt", calibDataPath); int lineNum = 0; float lineV = 0.0f; int dataCalib = 0; int maxTimeStamp = 0; int clockPerSecond = 0; std::vector> scanData; wdReadLaserScanPointFromFile_XYZ_vector(_calib_datafile, scanData); lineNum = (int)scanData.size(); if (scanData.size() > 0) { SSG_planeCalibPara calibPara = sx_rodPosition_getBaseCalibPara(scanData); //结果进行验证 for (int i = 0; i < lineNum; i++) { if (i == 14) int kkk = 1; //行处理 //调平,去除地面 sx_rodPosition_lineDataR(scanData[i], calibPara.planeCalib, -1); } // char calibFile[250]; sprintf_s(calibFile, "%sground_calib_para.txt", calibDataPath); _outputCalibPara(calibFile, calibPara); char _out_file[256]; sprintf_s(_out_file, "%sGroundData_1_calib_verify.txt", calibDataPath); _outputScanDataFile(_out_file, scanData, lineV, maxTimeStamp, clockPerSecond); #if 0 for (int fidx = fileIdx[cvtGrp].nMin; fidx <= fileIdx[cvtGrp].nMax; fidx++) { //fidx =4; char _scan_file[256]; sprintf_s(_scan_file, "%sLaserData_%d.txt", dataPath[cvtGrp], fidx); std::vector> scanLines; vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines); if (scanLines.size() == 0) continue; lineNum = (int)scanLines.size(); for (int i = 0; i < lineNum; i++) { //调平,去除地面 wd_lineDataR(scanLines[i], calibPara.planeCalib, -1); } sprintf_s(_scan_file, "%sLaserData_%d_calib_verify.txt", dataPath[cvtGrp], fidx); int headNullLines = 0; _outputScanDataFile_vector(_scan_file, scanLines, false, &headNullLines); } #endif printf("%s: calib done!\n", _calib_datafile); } #endif #if TEST_COMPUTE_ROD_POSITION const char* dataPath[ROD_POSITION_TEST_GROUP] = { "F:/ShangGu/项目/冠钦项目/矩森棒材抓取/测试数据/", //0 "F:/ShangGu/项目/冠钦项目/矩森棒材抓取/空料框及内剩一根棒材/", //1 "F:/ShangGu/项目/冠钦项目/矩森棒材抓取/其它尺寸棒材点云/", //2 "F:/ShangGu/项目/冠钦项目/胶布圆棒抓取/模拟测试数据/", //3 "F:/ShangGu/项目/冠钦项目/胶布圆棒抓取/模拟测试数据2/", //4 }; SVzNLRange fileIdx[ROD_POSITION_TEST_GROUP] = { {1,8}, {1,3}, {1,31}, {1,5},{1,11} }; const char* ver = wd_rodAndBarDetectionVersion(); printf("ver:%s\n", ver); for (int grp = 0; grp <= 2; grp++) { SSG_planeCalibPara poseCalibPara; //初始化成单位阵 poseCalibPara.planeCalib[0] = 1.0; poseCalibPara.planeCalib[1] = 0.0; poseCalibPara.planeCalib[2] = 0.0; poseCalibPara.planeCalib[3] = 0.0; poseCalibPara.planeCalib[4] = 1.0; poseCalibPara.planeCalib[5] = 0.0; poseCalibPara.planeCalib[6] = 0.0; poseCalibPara.planeCalib[7] = 0.0; poseCalibPara.planeCalib[8] = 1.0; poseCalibPara.planeHeight = -1.0; for (int i = 0; i < 9; i++) poseCalibPara.invRMatrix[i] = poseCalibPara.planeCalib[i]; char calibFile[250]; sprintf_s(calibFile, "%sground_calib_para.txt", dataPath[grp]); poseCalibPara = _readCalibPara(calibFile); sprintf_s(calibFile, "%sparameter.txt", dataPath[grp]); std::vector rodParas; if (grp <= 2) _readRodParas(calibFile, rodParas); for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++) { //fidx =5; char _scan_file[256]; if( (3 == grp) ||(4 == grp)) sprintf_s(_scan_file, "%s%d_LaserData_Hi229156.txt", dataPath[grp], fidx); else sprintf_s(_scan_file, "%sLaserData_%d.txt", dataPath[grp], fidx); std::vector> scanLines; wdReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines); //转成plyTxt格式 //sprintf_s(_scan_file, "%s%d_ply_Hi229229.txt", dataPath[grp], fidx); //wdSavePlyTxt(_scan_file, scanLines); long t1 = (long)GetTickCount64();//统计时间 SSX_rodParam rodParam; if (grp <= 2) { rodParam = rodParas[fidx]; } else { rodParam.diameter = 68.0; //圆棒直径 rodParam.len = 187; } SSG_cornerParam cornerParam; cornerParam.cornerTh = 45; //45度角 cornerParam.scale = rodParam.diameter / 4; // algoParam.bagParam.bagH / 8; // 15; // algoParam.bagParam.bagH / 8; cornerParam.minEndingGap = 20; // algoParam.bagParam.bagW / 4; cornerParam.minEndingGap_z = 5.0; cornerParam.jumpCornerTh_1 = 15; //水平角度,小于此角度视为水平 cornerParam.jumpCornerTh_2 = 60; SSG_outlierFilterParam filterParam; filterParam.continuityTh = 5.0; //噪声滤除。当相邻点的z跳变大于此门限时,检查是否为噪声。若长度小于outlierLen, 视为噪声 filterParam.outlierTh = 5; SSG_treeGrowParam growParam; growParam.maxLineSkipNum = 5; growParam.yDeviation_max = 10.0; growParam.maxSkipDistance = 10.0; growParam.zDeviation_max = 10.0;// growParam.minLTypeTreeLen = rodParam.len * 0.75; //mm, 螺杆长度 growParam.minVTypeTreeLen = rodParam.len * 0.75; //mm bool isHorizonScan = true; //true:激光线平行槽道;false:激光线垂直槽道 int errCode = 0; std::vector rodInfo; sx_rodPositioning( scanLines, poseCalibPara, cornerParam, filterParam, growParam, rodParam, rodInfo, &errCode); long t2 = (long)GetTickCount64(); printf("%s: %d(ms),errCode=%d\n", _scan_file, (int)(t2 - t1),errCode); //输出测试结果 sprintf_s(_scan_file, "%sresult\\%d_result.txt", dataPath[grp], fidx); _outputRGBDScan_RGBD_rodInfo(_scan_file, scanLines, rodInfo); sprintf_s(_scan_file, "%sresult\\%d_screw_info.txt", dataPath[grp], fidx); _outputRodtInfo(_scan_file, rodInfo); } } #endif } int counterValidPts(std::vector& lineData) { int num = 0; for (int i = 0; i < (int)lineData.size(); i++) { if (lineData[i].pt3D.z > 1e-4) num++; else { lineData[i].pt3D = { 0, 0, 0 }; } } return num; } #define WELD_SEAM_TEST_GROUP 4 void rodWeldSeamPosition_test(void) { const char* dataPath[WELD_SEAM_TEST_GROUP] = { "F:/ShangGu/项目/冠钦项目/筑裕视觉钢结构焊接/视觉照片1/", //0 "F:/ShangGu/项目/冠钦项目/筑裕视觉钢结构焊接/视觉照片2/", //1 "F:/ShangGu/项目/冠钦项目/筑裕视觉钢结构焊接/数据3/特征点1/", //2 "F:/ShangGu/项目/冠钦项目/筑裕视觉钢结构焊接/数据3/特征点2/", //3 }; SVzNLRange fileIdx[WELD_SEAM_TEST_GROUP] = { {1,20},{1,20},{1,27}, { 1,21 }, }; const char* ver = wd_rodAndBarDetectionVersion(); printf("ver:%s\n", ver); for (int grp = 2; grp < WELD_SEAM_TEST_GROUP; grp++) { SSG_planeCalibPara poseCalibPara; //初始化成单位阵 poseCalibPara.planeCalib[0] = 1.0; poseCalibPara.planeCalib[1] = 0.0; poseCalibPara.planeCalib[2] = 0.0; poseCalibPara.planeCalib[3] = 0.0; poseCalibPara.planeCalib[4] = 1.0; poseCalibPara.planeCalib[5] = 0.0; poseCalibPara.planeCalib[6] = 0.0; poseCalibPara.planeCalib[7] = 0.0; poseCalibPara.planeCalib[8] = 1.0; poseCalibPara.planeHeight = -1.0; for (int i = 0; i < 9; i++) poseCalibPara.invRMatrix[i] = poseCalibPara.planeCalib[i]; //char calibFile[250]; //sprintf_s(calibFile, "%sground_calib_para.txt", dataPath[grp]); //poseCalibPara = _readCalibPara(calibFile); for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++) { //fidx =1; char _scan_file[256]; sprintf_s(_scan_file, "%s%d_LaserData_groundAdjusted.txt", dataPath[grp], fidx); std::vector> scanLines; wdReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines); if ((grp == 2) || (grp == 3)) //计算调平矩阵 { #if 0 std::vector validPts; std::vector> copy_scanLines; copy_scanLines.resize(scanLines.size()); for (int line = 0; line < (int)scanLines.size(); line++) { std::vector< SVzNL3DPosition>& a_line = scanLines[line]; copy_scanLines[line].resize(a_line.size()); for (int j = 0; j < (int)a_line.size(); j++) { copy_scanLines[line][j] = a_line[j]; if (a_line[j].pt3D.z > 1e-4) { cv::Point3f a_pt = cv::Point3f((float)a_line[j].pt3D.x, (float)a_line[j].pt3D.y, (float)a_line[j].pt3D.z); validPts.push_back(a_pt); } } } std::vector out_inliers; Plane res = ransacFitPlane(validPts, out_inliers); if (res.C < 0) { res.A = -res.A; res.B = -res.B; res.C = -res.C; res.D = -res.D; } float meanH = 0; int counter = 0; for (int i = 0; i < (int)out_inliers.size(); i++) { meanH += out_inliers[i].z; counter++; } //计算投影向量 SVzNL3DPoint vec_1 = { res.A, res.B, res.C }; SVzNL3DPoint vec_2 = { 0, 0, 1.0 }; SSG_planeCalibPara calibPara = wd_computeRTMatrix(vec_1, vec_2); for (int m = 0; m < 9; m++) { poseCalibPara.planeCalib[m] = calibPara.planeCalib[m]; poseCalibPara.invRMatrix[m] = calibPara.invRMatrix[m]; } poseCalibPara.planeHeight = meanH / counter; char _out_file[256]; sprintf_s(_out_file, "%s%d_calib_para.txt", dataPath[grp], fidx); _outputCalibPara(_out_file, poseCalibPara); sprintf_s(_out_file, "%s%d_LaserData_groundAdjusted.txt", dataPath[grp], fidx); //if (false == fileExists(_out_file)) { //输出调平效果 int firstValidLine = -1; int lastValidLine = -1; for (int line = 0; line < (int)copy_scanLines.size(); line++) { //行处理 //调平,去除地面 double cuttingZ = poseCalibPara.planeHeight - 100; sx_rodPosition_lineDataR(copy_scanLines[line], poseCalibPara.planeCalib, cuttingZ); int ptsNum = counterValidPts(copy_scanLines[line]); if (ptsNum > 10) { if (firstValidLine < 0) firstValidLine = line; lastValidLine = line; } } if ((lastValidLine > 0) && (lastValidLine < copy_scanLines.size() - 1)) { copy_scanLines.erase(copy_scanLines.begin() + lastValidLine + 1, copy_scanLines.end()); } if(firstValidLine > 1) { copy_scanLines.erase(copy_scanLines.begin(), copy_scanLines.begin() + firstValidLine - 1); } _outputScanDataFile(_out_file, copy_scanLines, 0.0f, 0, 0); } #endif } long t1 = (long)GetTickCount64();//统计时间 SSX_rodParam rodParam; rodParam.diameter = 16.0; //钢筋直径 rodParam.len = 50; SSG_cornerParam cornerParam; cornerParam.cornerTh = 60; //45度角 cornerParam.scale = rodParam.diameter / 4; // algoParam.bagParam.bagH / 8; // 15; // algoParam.bagParam.bagH / 8; cornerParam.minEndingGap = 20; // algoParam.bagParam.bagW / 4; cornerParam.minEndingGap_z = 5.0; cornerParam.jumpCornerTh_1 = 15; //水平角度,小于此角度视为水平 cornerParam.jumpCornerTh_2 = 60; SSG_outlierFilterParam filterParam; filterParam.continuityTh = 4.0; //噪声滤除。当相邻点的z跳变大于此门限时,检查是否为噪声。若长度小于outlierLen, 视为噪声 filterParam.outlierTh = 4; SSG_treeGrowParam growParam; growParam.maxLineSkipNum = 5; growParam.yDeviation_max = 5.0; growParam.maxSkipDistance = 20.0; growParam.zDeviation_max = 5.0;// growParam.minLTypeTreeLen = 50; //mm, 螺杆长度 growParam.minVTypeTreeLen = 50; //mm bool isHorizonScan = true; //true:激光线平行槽道;false:激光线垂直槽道 double weldSeanRange = 100; //焊缝距钢筋交叉点的范围(最大值) int errCode = 0; std::vector weldSeamInfo; sx_rebarWeldSeamPositioning( scanLines, poseCalibPara, cornerParam, filterParam, growParam, rodParam, weldSeanRange, weldSeamInfo, &errCode); long t2 = (long)GetTickCount64(); printf("%s: %d(ms)!\n", _scan_file, (int)(t2 - t1)); if (errCode == 0) { //输出测试结果 sprintf_s(_scan_file, "%sresult\\%d_result.txt", dataPath[grp], fidx); _outputRGBDScan_RGBD_weldSeam(_scan_file, scanLines, weldSeamInfo); sprintf_s(_scan_file, "%sresult\\%d_screw_info.txt", dataPath[grp], fidx); _outputWeldSeamInfo(_scan_file, weldSeamInfo); } } } } typedef enum { keSG_测试_配天螺杆定位 = 0, keSG_测试_配天定位盘定位, keSG_测试_配天新定位盘定位, keSG_测试_棒材抓取, keSG_测试_筑裕钢筋焊缝定位, } ESG_testMode; int main() { //ESG_testMode testMode = keSG_测试_配天螺杆定位; //ESG_testMode testMode = keSG_测试_配天定位盘定位; //ESG_testMode testMode = keSG_测试_配天新定位盘定位; //ESG_testMode testMode = keSG_测试_棒材抓取; ESG_testMode testMode = keSG_测试_筑裕钢筋焊缝定位; if(keSG_测试_配天螺杆定位 == testMode) screwTest(); else if(keSG_测试_配天定位盘定位 == testMode) locatingPlateTest(); else if (keSG_测试_配天新定位盘定位 == testMode) newLocatingPlateTest(); else if(keSG_测试_棒材抓取 == testMode) rodPositionTest(); else if(keSG_测试_筑裕钢筋焊缝定位 == testMode) rodWeldSeamPosition_test(); return 0; } // 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单 // 调试程序: F5 或调试 >“开始调试”菜单 // 入门使用技巧: // 1. 使用解决方案资源管理器窗口添加/管理文件 // 2. 使用团队资源管理器窗口连接到源代码管理 // 3. 使用输出窗口查看生成输出和其他消息 // 4. 使用错误列表窗口查看错误 // 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目 // 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件