diff --git a/SG_Algorithm.sln b/SG_Algorithm.sln index ebdea36..1484cdd 100644 --- a/SG_Algorithm.sln +++ b/SG_Algorithm.sln @@ -157,7 +157,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BQ_assemblyPosition", "BQ_a EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BQ_assemblyPosition_test", "BQ_assemblyPosition_test\BQ_assemblyPosition_test.vcxproj", "{BC38D1E5-10CB-438B-AC72-6012303CE139}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wheelArchHeigthMeaure", "wheelArchHeigthMeaure\wheelArchHeigthMeaure.vcxproj", "{CFE11556-106A-4216-BF62-FDA980528F7A}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wheelArchHeigthMeasure", "wheelArchHeigthMeaure\wheelArchHeigthMeaure.vcxproj", "{CFE11556-106A-4216-BF62-FDA980528F7A}" ProjectSection(ProjectDependencies) = postProject {95DC3F1A-902A-490E-BD3B-B10463CF0EBD} = {95DC3F1A-902A-490E-BD3B-B10463CF0EBD} EndProjectSection @@ -168,6 +168,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wheelArchHeigthMeasure_test {CFE11556-106A-4216-BF62-FDA980528F7A} = {CFE11556-106A-4216-BF62-FDA980528F7A} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HC_channelSpaceMeasure", "HC_channelSpaceMeausre\HC_channelSpaceMeausre.vcxproj", "{52A65444-8505-4FD5-9501-E2D297E2EB2C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HC_channelSpaceMeasure_test", "HC_chanelSpaceMeasure_test\HC_chanelSpaceMeasure_test.vcxproj", "{3EC47D19-2562-4303-82B9-6B1C93C5A37A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -440,6 +444,22 @@ Global {BBF5341E-8447-45E9-ADA3-3E8A9B52F5EF}.Release|x64.Build.0 = Release|x64 {BBF5341E-8447-45E9-ADA3-3E8A9B52F5EF}.Release|x86.ActiveCfg = Release|Win32 {BBF5341E-8447-45E9-ADA3-3E8A9B52F5EF}.Release|x86.Build.0 = Release|Win32 + {52A65444-8505-4FD5-9501-E2D297E2EB2C}.Debug|x64.ActiveCfg = Debug|x64 + {52A65444-8505-4FD5-9501-E2D297E2EB2C}.Debug|x64.Build.0 = Debug|x64 + {52A65444-8505-4FD5-9501-E2D297E2EB2C}.Debug|x86.ActiveCfg = Debug|Win32 + {52A65444-8505-4FD5-9501-E2D297E2EB2C}.Debug|x86.Build.0 = Debug|Win32 + {52A65444-8505-4FD5-9501-E2D297E2EB2C}.Release|x64.ActiveCfg = Release|x64 + {52A65444-8505-4FD5-9501-E2D297E2EB2C}.Release|x64.Build.0 = Release|x64 + {52A65444-8505-4FD5-9501-E2D297E2EB2C}.Release|x86.ActiveCfg = Release|Win32 + {52A65444-8505-4FD5-9501-E2D297E2EB2C}.Release|x86.Build.0 = Release|Win32 + {3EC47D19-2562-4303-82B9-6B1C93C5A37A}.Debug|x64.ActiveCfg = Debug|x64 + {3EC47D19-2562-4303-82B9-6B1C93C5A37A}.Debug|x64.Build.0 = Debug|x64 + {3EC47D19-2562-4303-82B9-6B1C93C5A37A}.Debug|x86.ActiveCfg = Debug|Win32 + {3EC47D19-2562-4303-82B9-6B1C93C5A37A}.Debug|x86.Build.0 = Debug|Win32 + {3EC47D19-2562-4303-82B9-6B1C93C5A37A}.Release|x64.ActiveCfg = Release|x64 + {3EC47D19-2562-4303-82B9-6B1C93C5A37A}.Release|x64.Build.0 = Release|x64 + {3EC47D19-2562-4303-82B9-6B1C93C5A37A}.Release|x86.ActiveCfg = Release|Win32 + {3EC47D19-2562-4303-82B9-6B1C93C5A37A}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/sourceCode/SG_baseAlgo_Export.h b/sourceCode/SG_baseAlgo_Export.h index 29129d2..17d2028 100644 --- a/sourceCode/SG_baseAlgo_Export.h +++ b/sourceCode/SG_baseAlgo_Export.h @@ -488,6 +488,10 @@ SG_APISHARED_EXPORT SSG_planeCalibPara adjustPlaneToXYPlane( SG_APISHARED_EXPORT SSG_planeCalibPara sg_getPlaneCalibPara2( std::vector< std::vector>& scanLines); +//针对孔板计算一个平面调平参数:提取不经过孔的扫描线进行平面拟合 +SG_APISHARED_EXPORT SSG_planeCalibPara sg_getHolePlaneCalibPara( + std::vector< std::vector>& scanLines); + //计算一个平面调平参数。 //以数据输入中ROI以内的点进行平面拟合,计算调平参数 //旋转矩阵为调平参数,即将平面法向调整为垂直向量的参数 @@ -536,7 +540,7 @@ SG_APISHARED_EXPORT void sg_pointClustering( //基于栅格上点的窗口内的相邻点的聚类,聚类条件由3D点的邻域决定 //使用vector构成2维结构体数组 -SG_APISHARED_EXPORT void wd_pointClustering2D( +SG_APISHARED_EXPORT void wd_gridPointClustering( std::vector>& featureMask, std::vector>& feature3DInfo, int clusterCheckWin, //搜索窗口 @@ -546,6 +550,15 @@ SG_APISHARED_EXPORT void wd_pointClustering2D( SVzNL3DRangeD& clusterRoi //roi3D ); +//使用聚类方法完成8连通连通域分析 +SG_APISHARED_EXPORT void wd_gridPointClustering_labelling( + std::vector>& featureMask, + std::vector>& feature3DInfo, + int clusterID, //当前Cluster的ID + std::vector< SVzNL2DPoint>& a_cluster, //result + SVzNLRect& clusterRoi //roi2D +); + //对栅格化数据进行XY平面上的投影量化,并对量化产生的空白点进行插值 SG_APISHARED_EXPORT void pointClout2DProjection( std::vector< std::vector>& gridScanData, diff --git a/sourceCode/SG_clustering.cpp b/sourceCode/SG_clustering.cpp index f47f8c2..78fd39c 100644 --- a/sourceCode/SG_clustering.cpp +++ b/sourceCode/SG_clustering.cpp @@ -67,7 +67,7 @@ void sg_pointClustering( return; } -void wd_pointClustering2D( +void wd_gridPointClustering( std::vector>& featureMask, std::vector>& feature3DInfo, int clusterCheckWin, //搜索窗口 @@ -108,7 +108,7 @@ void wd_pointClustering2D( if ((chk_seed.featurType ==0) || (chk_seed.clusterID > 0)) //只检查未聚类的特征点 continue; - SVzNL3DPoint& chkValue = feature3DInfo[x][y];; + SVzNL3DPoint& chkValue = feature3DInfo[x][y]; double y_diff = abs(seedValue.y - chkValue.y); double z_diff = abs(seedValue.z - chkValue.z); double x_diff = abs(seedValue.x - chkValue.x); @@ -138,4 +138,66 @@ void wd_pointClustering2D( i++; } return; +} + +//使用聚类方法完成8连通连通域分析 +void wd_gridPointClustering_labelling( + std::vector>& featureMask, + std::vector>& feature3DInfo, + int clusterID, //当前Cluster的ID + std::vector< SVzNL2DPoint>& a_cluster, //result + SVzNLRect& clusterRoi //roi2D +) +{ + int i = 0; + int lineNum = (int)featureMask.size(); + int linePtNum = (int)featureMask[0].size(); + while (1) + { + if (i >= a_cluster.size()) + break; + + SVzNL2DPoint a_seedPos = a_cluster[i]; + if ((a_seedPos.x == 390) && (a_seedPos.y == 949)) + int kkk = 1; + + SSG_featureClusteringInfo& a_seed = featureMask[a_seedPos.x][a_seedPos.y]; + if (0 == a_seed.clusterID) //clusterID == 0, 未被处理,搜索邻域 + { + //8连通 + for (int i = -1; i <= 1; i++) + { + for (int j = -1; j <= 1; j++) + { + int y = j + a_seedPos.y; + int x = i + a_seedPos.x; + if ((x == 390) && (y == 949)) + int kkk = 1; + + if ((x >= 0) && (x < lineNum) && (y >= 0) && (y < linePtNum)) + { + SSG_featureClusteringInfo& chk_seed = featureMask[x][y]; + if ((chk_seed.featurType == 0) || (chk_seed.clusterID > 0)) //只检查未聚类的特征点 + continue; + + if (0 == chk_seed.flag)//防止被重复添加 + { + chk_seed.flag = 1; + SVzNL2DPoint new_seed = { x, y }; + a_cluster.push_back(new_seed); + } + } + + } + } + } + a_seed.clusterID = clusterID; + //更新ROI + clusterRoi.left = clusterRoi.left > a_seedPos.x ? a_seedPos.x : clusterRoi.left; + clusterRoi.right = clusterRoi.right < a_seedPos.x ? a_seedPos.x : clusterRoi.right; + clusterRoi.top = clusterRoi.top > a_seedPos.y ? a_seedPos.y : clusterRoi.top; + clusterRoi.bottom = clusterRoi.bottom < a_seedPos.y ? a_seedPos.y : clusterRoi.bottom; + i++; + } + return; } \ No newline at end of file diff --git a/sourceCode/wheelArchHeigthMeasure.cpp b/sourceCode/wheelArchHeigthMeasure.cpp index f563f84..79be6fe 100644 --- a/sourceCode/wheelArchHeigthMeasure.cpp +++ b/sourceCode/wheelArchHeigthMeasure.cpp @@ -6,7 +6,8 @@ #include //version 1.0.0 : base version release to customer -std::string m_strVersion = "1.0.0"; +//version 1.1.0 : 添加了轮眉到地面高度输出 +std::string m_strVersion = "1.1.0"; const char* wd_wheelArchHeigthMeasureVersion(void) { return m_strVersion.c_str(); @@ -346,7 +347,7 @@ WD_wheelArchInfo wd_wheelArchHeigthMeasure( SVzNL2DPoint a_seedPos = { x, y }; std::vector< SVzNL2DPoint> a_cluster; a_cluster.push_back(a_seedPos); - wd_pointClustering2D( + wd_gridPointClustering( featureInfoMask,//int,记录特征标记和clusterID,附加一个flag feature3DInfo,//double,记录坐标信息 clusterCheckWin, //搜索窗口 @@ -474,6 +475,7 @@ WD_wheelArchInfo wd_wheelArchHeigthMeasure( result.centerLine[0] = { downWheelPt.x - outLineLen, centerY, scanLines[searchLine][minPtIdx].pt3D.z }; result.centerLine[1] = { downWheelPt.x + outLineLen, centerY, scanLines[searchLine][minPtIdx].pt3D.z }; result.archToCenterHeigth = centerY - arcPt.y; + result.archToGroundHeigth = groundCalibPara.planeHeight - arcPt.y; //将数据重新投射回原来的坐标系,以保持手眼标定结果正确 for (int i = 0; i < lineNum; i++) lineDataRT_vector(scanLines[i], groundCalibPara.invRMatrix, -1); diff --git a/sourceCode/wheelArchHeigthMeasure_Export.h b/sourceCode/wheelArchHeigthMeasure_Export.h index 4bcf7df..05af0bf 100644 --- a/sourceCode/wheelArchHeigthMeasure_Export.h +++ b/sourceCode/wheelArchHeigthMeasure_Export.h @@ -15,6 +15,7 @@ typedef struct SVzNL3DPoint downLine[2]; SVzNL3DPoint centerLine[2]; double archToCenterHeigth; + double archToGroundHeigth; }WD_wheelArchInfo; //读版本号 diff --git a/wheelArchHeigthMeasure_test/wheelArchHeigthMeasure_test.cpp b/wheelArchHeigthMeasure_test/wheelArchHeigthMeasure_test.cpp index 69a2212..4cb4b58 100644 --- a/wheelArchHeigthMeasure_test/wheelArchHeigthMeasure_test.cpp +++ b/wheelArchHeigthMeasure_test/wheelArchHeigthMeasure_test.cpp @@ -2752,7 +2752,7 @@ int main() for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++) { //fidx = 193; - sprintf_s(_scan_file, "%sLaserLine1_grid.txt", dataPath[grp], fidx); + sprintf_s(_scan_file, "%sLaserLine%d_grid.txt", dataPath[grp], fidx); std::vector> scanData; vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanData); if (scanData.size() == 0) @@ -2769,7 +2769,7 @@ int main() int kkk = 1; //琛屽鐞 //璋冨钩锛屽幓闄ゅ湴闈 - wd_horizonCamera_lineDataR(scanData[i], poseCalibPara.planeCalib, poseCalibPara.planeHeight); + wd_horizonCamera_lineDataR(scanData[i], poseCalibPara.planeCalib, poseCalibPara.planeHeight-5); } #if 0 //鏁版嵁杞瓨 sprintf_s(_scan_file, "%sLaserLine%d_grid_RTadjust.txt", dataPath[grp], fidx); @@ -2818,7 +2818,7 @@ int main() sprintf_s(_dbg_file, "%sresult\\LaserLine%d_result.txt", dataPath[grp], fidx); _outputScanDataFile_RGBD_obj(_dbg_file, scanData, 0, 0, 0, wheelArcHeight); #endif - printf("%s: height=%f, %d(ms)!\n", _scan_file, wheelArcHeight.archToCenterHeigth, (int)(t2 - t1)); + printf("%s: height=%f, arcToGrund=%f, time=%d(ms)!\n", _scan_file, wheelArcHeight.archToCenterHeigth, wheelArcHeight.archToGroundHeigth, (int)(t2 - t1)); }