diff --git a/rodAndBarDetection_test/rodAndBarDetection_test.cpp b/rodAndBarDetection_test/rodAndBarDetection_test.cpp index e94b956..9e9a4de 100644 --- a/rodAndBarDetection_test/rodAndBarDetection_test.cpp +++ b/rodAndBarDetection_test/rodAndBarDetection_test.cpp @@ -429,13 +429,13 @@ void _outputRGBDScan_RGBD_rodInfo( int centerFlag = pt3D->nPointIdx >> 4; if (centerFlag > 0) { - rgb = { 250, 0, 0 }; - size = 6; + rgb = { 180, 0, 0 }; + size = 2; } else { rgb = objColor[pt3D->nPointIdx % 8]; - size = 3; + size = 2; } @@ -457,10 +457,13 @@ void _outputRGBDScan_RGBD_rodInfo( if (objNum > 0) { sw << "Line_" << lineIdx << "_0_" << objNum << std::endl; - rgb = { 250, 0, 0 }; - size = 8; + 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; @@ -468,51 +471,42 @@ void _outputRGBDScan_RGBD_rodInfo( sw << "{0,0}-{0,0}-"; sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl; } - //多输出一个,修正显示工具bug - float x = (float)rodInfo[0].center.x; - float y = (float)rodInfo[0].center.y; - float z = (float)rodInfo[0].center.z; - sw << "{" << x << "," << y << "," << z << "}-"; - sw << "{0,0}-{0,0}-"; - sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl; - //输出法向 - size = 1; + size = 8; double len = 60; lineIdx = 0; for (int i = 0; i < objNum; i++) { - SVzNL3DPoint pt0 = { 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 }; + 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 << "{" << pt1.x << "," << pt1.y << "," << pt1.z << "}-"; + 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++; } - //多输出一个,修正显示工具bug - SVzNL3DPoint pt0 = { rodInfo[0].center.x - len * rodInfo[0].axialDir.x, - rodInfo[0].center.y - len * rodInfo[0].axialDir.y, - rodInfo[0].center.z - len * rodInfo[0].axialDir.z }; - SVzNL3DPoint pt1 = { rodInfo[0].center.x + len * rodInfo[0].axialDir.x, - rodInfo[0].center.y + len * rodInfo[0].axialDir.y, - rodInfo[0].center.z + len * rodInfo[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(); @@ -630,7 +624,7 @@ void rodPositionTest(void) for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++) { - fidx =1; + //fidx =1; char _scan_file[256]; sprintf_s(_scan_file, "%sLaserData_%d.txt", dataPath[grp], fidx); diff --git a/sourceCode/rodAndBarDetection.cpp b/sourceCode/rodAndBarDetection.cpp index e5e4e26..9550bef 100644 --- a/sourceCode/rodAndBarDetection.cpp +++ b/sourceCode/rodAndBarDetection.cpp @@ -7,7 +7,8 @@ //version 1.0.0 : base version release to customer //version 1.1.0 : ˵ƽͰĶλ -std::string m_strVersion = "1.1.0"; +//version 1.1.1 : ʼͻİ汾 +std::string m_strVersion = "1.1.1"; const char* wd_rodAndBarDetectionVersion(void) { return m_strVersion.c_str(); @@ -477,6 +478,136 @@ void rodAarcFeatueDetection( return; } +SVzNL3DPoint _exchangeXY(SVzNL3DPoint pt) +{ + SVzNL3DPoint result = {pt.y, pt.x, pt.z}; + return result; +} + +void _computeRodInfo( + SWD_rodArcFeatureTree& a_objTree, + bool treeIsHorizon, + std::vector< SVzNL3DPoint>& fittingPoints, + SSX_rodPositionInfo& a_objRod) +{ + int nodeSize = a_objTree.treeNodes.size(); + // + double _a, _b, _c; + lineFitting_abc(fittingPoints, &_a, &_b, &_c); + int dataSize = (int)fittingPoints.size(); + SVzNL2DPointD foot1 = sx_getFootPoint_abc(fittingPoints[0].x, fittingPoints[0].y, _a, _b, _c); + SVzNL2DPointD foot2 = sx_getFootPoint_abc(fittingPoints[dataSize - 1].x, fittingPoints[dataSize - 1].y, _a, _b, _c); + double deltaZ = fittingPoints[dataSize - 1].z - fittingPoints[0].z; + double len = sqrt(pow(foot1.x - foot2.x, 2) + pow(foot1.y - foot2.y, 2)); + //ֱߵ + SVzNL3DPoint axialDir = { foot2.x - foot1.x, foot2.y - foot1.y, fittingPoints[dataSize - 1].z - fittingPoints[0].z }; + //һ + double normData = sqrt(pow(axialDir.x, 2) + pow(axialDir.y, 2) + pow(axialDir.z, 2)); + axialDir.x = axialDir.x / normData; + axialDir.y = axialDir.y / normData; + axialDir.z = axialDir.z / normData; + //һƽ棨Y=0ƽתһǶȣķ + double theta = atan2(foot2.y - foot1.y, foot2.x - foot1.x); + double sinTheta = sin(theta); + double cosTheta = cos(theta); + SVzNL3DPoint tmpDir = { sinTheta, -cosTheta, 0 }; + //˳ĵķ + SVzNL3DPoint normalDir = { axialDir.y * tmpDir.z - tmpDir.y * axialDir.z, + axialDir.z * tmpDir.x - tmpDir.z * axialDir.x, + axialDir.x * tmpDir.y - tmpDir.x * axialDir.y }; + + + //ȷյ㣺ֱ߾С5mm + double tmpData = sqrt(_a * _a + _b * _b); + _a = _a / tmpData; + _b = _b / tmpData; + _c = _c / tmpData; + SVzNL3DPoint realStart, realEnd; + bool foundStart = false; + for (int j = 0; j < nodeSize; j++) + { + SVzNL3DPoint a_pt = a_objTree.treeNodes[j].peakPt; + if (true == treeIsHorizon) + a_pt = _exchangeXY(a_pt); + double dist = abs(a_pt.x * _a + a_pt.y * _b + _c); + if (dist < 5.0) + { + realStart = a_pt; + foundStart = true; + break; + } + } + if (false == foundStart) + { + realStart = a_objTree.treeNodes[0].peakPt; + if (true == treeIsHorizon) + realStart = _exchangeXY(realStart); + } + + bool foundEnd = false; + for (int j = nodeSize - 1; j >= 0; j--) + { + SVzNL3DPoint a_pt = a_objTree.treeNodes[j].peakPt; + if (true == treeIsHorizon) + a_pt = _exchangeXY(a_pt); + double dist = abs(a_pt.x * _a + a_pt.y * _b + _c); + if (dist < 5.0) + { + realEnd = a_pt; + foundEnd = true; + break; + } + } + if (false == foundEnd) + { + realEnd = a_objTree.treeNodes[nodeSize - 1].peakPt; + if (true == treeIsHorizon) + realEnd = _exchangeXY(realEnd); + } + + SVzNL2DPointD foot_s = sx_getFootPoint_abc(realStart.x, realStart.y, _a, _b, _c); + SVzNL2DPointD foot_e = sx_getFootPoint_abc(realEnd.x, realEnd.y, _a, _b, _c); + double dist_s = sqrt(pow(foot_s.x - foot1.x, 2) + pow(foot_s.y - foot1.y, 2)); + double dist_e = sqrt(pow(foot_e.x - foot1.x, 2) + pow(foot_e.y - foot1.y, 2)); + //ĿϢ + ; + a_objRod.startPt = { foot_s.x, foot_s.y, -(dist_s / len) * deltaZ + fittingPoints[0].z }; + a_objRod.endPt = { foot_e.x, foot_e.y, (dist_e / len) * deltaZ + fittingPoints[0].z }; + a_objRod.center = { (a_objRod.startPt.x + a_objRod.endPt.x) / 2, + (a_objRod.startPt.y + a_objRod.endPt.y) / 2, + (a_objRod.startPt.z + a_objRod.endPt.z) / 2 }; + a_objRod.axialDir = axialDir; + a_objRod.normalDir = normalDir; + + return; +} + +bool checkObjEixst(SSX_rodPositionInfo& a_objRod, std::vector& existObjs, const SSX_rodParam rodParam) +{ + double minDistance = -1; + for (int i = 0; i < (int)existObjs.size(); i++) + { + double dist = sqrt(pow(a_objRod.center.x - existObjs[i].center.x, 2) + + pow(a_objRod.center.y - existObjs[i].center.y, 2) + + pow(a_objRod.center.z - existObjs[i].center.z, 2)); + if (minDistance < 0) + minDistance = dist; + else if (minDistance > dist) + minDistance = dist; + } + if (minDistance < 0) + return false; + else if (minDistance < rodParam.diameter / 4) // R/2 + return true; + else + return false; +} + +bool _commpareByCenterZ(SSX_rodPositionInfo& a, SSX_rodPositionInfo& b) +{ + return (a.center.z < b.center.z); +} + void sx_rodPositioning( std::vector< std::vector>& scanLines, const SSG_planeCalibPara poseCalibPara, @@ -597,6 +728,7 @@ void sx_rodPositioning( } //Ŀж //(1)ȹ + //ֱĿ for (int i = 0; i < (int)rodArcTrees_v.size(); i++) { int nodeSize = rodArcTrees_v[i].treeNodes.size(); @@ -606,7 +738,7 @@ void sx_rodPositioning( pow(startCenter.y - endCenter.y, 2) + pow(startCenter.z - endCenter.z, 2)); double lenDiff = abs(len - rodParam.len); - if (lenDiff < 10.0) //validObj + if (lenDiff < rodParam.len* 0.15) //validObj { //XYƽֱ //Ϊ˷ֹ˲Ӱ죬 @@ -624,48 +756,51 @@ void sx_rodPositioning( } if (fittingPoints.size() < 3) continue; - // - double _a, _b, _c; - lineFitting_abc(fittingPoints, &_a, &_b, &_c); - int dataSize = (int)fittingPoints.size(); - SVzNL2DPointD foot1 = sx_getFootPoint_abc(fittingPoints[0].x, fittingPoints[0].y, _a, _b, _c); - SVzNL2DPointD foot2 = sx_getFootPoint_abc(fittingPoints[dataSize - 1].x, fittingPoints[dataSize - 1].y, _a, _b, _c); - //ֱߵ - SVzNL3DPoint axialDir = { foot2.x - foot1.x, foot2.y - foot1.y, fittingPoints[dataSize - 1].z - fittingPoints[0].z }; - double theta = atan2(foot2.y - foot1.y, foot2.x - foot1.x); - double sinTheta = sin(theta); - double cosTheta = cos(theta); - SVzNL3DPoint tmpDir = { sinTheta, -cosTheta, 0 }; - SVzNL3DPoint normalDir = { axialDir.y * tmpDir.z - tmpDir.y * axialDir.z, - axialDir.z * tmpDir.x - tmpDir.z * axialDir.x, - axialDir.x * tmpDir.y - tmpDir.x * axialDir.y }; - SSX_rodPositionInfo a_objRod; - //ȷյ㣺ֱ߾С5mm - double tmpData = sqrt(_a * _a + _b * _b); - _a = _a / tmpData; - _b = _b / tmpData; - _c = _c / tmpData; - SVzNL3DPoint realStart, realEnd; - bool foundStart = false; + _computeRodInfo(rodArcTrees_v[i], false, fittingPoints, a_objRod); + rodInfo.push_back(a_objRod); + } + } + //ˮƽĿ + for (int i = 0; i < (int)rodArcTrees_h.size(); i++) + { + int nodeSize = rodArcTrees_h[i].treeNodes.size(); + SVzNL3DPoint startCenter = rodArcTrees_h[i].treeNodes[0].peakPt; + startCenter = _exchangeXY(startCenter); + SVzNL3DPoint endCenter = rodArcTrees_h[i].treeNodes[nodeSize - 1].peakPt; + endCenter = _exchangeXY(endCenter); + + double len = sqrt(pow(startCenter.x - endCenter.x, 2) + + pow(startCenter.y - endCenter.y, 2) + + pow(startCenter.z - endCenter.z, 2)); + double lenDiff = abs(len - rodParam.len); + if (lenDiff < rodParam.len * 0.15) //validObj + { + //XYƽֱ + //Ϊ˷ֹ˲Ӱ죬 + std::vector fittingPoints; for (int j = 0; j < nodeSize; j++) { - double dist = abs(rodArcTrees_v[i].treeNodes[j].peakPt.x * _a + - rodArcTrees_v[i].treeNodes[j].peakPt.y * _b + _c); - if (dist < 5.0) - { - realStart = rodArcTrees_v[i].treeNodes[j].peakPt; - foundStart = true; - break; - } + SVzNL3DPoint a_pt = _exchangeXY(rodArcTrees_h[i].treeNodes[j].peakPt); + double dist1 = sqrt(pow(a_pt.x - startCenter.x, 2) + pow(a_pt.y - startCenter.y, 2) + pow(a_pt.z - startCenter.z, 2)); + double dist2 = sqrt(pow(a_pt.x - endCenter.x, 2) + pow(a_pt.y - endCenter.y, 2) + pow(a_pt.z - endCenter.z, 2)); + if ((dist1 > rodParam.diameter / 2) && (dist2 > rodParam.diameter / 2)) + fittingPoints.push_back(a_pt); } + if (fittingPoints.size() < 3) + continue; - + SSX_rodPositionInfo a_objRod; + _computeRodInfo(rodArcTrees_h[i], true, fittingPoints, a_objRod); + //Ƿ봹ֱĿص + bool isExist = checkObjEixst(a_objRod, rodInfo, rodParam); + if(false == isExist) + rodInfo.push_back(a_objRod); } } //2ڵж - - + //߶ + std::sort(rodInfo.begin(), rodInfo.end(), _commpareByCenterZ); //ͶԭϵԱ۱궨ȷ for (int i = 0; i < lineNum; i++) @@ -680,6 +815,11 @@ void sx_rodPositioning( a_rod.axialDir = rawObj; rawObj = _translatePoint(a_rod.normalDir, poseCalibPara.invRMatrix); a_rod.normalDir = rawObj; + + rawObj = _translatePoint(a_rod.startPt, poseCalibPara.invRMatrix); + a_rod.startPt = rawObj; + rawObj = _translatePoint(a_rod.endPt, poseCalibPara.invRMatrix); + a_rod.endPt = rawObj; } return; }