algoLib/sourceCode/SG_featureGrow.cpp

918 lines
28 KiB
C++
Raw Normal View History

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)
{
2025-07-22 22:52:57 +08:00
for (int i = 0, i_max = (int)trees.size(); i < i_max; i++)
2025-06-08 10:46:41 +08:00
{
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>
2025-07-22 22:52:57 +08:00
int size = (int)a_tree.treeNodes.size();
2025-06-08 10:46:41 +08:00
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];
2025-07-22 22:52:57 +08:00
int endingNum = (int)a_line->endings.size();
2025-06-08 10:46:41 +08:00
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];
2025-07-22 22:52:57 +08:00
int endingNum = (int)a_line->endings.size();
2025-06-08 10:46:41 +08:00
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;
2025-07-22 22:52:57 +08:00
for (int i = 1, i_max = (int)a_tree->treeNodes.size(); i < i_max; i++)
2025-06-08 10:46:41 +08:00
{
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;
2025-07-22 22:52:57 +08:00
for (int i = 0, i_max = (int)trees.size(); i < i_max; i++)
2025-06-08 10:46:41 +08:00
{
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)
{
2025-07-22 22:52:57 +08:00
for (int i = 0, i_max = (int)lineFeatures.size(); i < i_max; i++)
2025-06-08 10:46:41 +08:00
{
SSG_lineFeature& a_line = lineFeatures[i];
if (a_line.features.size() > 0)
{
2025-07-22 22:52:57 +08:00
for (int j = 0, j_max = (int)a_line.features.size(); j < j_max; j++)
2025-06-08 10:46:41 +08:00
{
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;
2025-07-22 22:52:57 +08:00
int m_max = (int)trees.size();
2025-06-08 10:46:41 +08:00
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);
}
}
}
}
}
void sg_lineFeaturesGrowing(
int lineIdx,
bool isLastLine,
std::vector<SSG_basicFeature1D>& features,
std::vector<SSG_featureTree>& trees,
SSG_treeGrowParam growParam)
{
if (features.size() > 0)
{
2025-07-22 22:52:57 +08:00
for (int j = 0, j_max = (int)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>
2025-07-22 22:52:57 +08:00
int m_max = (int)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)
{
2025-07-22 22:52:57 +08:00
for (int i = 0, i_max = (int)lineEndings.size(); i < i_max; i++)
2025-06-08 10:46:41 +08:00
{
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;
2025-07-22 22:52:57 +08:00
int m_max = (int)trees.size();
2025-06-08 10:46:41 +08:00
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
2025-07-22 22:52:57 +08:00
for (int i = 0, i_max = (int)trees.size(); i < i_max; i++)
2025-06-08 10:46:41 +08:00
{
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);
2025-07-22 22:52:57 +08:00
for (int m = 0, m_max = (int)a_tree->treeNodes.size(); m < m_max; m++)
2025-06-08 10:46:41 +08:00
{
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>
2025-07-22 22:52:57 +08:00
int tree_size = (int)trees.size();
2025-06-08 10:46:41 +08:00
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);
}
}
}
2025-07-22 22:52:57 +08:00
tree_size = (int)trees.size();
2025-06-08 10:46:41 +08:00
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;
2025-07-22 22:52:57 +08:00
for (int i = 0, i_max = (int)lineFeatures.size(); i < i_max; i++)
2025-06-08 10:46:41 +08:00
{
SSG_lineFeature& a_line = lineFeatures[i];
2025-07-22 22:52:57 +08:00
int a_line_endingNum = (int)a_line.endings.size();
2025-06-08 10:46:41 +08:00
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)
{
2025-07-22 22:52:57 +08:00
for (int i = 0, i_max = (int)peakFeatures.size(); i < i_max; i++)
2025-06-08 10:46:41 +08:00
{
int lineIdx = i;
if (i == 761)
int kkk = 1;
std::vector< SSG_basicFeature1D>& a_linePeak = peakFeatures[i];
if (a_linePeak.size() > 0)
{
2025-07-22 22:52:57 +08:00
for (int j = 0, j_max = (int)a_linePeak.size(); j < j_max; j++)
2025-06-08 10:46:41 +08:00
{
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>
2025-07-22 22:52:57 +08:00
int m_max = (int)trees.size();
2025-06-08 10:46:41 +08:00
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);
2025-07-22 22:52:57 +08:00
for (int i = 0, i_max = (int)trees.size(); i < i_max; i++)
2025-06-08 10:46:41 +08:00
{
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
//<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;
2025-07-22 22:52:57 +08:00
for (int i = 0, i_max = (int)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,
const int lineIdx,
const int lineSize,
2025-06-08 10:46:41 +08:00
std::vector<SSG_semiCircleFeatureTree>& trees,
std::vector<SSG_semiCircleFeatureTree>& stopTrees,
std::vector<SSG_semiCircleFeatureTree>& invalidTrees,
2025-06-08 10:46:41 +08:00
SSG_treeGrowParam growParam)
{
2025-07-22 22:52:57 +08:00
for (int i = 0, i_max = (int)lineFeatures.size(); i < i_max; i++)
2025-06-08 10:46:41 +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
{
//<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
{
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>
2025-07-22 22:52:57 +08:00
for (int m = 0, m_max = (int)otherMatching.size(); m < m_max; m++)
2025-06-08 10:46:41 +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
}
otherMatching.push_back(i);
2025-07-22 22:52:57 +08:00
for (int m = 0, m_max = (int)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
}
}
else //(false == isMatched)
2025-06-08 10:46:41 +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>
2025-07-22 22:52:57 +08:00
int m_max = (int)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
{
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
}
}
}
}