#include #include #include #include #include #include "direct.h" #include #include "hybridPosePositioning_Export.h" #include #include #include #include "SG_baseAlgo_Export.h" 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; SVzNL3DPoint _ptRotate(SVzNL3DPoint pt3D, double matrix3d[9]) { SVzNL3DPoint _r_pt; _r_pt.x = pt3D.x * matrix3d[0] + pt3D.y * matrix3d[1] + pt3D.z * matrix3d[2]; _r_pt.y = pt3D.x * matrix3d[3] + pt3D.y * matrix3d[4] + pt3D.z * matrix3d[5]; _r_pt.z = pt3D.x * matrix3d[6] + pt3D.y * matrix3d[7] + pt3D.z * matrix3d[8]; return _r_pt; } 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 _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(); } //读取3D和2D数据 void vzReadLaserScanPointFromFile_XYZUV_vector(const char* fileName, std::vector>& scanData) { std::ifstream inputFile(fileName); std::string linedata; if (inputFile.is_open() == false) return; std::vector< SVzNLPositionD> 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; float leftU, leftV; float rightU, rightV; sscanf_s(linedata.c_str(), "{ %f, %f, %f }-{ %f, %f }-{ %f, %f }", &X, &Y, &Z, &leftU, &leftV, &rightU, &rightV); if (Z > 1e-4) int kkk = 1; SVzNLPositionD a_pt; a_pt.ptLeft2D.x = leftU; a_pt.ptLeft2D.y = leftV; a_pt.ptRight2D.x = rightU; a_pt.ptRight2D.y = rightV; 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 vzReadLaserScanPointFromFile_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; } int counterLinePtNum_XYZ(std::vector< SVzNL3DPosition>& lineData) { int num = 0; for (int i = 0; i < (int)lineData.size(); i++) { if (lineData[i].pt3D.z > 1e-4) num++; } return num; } int counterLinePtNum_XYZUV(std::vector< SVzNLPositionD>& lineData) { int num = 0; for (int i = 0; i < (int)lineData.size(); i++) { if (lineData[i].pt3D.z > 1e-4) num++; } return num; } void _removeZeroLines_XYZ(std::vector>& scanData) { int lineNum = (int)scanData.size(); int firstLine = -1; int lastLine = 0; for (int line = 0; line < lineNum; line++) { int num = counterLinePtNum_XYZ(scanData[line]); if ((num > 0) && (firstLine < 0)) firstLine = line; if (num > 0) lastLine = line; } if (firstLine < 0) { scanData.clear(); return; } if ((lastLine < (lineNum - 1)) && (lastLine > 0)) scanData.erase(scanData.begin() + lastLine + 1, scanData.end()); scanData.erase(scanData.begin(), scanData.begin() + firstLine); return; } void _removeZeroLines_XYZUV(std::vector>& scanData) { int lineNum = (int)scanData.size(); int firstLine = -1; int lastLine = 0; for (int line = 0; line < lineNum; line++) { int num = counterLinePtNum_XYZUV(scanData[line]); if ((num > 0) && (firstLine < 0)) firstLine = line; if (num > 0) lastLine = line; } if (firstLine < 0) { scanData.clear(); return; } if ((lastLine < (lineNum - 1)) && (lastLine > 0)) scanData.erase(scanData.begin() + lastLine + 1, scanData.end()); scanData.erase(scanData.begin(), scanData.begin() + firstLine); return; } void vzReadObj2DROI_1(const char* fileName, std::vector& objROIs) { std::ifstream inputFile(fileName); std::string linedata; if (inputFile.is_open() == false) return; while (getline(inputFile, linedata)) { if (0 == strncmp("obj_", linedata.c_str(), 4)) { int objID; char type; float L, T, W, H, score; sscanf_s(linedata.c_str(), "obj_%d: C=%c, Rect={ %f, %f, %f, %f }, Score=%f", &objID, &type, sizeof(type), &L, &T, &W, &H, &score); WD_objArea2D a_roi; if ('a' == type) a_roi.workpieceType = 1; else if ('b' == type) a_roi.workpieceType = 2; else if ('c' == type) a_roi.workpieceType = 3; a_roi.roi.left = L; a_roi.roi.top = T; a_roi.roi.right = L + W; a_roi.roi.bottom = T + H; a_roi.score2D = score; objROIs.push_back(a_roi); } } inputFile.close(); return; } void vzReadObj2DROI(const char* fileName, std::vector& objROIs) { std::ifstream inputFile(fileName); std::string linedata; if (inputFile.is_open() == false) return; while (getline(inputFile, linedata)) { if (0 == strncmp("obj_", linedata.c_str(), 4)) { int objID; char type; float Cx, Cy, R, score; sscanf_s(linedata.c_str(), "obj_%d: C=%c, { %f, %f }, R=%f, Score=%f", &objID, &type, sizeof(type), &Cx, &Cy, &R, &score); WD_objArea2D a_roi; if ('a' == type) a_roi.workpieceType = 1; else if ('b' == type) a_roi.workpieceType = 2; else if ('c' == type) a_roi.workpieceType = 3; a_roi.roi.left = Cx - R ; a_roi.roi.top = Cy - R; a_roi.roi.right = Cx + R; a_roi.roi.bottom = Cy + R; a_roi.score2D = score; objROIs.push_back(a_roi); } } inputFile.close(); return; } void _outputRGBDResult_XYZUV_RGBD( char* fileName, std::vector>& scanLines, std::vector< WD_workpieceInfo>& workpiecePositions) { std::vector objects; int objNumber = (int)workpiecePositions.size(); for (int i = 0; i < objNumber; i++) { SVzNL3DPosition a_objPt; a_objPt.pt3D = workpiecePositions[i].center; objects.push_back(a_objPt); } int lineNum = (int)scanLines.size(); std::ofstream sw(fileName); int realLines = (objNumber == 0) ? lineNum : (lineNum + 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++) { SVzNLPositionD* pt3D = &scanLines[line][i]; if (pt3D->nPointIdx > 0) int kkk = 1; int flag = pt3D->nPointIdx & 0xffff; if (flag > 0) { rgb = objColor[flag % 8]; // { 255, 97, 0 }; size = 1; } else { 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; } } int linePtNum = (int)objects.size(); sw << "Line_" << lineNum << "_0_" << linePtNum + 1 << std::endl; lineNum++; for (int i = 0; i < linePtNum; i++) { if (i == 0) { size = 10; rgb = { 255, 0, 0 }; } else { rgb = { 255, 255, 0 }; size = 10; } //int colorIdx = objects[i].nPointIdx % 8; //rgb = objColor[colorIdx]; float x = (float)objects[i].pt3D.x; float y = (float)objects[i].pt3D.y; float z = (float)objects[i].pt3D.z; sw << "{" << x << "," << y << "," << z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl; } //输出方向线条 rgb = { 255, 0, 0 }; size = 2; for (int i = 0; i < objNumber; i++) { if (abs(workpiecePositions[i].y_dir.z) > 1e-4) { SVzNL3DPoint dirPt; dirPt = { workpiecePositions[i].center.x + workpiecePositions[i].y_dir.x * 10, workpiecePositions[i].center.y + workpiecePositions[i].y_dir.y * 10, workpiecePositions[i].center.z + workpiecePositions[i].y_dir.z * 10 }; sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << workpiecePositions[i].center.x << "," << workpiecePositions[i].center.y << "," << workpiecePositions[i].center.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; sw << "{" << dirPt.x << "," << dirPt.y << "," << dirPt.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; dirPt = { workpiecePositions[i].center.x + workpiecePositions[i].z_dir.x * 10, workpiecePositions[i].center.y + workpiecePositions[i].z_dir.y * 10, workpiecePositions[i].center.z + workpiecePositions[i].z_dir.z * 10 }; sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << workpiecePositions[i].center.x << "," << workpiecePositions[i].center.y << "," << workpiecePositions[i].center.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; sw << "{" << dirPt.x << "," << dirPt.y << "," << dirPt.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; } } sw.close(); } void _outputRGBDResult_XYZ_RGBD_binInfo( char* fileName, std::vector>& scanLines, WD_HRM_BinInfo& poseInfo) { int objNumber = 0; if (poseInfo.center.z > 1e-4) objNumber = 1; int lineNum = (int)scanLines.size(); std::ofstream sw(fileName); int realLines = (objNumber == 0) ? lineNum : (lineNum + 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 kkk = 1; int flag = pt3D->nPointIdx & 0xffff; if (flag > 0) { rgb = objColor[flag % 8]; // { 255, 97, 0 }; size = 5; } else { 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 (poseInfo.center.z > 1e-4) { sw << "Line_" << lineNum << "_0_1" << std::endl; lineNum++; size = 20; rgb = { 255, 255, 0 }; 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; //输出方向线条 rgb = { 250, 0, 0 }; size = 2; double dirLen = 500; SVzNL3DPoint dirPt1 = { poseInfo.center.x + poseInfo.x_dir.x * dirLen, poseInfo.center.y + poseInfo.x_dir.y * dirLen, poseInfo.center.z + poseInfo.x_dir.z * dirLen }; SVzNL3DPoint dirPt2 = { poseInfo.center.x - poseInfo.x_dir.x * dirLen, poseInfo.center.y - poseInfo.x_dir.y * dirLen, poseInfo.center.z - poseInfo.x_dir.z * dirLen }; sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; SVzNL3DPoint pose_y = poseInfo.y_dir; rgb = { 0, 250, 0 }; SVzNL3DPoint dirPt; dirPt = { poseInfo.center.x + pose_y.x * dirLen, poseInfo.center.y + pose_y.y * dirLen, poseInfo.center.z + pose_y.z * dirLen }; sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << poseInfo.center.x << "," << poseInfo.center.y << "," << poseInfo.center.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; sw << "{" << dirPt.x << "," << dirPt.y << "," << dirPt.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; rgb = { 0, 0, 250 }; dirPt1 = { poseInfo.center.x + poseInfo.bottomNormal.x * dirLen, poseInfo.center.y + poseInfo.bottomNormal.y * dirLen, poseInfo.center.z + poseInfo.bottomNormal.z * dirLen }; dirPt2 = { poseInfo.center.x - poseInfo.bottomNormal.x * dirLen, poseInfo.center.y - poseInfo.bottomNormal.y * dirLen, poseInfo.center.z - poseInfo.bottomNormal.z * dirLen }; sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; //输出外接矩形 dirPt1 = poseInfo.minRectVertex[0]; dirPt2 = poseInfo.minRectVertex[1]; sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; dirPt1 = poseInfo.minRectVertex[1]; dirPt2 = poseInfo.minRectVertex[2]; sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; dirPt1 = poseInfo.minRectVertex[2]; dirPt2 = poseInfo.minRectVertex[3]; sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; dirPt1 = poseInfo.minRectVertex[3]; dirPt2 = poseInfo.minRectVertex[0]; sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; } sw.close(); } void _outputRGBDResult_XYZ_RGBD_workpieceInfo( char* fileName, std::vector>& scanLines, std::vector& poseInfo, double dirLen) { int objNumber = 0; if (poseInfo.size()>0) objNumber = 1; int lineNum = (int)scanLines.size(); std::ofstream sw(fileName); int realLines = (objNumber == 0) ? lineNum : (lineNum + 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 kkk = 1; int flag = pt3D->nPointIdx & 0xffff; int highFlag = pt3D->nPointIdx >> 16; #if 0 if (flag > 0) { rgb = objColor[flag % 8]; // { 255, 97, 0 }; size = 5; } else #endif { rgb = { 200, 200, 200 }; size = 1; } if (highFlag == 1) { rgb = { 250, 0, 0 }; size = 2; } else if (highFlag == 2) { rgb = { 0, 0, 250 }; size = 2; } 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 (poseInfo.size() > 1e-4) { int objNum = (int)poseInfo.size(); sw << "Line_" << lineNum << "_0_" << objNum << std::endl; lineNum++; size = 20; rgb = { 255, 255, 0 }; for (int m = 0; m < (int)poseInfo.size(); m++) { float x = (float)poseInfo[m].center.x; float y = (float)poseInfo[m].center.y; float z = (float)poseInfo[m].center.z; sw << "{" << x << "," << y << "," << z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl; } //输出方向线条 rgb = { 250, 0, 0 }; size = 2; //double dirLen = 500; for (int m = 0; m < (int)poseInfo.size(); m++) { SVzNL3DPoint dirPt1 = { poseInfo[m].center.x + poseInfo[m].z_dir.x * dirLen, poseInfo[m].center.y + poseInfo[m].z_dir.y * dirLen, poseInfo[m].center.z + poseInfo[m].z_dir.z * dirLen }; SVzNL3DPoint dirPt2 = { poseInfo[m].center.x - poseInfo[m].z_dir.x * dirLen, poseInfo[m].center.y - poseInfo[m].z_dir.y * dirLen, poseInfo[m].center.z - poseInfo[m].z_dir.z * dirLen }; sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; } } sw.close(); } void _outputRGBDResult_XYZ_RGBD_planningResult( char* fileName, std::vector>& scanLines, WD_HRM_BinInfo& binInfo, std::vector& posInfo, const double workpieceHeight) { int objNumber = 0; if (posInfo.size() > 0) objNumber = 1; int lineNum = (int)scanLines.size(); std::ofstream sw(fileName); int realLines = (objNumber == 0) ? lineNum : (lineNum + 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 kkk = 1; int flag = pt3D->nPointIdx & 0xffff; if (flag > 0) { rgb = objColor[flag % 8]; // { 255, 97, 0 }; size = 5; } else { 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 (posInfo.size() > 0) { int num = (int)posInfo.size(); sw << "Line_" << lineNum << "_0_" << num << std::endl; lineNum++; size = 20; rgb = { 255, 255, 0 }; for(int m = 0; m >& scanLines, bool removeZeros, int* headNullLines) { std::ofstream sw(fileName); int lineNum = (int)scanLines.size(); if (lineNum == 0) return; sw << "LineNum:" << lineNum << std::endl; sw << "DataType: 0" << std::endl; sw << "ScanSpeed: 0" << std::endl; sw << "PointAdjust: 1" << std::endl; sw << "MaxTimeStamp: 0_0" << std::endl; int lineIdx = 0; int null_lines = 0; bool counterNull = true; for (int line = 0; line < lineNum; line++) { int linePtNum = (int)scanLines[line].size(); if (linePtNum == 0) continue; if (true == removeZeros) { int vldPtNum = 0; for (int i = 0; i < linePtNum; i++) { if (scanLines[line][i].pt3D.z > 1e-4) vldPtNum++; } linePtNum = vldPtNum; } sw << "Line_" << lineIdx << "_0_" << linePtNum << std::endl; lineIdx++; bool isNull = true; for (int i = 0; i < linePtNum; i++) { SVzNL3DPoint* pt3D = &scanLines[line][i].pt3D; if ((pt3D->z > 1e-4) && (isNull == true)) isNull = false; if ((true == removeZeros) && (pt3D->z < 1e-4)) continue; float x = (float)pt3D->x; float y = (float)pt3D->y; float z = (float)pt3D->z; sw << "{ " << x << "," << y << "," << z << " }-"; sw << "{0,0}-{0,0}" << std::endl; } if (true == counterNull) { if (true == isNull) null_lines++; else counterNull = false; } } *headNullLines = null_lines; sw.close(); } void _outputWorkpieceInfo(char* fileName, std::vector< WD_workpieceInfo>& workpiecePositions) { std::ofstream sw(fileName); char dataStr[250]; int number = (int)workpiecePositions.size(); for (int i = 0; i < number; i++) { sprintf_s(dataStr, 250, "工件_%d", i + 1); sw << dataStr << std::endl; sprintf_s(dataStr, 50, " center: (%g, %g, %g)", workpiecePositions[i].center.x, workpiecePositions[i].center.y, workpiecePositions[i].center.z); sw << dataStr << std::endl; sprintf_s(dataStr, 50, " x_dir: (%g, %g, %g)", workpiecePositions[i].x_dir.x, workpiecePositions[i].x_dir.y, workpiecePositions[i].x_dir.z); sw << dataStr << std::endl; sprintf_s(dataStr, 50, " y_dir: (%g, %g, %g)", workpiecePositions[i].y_dir.x, workpiecePositions[i].y_dir.y, workpiecePositions[i].y_dir.z); sw << dataStr << std::endl; sprintf_s(dataStr, 50, " z_dir: (%g, %g, %g)", workpiecePositions[i].z_dir.x, workpiecePositions[i].z_dir.y, workpiecePositions[i].z_dir.z); sw << dataStr << std::endl; } sw.close(); } void _outputBinInfo(char* fileName, WD_HRM_BinInfo& binInfo) { std::ofstream sw(fileName); char dataStr[250]; sprintf_s(dataStr, 50, " center: (%g, %g, %g)", binInfo.center.x, binInfo.center.y, binInfo.center.z); sw << dataStr << std::endl; sprintf_s(dataStr, 50, " L: %g; W: %g", binInfo.length, binInfo.width); sw << dataStr << std::endl; sprintf_s(dataStr, 50, " topZ: %g", binInfo.binTopZ); sw << dataStr << std::endl; sprintf_s(dataStr, 50, " bottom_dir: (%g, %g, %g)", binInfo.bottomNormal.x, binInfo.bottomNormal.y, binInfo.bottomNormal.z); sw << dataStr << std::endl; sprintf_s(dataStr, 50, " x_dir: (%g, %g, %g)", binInfo.x_dir.x, binInfo.x_dir.y, binInfo.x_dir.z); sw << dataStr << std::endl; sprintf_s(dataStr, 50, " y_dir: (%g, %g, %g)", binInfo.y_dir.x, binInfo.y_dir.y, binInfo.y_dir.z); sw << dataStr << std::endl; for (int i = 0; i < 4; i++) { sprintf_s(dataStr, 50, " vertex: (%g, %g, %g)", binInfo.minRectVertex[i].x, binInfo.minRectVertex[i].y, binInfo.minRectVertex[i].z); sw << dataStr << std::endl; } sw.close(); } WD_HRM_BinInfo _readBinInfo(char* fileName) { //设置初始结果 WD_HRM_BinInfo binInfo; memset(&binInfo, 0, sizeof(WD_HRM_BinInfo)); std::ifstream inputFile(fileName); std::string linedata; if (inputFile.is_open() == false) return binInfo; float x, y, z; std::getline(inputFile, linedata); sscanf_s(linedata.c_str(), " center: (%f, %f, %f)", &x, &y, &z); binInfo.center = { x, y, z }; std::getline(inputFile, linedata); sscanf_s(linedata.c_str(), " L: %lf; W: %lf", &binInfo.length, &binInfo.width); std::getline(inputFile, linedata); sscanf_s(linedata.c_str(), " topZ: %lf", &binInfo.binTopZ); std::getline(inputFile, linedata); sscanf_s(linedata.c_str(), " bottom_dir: (%lf, %lf, %lf)", &binInfo.bottomNormal.x, &binInfo.bottomNormal.y, &binInfo.bottomNormal.z); std::getline(inputFile, linedata); sscanf_s(linedata.c_str(), " x_dir: (%lf, %lf, %lf)", &binInfo.x_dir.x, &binInfo.x_dir.y, &binInfo.x_dir.z); std::getline(inputFile, linedata); sscanf_s(linedata.c_str(), " y_dir: (%lf, %lf, %lf)", &binInfo.y_dir.x, &binInfo.y_dir.y, &binInfo.y_dir.z); for (int i = 0; i < 4; i++) { std::getline(inputFile, linedata); sscanf_s(linedata.c_str(), " vertex: (%f, %f, %f)", &x, &y, &z); binInfo.minRectVertex[i] = { x, y, z }; } inputFile.close(); return binInfo; } void _outputWorkpieceInfo(char* fileName, WD_HRM_workpieceSizeInfo& workpieceInfo) { std::ofstream sw(fileName); char dataStr[250]; sprintf_s(dataStr, 50, " center: (%g, %g, %g)", workpieceInfo.center.x, workpieceInfo.center.y, workpieceInfo.center.z); sw << dataStr << std::endl; sprintf_s(dataStr, 50, " R: %g; H: %g", workpieceInfo.workpieceRadius, workpieceInfo.workpieceHeight); sw << dataStr << std::endl; sprintf_s(dataStr, 50, " layerZ: %g", workpieceInfo.layerZValue); sw << dataStr << std::endl; sw.close(); } WD_HRM_workpieceSizeInfo _readWorkpieceInfo(char* fileName) { //设置初始结果 WD_HRM_workpieceSizeInfo workpieceInfo; memset(&workpieceInfo, 0, sizeof(WD_HRM_workpieceSizeInfo)); std::ifstream inputFile(fileName); std::string linedata; if (inputFile.is_open() == false) return workpieceInfo; std::getline(inputFile, linedata); sscanf_s(linedata.c_str(), " center: (%lf, %lf, %lf)", &workpieceInfo.center.x, &workpieceInfo.center.y, &workpieceInfo.center.z); std::getline(inputFile, linedata); sscanf_s(linedata.c_str(), " R: %lf; H: %lf", &workpieceInfo.workpieceRadius, &workpieceInfo.workpieceHeight); std::getline(inputFile, linedata); sscanf_s(linedata.c_str(), " layerZ: %lf", &workpieceInfo.layerZValue); inputFile.close(); return workpieceInfo; } void _XOYprojection_XYZUV( cv::Mat& img, std::vector>& dataLines, std::vector< WD_workpieceInfo>& holes, const double scale, const int sideWidth, const SVzNLRangeD x_range, const SVzNLRangeD y_range, bool drawDirAngle, const double dirAngleLen) { cv::Vec3b rgb = cv::Vec3b(0, 0, 0); cv::Vec3b 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; for (int line = 0; line < dataLines.size(); line++) { std::vector< SVzNLPositionD>& a_line = dataLines[line]; for (int i = 0; i < a_line.size(); i++) { SVzNLPositionD& pt3D = a_line[i]; if (pt3D.pt3D.z < 1e-4) continue; int flag = pt3D.nPointIdx & 0xffff; if (flag > 0) { rgb = objColor[flag % 8]; // { 255, 97, 0 }; size = 1; } else { rgb = { 150, 150, 150 }; size = 1; } double x = pt3D.pt3D.x; double y = pt3D.pt3D.y; int px = (int)((x - x_range.min) / scale + sideWidth); int py = (int)((y - y_range.min) / scale + sideWidth); if (size == 1) img.at(py, px) = cv::Vec3b(rgb[2], rgb[1], rgb[0]); else cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), -1); } } if (holes.size() > 0) { for (int i = 0; i < (int)holes.size(); i++) { if (i == 0) { rgb = { 255, 0, 0 }; size = int(3.0 / scale); } else { rgb = { 255, 255, 0 }; size = int(3.0 / scale); } WD_workpieceInfo& a_hole = holes[i]; int px = (int)((a_hole.center.x - x_range.min) / scale + sideWidth); int py = (int)((a_hole.center.y - y_range.min) / scale + sideWidth); cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), -1); rgb = { 0, 255, 0 }; size = int(2.0 / scale); if (true == drawDirAngle) { //画线 double x1 = a_hole.center.x; double y1 = a_hole.center.y; int px1 = (int)((x1 - x_range.min) / scale + sideWidth); int py1 = (int)((y1 - y_range.min) / scale + sideWidth); //x轴 double x2 = a_hole.center.x + dirAngleLen * a_hole.x_dir.x; double y2 = a_hole.center.y + dirAngleLen * a_hole.x_dir.y; int px2 = (int)((x2 - x_range.min) / scale + sideWidth); int py2 = (int)((y2 - y_range.min) / scale + sideWidth); rgb = { 255, 0, 0 }; //x轴用红色 cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 1); //y轴 x2 = a_hole.center.x + dirAngleLen * a_hole.y_dir.x; y2 = a_hole.center.y + dirAngleLen * a_hole.y_dir.y; px2 = (int)((x2 - x_range.min) / scale + sideWidth); py2 = (int)((y2 - y_range.min) / scale + sideWidth); rgb = { 0, 255, 0 }; //y轴用绿色 cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 1); //z轴 x2 = a_hole.center.x + dirAngleLen * a_hole.z_dir.x; y2 = a_hole.center.y + dirAngleLen * a_hole.z_dir.y; px2 = (int)((x2 - x_range.min) / scale + sideWidth); py2 = (int)((y2 - y_range.min) / scale + sideWidth); rgb = { 0, 0, 255 }; //z轴用蓝色 cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 1); } } } } void EulerRpyToRotation1(const double rpy[3], double matrix3d[9]) { double cos0 = cos(rpy[0] * PI / 180); double sin0 = sin(rpy[0] * PI / 180); double cos1 = cos(rpy[1] * PI / 180); double sin1 = sin(rpy[1] * PI / 180); double cos2 = cos(rpy[2] * PI / 180); double sin2 = sin(rpy[2] * PI / 180); matrix3d[0] = cos2 * cos1; matrix3d[1] = cos2 * sin1 * sin0 - sin2 * cos0; matrix3d[2] = cos2 * sin1 * cos0 + sin2 * sin0; matrix3d[3] = sin2 * cos1; matrix3d[4] = sin2 * sin1 * sin0 + cos2 * cos0; matrix3d[5] = sin2 * sin1 * cos0 - cos2 * sin0; matrix3d[6] = -sin1; matrix3d[7] = cos1 * sin0; matrix3d[8] = cos1 * cos0; return; } void _rotateCloudPts_XYZUV( std::vector>& scanLines, double matrix3d[9], std::vector>& rotateLines, SVzNLRangeD& rx_range, SVzNLRangeD& ry_range) { int lineNum = (int)scanLines.size(); rotateLines.resize(lineNum); rx_range.min = 0; rx_range.max = -1; ry_range.min = 0; ry_range.max = -1; for (int line = 0; line < lineNum; line++) { for (int i = 0; i < (int)scanLines[line].size(); i++) { SVzNLPositionD& pt3D = scanLines[line][i]; if (pt3D.pt3D.z < 1e-4) continue; SVzNLPositionD r_pt; r_pt.pt3D = _ptRotate(pt3D.pt3D, matrix3d); r_pt.nPointIdx = pt3D.nPointIdx; r_pt.ptLeft2D = pt3D.ptLeft2D; r_pt.ptRight2D = pt3D.ptRight2D; rotateLines[line].push_back(r_pt); if (rx_range.max < rx_range.min) { rx_range.min = r_pt.pt3D.x; rx_range.max = r_pt.pt3D.x; } else { if (rx_range.min > r_pt.pt3D.x) rx_range.min = r_pt.pt3D.x; if (rx_range.max < r_pt.pt3D.x) rx_range.max = r_pt.pt3D.x; } if (ry_range.max < ry_range.min) { ry_range.min = r_pt.pt3D.y; ry_range.max = r_pt.pt3D.y; } else { if (ry_range.min > r_pt.pt3D.y) ry_range.min = r_pt.pt3D.y; if (ry_range.max < r_pt.pt3D.y) ry_range.max = r_pt.pt3D.y; } } } } void _genXOYProjectionImage_XYZUV( cv::String& fileName, std::vector>& scanLines, const double scale, std::vector< WD_workpieceInfo>& holes, const double rpy[3], const double dirLen) { //旋转视角显示 double matrix3d[9]; EulerRpyToRotation1(rpy, matrix3d); std::vector r_objOps; r_objOps.resize(holes.size()); std::vector> rotateLines; SVzNLRangeD rx_range, ry_range; _rotateCloudPts_XYZUV(scanLines, matrix3d, rotateLines, rx_range, ry_range); //统计X和Y的范围 int x_cols = (int)((rx_range.max - rx_range.min) / scale) + 1; if (x_cols % 2 == 1) x_cols += 1; int y_rows = (int)((ry_range.max - ry_range.min) / scale) + 1; if (y_rows % 2 == 1) y_rows += 1; int sideWidth = 4; int imgCols = x_cols + sideWidth * 2; int imgRows = y_rows + sideWidth * 2; cv::Mat img = cv::Mat::zeros(imgRows, imgCols, CV_8UC3); //计算投影比例 _XOYprojection_XYZUV(img, rotateLines, r_objOps, scale, sideWidth, rx_range, ry_range, true, dirLen); cv::imwrite(fileName, img); return; } void _rotateCloudPts( std::vector>& scanLines, double matrix3d[9], std::vector>& rotateLines, SVzNLRangeD& rx_range, SVzNLRangeD& ry_range) { int lineNum = (int)scanLines.size(); rotateLines.resize(lineNum); rx_range.min = 0; rx_range.max = -1; ry_range.min = 0; ry_range.max = -1; for (int line = 0; line < lineNum; line++) { for (int i = 0; i < (int)scanLines[line].size(); i++) { SVzNL3DPosition& pt3D = scanLines[line][i]; if (pt3D.pt3D.z < 1e-4) continue; SVzNL3DPosition r_pt; r_pt.pt3D = _ptRotate(pt3D.pt3D, matrix3d); r_pt.nPointIdx = pt3D.nPointIdx; rotateLines[line].push_back(r_pt); if (rx_range.max < rx_range.min) { rx_range.min = r_pt.pt3D.x; rx_range.max = r_pt.pt3D.x; } else { if (rx_range.min > r_pt.pt3D.x) rx_range.min = r_pt.pt3D.x; if (rx_range.max < r_pt.pt3D.x) rx_range.max = r_pt.pt3D.x; } if (ry_range.max < ry_range.min) { ry_range.min = r_pt.pt3D.y; ry_range.max = r_pt.pt3D.y; } else { if (ry_range.min > r_pt.pt3D.y) ry_range.min = r_pt.pt3D.y; if (ry_range.max < r_pt.pt3D.y) ry_range.max = r_pt.pt3D.y; } } } } void _XOYprojection_binInfo( cv::Mat& img, std::vector>& dataLines, WD_HRM_BinInfo& binInfo, const double scale, const int sideWidth, const SVzNLRangeD x_range, const SVzNLRangeD y_range, const double dirAngleLen) { cv::Vec3b rgb = cv::Vec3b(0, 0, 0); cv::Vec3b 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; for (int line = 0; line < dataLines.size(); line++) { std::vector< SVzNL3DPosition>& a_line = dataLines[line]; for (int i = 0; i < a_line.size(); i++) { SVzNL3DPosition& pt3D = a_line[i]; if (pt3D.pt3D.z < 1e-4) continue; int flag = pt3D.nPointIdx & 0xffff; if (flag > 0) { rgb = objColor[flag % 8]; // { 255, 97, 0 }; size = 1; } else { rgb = { 150, 150, 150 }; size = 1; } double x = pt3D.pt3D.x; double y = pt3D.pt3D.y; int px = (int)((x - x_range.min) / scale + sideWidth); int py = (int)((y - y_range.min) / scale + sideWidth); if (size == 1) img.at(py, px) = cv::Vec3b(rgb[2], rgb[1], rgb[0]); else cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), -1); } } if (binInfo.center.z > 1e-4) { rgb = { 255, 0, 0 }; size = int(10.0 / scale); int px = (int)((binInfo.center.x - x_range.min) / scale + sideWidth); int py = (int)((binInfo.center.y - y_range.min) / scale + sideWidth); cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), -1); //画线 double x1 = binInfo.center.x; double y1 = binInfo.center.y; int px1 = (int)((x1 - x_range.min) / scale + sideWidth); int py1 = (int)((y1 - y_range.min) / scale + sideWidth); //x轴 double mx2 = binInfo.center.x - dirAngleLen * binInfo.x_dir.x; double my2 = binInfo.center.y - dirAngleLen * binInfo.x_dir.y; int mpx2 = (int)((mx2 - x_range.min) / scale + sideWidth); int mpy2 = (int)((my2 - y_range.min) / scale + sideWidth); double x2 = binInfo.center.x + dirAngleLen * binInfo.x_dir.x; double y2 = binInfo.center.y + dirAngleLen * binInfo.x_dir.y; int px2 = (int)((x2 - x_range.min) / scale + sideWidth); int py2 = (int)((y2 - y_range.min) / scale + sideWidth); rgb = { 255, 0, 0 }; //x轴用红色 cv::line(img, cv::Point(mpx2, mpy2), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 1); //y轴 x2 = binInfo.center.x + dirAngleLen * binInfo.y_dir.x; y2 = binInfo.center.y + dirAngleLen * binInfo.y_dir.y; px2 = (int)((x2 - x_range.min) / scale + sideWidth); py2 = (int)((y2 - y_range.min) / scale + sideWidth); rgb = { 0, 255, 0 }; //y轴用绿色 cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 1); //边1 x1 = binInfo.minRectVertex[0].x; y1 = binInfo.minRectVertex[0].y; px1 = (int)((x1 - x_range.min) / scale + sideWidth); py1 = (int)((y1 - y_range.min) / scale + sideWidth); x2 = binInfo.minRectVertex[1].x; y2 = binInfo.minRectVertex[1].y; px2 = (int)((x2 - x_range.min) / scale + sideWidth); py2 = (int)((y2 - y_range.min) / scale + sideWidth); rgb = { 0, 0, 255 }; //y轴用绿色 cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 2); //边2 x1 = binInfo.minRectVertex[1].x; y1 = binInfo.minRectVertex[1].y; px1 = (int)((x1 - x_range.min) / scale + sideWidth); py1 = (int)((y1 - y_range.min) / scale + sideWidth); x2 = binInfo.minRectVertex[2].x; y2 = binInfo.minRectVertex[2].y; px2 = (int)((x2 - x_range.min) / scale + sideWidth); py2 = (int)((y2 - y_range.min) / scale + sideWidth); rgb = { 0, 0, 255 }; //y轴用绿色 cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 2); //边3 x1 = binInfo.minRectVertex[2].x; y1 = binInfo.minRectVertex[2].y; px1 = (int)((x1 - x_range.min) / scale + sideWidth); py1 = (int)((y1 - y_range.min) / scale + sideWidth); x2 = binInfo.minRectVertex[3].x; y2 = binInfo.minRectVertex[3].y; px2 = (int)((x2 - x_range.min) / scale + sideWidth); py2 = (int)((y2 - y_range.min) / scale + sideWidth); rgb = { 0, 0, 255 }; //y轴用绿色 cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 2); //边4 x1 = binInfo.minRectVertex[3].x; y1 = binInfo.minRectVertex[3].y; px1 = (int)((x1 - x_range.min) / scale + sideWidth); py1 = (int)((y1 - y_range.min) / scale + sideWidth); x2 = binInfo.minRectVertex[0].x; y2 = binInfo.minRectVertex[0].y; px2 = (int)((x2 - x_range.min) / scale + sideWidth); py2 = (int)((y2 - y_range.min) / scale + sideWidth); rgb = { 0, 0, 255 }; //y轴用绿色 cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 2); } } void _genXOYProjectionImage_binInfo( cv::String& fileName, std::vector>& scanLines, const double scale, WD_HRM_BinInfo& binInfo, const double rpy[3], const double dirLen) { //旋转视角显示 double matrix3d[9]; EulerRpyToRotation1(rpy, matrix3d); WD_HRM_BinInfo rotateBin; rotateBin.length = binInfo.length; rotateBin.width = binInfo.width; rotateBin.center = _ptRotate(binInfo.center, matrix3d); rotateBin.bottomNormal = _ptRotate(binInfo.bottomNormal, matrix3d); rotateBin.x_dir = _ptRotate(binInfo.x_dir, matrix3d); rotateBin.y_dir = _ptRotate(binInfo.y_dir, matrix3d); for (int i = 0; i < 4; i++) rotateBin.minRectVertex[i] = _ptRotate(binInfo.minRectVertex[i], matrix3d); std::vector> rotateLines; SVzNLRangeD rx_range, ry_range; _rotateCloudPts(scanLines, matrix3d, rotateLines, rx_range, ry_range); //统计X和Y的范围 int x_cols = (int)((rx_range.max - rx_range.min) / scale) + 1; if (x_cols % 2 == 1) x_cols += 1; int y_rows = (int)((ry_range.max - ry_range.min) / scale) + 1; if (y_rows % 2 == 1) y_rows += 1; int sideWidth = 32; int imgCols = x_cols + sideWidth * 2; int imgRows = y_rows + sideWidth * 2; cv::Mat img = cv::Mat::zeros(imgRows, imgCols, CV_8UC3); //计算投影比例 _XOYprojection_binInfo(img, rotateLines, rotateBin, scale, sideWidth, rx_range, ry_range, dirLen); cv::imwrite(fileName, img); return; } void _XOYprojection_workpieceInfo( cv::Mat& img, std::vector>& dataLines, std::vector& workpieceInfo, const double scale, const int sideWidth, const SVzNLRangeD x_range, const SVzNLRangeD y_range, const double dirAngleLen) { cv::Vec3b rgb = cv::Vec3b(0, 0, 0); cv::Vec3b 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; for (int line = 0; line < dataLines.size(); line++) { std::vector< SVzNL3DPosition>& a_line = dataLines[line]; for (int i = 0; i < a_line.size(); i++) { SVzNL3DPosition& pt3D = a_line[i]; if (pt3D.pt3D.z < 1e-4) continue; int flag = pt3D.nPointIdx & 0xffff; if (flag > 0) { rgb = objColor[flag % 8]; // { 255, 97, 0 }; size = 1; } else { rgb = { 150, 150, 150 }; size = 1; } double x = pt3D.pt3D.x; double y = pt3D.pt3D.y; int px = (int)((x - x_range.min) / scale + sideWidth); int py = (int)((y - y_range.min) / scale + sideWidth); if (size == 1) img.at(py, px) = cv::Vec3b(rgb[2], rgb[1], rgb[0]); else cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), -1); } } if (workpieceInfo.size() > 0) { for (int i = 0; i < (int)workpieceInfo.size(); i++) { rgb = { 255, 0, 0 }; size = int(10.0 / scale); int px = (int)((workpieceInfo[i].center.x - x_range.min) / scale + sideWidth); int py = (int)((workpieceInfo[i].center.y - y_range.min) / scale + sideWidth); cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), -1); //画圆 rgb = { 0, 0, 255 }; size = (int)(workpieceInfo[i].value / scale); cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), 2); } } } void _genXOYProjectionImage_workpieceInfo( cv::String& fileName, std::vector>& scanLines, const double scale, std::vector& workpieceInfo, const double rpy[3], const double dirLen) { //旋转视角显示 double matrix3d[9]; EulerRpyToRotation1(rpy, matrix3d); std::vector rotatedWorkpiece; for (int i = 0; i < (int)workpieceInfo.size(); i++) { WD_workpieceInfo rotateObj; rotateObj.workpieceType = workpieceInfo[i].workpieceType; rotateObj.value = workpieceInfo[i].value; rotateObj.center = _ptRotate(workpieceInfo[i].center, matrix3d); rotateObj.z_dir = _ptRotate(workpieceInfo[i].z_dir, matrix3d); rotateObj.x_dir = _ptRotate(workpieceInfo[i].x_dir, matrix3d); rotateObj.y_dir = _ptRotate(workpieceInfo[i].y_dir, matrix3d); rotatedWorkpiece.push_back(rotateObj); } std::vector> rotateLines; SVzNLRangeD rx_range, ry_range; _rotateCloudPts(scanLines, matrix3d, rotateLines, rx_range, ry_range); //统计X和Y的范围 int x_cols = (int)((rx_range.max - rx_range.min) / scale) + 1; if (x_cols % 2 == 1) x_cols += 1; int y_rows = (int)((ry_range.max - ry_range.min) / scale) + 1; if (y_rows % 2 == 1) y_rows += 1; int sideWidth = 32; int imgCols = x_cols + sideWidth * 2; int imgRows = y_rows + sideWidth * 2; cv::Mat img = cv::Mat::zeros(imgRows, imgCols, CV_8UC3); //计算投影比例 _XOYprojection_workpieceInfo(img, rotateLines, rotatedWorkpiece, scale, sideWidth, rx_range, ry_range, dirLen); cv::imwrite(fileName, img); return; } void _XOYprojection_planningResult( cv::Mat& img, std::vector>& dataLines, std::vector& workpieceInfo, WD_HRM_BinInfo& binInfo, const double scale, const int sideWidth, const SVzNLRangeD x_range, const SVzNLRangeD y_range, const double dirAngleLen) { cv::Vec3b rgb = cv::Vec3b(0, 0, 0); cv::Vec3b 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; for (int line = 0; line < dataLines.size(); line++) { std::vector< SVzNL3DPosition>& a_line = dataLines[line]; for (int i = 0; i < a_line.size(); i++) { SVzNL3DPosition& pt3D = a_line[i]; if (pt3D.pt3D.z < 1e-4) continue; int flag = pt3D.nPointIdx & 0xffff; if (flag > 0) { rgb = objColor[flag % 8]; // { 255, 97, 0 }; size = 1; } else { rgb = { 150, 150, 150 }; size = 1; } double x = pt3D.pt3D.x; double y = pt3D.pt3D.y; int px = (int)((x - x_range.min) / scale + sideWidth); int py = (int)((y - y_range.min) / scale + sideWidth); if (size == 1) img.at(py, px) = cv::Vec3b(rgb[2], rgb[1], rgb[0]); else cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), -1); } } if (workpieceInfo.size() > 0) { for (int i = 0; i < (int)workpieceInfo.size(); i++) { rgb = { 255, 0, 0 }; size = int(10.0 / scale); int px = (int)((workpieceInfo[i].center.x - x_range.min) / scale + sideWidth); int py = (int)((workpieceInfo[i].center.y - y_range.min) / scale + sideWidth); cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), -1); //画圆 rgb = { 0, 0, 255 }; size = (int)(workpieceInfo[i].value / scale); cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), 2); } //边1 double x1 = binInfo.minRectVertex[0].x; double y1 = binInfo.minRectVertex[0].y; int px1 = (int)((x1 - x_range.min) / scale + sideWidth); int py1 = (int)((y1 - y_range.min) / scale + sideWidth); double x2 = binInfo.minRectVertex[1].x; double y2 = binInfo.minRectVertex[1].y; int px2 = (int)((x2 - x_range.min) / scale + sideWidth); int py2 = (int)((y2 - y_range.min) / scale + sideWidth); rgb = { 0, 0, 255 }; //y轴用绿色 cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 2); //边2 x1 = binInfo.minRectVertex[1].x; y1 = binInfo.minRectVertex[1].y; px1 = (int)((x1 - x_range.min) / scale + sideWidth); py1 = (int)((y1 - y_range.min) / scale + sideWidth); x2 = binInfo.minRectVertex[2].x; y2 = binInfo.minRectVertex[2].y; px2 = (int)((x2 - x_range.min) / scale + sideWidth); py2 = (int)((y2 - y_range.min) / scale + sideWidth); rgb = { 0, 0, 255 }; //y轴用绿色 cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 2); //边3 x1 = binInfo.minRectVertex[2].x; y1 = binInfo.minRectVertex[2].y; px1 = (int)((x1 - x_range.min) / scale + sideWidth); py1 = (int)((y1 - y_range.min) / scale + sideWidth); x2 = binInfo.minRectVertex[3].x; y2 = binInfo.minRectVertex[3].y; px2 = (int)((x2 - x_range.min) / scale + sideWidth); py2 = (int)((y2 - y_range.min) / scale + sideWidth); rgb = { 0, 0, 255 }; //y轴用绿色 cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 2); //边4 x1 = binInfo.minRectVertex[3].x; y1 = binInfo.minRectVertex[3].y; px1 = (int)((x1 - x_range.min) / scale + sideWidth); py1 = (int)((y1 - y_range.min) / scale + sideWidth); x2 = binInfo.minRectVertex[0].x; y2 = binInfo.minRectVertex[0].y; px2 = (int)((x2 - x_range.min) / scale + sideWidth); py2 = (int)((y2 - y_range.min) / scale + sideWidth); rgb = { 0, 0, 255 }; //y轴用绿色 cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 2); } } void _genXOYProjectionImage_planningResult( cv::String& fileName, std::vector>& scanLines, const double scale, WD_HRM_BinInfo& binInfo, std::vector& workpieceInfo, const double rpy[3], const double dirLen) { //旋转视角显示 double matrix3d[9]; EulerRpyToRotation1(rpy, matrix3d); std::vector rotatedWorkpiece; for (int i = 0; i < (int)workpieceInfo.size(); i++) { WD_workpieceInfo rotateObj; rotateObj.workpieceType = workpieceInfo[i].workpieceType; rotateObj.value = workpieceInfo[i].value; rotateObj.center = _ptRotate(workpieceInfo[i].center, matrix3d); rotateObj.z_dir = _ptRotate(workpieceInfo[i].z_dir, matrix3d); rotateObj.x_dir = _ptRotate(workpieceInfo[i].x_dir, matrix3d); rotateObj.y_dir = _ptRotate(workpieceInfo[i].y_dir, matrix3d); rotatedWorkpiece.push_back(rotateObj); } std::vector> rotateLines; SVzNLRangeD rx_range, ry_range; _rotateCloudPts(scanLines, matrix3d, rotateLines, rx_range, ry_range); //统计X和Y的范围 int x_cols = (int)((rx_range.max - rx_range.min) / scale) + 1; if (x_cols % 2 == 1) x_cols += 1; int y_rows = (int)((ry_range.max - ry_range.min) / scale) + 1; if (y_rows % 2 == 1) y_rows += 1; int sideWidth = 32; int imgCols = x_cols + sideWidth * 2; int imgRows = y_rows + sideWidth * 2; cv::Mat img = cv::Mat::zeros(imgRows, imgCols, CV_8UC3); //计算投影比例 _XOYprojection_planningResult(img, rotateLines, rotatedWorkpiece, binInfo, scale, sideWidth, rx_range, ry_range, dirLen); cv::imwrite(fileName, img); return; } void zPassThroughFilter(std::vector>& scanData, const SVzNLRangeD zRange) { for (int i = 0; i < (int)scanData.size(); i++) { for (int j = 0; j < (int)scanData[i].size(); j++) { if ((scanData[i][j].pt3D.z < zRange.min) || (scanData[i][j].pt3D.z > zRange.max)) scanData[i][j].pt3D = { 0.0, 0.0, 0.0 }; } } return; } //拓普发工件孔定位(工件定位) #define HRM_TaperedWorkpiece_TEST_GROUP 1 void HaiRuiMa_TaperedWorkpiece_test(void) { const char* dataPath[HRM_TaperedWorkpiece_TEST_GROUP] = { "F:/ShangGu/项目/冠钦项目/宁波海瑞马/锥形工作2D+3D数据/数据1/", //0 }; SVzNLRange fileIdx[HRM_TaperedWorkpiece_TEST_GROUP] = { {1,21}, }; const char* ver = wd_hybridPositioningVersion(); printf("ver:%s\n", ver); for (int grp = 0; grp < HRM_TaperedWorkpiece_TEST_GROUP; grp++) { SSG_planeCalibPara groundCalibPara; //初始化成单位阵 groundCalibPara.planeCalib[0] = 1.0; groundCalibPara.planeCalib[1] = 0.0; groundCalibPara.planeCalib[2] = 0.0; groundCalibPara.planeCalib[3] = 0.0; groundCalibPara.planeCalib[4] = 1.0; groundCalibPara.planeCalib[5] = 0.0; groundCalibPara.planeCalib[6] = 0.0; groundCalibPara.planeCalib[7] = 0.0; groundCalibPara.planeCalib[8] = 1.0; groundCalibPara.planeHeight = -1.0; for (int i = 0; i < 9; i++) groundCalibPara.invRMatrix[i] = groundCalibPara.planeCalib[i]; char calibFile[250]; sprintf_s(calibFile, "%sground_calib_para.txt", dataPath[grp]); //groundCalibPara = _readCalibPara(calibFile); for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++) { //fidx =15; char _scan_file[256]; sprintf_s(_scan_file, "%s%d_cloud.txt", dataPath[grp], fidx); std::vector> scanLines; vzReadLaserScanPointFromFile_XYZUV_vector(_scan_file, scanLines); _removeZeroLines_XYZUV(scanLines); if (scanLines.size() == 0) continue; sprintf_s(_scan_file, "%s%d_result.txt", dataPath[grp], fidx); std::vector objROIs; vzReadObj2DROI_1(_scan_file, objROIs); long t1 = (long)GetTickCount64();//统计时间 int errCode = 0; std::vector< WD_workpieceInfo> workpiecePositions; wd_HRM_TaperedWorkpiecePositioning( scanLines, objROIs, groundCalibPara, workpiecePositions, &errCode); long t2 = (long)GetTickCount64(); if (errCode == SX_ERR_UNKNOWN_OBJECT) printf("%s: %d(ms), 有异物残留!\n", _scan_file, (int)(t2 - t1)); else if (errCode == SX_ERR_ZERO_OBJECTS) printf("%s: %d(ms), 无产品!\n", _scan_file, (int)(t2 - t1)); else printf("%s: %d(ms), errCode=%d ...", _scan_file, (int)(t2 - t1), errCode); //输出测试结果 sprintf_s(_scan_file, "%sresult/LaserLine%d_result.txt", dataPath[grp], fidx); _outputRGBDResult_XYZUV_RGBD(_scan_file, scanLines, workpiecePositions); sprintf_s(calibFile, "%sresult/LaserLine%d_hole_info.txt", dataPath[grp], fidx); _outputWorkpieceInfo(calibFile, workpiecePositions); #if 0 sprintf_s(calibFile, "%sresult/LaserLine%d_holes_projection.png", dataPath[grp], fidx); double rpy[3] = { -30, 15, 0 }; //{ 0,-45, 0 }; // double angleDrawLen = 15; double displayScale = 0.3; cv::String imgName(calibFile); _genXOYProjectionImage(imgName, scanLines, displayScale, workpiecePositions, rpy, angleDrawLen); #endif printf("done\n"); } } } //地面调平 #define HRM_GroundCalib_TEST_GROUP 1 void HaiRuiMa_groundCalib_test(void) { #if 0 const char* dataPath[HRM_GroundCalib_TEST_GROUP] = { "F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件1/", //0 "F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件2/", //1 "F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件3/", //2 }; SVzNLRange fileIdx[HRM_GroundCalib_TEST_GROUP] = { {1,7}, {1,9}, {1,7}, }; #else const char* dataPath[HRM_GroundCalib_TEST_GROUP] = { "F:/ShangGu/项目/冠钦项目/宁波海瑞马/转子钢芯/数据2D3D/", //0 }; SVzNLRange fileIdx[HRM_GroundCalib_TEST_GROUP] = { {1,9}, }; #endif const char* ver = wd_hybridPositioningVersion(); printf("ver:%s\n", ver); char _calib_datafile[256]; sprintf_s(_calib_datafile, "F:/ShangGu/项目/冠钦项目/宁波海瑞马/转子钢芯/数据2D3D/ground_cloud.txt"); int lineNum = 0; float lineV = 0.0f; int dataCalib = 0; int maxTimeStamp = 0; int clockPerSecond = 0; std::vector> scanData; vzReadLaserScanPointFromFile_XYZ_vector(_calib_datafile, scanData); lineNum = (int)scanData.size(); if (scanData.size() > 0) { #if 1 //过滤背景数据 SVzNLRangeD validZRange = { 100.0, 1600.0 }; zPassThroughFilter(scanData, validZRange); #endif SSG_planeCalibPara calibPara = wd_getGroundCalibPara(scanData); // char calibFile[250]; sprintf_s(calibFile, "F:/ShangGu/项目/冠钦项目/宁波海瑞马/转子钢芯/数据2D3D/ground_calib_para.txt"); _outputCalibPara(calibFile, calibPara); #if 1 for (int grp = 0; grp < HRM_GroundCalib_TEST_GROUP; grp++) { for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++) { #if 0 //fidx =4; char _scan_file[256]; sprintf_s(_scan_file, "%s隔板%d_LaserData_Jl26C177.txt", dataPath[grp], fidx); std::vector> scanLines; vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines); _removeZeroLines_XYZ(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, "%s隔板%d_LaserData_Jl26C177_ground_calibrated.txt", dataPath[grp], fidx); int headNullLines = 0; _outputScanDataFile_vector(_scan_file, scanLines, false, &headNullLines); sprintf_s(_scan_file, "%s工件%d_LaserData_Jl26C177.txt", dataPath[grp], fidx); scanLines.clear(); vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines); _removeZeroLines_XYZ(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, "%s工件%d_LaserData_Jl26C177_ground_calibrated.txt", dataPath[grp], fidx); headNullLines = 0; _outputScanDataFile_vector(_scan_file, scanLines, false, &headNullLines); #else char _scan_file[256]; sprintf_s(_scan_file, "%s%d_cloud.txt", dataPath[grp], fidx); std::vector> scanLines; vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines); _removeZeroLines_XYZ(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, "%s%d_cloud_ground_calibrated.txt", dataPath[grp], fidx); int headNullLines = 0; _outputScanDataFile_vector(_scan_file, scanLines, false, &headNullLines); #endif printf("%s: calib done!\n", _scan_file); } } #endif printf("all calib done!\n", _calib_datafile); } } //拓普发工件孔定位(工件定位) #define HRM_RotorCore_TEST_GROUP 1 void HaiRuiMa_rotorCorePositioning_test(void) { const char* dataPath[HRM_RotorCore_TEST_GROUP] = { "F:/ShangGu/项目/冠钦项目/宁波海瑞马/转子钢芯/数据2D3D/", //0 }; SVzNLRange fileIdx[HRM_RotorCore_TEST_GROUP] = { {1,9}, }; const char* ver = wd_hybridPositioningVersion(); printf("ver:%s\n", ver); for (int grp = 0; grp < HRM_RotorCore_TEST_GROUP; grp++) { SSG_planeCalibPara groundCalibPara; //初始化成单位阵 groundCalibPara.planeCalib[0] = 1.0; groundCalibPara.planeCalib[1] = 0.0; groundCalibPara.planeCalib[2] = 0.0; groundCalibPara.planeCalib[3] = 0.0; groundCalibPara.planeCalib[4] = 1.0; groundCalibPara.planeCalib[5] = 0.0; groundCalibPara.planeCalib[6] = 0.0; groundCalibPara.planeCalib[7] = 0.0; groundCalibPara.planeCalib[8] = 1.0; groundCalibPara.planeHeight = -1.0; for (int i = 0; i < 9; i++) groundCalibPara.invRMatrix[i] = groundCalibPara.planeCalib[i]; char calibFile[250]; sprintf_s(calibFile, "%sground_calib_para.txt", dataPath[grp]); groundCalibPara = _readCalibPara(calibFile); //读取料筐参数 sprintf_s(calibFile, "%sbin_info.txt", dataPath[grp]); WD_HRM_BinInfo binInfo = _readBinInfo(calibFile); for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++) { //fidx = 3; char _scan_file[256]; sprintf_s(_scan_file, "%s%d_cloud.txt", dataPath[grp], fidx); std::vector> scanLines; vzReadLaserScanPointFromFile_XYZUV_vector(_scan_file, scanLines); _removeZeroLines_XYZUV(scanLines); if (scanLines.size() == 0) continue; sprintf_s(_scan_file, "%s%d_result.txt", dataPath[grp], fidx); std::vector objROIs; vzReadObj2DROI(_scan_file, objROIs); SWD_Cylinder workpieceParam; //圆柱形工件的标称半径和高度 workpieceParam.radius = 45.0; workpieceParam.height = 20.0; long t1 = (long)GetTickCount64();//统计时间 int errCode = 0; std::vector< WD_workpieceInfo> workpiecePositions; std::vector> debugScanLines; wd_HRM_RotorCorePositioning( scanLines, objROIs, binInfo, groundCalibPara, workpieceParam, workpiecePositions, #ifdef _OUTPUT_DEBUG_DATA debugScanLines, #endif &errCode); long t2 = (long)GetTickCount64(); if (errCode == SX_ERR_UNKNOWN_OBJECT) printf("%s: %d(ms), 有异物残留!\n", _scan_file, (int)(t2 - t1)); else if (errCode == SX_ERR_ZERO_OBJECTS) printf("%s: %d(ms), 无产品!\n", _scan_file, (int)(t2 - t1)); else printf("%s: %d(ms), errCode=%d ...", _scan_file, (int)(t2 - t1), errCode); //输出测试结果 sprintf_s(calibFile, "%sresult/LaserLine%d_workpiece_info.txt", dataPath[grp], fidx); _outputWorkpieceInfo(calibFile, workpiecePositions); //旋转到调平坐标系 int workpieceNum = (int)workpiecePositions.size(); for (int i = 0; i < workpieceNum; i++) { SVzNL3DPoint rpt; rpt = wd_ptRotate(workpiecePositions[i].center, groundCalibPara.planeCalib); workpiecePositions[i].center = rpt; rpt = wd_ptRotate(workpiecePositions[i].y_dir, groundCalibPara.planeCalib); workpiecePositions[i].y_dir = rpt; rpt = wd_ptRotate(workpiecePositions[i].z_dir, groundCalibPara.planeCalib); workpiecePositions[i].z_dir = rpt; rpt = wd_ptRotate(workpiecePositions[i].x_dir, groundCalibPara.planeCalib); workpiecePositions[i].x_dir = rpt; } sprintf_s(_scan_file, "%sresult/result_%d.txt", dataPath[grp], fidx); _outputRGBDResult_XYZ_RGBD_workpieceInfo(_scan_file, debugScanLines, workpiecePositions, 50); #if 0 sprintf_s(calibFile, "%sresult/LaserLine%d_holes_projection.png", dataPath[grp], fidx); double rpy[3] = { -30, 15, 0 }; //{ 0,-45, 0 }; // double angleDrawLen = 15; double displayScale = 0.3; cv::String imgName(calibFile); _genXOYProjectionImage(imgName, scanLines, displayScale, workpiecePositions, rpy, angleDrawLen); #endif printf("done\n"); } } } #define HRM_BIN_TEST_GROUP 3 //海瑞马料筐尺寸计算 void HaiRuiMa_BinSizeCompute_test(void) { const char* dataPath[HRM_BIN_TEST_GROUP] = { "F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件1/", //0 "F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件2/", //1 "F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件3/", //2 }; SVzNLRange fileIdx[HRM_BIN_TEST_GROUP] = { {1,7}, {1,9}, {1,7}, }; const char* ver = wd_hybridPositioningVersion(); printf("ver:%s 料筐尺寸计算\n", ver); for (int grp = 0; grp < HRM_BIN_TEST_GROUP; grp++) { SSG_planeCalibPara groundCalibPara; //初始化成单位阵 groundCalibPara.planeCalib[0] = 1.0; groundCalibPara.planeCalib[1] = 0.0; groundCalibPara.planeCalib[2] = 0.0; groundCalibPara.planeCalib[3] = 0.0; groundCalibPara.planeCalib[4] = 1.0; groundCalibPara.planeCalib[5] = 0.0; groundCalibPara.planeCalib[6] = 0.0; groundCalibPara.planeCalib[7] = 0.0; groundCalibPara.planeCalib[8] = 1.0; groundCalibPara.planeHeight = -1.0; for (int i = 0; i < 9; i++) groundCalibPara.invRMatrix[i] = groundCalibPara.planeCalib[i]; char calibFile[250]; sprintf_s(calibFile, "%sground_calib_para.txt", dataPath[grp]); groundCalibPara = _readCalibPara(calibFile); double binHeight = 640; //料筐最上边沿距地面高度 for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++) { //fidx = 15; char _scan_file[256]; sprintf_s(_scan_file, "%s隔板%d_LaserData_Jl26C177.txt", dataPath[grp], fidx); std::vector> scanLines; vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines); _removeZeroLines_XYZ(scanLines); if (scanLines.size() == 0) continue; long t1 = (long)GetTickCount64();//统计时间 int errCode = 0; #if 0 SSG_cornerParam cornerParam; cornerParam.cornerTh = 60; //45度角 cornerParam.scale = 10; // algoParam.bagParam.bagH / 8; // 15; // algoParam.bagParam.bagH / 8; cornerParam.minEndingGap = 10; // algoParam.bagParam.bagW / 4; cornerParam.minEndingGap_z = 5.0; cornerParam.jumpCornerTh_1 = 15; //水平角度,小于此角度视为水平 cornerParam.jumpCornerTh_2 = 60; //料筐码放:获取料筐尺寸、料筐姿态、料筐中心点坐标 WD_HRM_BinInfo binInfo = wd_HRM_getBinSize( scanLines, cornerParam, &errCode); #else //料筐码放:获取料筐尺寸、料筐姿态、料筐中心点坐标 WD_HRM_BinInfo binInfo = wd_HRM_getBinSize( scanLines, groundCalibPara, binHeight, //料筐高度 &errCode); #endif long t2 = (long)GetTickCount64(); printf("%s: %d(ms), errCode=%d ...", _scan_file, (int)(t2 - t1), errCode); //输出测试结果 sprintf_s(_scan_file, "%sresult/LaserLine%d_result.txt", dataPath[grp], fidx); _outputRGBDResult_XYZ_RGBD_binInfo(_scan_file, scanLines, binInfo); sprintf_s(_scan_file, "%sresult/%d_bin_info.txt", dataPath[grp], fidx); _outputBinInfo(_scan_file, binInfo); sprintf_s(calibFile, "%sresult/LaserLine%d_bin_projection.png", dataPath[grp], fidx); double rpy[3] = { 0, 0, 0 }; // { -30, 15, 0 }; //{ 0,-45, 0 }; // double angleDrawLen = 500; double displayScale = 1.0; cv::String imgName(calibFile); _genXOYProjectionImage_binInfo(imgName, scanLines, displayScale, binInfo, rpy, angleDrawLen); printf("done\n"); } } } //海瑞马工件尺寸测量 void HaiRuiMa_workpieceSizeCompute_test(void) { const char* dataPath[HRM_BIN_TEST_GROUP] = { "F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件1/", //0 "F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件2/", //1 "F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件3/", //2 }; SVzNLRange fileIdx[HRM_BIN_TEST_GROUP] = { {1,7}, {1,9}, {1,7}, }; const char* ver = wd_hybridPositioningVersion(); printf("ver:%s 工件尺寸测量 \n", ver); for (int grp = 0; grp < HRM_BIN_TEST_GROUP; grp++) { SSG_planeCalibPara groundCalibPara; //初始化成单位阵 groundCalibPara.planeCalib[0] = 1.0; groundCalibPara.planeCalib[1] = 0.0; groundCalibPara.planeCalib[2] = 0.0; groundCalibPara.planeCalib[3] = 0.0; groundCalibPara.planeCalib[4] = 1.0; groundCalibPara.planeCalib[5] = 0.0; groundCalibPara.planeCalib[6] = 0.0; groundCalibPara.planeCalib[7] = 0.0; groundCalibPara.planeCalib[8] = 1.0; groundCalibPara.planeHeight = -1.0; for (int i = 0; i < 9; i++) groundCalibPara.invRMatrix[i] = groundCalibPara.planeCalib[i]; char calibFile[250]; sprintf_s(calibFile, "%sground_calib_para.txt", dataPath[grp]); groundCalibPara = _readCalibPara(calibFile); double binHeight = 640; //料筐最上边沿距地面高度 for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++) { //fidx = 15; char _scan_file[256]; sprintf_s(_scan_file, "%s工件%d_LaserData_Jl26C177.txt", dataPath[grp], fidx); std::vector> scanLines; vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines); _removeZeroLines_XYZ(scanLines); if (scanLines.size() == 0) continue; long t1 = (long)GetTickCount64();//统计时间 int errCode = 0; SSG_cornerParam cornerParam; cornerParam.cornerTh = 60; //45度角 cornerParam.scale = 10; // algoParam.bagParam.bagH / 8; // 15; // algoParam.bagParam.bagH / 8; cornerParam.minEndingGap = 10; // algoParam.bagParam.bagW / 4; cornerParam.minEndingGap_z = 5.0; cornerParam.jumpCornerTh_1 = 15; //水平角度,小于此角度视为水平 cornerParam.jumpCornerTh_2 = 60; //标准工件尺寸。目前3种工件尺寸 std::vector standardWorkpieceSize; standardWorkpieceSize.resize(3); //工件1 standardWorkpieceSize[0].center = { 0, 0, 0 }; standardWorkpieceSize[0].layerZValue = 0; standardWorkpieceSize[0].workpieceHeight = 40.0; standardWorkpieceSize[0].workpieceRadius = 45.0; //工件2 standardWorkpieceSize[1].center = { 0, 0, 0 }; standardWorkpieceSize[1].layerZValue = 0; standardWorkpieceSize[1].workpieceHeight = 70.0; standardWorkpieceSize[1].workpieceRadius = 45.0; //工件3 standardWorkpieceSize[2].center = { 0, 0, 0 }; standardWorkpieceSize[2].layerZValue = 0; standardWorkpieceSize[2].workpieceHeight = 60.0; standardWorkpieceSize[2].workpieceRadius = 62.5; //料筐码放:获取工件尺寸 WD_HRM_workpieceSizeInfo workpieceInfo = wd_HRM_getWorkpieceSize( scanLines, standardWorkpieceSize, cornerParam, groundCalibPara, &errCode); long t2 = (long)GetTickCount64(); printf("%s: %d(ms), R=%f, H=%f, errCode=%d ...", _scan_file, (int)(t2 - t1), workpieceInfo.workpieceRadius, workpieceInfo.workpieceHeight, errCode); //输出测试结果 sprintf_s(_scan_file, "%sresult/LaserLine%d_workpiece_result.txt", dataPath[grp], fidx); std::vector poseInfo; WD_workpieceInfo a_pose; memset(&a_pose, 0, sizeof(WD_workpieceInfo)); a_pose.center = workpieceInfo.center; a_pose.value = workpieceInfo.workpieceRadius; a_pose.z_dir = { 0, 0, 1.0 }; poseInfo.push_back(a_pose); _outputRGBDResult_XYZ_RGBD_workpieceInfo(_scan_file, scanLines, poseInfo, 500); sprintf_s(_scan_file, "%sresult/%d_workpiece_info.txt", dataPath[grp], fidx); _outputWorkpieceInfo(_scan_file, workpieceInfo); sprintf_s(calibFile, "%sresult/LaserLine%d_workpiece_projection.png", dataPath[grp], fidx); double rpy[3] = { 0, 0, 0 }; // { -30, 15, 0 }; //{ 0,-45, 0 }; // double angleDrawLen = 500; double displayScale = 1.0; cv::String imgName(calibFile); _genXOYProjectionImage_workpieceInfo(imgName, scanLines, displayScale, poseInfo, rpy, angleDrawLen); printf("done\n"); } } } //海瑞马码垛规划 void HaiRuiMa_positionPlanning_test(void) { const char* dataPath[HRM_BIN_TEST_GROUP] = { "F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件1/", //0 "F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件2/", //1 "F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件3/", //2 }; SVzNLRange fileIdx[HRM_BIN_TEST_GROUP] = { {1,7}, {1,9}, {1,7}, }; const char* ver = wd_hybridPositioningVersion(); printf("ver:%s 码垛规划\n", ver); for (int grp = 0; grp < HRM_BIN_TEST_GROUP; grp++) { SSG_planeCalibPara groundCalibPara; //初始化成单位阵 groundCalibPara.planeCalib[0] = 1.0; groundCalibPara.planeCalib[1] = 0.0; groundCalibPara.planeCalib[2] = 0.0; groundCalibPara.planeCalib[3] = 0.0; groundCalibPara.planeCalib[4] = 1.0; groundCalibPara.planeCalib[5] = 0.0; groundCalibPara.planeCalib[6] = 0.0; groundCalibPara.planeCalib[7] = 0.0; groundCalibPara.planeCalib[8] = 1.0; groundCalibPara.planeHeight = -1.0; for (int i = 0; i < 9; i++) groundCalibPara.invRMatrix[i] = groundCalibPara.planeCalib[i]; char calibFile[250]; sprintf_s(calibFile, "%sground_calib_para.txt", dataPath[grp]); groundCalibPara = _readCalibPara(calibFile); double binHeight = 640; //料筐最上边沿距地面高度 for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++) { //fidx = 15; char _scan_file[256]; sprintf_s(_scan_file, "%s隔板%d_LaserData_Jl26C177.txt", dataPath[grp], fidx); std::vector> scanLines; vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines); _removeZeroLines_XYZ(scanLines); if (scanLines.size() == 0) continue; //地面调平 for (int i = 0; i < (int)scanLines.size(); i++) { wd_lineDataR(scanLines[i], groundCalibPara.planeCalib, -1);//调平 for (int j = 0; j < (int)scanLines[i].size(); j++) scanLines[i][j].nPointIdx = 0; } //读取料筐参数 sprintf_s(_scan_file, "%sresult/%d_bin_info.txt", dataPath[grp], fidx); WD_HRM_BinInfo binInfo = _readBinInfo(_scan_file); //读取工件参数 sprintf_s(_scan_file, "%sresult/%d_workpiece_info.txt", dataPath[grp], fidx); WD_HRM_workpieceSizeInfo workpieceInfo = _readWorkpieceInfo(_scan_file); SSG_size2D realBoardSize; //实际的托板大小 realBoardSize.width = 720.0; realBoardSize.height = 520.0; double guardingInterval = 3.0; //工作与工件的保护间隔 long t1 = (long)GetTickCount64();//统计时间 int out_rows = 0, out_cols = 0, isLastLayere = 0; std::vector< WD_workpieceInfo> planningPositions; wd_HRM_PlanBinPlacement( binInfo, realBoardSize, workpieceInfo, groundCalibPara, guardingInterval, //工作与工件的保护间隔 planningPositions, &out_rows, &out_cols, &isLastLayere); long t2 = (long)GetTickCount64(); printf("%s: %d(ms), rows=%d cols=%d, isLastLayer=%d...", _scan_file, (int)(t2 - t1), out_rows, out_cols, isLastLayere); //输出测试结果 sprintf_s(_scan_file, "%sresult/%d_planning_result.txt", dataPath[grp], fidx); _outputWorkpieceInfo(_scan_file, planningPositions); //旋转到调平坐标系中 for (int i = 0; i < (int)planningPositions.size(); i++) { planningPositions[i].center = wd_ptRotate(planningPositions[i].center, groundCalibPara.planeCalib); planningPositions[i].x_dir = wd_ptRotate(planningPositions[i].x_dir, groundCalibPara.planeCalib); planningPositions[i].y_dir = wd_ptRotate(planningPositions[i].y_dir, groundCalibPara.planeCalib); planningPositions[i].z_dir = wd_ptRotate(planningPositions[i].z_dir, groundCalibPara.planeCalib); } sprintf_s(_scan_file, "%sresult/LaserLine%d_planning_result.txt", dataPath[grp], fidx); _outputRGBDResult_XYZ_RGBD_planningResult(_scan_file, scanLines, binInfo, planningPositions, workpieceInfo.workpieceHeight); sprintf_s(calibFile, "%sresult/LaserLine%d_planning_result.png", dataPath[grp], fidx); double rpy[3] = { 0, 0, 0 }; // { -30, 15, 0 }; //{ 0,-45, 0 }; // double angleDrawLen = 500; double displayScale = 1.0; cv::String imgName(calibFile); _genXOYProjectionImage_planningResult(imgName, scanLines, displayScale, binInfo, planningPositions, rpy, angleDrawLen); printf("done\n"); } } } typedef enum { keSG_2D3D定位_海瑞马_地面调平 = 0, keSG_2D3D定位_海瑞马_锥形工件, keSG_2D3D定位_海瑞马_转子芯, keSG_2D3D定位_海瑞马_码垛料筐定位, keSG_2D3D定位_海瑞马_码垛工件尺寸测量, keSG_2D3D定位_海瑞马_码垛位置规划, } ESG_testMode; int main() { //ESG_testMode testMode = keSG_2D3D定位_海瑞马_地面调平; //ESG_testMode testMode = keSG_2D3D定位_海瑞马_锥形工件; ESG_testMode testMode = keSG_2D3D定位_海瑞马_转子芯; //ESG_testMode testMode = keSG_2D3D定位_海瑞马_码垛料筐定位; //ESG_testMode testMode = keSG_2D3D定位_海瑞马_码垛工件尺寸测量; //ESG_testMode testMode = keSG_2D3D定位_海瑞马_码垛位置规划; if (keSG_2D3D定位_海瑞马_锥形工件 == testMode) HaiRuiMa_TaperedWorkpiece_test(); else if (keSG_2D3D定位_海瑞马_地面调平 == testMode) HaiRuiMa_groundCalib_test(); else if (keSG_2D3D定位_海瑞马_转子芯 == testMode) HaiRuiMa_rotorCorePositioning_test(); else if (keSG_2D3D定位_海瑞马_码垛料筐定位 == testMode) HaiRuiMa_BinSizeCompute_test(); else if (keSG_2D3D定位_海瑞马_码垛工件尺寸测量 == testMode) HaiRuiMa_workpieceSizeCompute_test(); else if (keSG_2D3D定位_海瑞马_码垛位置规划 == testMode) { //HaiRuiMa_BinSizeCompute_test(); HaiRuiMa_workpieceSizeCompute_test(); HaiRuiMa_positionPlanning_test(); } }