2025-06-08 10:46:41 +08:00
|
|
|
|
#include "SG_baseDataType.h"
|
|
|
|
|
|
#include "SG_baseAlgo_Export.h"
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
|
|
bool _checkTypeMatch(int treeType, int featureType)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool isMatch = false;
|
|
|
|
|
|
switch (treeType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case LINE_FEATURE_L_JUMP_H2L:
|
|
|
|
|
|
if ((LINE_FEATURE_L_JUMP_H2L == featureType) || (LINE_FEATURE_L_SLOPE_H2L == featureType))
|
|
|
|
|
|
isMatch = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case LINE_FEATURE_L_JUMP_L2H:
|
|
|
|
|
|
if ((LINE_FEATURE_L_JUMP_L2H == featureType) || (LINE_FEATURE_L_SLOPE_L2H == featureType))
|
|
|
|
|
|
isMatch = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case LINE_FEATURE_L_SLOPE_H2L:
|
|
|
|
|
|
if ((LINE_FEATURE_L_SLOPE_H2L == featureType) || (LINE_FEATURE_L_JUMP_H2L == featureType))
|
|
|
|
|
|
isMatch = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case LINE_FEATURE_L_SLOPE_L2H:
|
|
|
|
|
|
if ((LINE_FEATURE_L_SLOPE_L2H == featureType) || (LINE_FEATURE_L_JUMP_L2H == featureType))
|
|
|
|
|
|
isMatch = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case LINE_FEATURE_V_SLOPE:
|
|
|
|
|
|
if ((LINE_FEATURE_V_SLOPE == featureType) ||
|
|
|
|
|
|
(LINE_FEATURE_L_SLOPE_L2H == featureType) ||
|
|
|
|
|
|
(LINE_FEATURE_L_SLOPE_H2L == featureType))
|
|
|
|
|
|
isMatch = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case LINE_FEATURE_RIGHT_ANGLE_HR:
|
|
|
|
|
|
case LINE_FEATURE_RIGHT_ANGLE_HF:
|
|
|
|
|
|
case LINE_FEATURE_RIGHT_ANGLE_RH:
|
|
|
|
|
|
case LINE_FEATURE_RIGHT_ANGLE_FH:
|
|
|
|
|
|
case LINE_FEATURE_PEAK_TOP:
|
|
|
|
|
|
case LINE_FEATURE_PEAK_BOTTOM:
|
|
|
|
|
|
case LINE_FEATURE_CORNER_V:
|
|
|
|
|
|
case LINE_FEATURE_LINE_ENDING_0:
|
|
|
|
|
|
case LINE_FEATURE_LINE_ENDING_1:
|
|
|
|
|
|
if (featureType == treeType)
|
|
|
|
|
|
isMatch = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
return isMatch;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#define TREE_STATE_UNDEF 0
|
|
|
|
|
|
#define TREE_STATE_ALIVE 1
|
|
|
|
|
|
#define TREE_STATE_DEAD 2
|
|
|
|
|
|
//<2F><>feature<72><65>trees<65><73>Ѱ<EFBFBD>Һ<EFBFBD><D2BA>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD>к<EFBFBD><D0BA>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㣬 <20><><EFBFBD><EFBFBD>false
|
|
|
|
|
|
//û<><C3BB>ʹ<EFBFBD><CAB9>ȫƥ<C8AB>䡣һ<E4A1A3><D2BB>featureһ<65><D2BB><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5><EFBFBD>ϣ<EFBFBD>ƥ<EFBFBD><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɡ<EFBFBD>û<EFBFBD><C3BB>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD>䡣
|
|
|
|
|
|
bool _featureGrowing(SSG_basicFeature1D& a_feature, const int lineIdx, std::vector<SSG_featureTree>& trees, SSG_treeGrowParam growParam)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int i = 0, i_max = trees.size(); i < i_max; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_featureTree& a_tree = trees[i];
|
|
|
|
|
|
if (TREE_STATE_DEAD == a_tree.treeState)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
SSG_basicFeature1D last_node = a_tree.treeNodes.back();
|
|
|
|
|
|
if (last_node.jumpPos2D.x == a_feature.jumpPos2D.x) //xΪlineIdx<64><78>ͬһ<CDAC><D2BB>ɨ<EFBFBD><C9A8><EFBFBD><EFBFBD><EFBFBD>ϵIJ<CFB5><C4B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
//<2F>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
double y_diff = abs(a_feature.jumpPos.y - last_node.jumpPos.y);
|
|
|
|
|
|
double z_diff = abs(a_feature.jumpPos.z - last_node.jumpPos.z);
|
|
|
|
|
|
int line_diff = abs(a_feature.jumpPos2D.x - last_node.jumpPos2D.x);
|
|
|
|
|
|
double x_diff = abs(a_feature.jumpPos.x - last_node.jumpPos.x);
|
|
|
|
|
|
bool typeMatch = _checkTypeMatch(a_tree.treeType, a_feature.featureType);
|
|
|
|
|
|
if ((y_diff < growParam.yDeviation_max) && (z_diff < growParam.zDeviation_max) &&
|
|
|
|
|
|
( (line_diff < growParam.maxLineSkipNum)||(x_diff < growParam.maxSkipDistance)) && (true == typeMatch))
|
|
|
|
|
|
{
|
|
|
|
|
|
a_tree.eLineIdx = lineIdx;
|
|
|
|
|
|
a_tree.treeNodes.push_back(a_feature);
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
//<2F><>feature<72><65>trees<65><73>Ѱ<EFBFBD>Һ<EFBFBD><D2BA>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD>к<EFBFBD><D0BA>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㣬 <20><><EFBFBD><EFBFBD>false
|
|
|
|
|
|
//û<><C3BB>ʹ<EFBFBD><CAB9>ȫƥ<C8AB>䡣һ<E4A1A3><D2BB>featureһ<65><D2BB><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5><EFBFBD>ϣ<EFBFBD>ƥ<EFBFBD><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɡ<EFBFBD>û<EFBFBD><C3BB>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD>䡣
|
|
|
|
|
|
bool _hFeatureGrowing(SSG_basicFeature1D& a_feature, const int lineIdx, std::vector<SSG_featureTree>& trees, SSG_treeGrowParam growParam)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int i = 0, i_max = trees.size(); i < i_max; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_featureTree& a_tree = trees[i];
|
|
|
|
|
|
if (TREE_STATE_DEAD == a_tree.treeState)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
SSG_basicFeature1D last_node = a_tree.treeNodes.back();
|
|
|
|
|
|
if (last_node.jumpPos2D.x == a_feature.jumpPos2D.x) //xΪlineIdx<64><78>ͬһ<CDAC><D2BB>ɨ<EFBFBD><C9A8><EFBFBD><EFBFBD><EFBFBD>ϵIJ<CFB5><C4B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
//<2F>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
double x_diff = abs(a_feature.jumpPos.x - last_node.jumpPos.x);
|
|
|
|
|
|
double y_diff = abs(a_feature.jumpPos.y - last_node.jumpPos.y);
|
|
|
|
|
|
double z_diff = abs(a_feature.jumpPos.z - last_node.jumpPos.z);
|
|
|
|
|
|
int line_diff = abs(a_feature.jumpPos2D.x - last_node.jumpPos2D.x);
|
|
|
|
|
|
bool typeMatch = _checkTypeMatch(a_tree.treeType, a_feature.featureType);
|
|
|
|
|
|
if ((x_diff < growParam.yDeviation_max) && (z_diff < growParam.zDeviation_max) &&
|
|
|
|
|
|
((line_diff < growParam.maxLineSkipNum) || (y_diff < growParam.maxSkipDistance)) && (true == typeMatch))
|
|
|
|
|
|
{
|
|
|
|
|
|
a_tree.eLineIdx = lineIdx;
|
|
|
|
|
|
a_tree.treeNodes.push_back(a_feature);
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
bool compareByLen(const SSG_RUN& a, const SSG_RUN& b) {
|
|
|
|
|
|
return a.len < b.len;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool _checkCombine(SSG_featureTree* a_tree, SSG_featureTree* chk_tree)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
double y_diff = abs(a_feature.jumpPos.y - last_node.jumpPos.y);
|
|
|
|
|
|
double z_diff = abs(a_feature.jumpPos.z - last_node.jumpPos.z);
|
|
|
|
|
|
int line_diff = abs(a_feature.jumpPos2D.x - last_node.jumpPos2D.x);
|
|
|
|
|
|
if ((y_diff < growParam.yDeviation_max) && (z_diff < growParam.zDeviation_max) &&
|
|
|
|
|
|
(line_diff < growParam.maxLineSkipNum) && (a_feature.featureType == a_tree.treeType))
|
|
|
|
|
|
{
|
|
|
|
|
|
a_tree.treeNodes.push_back(a_feature);
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void _growTreeCombine(std::vector<SSG_featureTree>& trees)
|
|
|
|
|
|
{
|
|
|
|
|
|
std::vector< SSG_RUN> treeInfo;
|
|
|
|
|
|
treeInfo.resize(trees.size());
|
|
|
|
|
|
for (int i = 0, i_max = trees.size(); i < i_max; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_featureTree* a_tree = &trees[i];
|
|
|
|
|
|
SSG_lineFeature* first_node = &(a_tree->treeNodes[0]);
|
|
|
|
|
|
SSG_lineFeature* last_node = &(a_tree->treeNodes[a_tree->treeNodes.size() - 1]);
|
|
|
|
|
|
int len = last_node->jumpPos2D.x - first_node->jumpPos2D.x;
|
|
|
|
|
|
SSG_RUN an_info = { i, len, a_tree->treeType };
|
|
|
|
|
|
treeInfo.push_back(an_info);
|
|
|
|
|
|
}
|
|
|
|
|
|
//<2F>ӳ<EFBFBD><D3B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
std::sort(treeInfo.begin(), treeInfo.end(), compareByLen);
|
|
|
|
|
|
//<2F>Գ<EFBFBD><D4B3><EFBFBD>
|
|
|
|
|
|
int treeSize = treeInfo.size();
|
|
|
|
|
|
for (int i = 0; i < treeSize; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_RUN* an_info = &treeInfo[i];
|
|
|
|
|
|
if (an_info->value == 0)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
SSG_featureTree* a_tree = &trees[an_info->start];
|
|
|
|
|
|
bool toChk = true;
|
|
|
|
|
|
while (toChk)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int j = i + 1; j < treeSize; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_featureTree* chk_tree = &trees[j];
|
|
|
|
|
|
if (chk_tree->treeType == 0)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
bool vldToCombine = _checkCombine(a_tree, chk_tree);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>V<EFBFBD><56><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǵ<EFBFBD><C7B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><F2B5A5B5>½<EFBFBD><C2BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD>û<EFBFBD>м<EFBFBD><D0BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
|
|
|
|
|
bool _invalidateVSlopeTrees(SSG_featureTree& a_tree, double minLTypeTreeLen, double minVTypeTreeLen)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_basicFeature1D* first_node = &(a_tree.treeNodes[0]);
|
|
|
|
|
|
SSG_basicFeature1D* last_node = &(a_tree.treeNodes[a_tree.treeNodes.size() - 1]);
|
|
|
|
|
|
double len = sqrt(pow(first_node->jumpPos.x - last_node->jumpPos.x, 2) + pow(first_node->jumpPos.y - last_node->jumpPos.y, 2));
|
|
|
|
|
|
if ( ((LINE_FEATURE_V_SLOPE!=a_tree.treeType)&&(len <= minLTypeTreeLen)) ||
|
|
|
|
|
|
((LINE_FEATURE_V_SLOPE == a_tree.treeType) && (len <= minVTypeTreeLen)))
|
|
|
|
|
|
return false;
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (LINE_FEATURE_V_SLOPE != a_tree.treeType)
|
|
|
|
|
|
return true;
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//Ϊ<>˷<EFBFBD>ֹ<EFBFBD><D6B9><EFBFBD>˵ĵ<CBB5><C4B5><EFBFBD>ɨ<EFBFBD><C9A8><EFBFBD><EFBFBD><EFBFBD>ĸ߶<C4B8><DFB6>쳣<EFBFBD>仯<EFBFBD><E4BBAF> ȡ<>м<EFBFBD><D0BC>ν<EFBFBD><CEBD><EFBFBD><EFBFBD>¶ȼ<C2B6><C8BC><EFBFBD>
|
|
|
|
|
|
int size = a_tree.treeNodes.size();
|
|
|
|
|
|
int pos_0 = size / 4;
|
|
|
|
|
|
int pos_1 = size * 3 / 4;
|
|
|
|
|
|
SSG_basicFeature1D* node_0 = &(a_tree.treeNodes[pos_0]);
|
|
|
|
|
|
SSG_basicFeature1D* node_1 = &(a_tree.treeNodes[pos_1]);
|
|
|
|
|
|
double node_len = sqrt(pow(node_0->jumpPos.x - node_1->jumpPos.x, 2) + pow(node_0->jumpPos.y - node_1->jumpPos.y, 2));
|
|
|
|
|
|
double height = abs(node_0->jumpPos.z - node_1->jumpPos.z);
|
|
|
|
|
|
double k = height / len;
|
|
|
|
|
|
if (k < 0.3) //<2F><>ԼΪ16<31>ȵ<EFBFBD><C8B5>¶<EFBFBD>
|
|
|
|
|
|
return true;
|
|
|
|
|
|
else
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool _checkTwoFeatureVldToGrow(SSG_basicFeature1D& a_node, SSG_basicFeature1D* a_feature, SSG_treeGrowParam growParam)
|
|
|
|
|
|
{
|
|
|
|
|
|
//<2F>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
double y_diff = abs(a_feature->jumpPos.y - a_node.jumpPos.y);
|
|
|
|
|
|
double z_diff = abs(a_feature->jumpPos.z - a_node.jumpPos.z);
|
|
|
|
|
|
int line_diff = abs(a_feature->jumpPos2D.x - a_node.jumpPos2D.x);
|
|
|
|
|
|
if ((y_diff < growParam.yDeviation_max) && (z_diff < growParam.zDeviation_max) &&
|
|
|
|
|
|
(line_diff < growParam.maxLineSkipNum))
|
|
|
|
|
|
{
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void _growingFromHead(SSG_featureTree* a_tree, std::vector<SSG_lineFeature>& lineFeatures, SSG_treeGrowParam growParam)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_basicFeature1D& head_node = a_tree->treeNodes[0];
|
|
|
|
|
|
int head_line = head_node.jumpPos2D.x;
|
|
|
|
|
|
for (int i = head_line-1; i >= 0; i--)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_lineFeature* a_line = &lineFeatures[i];
|
|
|
|
|
|
int endingNum = a_line->endings.size();
|
|
|
|
|
|
|
|
|
|
|
|
bool growFlag = false;
|
|
|
|
|
|
for (int m = 0; m < endingNum; m++)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool vld_0 = _checkTwoFeatureVldToGrow(head_node, &a_line->endings[m], growParam);
|
|
|
|
|
|
if (true == vld_0)
|
|
|
|
|
|
{
|
|
|
|
|
|
a_line->endings[m].featureType = a_tree->treeType;
|
|
|
|
|
|
a_tree->treeNodes.insert(a_tree->treeNodes.begin(), a_line->endings[m]);
|
|
|
|
|
|
growFlag = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (false == growFlag)
|
|
|
|
|
|
{
|
|
|
|
|
|
int line_diff = abs(a_line->lineIdx - a_tree->treeNodes[0].jumpPos2D.x);
|
|
|
|
|
|
if (line_diff > growParam.maxLineSkipNum)
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void _growingFromTail(SSG_featureTree* a_tree, std::vector<SSG_lineFeature>& lineFeatures, SSG_treeGrowParam growParam)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_basicFeature1D& tail_node = a_tree->treeNodes[a_tree->treeNodes.size()-1];
|
|
|
|
|
|
int tail_line = tail_node.jumpPos2D.x;
|
|
|
|
|
|
for (int i = tail_line + 1; i < lineFeatures.size(); i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_lineFeature* a_line = &lineFeatures[i];
|
|
|
|
|
|
int endingNum = a_line->endings.size();
|
|
|
|
|
|
|
|
|
|
|
|
bool growFlag = false;
|
|
|
|
|
|
for (int m = 0; m < endingNum; m++)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool vld_0 = _checkTwoFeatureVldToGrow(tail_node, &a_line->endings[m], growParam);
|
|
|
|
|
|
if (true == vld_0)
|
|
|
|
|
|
{
|
|
|
|
|
|
a_line->endings[m].featureType = a_tree->treeType;
|
|
|
|
|
|
a_tree->treeNodes.push_back(a_line->endings[m]);
|
|
|
|
|
|
growFlag = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (false == growFlag)
|
|
|
|
|
|
{
|
|
|
|
|
|
int line_diff = abs(a_line->lineIdx - a_tree->treeNodes.back().jumpPos2D.x);
|
|
|
|
|
|
if (line_diff > growParam.maxLineSkipNum)
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ROI
|
|
|
|
|
|
void _getTreeROI(SSG_featureTree* a_tree)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (a_tree->treeNodes.size() == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
a_tree->roi.left = 0;
|
|
|
|
|
|
a_tree->roi.right = 0;
|
|
|
|
|
|
a_tree->roi.top = 0;
|
|
|
|
|
|
a_tree->roi.bottom = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
a_tree->roi.left = a_tree->treeNodes[0].jumpPos.x;
|
|
|
|
|
|
a_tree->roi.right = a_tree->treeNodes[0].jumpPos.x;
|
|
|
|
|
|
a_tree->roi.top = a_tree->treeNodes[0].jumpPos.y;
|
|
|
|
|
|
a_tree->roi.bottom = a_tree->treeNodes[0].jumpPos.y;
|
|
|
|
|
|
for (int i = 1, i_max = a_tree->treeNodes.size(); i < i_max; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(a_tree->roi.left > a_tree->treeNodes[i].jumpPos.x)
|
|
|
|
|
|
a_tree->roi.left = a_tree->treeNodes[i].jumpPos.x;
|
|
|
|
|
|
if (a_tree->roi.right < a_tree->treeNodes[i].jumpPos.x)
|
|
|
|
|
|
a_tree->roi.right = a_tree->treeNodes[i].jumpPos.x;
|
|
|
|
|
|
if (a_tree->roi.top > a_tree->treeNodes[i].jumpPos.y)
|
|
|
|
|
|
a_tree->roi.top = a_tree->treeNodes[i].jumpPos.y;
|
|
|
|
|
|
if (a_tree->roi.bottom < a_tree->treeNodes[i].jumpPos.y)
|
|
|
|
|
|
a_tree->roi.bottom = a_tree->treeNodes[i].jumpPos.y;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SSG_featureTree* _getIncludingBigTree(SSG_featureTree* a_tree, std::vector<SSG_featureTree>& trees, bool chk_up)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_featureTree* _bigTree = NULL;
|
|
|
|
|
|
for (int i = 0, i_max = trees.size(); i < i_max; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_featureTree* chk_tree = &trees[i];
|
|
|
|
|
|
if (a_tree == chk_tree)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
if (true == chk_up)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (chk_tree->roi.bottom < a_tree->roi.top)
|
|
|
|
|
|
{
|
|
|
|
|
|
if ((chk_tree->roi.left < a_tree->roi.left) &&
|
|
|
|
|
|
(chk_tree->roi.right > a_tree->roi.right)) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (NULL == _bigTree)
|
|
|
|
|
|
_bigTree = chk_tree;
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if(chk_tree->roi.bottom > _bigTree->roi.bottom)
|
|
|
|
|
|
_bigTree = chk_tree;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (chk_tree->roi.top > a_tree->roi.bottom)
|
|
|
|
|
|
{
|
|
|
|
|
|
if ((chk_tree->roi.left < a_tree->roi.left) &&
|
|
|
|
|
|
(chk_tree->roi.right > a_tree->roi.right)) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (NULL == _bigTree)
|
|
|
|
|
|
_bigTree = chk_tree;
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (chk_tree->roi.bottom < _bigTree->roi.bottom)
|
|
|
|
|
|
_bigTree = chk_tree;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return _bigTree;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void sg_getFeatureGrowingTrees(
|
|
|
|
|
|
std::vector<SSG_lineFeature>& lineFeatures,
|
|
|
|
|
|
std::vector<SSG_featureTree>& trees,
|
|
|
|
|
|
SSG_treeGrowParam growParam)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int i = 0, i_max = lineFeatures.size(); i < i_max; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_lineFeature& a_line = lineFeatures[i];
|
|
|
|
|
|
if (a_line.features.size() > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int j = 0, j_max = a_line.features.size(); j < j_max; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_basicFeature1D& a_feature = a_line.features[j];
|
|
|
|
|
|
if (a_feature.jumpPos2D.x == 207)
|
|
|
|
|
|
int kkk = 1;
|
|
|
|
|
|
bool isMatched = _featureGrowing(a_feature, a_line.lineIdx, trees, growParam);
|
|
|
|
|
|
if (false == isMatched)
|
|
|
|
|
|
{
|
|
|
|
|
|
//<2F>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
SSG_featureTree a_newTree;
|
|
|
|
|
|
a_newTree.treeNodes.push_back(a_feature);
|
|
|
|
|
|
a_newTree.treeState = TREE_STATE_ALIVE;
|
|
|
|
|
|
a_newTree.treeType = a_feature.featureType;
|
|
|
|
|
|
a_newTree.sLineIdx = a_line.lineIdx;
|
|
|
|
|
|
a_newTree.eLineIdx = a_line.lineIdx;
|
|
|
|
|
|
trees.push_back(a_newTree);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD>١<EFBFBD>
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>Ϊ1<CEAA><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƴ<EFBFBD>
|
|
|
|
|
|
int lineIdx = a_line.lineIdx;
|
|
|
|
|
|
int m_max = trees.size();
|
|
|
|
|
|
for (int m = m_max - 1; m >= 0; m--) //<2F>Ӻ<EFBFBD><D3BA><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><D3B0>ѭ<EFBFBD><D1AD>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (TREE_STATE_ALIVE == trees[m].treeState)
|
|
|
|
|
|
{
|
|
|
|
|
|
int line_diff = abs(lineIdx - trees[m].treeNodes.back().jumpPos2D.x);
|
|
|
|
|
|
if ( ((growParam.maxLineSkipNum > 0) &&(line_diff > growParam.maxLineSkipNum)) ||
|
|
|
|
|
|
(i == i_max - 1))
|
|
|
|
|
|
{
|
|
|
|
|
|
trees[m].treeState = TREE_STATE_DEAD;
|
|
|
|
|
|
bool isValid = _invalidateVSlopeTrees(trees[m], growParam.minLTypeTreeLen, growParam.minVTypeTreeLen);
|
|
|
|
|
|
if (false == isValid)
|
|
|
|
|
|
trees.erase(trees.begin() + m);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-15 21:39:09 +08:00
|
|
|
|
void sg_lineFeaturesGrowing(
|
|
|
|
|
|
int lineIdx,
|
|
|
|
|
|
bool isLastLine,
|
|
|
|
|
|
std::vector<SSG_basicFeature1D>& features,
|
|
|
|
|
|
std::vector<SSG_featureTree>& trees,
|
|
|
|
|
|
SSG_treeGrowParam growParam)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (features.size() > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int j = 0, j_max = features.size(); j < j_max; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_basicFeature1D& a_feature = features[j];
|
|
|
|
|
|
if (a_feature.jumpPos2D.x== 207)
|
|
|
|
|
|
int kkk = 1;
|
|
|
|
|
|
bool isMatched = _featureGrowing(a_feature, lineIdx, trees, growParam);
|
|
|
|
|
|
if (false == isMatched)
|
|
|
|
|
|
{
|
|
|
|
|
|
//<2F>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
SSG_featureTree a_newTree;
|
|
|
|
|
|
a_newTree.treeNodes.push_back(a_feature);
|
|
|
|
|
|
a_newTree.treeState = TREE_STATE_ALIVE;
|
|
|
|
|
|
a_newTree.treeType = a_feature.featureType;
|
|
|
|
|
|
a_newTree.sLineIdx = lineIdx;
|
|
|
|
|
|
a_newTree.eLineIdx = lineIdx;
|
|
|
|
|
|
trees.push_back(a_newTree);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD>١<EFBFBD>
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>Ϊ1<CEAA><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƴ<EFBFBD>
|
|
|
|
|
|
int m_max = trees.size();
|
|
|
|
|
|
for (int m = m_max - 1; m >= 0; m--) //<2F>Ӻ<EFBFBD><D3BA><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><D3B0>ѭ<EFBFBD><D1AD>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (TREE_STATE_ALIVE == trees[m].treeState)
|
|
|
|
|
|
{
|
|
|
|
|
|
int line_diff = abs(lineIdx - trees[m].treeNodes.back().jumpPos2D.x);
|
|
|
|
|
|
if (((growParam.maxLineSkipNum > 0) && (line_diff > growParam.maxLineSkipNum)) ||
|
|
|
|
|
|
(true == isLastLine))
|
|
|
|
|
|
{
|
|
|
|
|
|
trees[m].treeState = TREE_STATE_DEAD;
|
|
|
|
|
|
bool isValid = _invalidateVSlopeTrees(trees[m], growParam.minLTypeTreeLen, growParam.minVTypeTreeLen);
|
|
|
|
|
|
if (false == isValid)
|
|
|
|
|
|
trees.erase(trees.begin() + m);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-08 10:46:41 +08:00
|
|
|
|
void sg_getEndingGrowingTrees(
|
|
|
|
|
|
std::vector<SSG_2DValueI>& lineEndings,
|
|
|
|
|
|
SVzNL3DLaserLine* laser3DPoints,
|
|
|
|
|
|
bool isVScan,
|
|
|
|
|
|
int featureType,
|
|
|
|
|
|
std::vector<SSG_featureTree>& trees,
|
|
|
|
|
|
SSG_treeGrowParam growParam)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int i = 0, i_max = lineEndings.size(); i < i_max; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (i == 175)
|
|
|
|
|
|
int kkk = 1;
|
|
|
|
|
|
SSG_2DValueI& an_ending = lineEndings[i];
|
|
|
|
|
|
SSG_basicFeature1D endingFeature;
|
|
|
|
|
|
endingFeature.featureType = featureType;
|
|
|
|
|
|
endingFeature.jumpPos2D.x = an_ending.x;
|
|
|
|
|
|
endingFeature.jumpPos2D.y = an_ending.y;
|
|
|
|
|
|
if(true == isVScan)
|
|
|
|
|
|
endingFeature.jumpPos = laser3DPoints[an_ending.x].p3DPosition[an_ending.y].pt3D;
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
endingFeature.jumpPos.x = laser3DPoints[an_ending.y].p3DPosition[an_ending.x].pt3D.y;
|
|
|
|
|
|
endingFeature.jumpPos.y = laser3DPoints[an_ending.y].p3DPosition[an_ending.x].pt3D.x;
|
|
|
|
|
|
endingFeature.jumpPos.z = laser3DPoints[an_ending.y].p3DPosition[an_ending.x].pt3D.z;
|
|
|
|
|
|
}
|
|
|
|
|
|
bool isMatched = _featureGrowing(endingFeature, an_ending.x, trees, growParam);
|
|
|
|
|
|
if (false == isMatched)
|
|
|
|
|
|
{
|
|
|
|
|
|
//<2F>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
SSG_featureTree a_newTree;
|
|
|
|
|
|
a_newTree.treeNodes.push_back(endingFeature);
|
|
|
|
|
|
a_newTree.treeState = TREE_STATE_ALIVE;
|
|
|
|
|
|
a_newTree.treeType = endingFeature.featureType;
|
|
|
|
|
|
a_newTree.sLineIdx = an_ending.x;
|
|
|
|
|
|
a_newTree.eLineIdx = an_ending.x;
|
|
|
|
|
|
trees.push_back(a_newTree);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD>١<EFBFBD>
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>Ϊ1<CEAA><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƴ<EFBFBD>
|
|
|
|
|
|
int lineIdx = an_ending.x;
|
|
|
|
|
|
int m_max = trees.size();
|
|
|
|
|
|
for (int m = m_max - 1; m >= 0; m--) //<2F>Ӻ<EFBFBD><D3BA><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><D3B0>ѭ<EFBFBD><D1AD>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (TREE_STATE_ALIVE == trees[m].treeState)
|
|
|
|
|
|
{
|
|
|
|
|
|
int line_diff = abs(lineIdx - trees[m].treeNodes.back().jumpPos2D.x);
|
|
|
|
|
|
if (((growParam.maxLineSkipNum > 0) && (line_diff > growParam.maxLineSkipNum)) ||
|
|
|
|
|
|
(i == i_max - 1))
|
|
|
|
|
|
{
|
|
|
|
|
|
trees[m].treeState = TREE_STATE_DEAD;
|
|
|
|
|
|
bool isValid = _invalidateVSlopeTrees(trees[m], growParam.minLTypeTreeLen, growParam.minVTypeTreeLen);
|
|
|
|
|
|
if (false == isValid)
|
|
|
|
|
|
trees.erase(trees.begin() + m);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//<2F><>ɨ<EFBFBD><C9A8><EFBFBD>ߵ<EFBFBD>V<EFBFBD><56><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
void sg_LVFeatureGrowing(
|
|
|
|
|
|
std::vector<SSG_lineFeature>& lineFeatures,
|
|
|
|
|
|
std::vector<SSG_featureTree>& trees,
|
|
|
|
|
|
SSG_bagParam bagParam,
|
|
|
|
|
|
SSG_treeGrowParam growParam,
|
|
|
|
|
|
std::vector<SSG_2DValueI>& edgePts_0,
|
|
|
|
|
|
std::vector<SSG_2DValueI>& edgePts_1)
|
|
|
|
|
|
{
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
sg_getFeatureGrowingTrees(
|
|
|
|
|
|
lineFeatures,
|
|
|
|
|
|
trees,
|
|
|
|
|
|
growParam);
|
|
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>һ<EFBFBD>Σ<EFBFBD><CEA3><EFBFBD><EFBFBD>¶<EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD>ͷβ<CDB7><CEB2><EFBFBD>飬<EFBFBD><E9A3AC><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>LINE_EDGE
|
|
|
|
|
|
for (int i = 0, i_max = trees.size(); i < i_max; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_featureTree* a_tree = &trees[i];
|
|
|
|
|
|
|
|
|
|
|
|
//Tree<65><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͳ<EFBFBD><CDB3>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD>
|
|
|
|
|
|
std::vector<int> typeStat;
|
|
|
|
|
|
typeStat.resize(LINE_FEATURE_NUM);
|
|
|
|
|
|
for (int m = 0, m_max = a_tree->treeNodes.size(); m < m_max; m++)
|
|
|
|
|
|
{
|
|
|
|
|
|
int type = a_tree->treeNodes[m].featureType;
|
|
|
|
|
|
typeStat[type]++;
|
|
|
|
|
|
}
|
|
|
|
|
|
int maxId = -1;
|
|
|
|
|
|
int maxSize = 0;
|
|
|
|
|
|
for (int m = 0; m < typeStat.size(); m++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (maxSize < typeStat[m])
|
|
|
|
|
|
{
|
|
|
|
|
|
maxId = m;
|
|
|
|
|
|
maxSize = typeStat[m];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (maxId > 0)
|
|
|
|
|
|
a_tree->treeType = maxId;
|
|
|
|
|
|
|
|
|
|
|
|
_growingFromHead(a_tree, lineFeatures, growParam);
|
|
|
|
|
|
_growingFromTail(a_tree, lineFeatures, growParam);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
///<2F><><EFBFBD><EFBFBD>
|
|
|
|
|
|
///<2F><><EFBFBD>ֹ<EFBFBD><D6B9>˷<EFBFBD><CBB7><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
///<2F><>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SLOPE<50><45>V<EFBFBD><56><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><C4B1><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
///<2F><>2<EFBFBD><32><EFBFBD><EFBFBD><EFBFBD>ۼ<EFBFBD><DBBC>飺<EFBFBD><E9A3BA><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD><CCB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<C7B7><F1B1BBB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
int tree_size = trees.size();
|
|
|
|
|
|
for (int m = tree_size - 1; m >= 0; m--) //<2F>Ӻ<EFBFBD><D3BA><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><D3B0>ѭ<EFBFBD><D1AD>
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_featureTree* a_tree = &trees[m];
|
|
|
|
|
|
_getTreeROI(a_tree);
|
|
|
|
|
|
if ((LINE_FEATURE_V_SLOPE == a_tree->treeType) ||
|
|
|
|
|
|
(LINE_FEATURE_L_SLOPE_H2L == a_tree->treeType) ||
|
|
|
|
|
|
(LINE_FEATURE_L_SLOPE_L2H == a_tree->treeType) ||
|
|
|
|
|
|
(LINE_FEATURE_CORNER_V == a_tree->treeType))
|
|
|
|
|
|
{
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>x<EFBFBD><78><EFBFBD>ij<F2A3A9B5><C4B3><EFBFBD>
|
|
|
|
|
|
double grow_len = a_tree->roi.right - a_tree->roi.left;
|
|
|
|
|
|
double grow_width = a_tree->roi.bottom - a_tree->roi.top;
|
|
|
|
|
|
if ((grow_len < bagParam.bagW / 4) && (grow_width > grow_len / 2))
|
|
|
|
|
|
{
|
|
|
|
|
|
trees.erase(trees.begin() + m);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
tree_size = trees.size();
|
|
|
|
|
|
for (int m = tree_size - 1; m >= 0; m--) //<2F>Ӻ<EFBFBD><D3BA><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><D3B0>ѭ<EFBFBD><D1AD>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (m == 24)
|
|
|
|
|
|
int kkk = 1;
|
|
|
|
|
|
SSG_featureTree* a_tree = &trees[m];
|
|
|
|
|
|
double grow_len = a_tree->roi.right - a_tree->roi.left;
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD>Ƿ<C7B7><F1B1BBB0><EFBFBD>
|
|
|
|
|
|
//ȡǰ<C8A1><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>İ<EFBFBD><C4B0><EFBFBD>a_tree<65><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
if ((grow_len < bagParam.bagW / 2) && ((LINE_FEATURE_V_SLOPE == a_tree->treeType) ||
|
|
|
|
|
|
(LINE_FEATURE_L_SLOPE_H2L == a_tree->treeType) ||
|
|
|
|
|
|
(LINE_FEATURE_L_SLOPE_L2H == a_tree->treeType) ||
|
|
|
|
|
|
(LINE_FEATURE_CORNER_V == a_tree->treeType)))
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_featureTree* up_bigTree = _getIncludingBigTree(a_tree, trees, true);
|
|
|
|
|
|
SSG_featureTree* down_bigTree = _getIncludingBigTree(a_tree, trees, false);
|
|
|
|
|
|
if ((NULL != up_bigTree) && (NULL != down_bigTree))
|
|
|
|
|
|
{
|
|
|
|
|
|
double dist = (down_bigTree->roi.top + down_bigTree->roi.bottom - up_bigTree->roi.top - up_bigTree->roi.bottom) / 2;
|
|
|
|
|
|
if (dist < bagParam.bagL * 1.3)
|
|
|
|
|
|
{
|
|
|
|
|
|
trees.erase(trees.begin() + m);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<SSG_2DValueI> edge0_pts;
|
|
|
|
|
|
std::vector<SSG_2DValueI> edge1_pts;
|
|
|
|
|
|
std::vector<double> edge0_y;
|
|
|
|
|
|
std::vector<double> edge1_y;
|
|
|
|
|
|
for (int i = 0, i_max = lineFeatures.size(); i < i_max; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_lineFeature& a_line = lineFeatures[i];
|
|
|
|
|
|
int a_line_endingNum = a_line.endings.size();
|
|
|
|
|
|
if (a_line_endingNum > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int m = 0; m < a_line_endingNum; m++)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_2DValueI an_edge = { a_line.endings[m].jumpPos2D.x, a_line.endings[m].jumpPos2D.y, a_line.endings[m].featureType, a_line.endings[m].jumpPos.z };
|
|
|
|
|
|
if (LINE_FEATURE_LINE_ENDING_0 == a_line.endings[m].featureType)
|
|
|
|
|
|
{
|
|
|
|
|
|
edge0_pts.push_back(an_edge);
|
|
|
|
|
|
edge0_y.push_back(a_line.endings[m].jumpPos.y);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(LINE_FEATURE_LINE_ENDING_1 == a_line.endings[m].featureType)
|
|
|
|
|
|
{
|
|
|
|
|
|
edge1_pts.push_back(an_edge);
|
|
|
|
|
|
edge1_y.push_back(a_line.endings[m].jumpPos.y);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#if 1
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
edgePts_0.insert(edgePts_0.end(), edge0_pts.begin(), edge0_pts.end());
|
|
|
|
|
|
edgePts_1.insert(edgePts_1.end(), edge1_pts.begin(), edge1_pts.end());
|
|
|
|
|
|
#else
|
|
|
|
|
|
//Edge<67><65><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><CBB3><EFBFBD>Ⱥ<EFBFBD>㣨<EFBFBD><E3A3A8><EFBFBD><EFBFBD>ɨ<EFBFBD><C9A8>ԭ<EFBFBD><EFBFBD><F2A3ACBF>ܻ<EFBFBD><DCBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
const double outlier_sigma_k = 5.0;//5<><35>sigma
|
|
|
|
|
|
SSG_meanVar meanVar_edge0 = _computeMeanVar(edge0_y.data(), edge0_y.size());
|
|
|
|
|
|
double edge0_dyTh = meanVar_edge0.var * outlier_sigma_k; //5<><35>sigma
|
|
|
|
|
|
for (int i = 0; i < edge0_pts.size(); i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (edge0_pts[i].x == 622)
|
|
|
|
|
|
int kkk = 1;
|
|
|
|
|
|
double yDiff = abs(edge0_y[i] - meanVar_edge0.mean);
|
|
|
|
|
|
if (yDiff < edge0_dyTh)
|
|
|
|
|
|
edgePts.push_back(edge0_pts[i]);
|
|
|
|
|
|
}
|
|
|
|
|
|
SSG_meanVar meanVar_edge1 = _computeMeanVar(edge1_y.data(), edge1_y.size());
|
|
|
|
|
|
double edge1_dyTh = meanVar_edge1.var * outlier_sigma_k; //5<><35>sigma
|
|
|
|
|
|
for (int i = 1; i < edge1_pts.size(); i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (edge1_pts[i].x == 622)
|
|
|
|
|
|
int kkk = 1;
|
|
|
|
|
|
double yDiff = abs(edge1_y[i] - meanVar_edge1.mean);
|
|
|
|
|
|
if (yDiff < edge1_dyTh)
|
|
|
|
|
|
edgePts.push_back(edge1_pts[i]);
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void sg_getPeakGrowingTrees(
|
|
|
|
|
|
std::vector<std::vector< SSG_basicFeature1D>>& peakFeatures,
|
|
|
|
|
|
std::vector<SSG_featureTree>& trees,
|
|
|
|
|
|
SSG_treeGrowParam growParam)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int i = 0, i_max = peakFeatures.size(); i < i_max; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
int lineIdx = i;
|
|
|
|
|
|
if (i == 761)
|
|
|
|
|
|
int kkk = 1;
|
|
|
|
|
|
std::vector< SSG_basicFeature1D>& a_linePeak = peakFeatures[i];
|
|
|
|
|
|
if (a_linePeak.size() > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int j = 0, j_max = a_linePeak.size(); j < j_max; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_basicFeature1D& a_feature = a_linePeak[j];
|
|
|
|
|
|
if (a_feature.jumpPos2D.x == 207)
|
|
|
|
|
|
int kkk = 1;
|
|
|
|
|
|
bool isMatched = _featureGrowing(a_feature, lineIdx, trees, growParam);
|
|
|
|
|
|
if (false == isMatched)
|
|
|
|
|
|
{
|
|
|
|
|
|
//<2F>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
SSG_featureTree a_newTree;
|
|
|
|
|
|
a_newTree.treeNodes.push_back(a_feature);
|
|
|
|
|
|
a_newTree.treeState = TREE_STATE_ALIVE;
|
|
|
|
|
|
a_newTree.treeType = a_feature.featureType;
|
|
|
|
|
|
a_newTree.sLineIdx = lineIdx;
|
|
|
|
|
|
a_newTree.eLineIdx = lineIdx;
|
|
|
|
|
|
trees.push_back(a_newTree);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD>١<EFBFBD>
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>Ϊ1<CEAA><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƴ<EFBFBD>
|
|
|
|
|
|
int m_max = trees.size();
|
|
|
|
|
|
for (int m = m_max - 1; m >= 0; m--) //<2F>Ӻ<EFBFBD><D3BA><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><D3B0>ѭ<EFBFBD><D1AD>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (TREE_STATE_ALIVE == trees[m].treeState)
|
|
|
|
|
|
{
|
|
|
|
|
|
int line_diff = abs(lineIdx - trees[m].treeNodes.back().jumpPos2D.x);
|
|
|
|
|
|
if (((growParam.maxLineSkipNum > 0) && (line_diff > growParam.maxLineSkipNum)) ||
|
|
|
|
|
|
(i == i_max - 1))
|
|
|
|
|
|
{
|
|
|
|
|
|
trees[m].treeState = TREE_STATE_DEAD;
|
|
|
|
|
|
bool isValid = _invalidateVSlopeTrees(trees[m], growParam.minLTypeTreeLen, growParam.minVTypeTreeLen);
|
|
|
|
|
|
if (false == isValid)
|
|
|
|
|
|
trees.erase(trees.begin() + m);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//<2F><>ɨ<EFBFBD><C9A8><EFBFBD>ߵ<EFBFBD>peak<61><6B><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
void sg_peakFeatureGrowing(
|
|
|
|
|
|
std::vector<std::vector< SSG_basicFeature1D>>& lineFeatures,
|
|
|
|
|
|
std::vector<SSG_featureTree>& trees,
|
|
|
|
|
|
SSG_treeGrowParam growParam)
|
|
|
|
|
|
{
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
sg_getPeakGrowingTrees(
|
|
|
|
|
|
lineFeatures,
|
|
|
|
|
|
trees,
|
|
|
|
|
|
growParam);
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0, i_max = trees.size(); i < i_max; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_featureTree* a_tree = &trees[i];
|
|
|
|
|
|
_getTreeROI(a_tree);
|
|
|
|
|
|
}
|
|
|
|
|
|
///<2F><><EFBFBD><EFBFBD>
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
void sg_fillingNullNodes(std::vector<SSG_featureTree>& trees)
|
|
|
|
|
|
{
|
|
|
|
|
|
int treeSize = trees.size();
|
|
|
|
|
|
for (int i = 0; i < treeSize; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_featureTree* a_tree = &trees[i];
|
|
|
|
|
|
int nodeSize = a_tree->treeNodes.size();
|
|
|
|
|
|
for (int j = nodeSize-2; j >= 0; j--)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_lineFeature* curr_node = &(a_tree->treeNodes[j]);
|
|
|
|
|
|
SSG_lineFeature* nxt_node = &(a_tree->treeNodes[j+1]);
|
|
|
|
|
|
int line_diff = nxt_node->jumpPos2D.x - curr_node->jumpPos2D.x;
|
|
|
|
|
|
if (line_diff > 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2025-06-11 22:14:52 +08:00
|
|
|
|
|
|
|
|
|
|
//<2F>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
bool validGrowing(
|
|
|
|
|
|
SSG_featureSemiCircle& a_feature,
|
|
|
|
|
|
SSG_semiCircleFeatureTree& a_tree,
|
|
|
|
|
|
SSG_treeGrowParam growParam)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_featureSemiCircle last_node = a_tree.treeNodes.back();
|
|
|
|
|
|
double y_diff = abs(a_feature.midPt.y - last_node.midPt.y);
|
|
|
|
|
|
int line_diff = abs(a_feature.lineIdx - last_node.lineIdx);
|
|
|
|
|
|
double x_diff = abs(a_feature.midPt.x - last_node.midPt.x);
|
|
|
|
|
|
if ((y_diff < growParam.yDeviation_max) &&
|
|
|
|
|
|
((line_diff < growParam.maxLineSkipNum) || (x_diff < growParam.maxSkipDistance)))
|
|
|
|
|
|
return true;
|
|
|
|
|
|
else
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
// <20><>feature<72><65>trees<65><73>Ѱ<EFBFBD>Һ<EFBFBD><D2BA>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD>к<EFBFBD><D0BA>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㣬 <20><><EFBFBD><EFBFBD>false
|
|
|
|
|
|
//û<><C3BB>ʹ<EFBFBD><CAB9>ȫƥ<C8AB>䡣һ<E4A1A3><D2BB>featureһ<65><D2BB><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5><EFBFBD>ϣ<EFBFBD>ƥ<EFBFBD><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɡ<EFBFBD>û<EFBFBD><C3BB>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD>䡣
|
|
|
|
|
|
int _featureGrowing_semiCircle(
|
|
|
|
|
|
SSG_featureSemiCircle& a_feature,
|
|
|
|
|
|
std::vector<SSG_semiCircleFeatureTree>&trees,
|
|
|
|
|
|
SSG_treeGrowParam growParam)
|
|
|
|
|
|
{
|
|
|
|
|
|
if ((FEATURE_FLAG_INVLD_START == a_feature.flag) || (FEATURE_FLAG_VALID_START == a_feature.flag))
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0, i_max = trees.size(); i < i_max; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_semiCircleFeatureTree& a_tree = trees[i];
|
|
|
|
|
|
if (TREE_STATE_DEAD == a_tree.treeState)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
SSG_featureSemiCircle last_node = a_tree.treeNodes.back();
|
|
|
|
|
|
if ( (last_node.lineIdx == a_feature.lineIdx)|| //xΪlineIdx<64><78>ͬһ<CDAC><D2BB>ɨ<EFBFBD><C9A8><EFBFBD><EFBFBD><EFBFBD>ϵIJ<CFB5><C4B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
(FEATURE_FLAG_INVLD_END == last_node.flag) || (FEATURE_FLAG_VALID_END == last_node.flag))
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
//<2F>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
bool vldGrowing = validGrowing(a_feature, a_tree, growParam);
|
|
|
|
|
|
if (true == vldGrowing)
|
|
|
|
|
|
return i;
|
|
|
|
|
|
}
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool _invalidateSemiCircleTrees(SSG_semiCircleFeatureTree& a_tree, double minTreeLen)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_featureSemiCircle* first_node = &(a_tree.treeNodes[0]);
|
|
|
|
|
|
SSG_featureSemiCircle* last_node = &(a_tree.treeNodes[a_tree.treeNodes.size() - 1]);
|
|
|
|
|
|
double len = sqrt(pow(first_node->midPt.x - last_node->midPt.x, 2) + pow(first_node->midPt.y - last_node->midPt.y, 2));
|
|
|
|
|
|
if (len <= minTreeLen)
|
|
|
|
|
|
return false;
|
|
|
|
|
|
else
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-08 10:46:41 +08:00
|
|
|
|
void sg_getFeatureGrowingTrees_semiCircle(
|
|
|
|
|
|
std::vector< SSG_featureSemiCircle>& lineFeatures,
|
2025-06-11 22:14:52 +08:00
|
|
|
|
const int lineIdx,
|
|
|
|
|
|
const int lineSize,
|
2025-06-08 10:46:41 +08:00
|
|
|
|
std::vector<SSG_semiCircleFeatureTree>& trees,
|
2025-06-11 22:14:52 +08:00
|
|
|
|
std::vector<SSG_semiCircleFeatureTree>& stopTrees,
|
|
|
|
|
|
std::vector<SSG_semiCircleFeatureTree>& invalidTrees,
|
2025-06-08 10:46:41 +08:00
|
|
|
|
SSG_treeGrowParam growParam)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int i = 0, i_max = lineFeatures.size(); i < i_max; i++)
|
|
|
|
|
|
{
|
2025-06-11 22:14:52 +08:00
|
|
|
|
SSG_featureSemiCircle& a_feature = lineFeatures[i];
|
|
|
|
|
|
if (FEATURE_FLAG_INVALID == a_feature.flag)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
if ( (a_feature.lineIdx >= 205) && (i == 5))
|
|
|
|
|
|
int kkk = 1;
|
|
|
|
|
|
int matchedTreeIdx = _featureGrowing_semiCircle(a_feature, trees, growParam);
|
|
|
|
|
|
if (matchedTreeIdx >= 0)
|
2025-06-08 10:46:41 +08:00
|
|
|
|
{
|
2025-06-11 22:14:52 +08:00
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5>
|
|
|
|
|
|
std::vector<int> otherMatching;
|
|
|
|
|
|
for (int j = i + 1; j < i_max; j++)
|
2025-06-08 10:46:41 +08:00
|
|
|
|
{
|
2025-06-11 22:14:52 +08:00
|
|
|
|
bool vldGrowing = validGrowing(lineFeatures[j], trees[matchedTreeIdx], growParam);
|
|
|
|
|
|
if (false == vldGrowing)
|
|
|
|
|
|
break;
|
|
|
|
|
|
otherMatching.push_back(j);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (otherMatching.size() > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
SSG_featureSemiCircle last_node = trees[matchedTreeIdx].treeNodes.back();
|
|
|
|
|
|
double minDist = abs(a_feature.midPt.y - last_node.midPt.y);
|
|
|
|
|
|
int bestMatch = i;
|
|
|
|
|
|
//ȡ<><C8A1>С<EFBFBD><D0A1>ƥ<EFBFBD><C6A5>
|
|
|
|
|
|
for (int m = 0, m_max = otherMatching.size(); m < m_max; m++)
|
2025-06-08 10:46:41 +08:00
|
|
|
|
{
|
2025-06-11 22:14:52 +08:00
|
|
|
|
int idx = otherMatching[m];
|
|
|
|
|
|
double y_diff = abs(lineFeatures[idx].midPt.y - last_node.midPt.y);
|
|
|
|
|
|
if (y_diff < minDist)
|
|
|
|
|
|
{
|
|
|
|
|
|
minDist = y_diff;
|
|
|
|
|
|
bestMatch = idx;
|
|
|
|
|
|
}
|
2025-06-08 10:46:41 +08:00
|
|
|
|
}
|
2025-06-11 22:14:52 +08:00
|
|
|
|
otherMatching.push_back(i);
|
|
|
|
|
|
for (int m = 0, m_max = otherMatching.size(); m < m_max; m++)
|
|
|
|
|
|
{
|
|
|
|
|
|
int idx = otherMatching[m];
|
|
|
|
|
|
if (bestMatch == idx)
|
|
|
|
|
|
{
|
|
|
|
|
|
trees[matchedTreeIdx].eLineIdx = lineFeatures[idx].lineIdx;
|
|
|
|
|
|
trees[matchedTreeIdx].treeNodes.push_back(lineFeatures[idx]);
|
|
|
|
|
|
}
|
|
|
|
|
|
lineFeatures[idx].flag = FEATURE_FLAG_INVALID;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
trees[matchedTreeIdx].eLineIdx = a_feature.lineIdx;
|
|
|
|
|
|
trees[matchedTreeIdx].treeNodes.push_back(a_feature);
|
2025-06-08 10:46:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-06-11 22:14:52 +08:00
|
|
|
|
else //(false == isMatched)
|
2025-06-08 10:46:41 +08:00
|
|
|
|
{
|
2025-06-11 22:14:52 +08:00
|
|
|
|
//<2F>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
SSG_semiCircleFeatureTree a_newTree;
|
|
|
|
|
|
a_newTree.treeNodes.push_back(a_feature);
|
|
|
|
|
|
a_newTree.treeState = TREE_STATE_ALIVE;
|
|
|
|
|
|
a_newTree.treeType = 0;
|
|
|
|
|
|
a_newTree.sLineIdx = a_feature.lineIdx;
|
|
|
|
|
|
a_newTree.eLineIdx = a_feature.lineIdx;
|
|
|
|
|
|
trees.push_back(a_newTree);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD>١<EFBFBD>
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>Ϊ1<CEAA><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƴ<EFBFBD>
|
|
|
|
|
|
int m_max = trees.size();
|
|
|
|
|
|
for (int m = m_max - 1; m >= 0; m--) //<2F>Ӻ<EFBFBD><D3BA><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><D3B0>ѭ<EFBFBD><D1AD>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (TREE_STATE_ALIVE == trees[m].treeState)
|
|
|
|
|
|
{
|
|
|
|
|
|
int line_diff = abs(lineIdx - trees[m].treeNodes.back().lineIdx);
|
|
|
|
|
|
if (((growParam.maxLineSkipNum > 0) && (line_diff > growParam.maxLineSkipNum)) ||
|
|
|
|
|
|
(lineIdx == lineSize-1))
|
2025-06-08 10:46:41 +08:00
|
|
|
|
{
|
2025-06-11 22:14:52 +08:00
|
|
|
|
trees[m].treeState = TREE_STATE_DEAD;
|
|
|
|
|
|
bool isValid = _invalidateSemiCircleTrees(trees[m], growParam.minVTypeTreeLen);
|
|
|
|
|
|
if (true == isValid)
|
|
|
|
|
|
stopTrees.push_back(trees[m]);
|
|
|
|
|
|
else
|
|
|
|
|
|
invalidTrees.push_back(trees[m]);
|
|
|
|
|
|
trees.erase(trees.begin() + m);
|
2025-06-08 10:46:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|