diff --git a/rodAndBarDetection_test/rodAndBarDetection_test.cpp b/rodAndBarDetection_test/rodAndBarDetection_test.cpp index 456e95c..30e7b81 100644 --- a/rodAndBarDetection_test/rodAndBarDetection_test.cpp +++ b/rodAndBarDetection_test/rodAndBarDetection_test.cpp @@ -378,16 +378,17 @@ void _outputRGBDScan_RGBD( //输出法向 size = 1; - double len = 60; + double len1 = 30; + double len2 = 200; lineIdx = 0; for (int i = 0; i < objNum; i++) { - SVzNL3DPoint pt0 = { screwInfo[i].center.x - len * screwInfo[i].axialDir.x, - screwInfo[i].center.y - len * screwInfo[i].axialDir.y, - screwInfo[i].center.z - len * screwInfo[i].axialDir.z }; - SVzNL3DPoint pt1 = { screwInfo[i].center.x + len * screwInfo[i].axialDir.x, - screwInfo[i].center.y + len * screwInfo[i].axialDir.y, - screwInfo[i].center.z + len * screwInfo[i].axialDir.z }; + 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 << "}-"; @@ -398,22 +399,6 @@ void _outputRGBDScan_RGBD( sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; } - //多输出一个,修正显示工具bug - SVzNL3DPoint pt0 = { screwInfo[0].center.x - len * screwInfo[0].axialDir.x, - screwInfo[0].center.y - len * screwInfo[0].axialDir.y, - screwInfo[0].center.z - len * screwInfo[0].axialDir.z }; - SVzNL3DPoint pt1 = { screwInfo[0].center.x + len * screwInfo[0].axialDir.x, - screwInfo[0].center.y + len * screwInfo[0].axialDir.y, - screwInfo[0].center.z + len * screwInfo[0].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(); } @@ -893,31 +878,33 @@ void _outputRGBDScan_RGBD_weldSeam( sw.close(); } -#define SCREW_TEST_GROUP 2 +#define SCREW_TEST_GROUP 3 void screwTest(void) { const char* dataPath[SCREW_TEST_GROUP] = { "F:/ShangGu/项目/冠钦项目/螺杆测量/数据/模拟数据/", //0 "F:/ShangGu/项目/冠钦项目/螺杆测量/配天现场点云/螺杆点云2/上方两根/", //1 + "F:/ShangGu/项目/冠钦项目/螺杆测量/配天现场点云/螺杆点云3/", //2 }; SVzNLRange fileIdx[SCREW_TEST_GROUP] = { - {1,4},{1,30} + {1,4},{1,30},{1,11} }; const char* ver = wd_rodAndBarDetectionVersion(); printf("ver:%s\n", ver); - for (int grp = 1; grp < SCREW_TEST_GROUP; grp++) + for (int grp = 2; grp < SCREW_TEST_GROUP; grp++) { for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++) { - //fidx =7; + //fidx =3; char _scan_file[256]; - if(1 == grp) - sprintf_s(_scan_file, "%s%d_LaserData_Jl26C299.txt", dataPath[grp], fidx); - else + + if(0 == grp) sprintf_s(_scan_file, "%sLaserData_%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); @@ -970,7 +957,7 @@ void screwTest(void) &errCode); long t2 = (long)GetTickCount64(); - printf("%s: %d(ms)!\n", _scan_file, (int)(t2 - t1)); + 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(_scan_file, scanLines, screwInfo); diff --git a/sourceCode/SG_baseFunc.cpp b/sourceCode/SG_baseFunc.cpp index 3c51baf..18468c6 100644 --- a/sourceCode/SG_baseFunc.cpp +++ b/sourceCode/SG_baseFunc.cpp @@ -2171,6 +2171,9 @@ SSG_planeCalibPara sg_HCameraVScan_getGroundCalibPara( //ֱ߷ָ std::vector< SSG_RUN> segmentationLines; split(lastSeg, lineData, lineSegPara.distScale, segmentationLines); + if (segmentationLines.size() == 0) + continue; + //һεֱ߶εб SSG_RUN lastLine = segmentationLines.back(); //б diff --git a/sourceCode/rodAndBarDetection.cpp b/sourceCode/rodAndBarDetection.cpp index 274d049..5754cd7 100644 --- a/sourceCode/rodAndBarDetection.cpp +++ b/sourceCode/rodAndBarDetection.cpp @@ -18,7 +18,8 @@ //version 1.2.7 : (1)ʵʵݸ˶λ㷨2λλ˼ĻRANSAC //version 1.2.8 : ݸ˶λ㷨еһBug //version 1.2.9 : ݸ˶λ㷨ϼʱȷ⣬֤ͶӰĵͶӰǰĵƵZ仯һ -std::string m_strVersion = "1.2.9"; +//version 1.2.10 : Ľݸ˶λȡ㷨 +std::string m_strVersion = "1.2.10"; const char* wd_rodAndBarDetectionVersion(void) { return m_strVersion.c_str(); @@ -136,7 +137,7 @@ void xoyROIProjection( SSG_ROIRectD& roi_xoy, int objClusterId, std::vector>& clusterIdMask, - std::vector& projectPoints + std::vector& projectPoints ) { int lineNum = (int)scanLines.size(); @@ -159,16 +160,19 @@ void xoyROIProjection( if ((x >= roi_xoy.left) && (x <= roi_xoy.right) && (y >= roi_xoy.top) && (y <= roi_xoy.bottom)) { - a_pt.x = x; - a_pt.y = y; - a_pt.z = z; - projectPoints.push_back(a_pt); + SWD3DPointPostion projectPt; + projectPt.lineIdx = line; + projectPt.ptIdx = i; + projectPt.point.x = x; + projectPt.point.y = y; + projectPt.point.z = z; + projectPoints.push_back(projectPt); } } } } -SVzNLRangeD getZRange(std::vector& projectPoints) +SVzNLRangeD getZRange(std::vector& projectPoints) { int ptNum = (int)projectPoints.size(); SVzNLRangeD zRange; @@ -176,22 +180,28 @@ SVzNLRangeD getZRange(std::vector& projectPoints) zRange.max = -DBL_MAX; for (int i = 0; i < ptNum; i++) { - zRange.min = zRange.min > projectPoints[i].z ? projectPoints[i].z : zRange.min; - zRange.max = zRange.max < projectPoints[i].z ? projectPoints[i].z : zRange.max; + zRange.min = zRange.min > projectPoints[i].point.z ? projectPoints[i].point.z : zRange.min; + zRange.max = zRange.max < projectPoints[i].point.z ? projectPoints[i].point.z : zRange.max; } return zRange; } void zCutPointClouds( - std::vector& projectPoints, + std::vector& projectPoints, SVzNLRangeD& zRange, - std::vector& cutLayerPoints) + std::vector& cutLayerPoints, + std::vector>& addrMapping) { int ptNum = (int)projectPoints.size(); for (int i = 0; i < ptNum; i++) { - if ((projectPoints[i].z >= zRange.min) && (projectPoints[i].z <= zRange.max)) + if ((projectPoints[i].point.z >= zRange.min) && (projectPoints[i].point.z <= zRange.max)) + { cutLayerPoints.push_back(projectPoints[i]); + int lineIdx = projectPoints[i].lineIdx; + int ptIdx = projectPoints[i].ptIdx; + addrMapping[lineIdx][ptIdx] = i; + } } } @@ -256,7 +266,7 @@ void rodAarcFeatueDetection( } //еROI: vecotrʽ, zС0ĵ㣩 -SVzNL3DRangeD _getPointCloudROI(std::vector& scanData) +SVzNL3DRangeD _getPointCloudROI(std::vector& scanData) { SVzNL3DRangeD roi; roi.xRange = { 0, -1 }; @@ -266,44 +276,44 @@ SVzNL3DRangeD _getPointCloudROI(std::vector& scanData) int nPositionCnt = (int)scanData.size(); for (int i = 0; i < nPositionCnt; i++) { - SVzNL3DPoint& pt3D = scanData[i]; + SWD3DPointPostion& pt3D = scanData[i]; if (roi.xRange.max < roi.xRange.min) { - roi.xRange.min = pt3D.x; - roi.xRange.max = pt3D.x; + roi.xRange.min = pt3D.point.x; + roi.xRange.max = pt3D.point.x; } else { - if (roi.xRange.min > pt3D.x) - roi.xRange.min = pt3D.x; - if (roi.xRange.max < pt3D.x) - roi.xRange.max = pt3D.x; + if (roi.xRange.min > pt3D.point.x) + roi.xRange.min = pt3D.point.x; + if (roi.xRange.max < pt3D.point.x) + roi.xRange.max = pt3D.point.x; } //y if (roi.yRange.max < roi.yRange.min) { - roi.yRange.min = pt3D.y; - roi.yRange.max = pt3D.y; + roi.yRange.min = pt3D.point.y; + roi.yRange.max = pt3D.point.y; } else { - if (roi.yRange.min > pt3D.y) - roi.yRange.min = pt3D.y; - if (roi.yRange.max < pt3D.y) - roi.yRange.max = pt3D.y; + if (roi.yRange.min > pt3D.point.y) + roi.yRange.min = pt3D.point.y; + if (roi.yRange.max < pt3D.point.y) + roi.yRange.max = pt3D.point.y; } //z if (roi.zRange.max < roi.zRange.min) { - roi.zRange.min = pt3D.z; - roi.zRange.max = pt3D.z; + roi.zRange.min = pt3D.point.z; + roi.zRange.max = pt3D.point.z; } else { - if (roi.zRange.min > pt3D.z) - roi.zRange.min = pt3D.z; - if (roi.zRange.max < pt3D.z) - roi.zRange.max = pt3D.z; + if (roi.zRange.min > pt3D.point.z) + roi.zRange.min = pt3D.point.z; + if (roi.zRange.max < pt3D.point.z) + roi.zRange.max = pt3D.point.z; } } @@ -450,6 +460,9 @@ SVzNL3DRangeD _getPointCloudROI(std::vector& scanData) return; } int objNum = (int)rodArcTrees.size(); + + //ڲnodeSizeСڴ˵ΪЧ + int validNodeSizeTH = 30; //ñ־debug for (int i = 0; i < objNum; i++) @@ -551,6 +564,10 @@ SVzNL3DRangeD _getPointCloudROI(std::vector& scanData) int objIdx = -1; for (int i = 0; i < objNum; i++) { + int nodeNum = (int)rodArcTrees[i].treeNodes.size(); + if (nodeNum < validNodeSizeTH) + continue; + if (objIdx < 0) objIdx = i; else if (objROIs[objIdx].zRange.min > objROIs[i].zRange.min) @@ -703,7 +720,7 @@ SVzNL3DRangeD _getPointCloudROI(std::vector& scanData) roi_xoy.top = P0_rotate.y - rodDiameter * 2.0; //2DΧ roi_xoy.bottom = P0_rotate.y + rodDiameter * 2.0; //2DΧ - std::vector< SVzNL3DPoint> roiProjectionData; + std::vector< SWD3DPointPostion> roiProjectionData; xoyROIProjection(scanLines, rotatePara.planeCalib, roi_xoy, resultObjClusterId, clusterIdMask, roiProjectionData); //ȡ @@ -712,37 +729,70 @@ SVzNL3DRangeD _getPointCloudROI(std::vector& scanData) if (false == dirInverting) { cutZRange.min = zRange.min; - cutZRange.max = zRange.min + 5.0; //5mmĶ + cutZRange.max = zRange.min + 10.0; //5mmĶ } else { cutZRange.max = zRange.max; - cutZRange.min = zRange.max - 5.0; //5mmĶ + cutZRange.min = zRange.max - 10.0; //5mmĶ } - std::vector surfacePoints; - zCutPointClouds(roiProjectionData, cutZRange, surfacePoints); + std::vector surfacePoints; + std::vector>addrMapping; + addrMapping.resize(scanLines.size()); + for (int i = 0; i < (int)scanLines.size(); i++) + { + addrMapping[i].resize(scanLines[i].size()); + std::fill(addrMapping[i].begin(), addrMapping[i].end(), -1); + } + zCutPointClouds(roiProjectionData, cutZRange, surfacePoints, addrMapping); //ĵ - SVzNL3DPoint projectionCenter;// = getXoYCentroid(surfacePoints); + SWD3DPointPostion projectionCenter;// = getXoYCentroid(surfacePoints); SVzNL3DRangeD roi3D = _getPointCloudROI(surfacePoints); - projectionCenter.x = (roi3D.xRange.min + roi3D.xRange.max) / 2; - projectionCenter.y = (roi3D.yRange.min + roi3D.yRange.max) / 2; - projectionCenter.z = zRange.min; + //XYƽϵ + double sum_x = 0, sum_y = 0; + int sum_size = 0; + for (int i = 0; i < (int)surfacePoints.size(); i++) + { + if (surfacePoints[i].point.z > 1e-4) + { + sum_x += surfacePoints[i].point.x; + sum_y += surfacePoints[i].point.y; + sum_size++; + } + } + if(sum_size == 0) + { + *errCode = SX_ERR_ZERO_OBJECTS; + return; + } + projectionCenter.lineIdx = -1; + projectionCenter.ptIdx = -1; + projectionCenter.point.x = sum_x / sum_size; // (roi3D.xRange.min + roi3D.xRange.max) / 2; + projectionCenter.point.y = sum_y / sum_size; // (roi3D.yRange.min + roi3D.yRange.max) / 2; + projectionCenter.point.z = zRange.min; //projectionCenterΪ5mmzĵĵΪĵ double searchR = 5.0; int centerIdx = -1; + double maxZ = -1; for (int i = 0; i < (int)surfacePoints.size(); i++) { - double dist = sqrt(pow(surfacePoints[i].x - projectionCenter.x, 2) + pow(surfacePoints[i].y - projectionCenter.y, 2)); + double dist = sqrt(pow(surfacePoints[i].point.x - projectionCenter.point.x, 2) + pow(surfacePoints[i].point.y - projectionCenter.point.y, 2)); if (dist < searchR) { if (centerIdx < 0) + { centerIdx = i; + maxZ = surfacePoints[i].point.z; + } else { - if (((false == dirInverting) && (surfacePoints[centerIdx].z < surfacePoints[i].z)) || - ((true == dirInverting) && (surfacePoints[centerIdx].z > surfacePoints[i].z))) + if (((false == dirInverting) && (surfacePoints[centerIdx].point.z < surfacePoints[i].point.z)) || + ((true == dirInverting) && (surfacePoints[centerIdx].point.z > surfacePoints[i].point.z))) + { centerIdx = i; + maxZ = surfacePoints[i].point.z; + } } } } @@ -751,9 +801,86 @@ SVzNL3DRangeD _getPointCloudROI(std::vector& scanData) *errCode = SX_ERR_ZERO_OBJECTS; return; } + int centerIdx_test = addrMapping[surfacePoints[centerIdx].lineIdx][surfacePoints[centerIdx].ptIdx]; + //һ + projectionCenter.lineIdx = surfacePoints[centerIdx].lineIdx; + projectionCenter.ptIdx = surfacePoints[centerIdx].ptIdx; + int sLine = projectionCenter.lineIdx - 5; + if (sLine < 0) + sLine = 0; + int eLine = projectionCenter.lineIdx + 5; + if (eLine >= (int)scanLines.size()) + eLine = (int)scanLines.size() - 1; + int sPtIdx = projectionCenter.ptIdx - 5; + if (sPtIdx < 0) + sPtIdx = 0; + int ePtIdx = projectionCenter.ptIdx + 5; + if (ePtIdx >= (int)scanLines[0].size()) + ePtIdx = (int)scanLines[0].size() - 1; + int objLine = -1; + int objPtIdx = -1; + maxZ = -1; + for (int line = sLine; line <= eLine; line++) + { + for (int ptIdx = sPtIdx; ptIdx <= ePtIdx; ptIdx++) + { + int idx_center = addrMapping[line][ptIdx]; + if (idx_center < 0) + continue; + + int sL = line - 1; + if (sL < 0) + sL = 0; + int eL = line + 1; + if (eL >= (int)scanLines.size()) + eL = (int)scanLines.size() - 1; + int sPt = ptIdx - 1; + if (sPt < 0) + sPt = 0; + int ePt = ptIdx + 1; + if (ePt >= (int)scanLines[0].size()) + ePt = (int)scanLines[0].size() - 1; + int size = 0; + double sumZ = 0; + for (int i = sL; i <= eL; i++) + { + for (int j = sPt; j <= ePt; j++) + { + int idx = addrMapping[i][j]; + if (idx >= 0) + { + if (roiProjectionData[idx].point.z > 1e-4) + { + sumZ += roiProjectionData[idx].point.z; + size++; + } + } + } + } + if (size > 0) + { + sumZ = sumZ / size; + if (maxZ < 0) + { + maxZ = sumZ; + objLine = line; + objPtIdx = ptIdx; + } + else if (((false == dirInverting) && (maxZ < sumZ)) || ((true == dirInverting) && (maxZ > sumZ))) + { + maxZ = sumZ; + objLine = line; + objPtIdx = ptIdx; + } + + } + } + } + if( (objLine >=0)&&(objPtIdx >=0)) + centerIdx = addrMapping[objLine][objPtIdx]; //תԭϵ - SVzNL3DPoint surfaceCenter = _ptRotate(surfacePoints[centerIdx], rotatePara.invRMatrix); + SVzNL3DPoint surfaceCenter = _ptRotate(roiProjectionData[centerIdx].point, rotatePara.invRMatrix); //RodϢ SSX_rodPoseInfo a_rod; a_rod.center = surfaceCenter;