modifié : include/ArrayTree/ArrayTreeBuilder.hpp

modifié :         include/ArrayTree/ArrayTreeBuilder.tpp
	modifié :         include/QuadTree/QuadTreeBuilder.hpp
	modifié :         include/Tree.hpp
	modifié :         include/TreeBuilder.hpp
	modifié :         include/XMLTree/XMLTreeBuilder.hpp
	modifié :         include/triskeleDealThreads.hpp
	modifié :         src/Attributes/AreaAttribute.cpp
	modifié :         src/QuadTree/QuadTreeBuilder.cpp
	modifié :         src/Tree.cpp
	modifié :         src/XMLTree/XMLTreeBuilder.cpp
	modifié :         src/testMain.cpp
This commit is contained in:
Git Merciol 2017-11-28 04:31:40 +01:00
parent e097095f3b
commit 273f7d6647
12 changed files with 582 additions and 488 deletions

View File

@ -19,40 +19,45 @@ namespace otb {
namespace triskele {
namespace arrayTree {
template <typename WeightT>
template <typename WeightT, typename PixelT>
class ArrayTreeBuilder : public TreeBuilder {
const unsigned int coreCount;
const IImage<PixelT> &image;
const GraphWalker &graphWalker;
TreeType type;
bool countingFlag;
Leader leaders;
DimNodeId *childCountRec;
DimImg *newCompIdx;
WeightT *compWeights; // [leafCount]
public:
inline ArrayTreeBuilder (IImage &imgInt, const TreeType &treeType, const bool &countingSort = true) :
image(imgInt),
type(treeType),
countingFlag(countingSort) {}
ArrayTreeBuilder (const unsigned int &coreCount,
IImage<PixelT> &image, const GraphWalker &graphWalker,
const TreeType &treeType, const bool &countingSort = true);
~ArrayTreeBuilder () {}
inline void
buildTree(Tree &tree);
buildTree (Tree &tree);
private:
template<typename WeightFunct>
inline void
setTiles (const Size &size, const unsigned int &coreCount, const Rect &tile,
std::vector<Rect> &tiles, std::vector<Rect> &boundaries, std::vector<bool> &verticalBoundaries);
buildTree (Tree &tree, const WeightFunct &weightFunct);
template<typename WeightFunct>
inline void
buildTree (Tree &tree, const GraphWalker &graphWalker, const WeightFunct &weightFunct, const bool &countingSortFlag);
fillAPTree (PixelT *leafAPTree, const WeightFunct &weightFunct);
template<typename WeightFunct>
inline void
buildTree (Edge<WeightT> *edges, const GraphWalker &graphWalker, const WeightFunct &weightFunct,
const Rect &tile, DimImg &topParent, const bool &countingSortFlag);
buildTree (Edge<WeightT> *edges, const WeightFunct &weightFunct, const Rect &tile, DimImg &topParent);
template<typename WeightFunct>
inline void
createAttributsProfile (const WeightFunct &weightFunct);
template<typename WeightFunct>
inline void
connectLeaf (Tree &tree, DimImg a, DimImg b, const WeightT &weight, DimImg &parCount, const WeightFunct &weightFunct);
connectLeaf (DimImg a, DimImg b, const WeightT &weight, DimImg &parCount, const WeightFunct &weightFunct);
template<typename WeightFunct>
inline void
@ -64,21 +69,29 @@ namespace otb {
template<typename WeightFunct>
inline DimImg
updateNewIdx (const std::vector<DimImg> &compBases, const std::vector<DimImg> &compTops, const WeightFunct &weightFunct);
updateNewIdx (const vector<DimImg> &compBases, const vector<DimImg> &compTops, const WeightFunct &weightFunct);
inline void
updateNewIdx (Tree &tree, const DimImg curComp, DimImg &compCount);
updateNewIdx (const DimImg curComp, DimImg &compCount);
template<typename WeightFunct>
inline void
compress(const GraphWalker &graphWalker, const Rect &tile,
const DimImg &compBase, const DimImg &compTop,
const WeightFunct &weightFunct);
compress (const DimImg &compTop);
inline void
createParent (DimImg &topParent, const WeightT &weight, DimImg &childA, DimImg &childB);
inline void
addChild (const DimImg &parent, DimImg &child);
inline void
addChildren (const DimImg &parent, const DimImg &sibling);
inline DimImg
findRoot (DimImg comp);
template<typename WeightFunct>
inline DimImg
findTopComp (Tree &tree, const DimImg &comp, const WeightFunct &weightFunct);
findTopComp (const DimImg &comp, const WeightFunct &weightFunct);
template<typename WeightFunct>
inline DimImg
@ -87,43 +100,23 @@ namespace otb {
inline DimImg
findCompMultiChild (DimImg comp);
inline DimImg
createComp(Tree &tree, const DimImg &leadPixel, const WeightT &weight, DimImg &compTop, const DimNodeId &childCount);
inline void
linkParent (Tree &tree, const DimImg &pixel, const DimImg &parent);
inline void
buildChildren (Tree &tree);
buildChildren ();
template<typename WeightFunct>
inline void
initWeights (Tree &tree, const GraphWalker &graphWalker, const WeightFunct &weightFunct);
initWeights (const GraphWalker &graphWalker, const WeightFunct &weightFunct);
private:
IImage &image;
DimNodeId *childCountRec;
DimNodeId nodeCapacity;
WeightT *compWeights; // [leafCount]
void *leafAP; // [nodeCapacity]
DimImg *newCompIdx;
ParRnk parRnk;
uint32_t *pixels;
TreeType type;
bool countingFlag;
#ifdef SMART_LOG
inline void
printTree (const Size &size, const bool &rec);
inline void
printLeaders (const Size &size);
inline void
printNewCompIdx (const Size &size);
#endif
};
#include "ArrayTreeBuilder.tpp"
} // arrayTree

View File

@ -1,199 +1,170 @@
#ifndef _OTB_TRISKELE_ARRAY_TREE_BUILDER_TPP
#define _OTB_TRISKELE_ARRAY_TREE_BUILDER_TPP
template<typename WeightT>
inline void
ArrayTreeBuilder<WeightT>::buildTree(Tree &tree) {
switch(type) {
case MIN:
break;
case MAX:
break;
case TOS:
break;
}
template<typename WeightT, typename PixelT>
ArrayTreeBuilder<WeightT, PixelT>::ArrayTreeBuilder (const unsigned int &coreCount,
IImage<PixelT> &image, const GraphWalker &graphWalker,
const TreeType &treeType, const bool &countingSort) :
coreCount (coreCount),
image (image),
graphWalker (graphWalker),
type (treeType),
countingFlag (countingSort)
{
}
template<typename WeightT>
template<typename WeightFunct>
template<typename WeightT, typename PixelT>
inline void
ArrayTreeBuilder<WeightT>::buildTree(Tree &tree, const GraphWalker &graphWalker, const WeightFunct &weightFunct, const bool &countingSortFlag) {
DEF_LOG ("ArrayTreeBuilder::buildTree", " counting:" << countingSortFlag << " vertexCount:" << graphWalker.vertexMaxCount () <<
" countEdge:" << graphWalker.edgeMaxCount ());
BOOST_ASSERT (newCompIdx == NULL);
// XXX
unsigned int coreCount = 1;
tree.resize(graphWalker.vertexMaxCount());
updateAttributes(tree);
compWeights = new WeightT[tree.getLeafCount()];
childCountRec = childCount + 2;
BOOST_ASSERT (tree.getLeafCount() == graphWalker.vertexMaxCount ());
LOG ("leafCount:" << tree.getLeafCount());
if (!tree.getLeafCount())
ArrayTreeBuilder<WeightT, PixelT>::buildTree (Tree &tree) {
tree.resize (graphWalker.vertexMaxCount ());
updateAttributes ();
if (!leafCount)
return;
parRnk.book (tree.getLeafCount());
newCompIdx = parRnk.getParent ();
std::vector<Edge<WeightT> > allEdges (graphWalker.edgeMaxCount ());
initWeights (graphWalker, weightFunct);
compWeights = new WeightT[tree.getLeafCount()];
childCountRec = childCount + 2;
leaders.book (leafCount);
// XXX dealThreadFill_n leaders
newCompIdx = leaders.getLeaders ();
std::vector<Rect> tiles;
std::vector<Rect> boundaries;
std::vector<bool> verticalBoundaries;
switch (type) {
case MIN:
buildTree<Edge<WeightT> > (tree, MinWeight<PixelT, WeightT> (image.getPixels (), image.getSize ()));
break;
case MAX:
buildTree<Edge<WeightT> > (tree, MaxWeight<PixelT, WeightT> (image.getPixels (), image.getSize ()));
break;
case TOS:
buildTree<Edge<WeightT> > (tree, MedianWeight<PixelT, WeightT> (image.getPixels (), graphWalker));
break;
// XXX msg
}
newCompIdx = NULL;
leaders.free ();
if (compWeights)
delete [] compWeights;
compWeights = nullptr;
}
template<typename WeightT, typename PixelT>
template<typename WeightFunct>
inline void
ArrayTreeBuilder<WeightT, PixelT>::buildTree (Tree &tree, const WeightFunct &weightFunct) {
initWeights (graphWalker, weightFunct);
vector<Edge<WeightT> > allEdges (graphWalker.edgeMaxCount ());
vector<Rect> tiles;
vector<Rect> boundaries;
vector<bool> verticalBoundaries;
const Size &size (graphWalker.size);
graphWalker.setTiles (coreCount, Rect (Point(), size), tiles, boundaries, verticalBoundaries);
graphWalker.setTiles (coreCount, Rect (NullPoint, size), tiles, boundaries, verticalBoundaries);
unsigned int tileCount = tiles.size ();
unsigned int boundCount = boundaries.size ();
#ifdef SMART_LOG
std::cout << "tile / bound" << std::endl;
for (unsigned int i = 0; i < tileCount; ++i)
std::cout << i << " tile: " << tiles [i] << std::endl;
for (unsigned int i = 0; i < boundCount; ++i)
std::cout << i << " bound: " << boundaries [i] << " " << (verticalBoundaries [i] ? "Vertical" : "Horizontal") << std::endl;
#endif
std::vector<Edge<WeightT> *> tileEdges (tileCount);
std::vector<DimImg> compBases (tileCount);
std::vector<DimImg> compTops (tileCount);
vector<Edge<WeightT> *> tileEdges (tileCount);
vector<DimImg> compBases (tileCount);
vector<DimImg> compTops (tileCount);
DimImg compBase = 0;
Edge<WeightT> *edgeBase = &allEdges[0];
for (unsigned int i = 0; i < tileCount; ++i) {
tileEdges [i] = edgeBase;
Size zoneSize (tiles[i].width, tiles[i].height);
edgeBase += graphWalker.edgeMaxCount (zoneSize);
compBases [i] = compBase;
compTops [i] = compBase;
compBase += graphWalker.vertexMaxCount (zoneSize); /* -1, but prety LOG */
}
#ifdef SMART_LOG
std::cout << "base / top" << std::endl;
for (unsigned int i = 0; i < tileCount; ++i)
std::cout << i << " base: " << compBases [i] << " top: " << compTops [i] << std::endl;
#endif
dealThreadRange (tileCount, coreCount, [this, &tileEdges, &graphWalker, &weightFunct, &tiles, &compTops, &countingSortFlag] (DimImg threadId) {
buildTree (tileEdges [threadId], graphWalker, weightFunct, tiles [threadId], compTops [threadId], countingSortFlag);
});
#ifdef SMART_LOG
std::cout << "base / top" << std::endl;
for (unsigned int i = 0; i < tileCount; ++i)
std::cout << i << " base: " << compBases [i] << " top: " << compTops [i] << std::endl;
std::cout << "build tiles" << std::endl;
//printParRnk (size);
//printTree (size, true);
#endif
dealThreadRange (tileCount, coreCount, [this, &tileEdges, &weightFunct, &tiles, &compTops] (DimImg threadId) {
buildTree (tileEdges [threadId], weightFunct, tiles [threadId], compTops [threadId]);
});
DimImg compCount = compTops [0];
DimImg *topC = NULL;
if (boundCount) {
std::vector<Edge<WeightT> *> edgeBounds (boundCount);
std::vector<DimImg> edgeCounts (boundCount);
vector<Edge<WeightT> *> edgeBounds (boundCount);
vector<DimImg> edgeCounts (boundCount);
Edge<WeightT> *allBoundEdges = edgeBase;
for (unsigned int i = 0; i < boundCount; ++i) {
edgeBounds [i] = edgeBase;
DimImg borderDim = verticalBoundaries [i] ? boundaries[i].height : boundaries[i].width;
edgeBase += graphWalker.edgeBoundaryMaxCount (borderDim);
}
#ifdef SMART_LOG
std::cout << "boundBase" << std::endl;
for (unsigned int i = 0; i < boundCount; ++i) {
DimImg borderDim = verticalBoundaries [i] ? boundaries[i].height : boundaries[i].width;
std::cout << i << " borderDim: " << borderDim
<< " edgeCount:" << graphWalker.edgeBoundaryMaxCount (borderDim)
<< " bound: " << boundaries [i] << " " << (verticalBoundaries [i] ? "Vertical" : "Horizontal") << std::endl;
}
#endif
dealThreadRange (boundCount, coreCount, [&edgeCounts, &graphWalker, &boundaries, &verticalBoundaries, &edgeBounds, &weightFunct] (DimImg id) {
dealThreadRange (boundCount, coreCount, [this, &edgeCounts, &boundaries, &verticalBoundaries, &edgeBounds, &weightFunct] (DimImg id) {
edgeCounts [id] = graphWalker.getSortedEdges (boundaries [id], verticalBoundaries [id] ?
Vertical : Horizontal, edgeBounds [id], weightFunct);
});
LOG ("edgeBounds: " << edgeBase-allBoundEdges);
#ifdef SMART_LOG
std::cout << "boundaries link list:" << std::endl;
for (int i = 0; i < edgeCounts.size (); ++i)
printEdges (std::cout, edgeBounds[i], size, edgeCounts [i]) << std::endl;
#endif
unsigned int rangeIdx = 0;
DimImg maxC = 0;
utils::callOnSortedSets<DimImg, WeightT> (edgeCounts,
[&edgeBounds] (const DimImg &vectId, const DimImg &itemId) {
return edgeBounds [vectId][itemId].weight;
},
weightFunct.isWeightInf,
[this, &tree, &edgeBounds, &topC, &maxC, &rangeIdx, &tileCount, &compBases, &compBase, &compTops, &size, &weightFunct] (const DimImg &vectId, const DimImg &itemId) {
Edge<WeightT> *edge = &edgeBounds [vectId][itemId];
if (topC == NULL || *topC >= maxC)
for ( ; rangeIdx < tileCount; ++rangeIdx) {
maxC = rangeIdx == tileCount-1 ? tree.getLeafCount() : compBases[rangeIdx+1];
if (compTops[rangeIdx] < maxC) {
compBase = compTops[rangeIdx];
compBases.push_back (compBase);
compTops.push_back (compBase);
topC = &compTops[compTops.size ()-1];
break;
}
}
connectLeaf (point2idx (size, edge->points[0]), point2idx (size, edge->points[1]), edge->weight, *topC, weightFunct);
});
callOnSortedSets<DimImg, WeightT> (edgeCounts,
[&edgeBounds] (const DimImg &vectId, const DimImg &itemId) {
return edgeBounds [vectId][itemId].weight;
},
weightFunct.isWeightInf,
[this, &edgeBounds, &topC, &maxC, &rangeIdx, &tileCount, &compBases, &compBase, &compTops, &size, &weightFunct] (const DimImg &vectId, const DimImg &itemId) {
Edge<WeightT> *edge = &edgeBounds [vectId][itemId];
if (topC == NULL || *topC >= maxC)
for ( ; rangeIdx < tileCount; ++rangeIdx) {
maxC = rangeIdx == tileCount-1 ? leafCount : compBases[rangeIdx+1];
if (compTops[rangeIdx] < maxC) {
compBase = compTops[rangeIdx];
compBases.push_back (compBase);
compTops.push_back (compBase);
topC = &compTops[compTops.size ()-1];
break;
}
}
connectLeaf (point2idx (size, edge->points[0]), point2idx (size, edge->points[1]), edge->weight, *topC, weightFunct);
});
}
#ifdef SMART_LOG
std::cout << "link tiles" << std::endl;
//printTree (size, true);
#endif
DimImg maxUsed = std::max(compTops[tileCount-1], topC != NULL ? *topC : 0);
std::fill_n (newCompIdx, maxUsed, DimImg_MAX);
#ifdef SMART_LOG
std::cout << "reuse parent" << std::endl;
//printNewCompIdx (size);
#endif
DimImg maxUsed = max (compTops[tileCount-1], topC != NULL ? *topC : 0);
dealThreadFill_n (maxUsed, coreCount, newCompIdx, DimImg_MAX);
compCount = updateNewIdx (compBases, compTops, weightFunct);
#ifdef SMART_LOG
std::cout << "newIndex" << std::endl;
//printNewCompIdx (size);
#endif
compress (graphWalker, Rect (Point(), size), 0, maxUsed, weightFunct);
#ifdef SMART_LOG
std::cout << "compressesed" << std::endl;
//printNewCompIdx (size);
//printTree (size, true);
#endif
compress (maxUsed);
newCompIdx = NULL;
parRnk.free ();
leaders.free ();
tree.setNodeCount(tree.getLeafCount() + compCount);
LOG ("nodeCount:" << tree.getNodeCount());
// XXX tree.setNode
nodeCount = leafCount+compCount;
LOG ("nodeCount:" << nodeCount);
DimEdge root = compCount-1;
compParents[root] = root;
buildChildren();
//createAttributsProfile (weightFunct);
#ifdef SMART_LOG
std::cout << "countRec children" << std::endl;
//printMap (std::cout, childCount, size) << std::endl;
Size doubleSize (size.width, 2*size.height);
//printMap (std::cout, children, doubleSize) << std::endl;
std::cout << "leafAP" << std::endl;
//printMap (std::cout, ((const WeightT *) leafAP), doubleSize) << std::endl;
#endif
delete[] compWeights;
buildChildren ();
}
// ========================================
template<typename WeightT>
template<typename WeightT, typename PixelT>
template<typename WeightFunct>
inline void
ArrayTreeBuilder<WeightT>::buildTree(Edge<WeightT> *edges, const GraphWalker &graphWalker, const WeightFunct &weightFunct,
const Rect &tile, DimImg &topParent, const bool &countingSortFlag) {
ArrayTreeBuilder<WeightT, PixelT>::fillAPTree (PixelT *leafAPTree, const WeightFunct &weightFunct) {
DEF_LOG ("ArrayTreeBuilder::fillLeafAPTree", "");
dealThreadBound (leafCount, coreCount, [&weightFunct, &leafAPTree] (const DimImg &minVal, const DimImg &maxVal) {
weightFunct.copyPixelsBound (leafAPTree, minVal, maxVal);
});
PixelT *compAPTree = leafAPTree+leafCount;
dealThreadBound (getCompCount (), coreCount, [this, &weightFunct, &compAPTree] (const DimImg &minVal, const DimImg &maxVal) {
weightFunct.weight2valueBound (compAPTree, compWeights, minVal, maxVal);
});
}
// ========================================
template<typename WeightT, typename PixelT>
template<typename WeightFunct>
inline void
ArrayTreeBuilder<WeightT, PixelT>::buildTree (Edge<WeightT> *edges, const WeightFunct &weightFunct,
const Rect &tile, DimImg &topParent) {
#ifdef SMART_LOG
DEF_LOG ("ArrayTreeBuilder::buildTree", " tile:" << tile << " topParent:" << topParent << " counting:" << countingSortFlag);
#endif
DimEdge edgeCount = (sizeof (WeightT) < 3 || countingSortFlag) ?
graphWalker.getCountingSortedEdges<WeightT, WeightFunct> (tile, Surface, edges, weightFunct) :
graphWalker.getSortedEdges (tile, Surface, edges, weightFunct);
@ -201,84 +172,166 @@ ArrayTreeBuilder<WeightT>::buildTree(Edge<WeightT> *edges, const GraphWalker &gr
const Size &size = graphWalker.size;
for (DimEdge edgeIdx = 0; edgeIdx < edgeCount; ++edgeIdx) {
Edge<WeightT> &curEdge = edges[edgeIdx];
DimImg la = point2idx (size, curEdge.points[0]);
DimImg lb = point2idx (size, curEdge.points[1]);
DimImg ra = parRnk.findUpdateParent (la);
DimImg rb = parRnk.findUpdateParent (lb);
DimImg pa = point2idx (size, curEdge.points[0]);
DimImg pb = point2idx (size, curEdge.points[1]);
DimImg la = leaders.find (pa);
DimImg lb = leaders.find (pb);
DimImg ra = leafParents [la];
DimImg rb = leafParents [lb];
BOOST_ASSERT (pa < leafCount);
BOOST_ASSERT (pb < leafCount);
BOOST_ASSERT (la < leafCount);
BOOST_ASSERT (lb < leafCount);
BOOST_ASSERT (ra < leafCount || ra == DimImg_MAX);
BOOST_ASSERT (rb < leafCount || rb == DimImg_MAX);
// BOOST_ASSERT (ra == DimImg_MAX || compParents [ra] == DimImg_MAX);
// BOOST_ASSERT (rb == DimImg_MAX || compParents [rb] == DimImg_MAX);
#ifdef SMART_LOG
LOG (" w:" << curEdge.weight << " la:" << la << " lb:" << lb << " ra:" << ra << " rb:" << rb);
LOG (" w:" << curEdge.weight << " pa:" << pa << " pb:" << pb << " la:" << la << " lb:" << lb << " ra:" << ra << " rb:" << rb);
#endif
if (ra == rb)
if (la == lb)
continue;
WeightT wa = leafParents[ra] != DimImg_MAX ? compWeights [leafParents[ra]] : weightFunct.getWeight (ra);
WeightT wb = leafParents[rb] != DimImg_MAX ? compWeights [leafParents[rb]] : weightFunct.getWeight (rb);
if (weightFunct.isWeightInf (wa, wb))
std::swap (ra, rb);
DimImg newLead = parRnk.linkParent (ra, rb, wa == wb, la, lb);
// ALPHA et TOS: ef.get (leadPixel) = curEdge.weight pour MAX et? pour MIN
DimImg parent = createComp (newLead, curEdge.weight, topParent, (DimNodeId) parRnk.getCount (newLead));
if (ra == DimImg_MAX) {
swap (la, lb);
swap (ra, rb);
}
DimImg leader = DimImg_MAX;
if (ra == DimImg_MAX) {
// ra = rb = DimImg_MAX
createParent (topParent, curEdge.weight, leafParents [la], leafParents [lb]);
if (weightFunct.isWeightInf (weightFunct.getWeight(la), weightFunct.getWeight(lb)))
swap (la, lb);
leader = la;
} else if (rb == DimImg_MAX) {
if (curEdge.weight == compWeights[ra]) {
// rb.weight <= curEdge.weight = ra.weight
addChild (ra, leafParents [lb]);
leader = la;
} else {
// ra.weight < curEdge.weight = rb.weight
createParent (topParent, curEdge.weight, compParents [ra], leafParents [lb]);
leader = lb;
}
} else if (ra == rb) {
// XXX
BOOST_ASSERT (false);
leader = lb;
} else if (compWeights[ra] == compWeights [rb]) {
// ra.weight = rb.weight // XXX ?= curEdge.weight
if (childCountRec [ra] < childCountRec [rb]) {
swap (la, lb);
swap (ra, rb);
}
addChildren (ra, rb);
leader = la;
} else {
if (weightFunct.isWeightInf (compWeights[ra], compWeights[rb])) {
swap (la, lb);
swap (ra, rb);
}
leader = la;
if (compWeights[ra] == curEdge.weight)
// rb.weight <= ra.weight = curEdge.weight
addChild (ra, compParents [rb]);
else
// ra.weight & rb.weight < curEdge.weight
createParent (topParent, curEdge.weight, compParents [ra], compParents [rb]);
}
BOOST_ASSERT (leader != DimImg_MAX);
leaders.link (pa, leader);
leaders.link (pb, leader);
#ifdef SMART_LOG
LOG (" newLead:" << newLead << " p:" << parent << " c:" << parRnk.getCount (newLead));
LOG (" leader:" << leader << " w:" << compWeights [leader] << " c:" << childCountRec [leader]);
#endif
if (ra != newLead)
linkParent (ra, parent);
if (rb != newLead)
linkParent (rb, parent);
}
#ifdef SMART_LOG
LOG ("topParent:" << topParent);
#endif
}
// ========================================
template<typename WeightT>
template<typename WeightT, typename PixelT>
template<typename WeightFunct>
inline void
ArrayTreeBuilder<WeightT>::connectLeaf (Tree &tree, DimImg a, DimImg b, const WeightT &weight, DimImg &parCount, const WeightFunct &weightFunct) {
ArrayTreeBuilder<WeightT, PixelT>::connectLeaf (DimImg a, DimImg b, const WeightT &weight, DimImg &parCount, const WeightFunct &weightFunct) {
#ifdef SMART_LOG
DEF_LOG ("ArrayTreeBuilder::connectLeaf", "a:" << a << " b:" << b << " weight:" << weight);
#endif
BOOST_ASSERT (a < tree.getLeafCount());
BOOST_ASSERT (b < tree.getLeafCount());
BOOST_ASSERT (leafParents[a] < tree.getLeafCount());
BOOST_ASSERT (leafParents[a] < tree.getLeafCount());
// XXX si mauvaise bordure il peu ne pas y avoir de parent pour A ou B
BOOST_ASSERT (a < leafCount);
BOOST_ASSERT (b < leafCount);
BOOST_ASSERT (leafParents[a] < leafCount || leafParents[a] == DimImg_MAX);
BOOST_ASSERT (leafParents[b] < leafCount || leafParents[b] == DimImg_MAX);
DimImg parA = findTopComp (leafParents[a], weightFunct);
DimImg parB = findTopComp (leafParents[b], weightFunct);
BOOST_ASSERT (parA < tree.getLeafCount());
BOOST_ASSERT (parB < tree.getLeafCount());
if (parA == DimImg_MAX) {
swap (a, b);
swap (parA, parB);
}
if (parB == DimImg_MAX) {
// parA = parB = DimImg_MAX
createParent (parCount, weight, leafParents [a], leafParents [b]);
return;
}
if (parA == DimImg_MAX) {
// parA = DimImg_MAX & parB != DimImg_MAX
parB = findTopComp (parB, weight, weightFunct);
if (!weightFunct.isWeightInf (compWeights[parB], weight)) {
leafParents[a] = parB;
++childCountRec[parB];
return;
}
parA = findTopComp (compParents[parB], weightFunct);
if (parA == DimImg_MAX) {
createParent (parCount, weight, leafParents [a], compParents [parB]);
return;
}
createParent (parCount, weight, leafParents [a], compParents [parB]);
compParents[leafParents [a]] = parA;
return;
}
BOOST_ASSERT (parA < leafCount);
BOOST_ASSERT (parB < leafCount);
if (parA == parB)
return;
if (weightFunct.isWeightInf (compWeights[parA], compWeights[parB])) {
std::swap(a, b);
std::swap(parA, parB);
swap (a, b);
swap (parA, parB);
}
if (weightFunct.isWeightInf (weight, compWeights[parB])) {
// 1
BOOST_ASSERT (weightFunct.isWeightInf (weight, compWeights[parA]));
--childCountRec[parA];
--childCountRec[parB];
--childCountRec [parA];
--childCountRec [parB];
#ifdef SMART_LOG
LOG ("connect leaf a:" << a << " b:" << b << " np:" << parCount << " (2)");
#endif
DimImg newParent = leafParents[b] = leafParents[a] = parCount++;
compWeights[newParent] = weight;
childCountRec[newParent] = 2;
connectComp (newParent, parA, parB, weightFunct);
// XXX newParent = leafParents[a] => return ?
createParent (parCount, weight, leafParents [a], leafParents [b]);
connectComp (leafParents [a], parA, parB, weightFunct);
return;
}
if (weightFunct.isWeightInf (weight, compWeights[parA])) {
// 2
--childCountRec [parA];
parB = findTopComp (parB, weight, weightFunct);
BOOST_ASSERT (parB < tree.getLeafCount());
BOOST_ASSERT (parB < leafCount);
if (weight == compWeights[parB]) {
// 2a
++childCountRec[parB];
leafParents[a] = parB;
#ifdef SMART_LOG
LOG ("connect leaf a:" << a << " p:" << parB << " (" << childCountRec[parB] << ")");
#endif
connectComp (parA, parB, weightFunct);
return;
}
@ -286,21 +339,22 @@ ArrayTreeBuilder<WeightT>::connectLeaf (Tree &tree, DimImg a, DimImg b, const We
BOOST_ASSERT (weightFunct.isWeightInf (compWeights[parB], weight));
DimImg grandParB = findTopComp (compParents[parB], weightFunct);
--childCountRec [grandParB];
#ifdef SMART_LOG
LOG ("connect leaf a:" << a << " pb:" << parB << " np:" << parCount << " (2)");
#endif
DimImg newParent = leafParents[a] = compParents[parB] = parCount++;
compWeights[newParent] = weight;
childCountRec[newParent] = 2;
connectComp (newParent, grandParB, parA, weightFunct);
// XXX newParent = leafParents[a] => return ?
createParent (parCount, weight, leafParents [a], compParents [parB]);
connectComp (leafParents [a], grandParB, parA, weightFunct);
return;
}
parA = findTopComp (parA, weight, weightFunct);
parB = findTopComp (parB, weight, weightFunct);
BOOST_ASSERT (parA < tree.getLeafCount());
BOOST_ASSERT (parB < tree.getLeafCount());
BOOST_ASSERT (parA < leafCount);
BOOST_ASSERT (parB < leafCount);
if (weightFunct.isWeightInf (compWeights[parA], compWeights[parB]))
std::swap(parA, parB);
swap (parA, parB);
if (weightFunct.isWeightInf (compWeights[parA], weight)) {
// 3
BOOST_ASSERT (!weightFunct.isWeightInf (weight, compWeights[parA]));
@ -312,13 +366,14 @@ ArrayTreeBuilder<WeightT>::connectLeaf (Tree &tree, DimImg a, DimImg b, const We
--childCountRec [grandParA];
if (grandParB != DimImg_MAX)
--childCountRec [grandParB];
#ifdef SMART_LOG
LOG ("connect leaf pa:" << parA << " pb:" << parB << " np:" << parCount << " (2)");
#endif
DimImg newParent = compParents[parA] = compParents[parB] = parCount++;
compWeights[newParent] = weight;
childCountRec[newParent] = 2;
connectComp (newParent, grandParA, grandParB, weightFunct);
// XXX newParent = compParents [parA] => return ?
createParent (parCount, weight, compParents [parA], compParents [parB]);
connectComp (compParents [parA], grandParA, grandParB, weightFunct);
return;
}
// 4
@ -326,57 +381,65 @@ ArrayTreeBuilder<WeightT>::connectLeaf (Tree &tree, DimImg a, DimImg b, const We
}
// ----------------------------------------
template<typename WeightT>
template<typename WeightT, PixelT>
template<typename WeightFunct>
inline void
ArrayTreeBuilder<WeightT>::connectComp (DimImg newComp, DimImg topA, DimImg topB, const WeightFunct &weightFunct) {
ArrayTreeBuilder<WeightT, PixelT>::connectComp (DimImg newComp, DimImg topA, DimImg topB, const WeightFunct &weightFunct) {
#ifdef SMART_LOG
DEF_LOG ("ArrayTreeBuilder::connectComp", "newComp:" << newComp << " topA:" << topA << " topB:" << topB);
#endif
if (topB == DimImg_MAX)
std::swap(topA, topB);
swap (topA, topB);
BOOST_ASSERT (topB != DimImg_MAX);
if (topA != DimImg_MAX && weightFunct.isWeightInf (compWeights[topA], compWeights[topB]))
std::swap(topA, topB);
swap (topA, topB);
BOOST_ASSERT (findTopComp (topB, weightFunct) == topB);
compParents[newComp] = topB;
++childCountRec[topB];
#ifdef SMART_LOG
LOG ("connect comp nc:" << newComp << " tb:" << topB << " (" << childCountRec[topB] << ")");
#endif
connectComp (topA, topB, weightFunct);
}
// ----------------------------------------
template<typename WeightT>
template<typename WeightT, typename PixelT>
template<typename WeightFunct>
inline void
ArrayTreeBuilder<WeightT>::connectComp (DimImg topA, DimImg topB, const WeightFunct &weightFunct) {
ArrayTreeBuilder<WeightT, PixelT>::connectComp (DimImg topA, DimImg topB, const WeightFunct &weightFunct) {
#ifdef SMART_LOG
DEF_LOG ("ArrayTreeBuilder::connectComp", "topA:" << topA << " topB:" << topB);
#endif
for (;;) {
if (topA == DimImg_MAX || topB == DimImg_MAX)
return;
BOOST_ASSERT (findTopComp (topA, weightFunct) == topA);
BOOST_ASSERT (findTopComp (topB, weightFunct) == topB);
if (weightFunct.isWeightInf (compWeights[topA], compWeights[topB]))
std::swap(topA, topB);
swap (topA, topB);
topB = findTopComp (topB, compWeights[topA], weightFunct);
if (topA == topB)
return;
if (compWeights[topA] == compWeights[topB]) {
if (childCountRec[topA] < childCountRec[topB])
std::swap (topA, topB);
swap (topA, topB);
DimImg parB = findTopComp (compParents[topB], weightFunct);
if (parB != DimImg_MAX)
--childCountRec[parB];
childCountRec [topA] += childCountRec[topB];
childCountRec[topB] = 0;
compParents[topB] = topA;
#ifdef SMART_LOG
LOG ("connect comp topB:" << topB << " topA:" << topA << " (" << childCountRec [topA] << ")");
#endif
topB = topA;
topA = findTopComp (parB, compWeights[topA], weightFunct);
continue;
@ -384,9 +447,11 @@ ArrayTreeBuilder<WeightT>::connectComp (DimImg topA, DimImg topB, const WeightFu
DimImg parB = findTopComp (compParents[topB], weightFunct);
++childCountRec[topA];
compParents[topB] = topA;
#ifdef SMART_LOG
LOG ("connect comp topB:" << topB << " topA:" << topA << " (" << childCountRec [topA] << ")");
#endif
if (parB == DimImg_MAX)
return;
--childCountRec[parB];
@ -396,9 +461,30 @@ ArrayTreeBuilder<WeightT>::connectComp (DimImg topA, DimImg topB, const WeightFu
}
// ----------------------------------------
template<typename WeightT>
template<typename WeightT, typename PixelT>
template<typename WeightFunct>
inline DimImg
ArrayTreeBuilder<WeightT, PixelT>::updateNewIdx (const vector<DimImg> &compBases, const vector<DimImg> &compTops,
const WeightFunct &weightFunct) {
// DEF_LOG ("ArrayTreeBuilder::updateNewIdx", "");
DimImg compCount = compBases[0];
vector<DimImg> sizes (compBases.size ());
for (DimImg i = 0; i < sizes.size (); ++i)
sizes [i] = compTops [i] - compBases [i];
// XXX non parallèle
callOnSortedSets<DimImg, WeightT> (sizes,
[this, &compBases] (const DimImg &vectId, const DimImg &itemId) {
return compWeights[compBases[vectId]+itemId]; },
weightFunct.isWeightInf,
[this, &compBases, &compCount] (const DimImg &vectId, const DimImg &itemId) {
updateNewIdx (compBases[vectId]+itemId, compCount); });
return compCount;
}
// ----------------------------------------
template<typename WeightT, PixelT>
inline void
ArrayTreeBuilder<WeightT>::updateNewIdx (Tree &tree, const DimImg curComp, DimImg &compCount) {
ArrayTreeBuilder<WeightT, PixelT>::updateNewIdx (const DimImg curComp, DimImg &compCount) {
if (newCompIdx[curComp] != DimImg_MAX)
// top already set
return;
@ -410,19 +496,17 @@ ArrayTreeBuilder<WeightT>::updateNewIdx (Tree &tree, const DimImg curComp, DimIm
DimImg newTopIdx = newCompIdx[top];
if (newTopIdx == DimImg_MAX) {
newTopIdx = newCompIdx[top] = compCount++;
#ifdef SMART_LOG
if (top == DimImg_MAX)
// XXX arbres non-connexe ?
std::cerr << "coucou top: " << curComp << std::endl;
else if (compParents[top] == tree.getLeafCount())
cerr << "coucou top: " << curComp << endl;
else if (compParents[top] == leafCount)
// XXX arbres non-connexe ?
std::cerr << "coucou ptop-top: " << curComp << std::endl;
cerr << "coucou ptop-top: " << curComp << endl;
else if (compParents[top] == DimImg_MAX)
// XXX arbres non-connexe ?
std::cerr << "coucou ptop-max: " << curComp << std::endl;
#endif
cerr << "coucou ptop-max: " << curComp << endl;
}
const DimNodeId &newTopChildCountRec = childCountRec[top];
const DimNodeIdx &newTopChildCountRec = childCountRec[top];
const DimImg &newTopCompParent = compParents[top];
const WeightT &newTopWeight = compWeights[top]; // only in case of unnecessary comp
for (DimImg sibling = curComp; sibling != top; ) {
@ -440,66 +524,104 @@ ArrayTreeBuilder<WeightT>::updateNewIdx (Tree &tree, const DimImg curComp, DimIm
}
// ----------------------------------------
template<typename WeightT>
template<typename WeightFunct>
template<typename WeightT, PixelT>
inline void
ArrayTreeBuilder<WeightT>::compress (const GraphWalker &graphWalker, const Rect &tile,
const DimImg &compBase, const DimImg &compTop,
const WeightFunct &weightFunct) {
// XXX compress n'est plus utilisé que pour la fin
// XXX donc virer l'argument tile et faire dealThreadRange pour la réindexation A et B mais pas C
ArrayTreeBuilder<WeightT, PixelT>::compress (const DimImg &compTop) {
#ifdef SMART_LOG
DEF_LOG ("ArrayTreeBuilder::compress", "compBase:" << compBase << " compTop:" << compTop);
DEF_LOG ("ArrayTreeBuilder::compress", " compTop:" << compTop);
#endif
// XXX dealThreadRange if all (A)
graphWalker.forEachVertexIdx (tile, [this] (const DimImg &leaf){
//LOG ("leaf:" << leaf << " curPar:" << leafParents[leaf] << " newPar:" << newCompIdx[leafParents[leaf]]);
dealThreadRange (leafCount, coreCount, [this] (const DimImg &leaf) {
DimImg old = leafParents[leaf];
if (old != DimImg_MAX)
leafParents[leaf] = newCompIdx[old];
});
// XXX dealThreadRange if all (B)
for (DimImg curComp = compBase; curComp < compTop; ++curComp) {
if (compParents[curComp] == DimImg_MAX)
continue;
compParents[curComp] = newCompIdx[compParents[curComp]];
}
// XXX (C)
for (DimImg curComp = compBase; curComp < compTop; ) {
dealThreadRange (compTop, coreCount, [this] (const DimImg &curComp) {
DimImg old = compParents[curComp];
if (old != DimImg_MAX)
compParents[curComp] = newCompIdx[old];
});
// XXX non parallèle
for (DimImg curComp = 0; curComp < compTop; ) {
DimImg newIdxComp = newCompIdx[curComp];
if (newIdxComp == curComp || newIdxComp == DimImg_MAX || newCompIdx[newIdxComp] == newIdxComp) {
++curComp;
continue;
}
#ifdef SMART_LOG
LOG ("comp curComp:" << curComp << " newIdxComp:" << newIdxComp);
#endif
std::swap(compParents[curComp], compParents[newIdxComp]);
std::swap(compWeights[curComp], compWeights[newIdxComp]);
std::swap(childCountRec[curComp], childCountRec[newIdxComp]);
std::swap(newCompIdx[curComp], newCompIdx[newIdxComp]);
swap (compParents[curComp], compParents[newIdxComp]);
swap (compWeights[curComp], compWeights[newIdxComp]);
swap (childCountRec[curComp], childCountRec[newIdxComp]);
swap (newCompIdx[curComp], newCompIdx[newIdxComp]);
}
// XXX YYY curComp ? compTop ?
}
// ========================================
template<typename WeightT>
template<typename WeightT, typename PixelT>
inline void
ArrayTreeBuilder<WeightT, PixelT>::createParent (DimImg &topParent, const WeightT &weight, DimImg &childA, DimImg &childB) {
childCountRec [topParent] = 2;
compWeights [topParent] = weight;
childA = childB = topParent;
++topParent;
}
// ----------------------------------------
template<typename WeightT, typename PixelT>
inline void
ArrayTreeBuilder<WeightT, PixelT>::addChild (const DimImg &parent, DimImg &child) {
++childCountRec [parent];
child = parent;
}
// ----------------------------------------
template<typename WeightT, typename PixelT>
inline void
ArrayTreeBuilder<WeightT, PixelT>::addChildren (const DimImg &parent, const DimImg &sibling) {
childCountRec [parent] += childCountRec [sibling];
compParents [sibling] = parent;
}
// ----------------------------------------
template<typename WeightT, typename PixelT>
inline DimImg
ArrayTreeBuilder<WeightT, PixelT>::findRoot (DimImg comp) {
if (comp == DimImg_MAX)
return comp;
for (;;) {
DimImg p = compParents [comp];
if (p == DimImg_MAX)
return comp;
comp = p;
}
}
// ----------------------------------------
template<typename WeightT, typename PixelT>
template<typename WeightFunct>
inline DimImg
ArrayTreeBuilder<WeightT>::findTopComp (Tree &tree, const DimImg &comp, const WeightFunct &weightFunct) {
ArrayTreeBuilder<WeightT, PixelT>::findTopComp (const DimImg &comp, const WeightFunct &weightFunct) {
if (comp == DimImg_MAX)
return DimImg_MAX;
DimImg result = findTopComp (comp, compWeights[comp], weightFunct);
BOOST_ASSERT (result < tree.getLeafCount());
BOOST_ASSERT (result < leafCount);
// XXX pas pour TOS ! BOOST_ASSERT (compWeights[result] == compWeights[comp]);
return result;
}
// ----------------------------------------
template<typename WeightT>
template<typename WeightT, typename PixelT>
template<typename WeightFunct>
inline DimImg
ArrayTreeBuilder<WeightT>::findTopComp (DimImg comp, const WeightT &weight, const WeightFunct &weightFunct) {
ArrayTreeBuilder<WeightT, PixelT>::findTopComp (DimImg comp, const WeightT &weight, const WeightFunct &weightFunct) {
DimImg last = comp;
for (;;) {
if (comp == DimImg_MAX)
@ -512,9 +634,9 @@ ArrayTreeBuilder<WeightT>::findTopComp (DimImg comp, const WeightT &weight, cons
}
// ----------------------------------------
template<typename WeightT>
template<typename WeightT, typename PixelT>
inline DimImg
ArrayTreeBuilder<WeightT>::findCompMultiChild (DimImg comp) {
ArrayTreeBuilder<WeightT, PixelT>::findCompMultiChild (DimImg comp) {
BOOST_ASSERT (comp != DimImg_MAX);
for (;;) {
if (newCompIdx [comp] != DimImg_MAX)
@ -529,56 +651,23 @@ ArrayTreeBuilder<WeightT>::findCompMultiChild (DimImg comp) {
}
// ========================================
template<typename WeightT>
inline DimImg
ArrayTreeBuilder<WeightT>::createComp (Tree &tree, const DimImg &leadPixel, const WeightT &weight, DimImg &compTop, const DimNodeId &childCount) {
BOOST_ASSERT (leadPixel < tree.getLeafCount());
BOOST_ASSERT (compTop < tree.getLeafCount());
DimImg newParent = leafParents[leadPixel];
if (newParent == DimImg_MAX) {
newParent = leafParents [leadPixel] = compTop++;
compWeights[newParent] = weight;
}
childCountRec[newParent] = childCount;
return newParent;
}
// ----------------------------------------
template<typename WeightT>
template<typename WeightT, typename PixelT>
inline void
ArrayTreeBuilder<WeightT>::linkParent (Tree &tree, const DimImg &pixel, const DimImg &parent) {
BOOST_ASSERT (pixel < tree.getLeafCount());
BOOST_ASSERT (parent < tree.getLeafCount());
//BOOST_ASSERT (parent < compTop);
if (leafParents [pixel] == parent)
return;
if (leafParents [pixel] == DimImg_MAX) {
leafParents [pixel] = parent;
return;
}
DimImg leadPixelParent = leafParents [pixel];
if (compParents [leadPixelParent] == parent)
return;
BOOST_ASSERT (compParents [leadPixelParent] == DimImg_MAX);
compParents [leadPixelParent] = parent;
}
ArrayTreeBuilder<WeightT, PixelT>::buildChildren () {
// ----------------------------------------
template<typename WeightT>
inline void
ArrayTreeBuilder<WeightT>::buildChildren(Tree &tree) {
#ifdef SMART_LOG
DEF_LOG ("ArrayTreeBuilder::buildChildren", "");
#endif
BOOST_ASSERT (childCount[0] == 0);
BOOST_ASSERT (childCount[1] == 0);
DimImg compCount = tree.getNodeCount() - tree.getLeafCount();
std::partial_sum(childCountRec, childCountRec+compCount, childCountRec);
DimImg compCount = getCompCount ();
partial_sum (childCountRec, childCountRec+compCount, childCountRec);
// set
DimNodeId *childGetOrder = childCount+1;
for (DimNodeId i = 0; i < tree.getNodeCount()-1; ++i) {
DimNodeIdx *childGetOrder = childCount+1;
for (DimNodeIdx i = 0; i < nodeCount-1; ++i) {
if (leafParents[i] == DimImg_MAX)
continue;
BOOST_ASSERT (leafParents[i] < compCount);
@ -588,18 +677,45 @@ ArrayTreeBuilder<WeightT>::buildChildren(Tree &tree) {
}
// ----------------------------------------
template<typename WeightT>
template<typename WeightT, typename PixelT>
template<typename WeightFunct>
inline void
ArrayTreeBuilder<WeightT>::initWeights (Tree &tree, const GraphWalker &graphWalker, const WeightFunct &weightFunct) {
ArrayTreeBuilder<WeightT, PixelT>::initWeights (const GraphWalker &graphWalker, const WeightFunct &weightFunct) {
#ifdef SMART_LOG
DEF_LOG ("ArrayTreeBuilder::initCompWeights", "leafCount:" << tree.getLeafCount());
DEF_LOG ("ArrayTreeBuilder::initCompWeights", "leafCount:" << leafCount);
#endif
// graphWalker.forEachVertexIdx ([this, &weightFunct] (const DimImg &compIdx){
// mapWeights[compIdx] = weightFunct.getWeight (compIdx);
// });
std::fill_n (compWeights, tree.getLeafCount(), 0);
dealThreadFill_n (leafCount, coreCount, compWeights, 0);
}
// ========================================
#ifndef LOG_DISABLE
template<typename WeightT, typename PixelT>
inline void
ArrayTreeBuilder<WeightT, PixelT>::printTree (const Size &size, const bool &rec) {
cout << "tree weight parent " << (rec ? "countRec" : "count") << endl;
Size doubleSize (size.width, 2*size.height);
cct::merciol::printMap (cout, compWeights, size) << endl;
cct::merciol::printMap (cout, leafParents, doubleSize) << endl;
cct::merciol::printMap (cout, rec ? childCountRec : childCount, size) << endl;
}
template<typename WeightT, typename PixelT>
inline void
ArrayTreeBuilder<WeightT, PixelT>::printLeaders (const Size &size) {
cout << "leaders" << endl;
cct::merciol::printMap (cout, newCompIdx, size) << endl;
}
template<typename WeightT, typename PixelT>
inline void
ArrayTreeBuilder<WeightT, PixelT>::printNewCompIdx (const Size &size) {
cout << "newCompIdx" << endl;
cct::merciol::printMap (cout, newCompIdx, size) << endl;
}
#endif
#endif // _OTB_TRISKELE_ARRAY_TREE_BUILDER_TPP

View File

@ -9,19 +9,19 @@ namespace otb {
class QuadTreeBuilder : public TreeBuilder {
public:
QuadTreeBuilder (const DimSideImg &w, const DimSideImg &h) : width (w), height (h) {}
QuadTreeBuilder (const DimSideImg &width, const DimSideImg &height) : width (width), height (height) {}
virtual void
buildTree (Tree &tree);
private:
DimImg
getStepCount (const DimSideImg &x, const DimSideImg &y, const DimSideImg &w, const DimSideImg &h) const;
getStepCount (const DimSideImg &x, const DimSideImg &y, const DimSideImg &width, const DimSideImg &height) const;
DimImg
setParents (DimImg &parentId,
const DimSideImg &x, const DimSideImg &y, const DimSideImg &w, const DimSideImg &h,
const DimSideImg &imgW, const DimSideImg &imgH, DimImg level = 0) const;
const DimSideImg &x, const DimSideImg &y, const DimSideImg &width, const DimSideImg &height,
const DimSideImg &imgWidth, const DimSideImg &imgHeight, DimImg level = 0) const;
private:
DimSideImg width, height;

View File

@ -36,32 +36,27 @@ namespace otb {
/*! Pointers on the children and count how many children a parents have */
DimNodeId *children, *childCount;
DimNodeId *newCompIndex;
/*! State of the tree */
State state;
/*! Reset the tree and allocate the memory according to the size defined */
void init ();
/*! Allocate the size according to the size previously defined */
void book ();
void book (const DimImg &leafCount);
/*! Free all the memory and set all pointers to nullptr */
void reset ();
void free ();
public:
// Constructors, destructor and resize method (does the same as the constructors)
Tree (const DimImg &leafCount, const DimSideImg &width, const DimSideImg &height);
Tree (const DimSideImg &width, const DimSideImg &height);
Tree (const DimImg &leafCount = 0);
~Tree ();
/*! clear values according to the size defined */
void clear ();
void resize (const DimImg &newLeafCount, const DimSideImg &w, const DimSideImg &h);
void resize (const DimImg &newLeafCount);
void resize (const DimSideImg &w, const DimSideImg &h);
void resize (const DimSideImg &width, const DimSideImg &height);
void resize (const DimImg &leafCount);
// Setter for nodeCount and size
void setNodeCount (const DimImg &newNodeCount) { nodeCount = newNodeCount; }
@ -76,34 +71,30 @@ namespace otb {
DimNodeId getAbsRoot () const { return nodeCount-1+leafCount; }
DimNodeId getCompCount () const { return nodeCount-leafCount; } // XXX
DimNodeId getParent (const DimNodeId &idx) const { return leafParents[idx]; }
DimNodeId getLeafParent (const DimNodeId &idx) const { return leafParents[idx]; }
DimNodeId getCompParent (const DimNodeId &idx) const { return compParents[idx]; }
std::vector<DimNodeId> getChildren (const DimImg &idx) const;
DimNodeId getChildrenCount (const DimImg &idx) const { return childCount[idx]; }
DimSideImg getLeafCount () const { return leafCount; }
DimSideImg getNodeCount () const { return nodeCount; }
const DimNodeId &getParent (const DimNodeId &idx) const { return leafParents[idx]; }
const DimNodeId &getLeafParent (const DimNodeId &idx) const { return leafParents[idx]; }
const DimNodeId &getCompParent (const DimNodeId &idx) const { return compParents[idx]; }
const DimNodeId &getChildrenCount (const DimImg &idx) const { return childCount[idx]; }
const DimSideImg &getLeafCount () const { return leafCount; }
const DimSideImg &getNodeCount () const { return nodeCount; }
// Functions to apply to specific entities
template<typename FuncToApply>
void forEachLeaf (const FuncToApply& f /* f(DimNodeId idx) */);
void forEachLeaf (const FuncToApply &f /* f (DimNodeId leafId) */) const;
template<typename FuncToApply>
void forEachComp (const FuncToApply& f /* f(DimNodeId idx) */);
void forEachComp (const FuncToApply &f /* f (DimNodeId compId) */) const;
template<typename FuncToApply>
void forEachChild (const DimNodeId &idx, const FuncToApply& f /* f(DimNodeId idx) */);
void forEachChild (const DimNodeId &parentId, const FuncToApply &f /* f (DimNodeId childId) */) const;
#ifdef SMART_LOG
// Print info about the tree
void printTree (const Size &size, const bool &rec);
void printNewCompIndex (const Size &size);
#endif
};
#include "Tree.tpp"
} // triskele
} // otb

View File

@ -23,23 +23,23 @@ namespace otb {
// Used to set the attributes below with the tree
inline void updateAttributes (Tree &tree) {
leafCount = tree.leafCount;
leafParents = tree.leafParents;
compParents = tree.compParents;
children = tree.children;
childCount = tree.childCount;
newCompIndex = tree.newCompIndex;
}
protected:
// Attributes corresponding to the tree, used to make the construction easier
DimImg leafCount;
/*! Pointers on the parents of each leafs / nodes */
DimNodeId *leafParents, *compParents;
/*! Pointers on the children and count how many children a parents have */
DimNodeId *children, *childCount, *childCountRec;
DimNodeId *children, *childCount;
DimNodeId *newCompIndex;
};
} // triskele

View File

@ -1,10 +1,8 @@
#ifndef _OTB_TRISKELE_XML_TREE_BUILDER_HPP
#define _OTB_TRISKELE_XML_TREE_BUILDER_HPP
#include <otb_tinyxml.h>
#include "TreeBuilder.hpp"
namespace otb {

View File

@ -103,6 +103,14 @@ namespace triskele {
tasks[i].join ();
}
// ========================================
template <typename DimImg, class OutputIterator, class T>
void dealThreadFill_n (const DimImg &maxId, unsigned int coreCount, OutputIterator first, const T& val) {
dealThreadBound (maxId, coreCount, [&first, &val] (const DimImg &minVal, const DimImg &maxVal) {
fill_n (first+minVal, maxVal-minVal, val);
});
}
// ========================================
template<typename DimImg, typename WeightT, typename WeightFunct, typename CmpFunct, typename CallFunct>
inline void

View File

@ -6,5 +6,5 @@ using namespace otb::triskele;
void
AreaAttribute::generate () {
DimNodeId root = tree->getRoot ();
//DimNodeId root = tree->getRoot ();
}

View File

@ -4,15 +4,13 @@ using namespace otb::triskele;
void
QuadTreeBuilder::buildTree (Tree &tree) {
// Building the tree by setting leafs's and components's parents
tree.resize ((DimImg)width, (DimImg)height);
tree.resize (width, height);
updateAttributes (tree);
DimImg parentCount = getStepCount (0, 0, width, height);
DimImg parentUsed = parentCount;
// We set the root
// Set the root
compParents[parentCount-1] = parentCount;
tree.setNodeCount (parentCount);
setParents (parentCount, 0, 0, width, height, width, height);
@ -31,57 +29,55 @@ QuadTreeBuilder::buildTree (Tree &tree) {
}
DimImg
QuadTreeBuilder::getStepCount (const DimSideImg &x, const DimSideImg &y, const DimSideImg &w, const DimSideImg &h) const {
QuadTreeBuilder::getStepCount (const DimSideImg &x, const DimSideImg &y, const DimSideImg &width, const DimSideImg &height) const {
DimImg nbSteps = 1;
if (w > 2 && h > 2) {
DimSideImg dw1 = w >> 1;
DimSideImg dh1 = h >> 1;
DimSideImg dw2 = (w >> 1) + (w & 1);
DimSideImg dh2 = (h >> 1) + (h & 1);
if (width <= 2 && height <= 2)
return nbSteps;
DimSideImg coords [4][4] = {
{x , y , dw1, dh1},
{x + dw1, y , dw2, dh1},
{x , y + dh1, dw1, dh2},
{x + dw1, y + dh1, dw2, dh2}
};
DimSideImg dw1 = width >> 1;
DimSideImg dh1 = height >> 1;
DimSideImg dw2 = (width >> 1) + (width & 1);
DimSideImg dh2 = (height >> 1) + (height & 1);
DimSideImg coords [4][4] = {
{x , y , dw1, dh1},
{x + dw1, y , dw2, dh1},
{x , y + dh1, dw1, dh2},
{x + dw1, y + dh1, dw2, dh2}
};
for (int i = 0; i < 4; i++)
nbSteps += getStepCount (coords[i][0], coords[i][1], coords[i][2], coords[i][3]);
}
for (int i = 0; i < 4; i++)
nbSteps += getStepCount (coords[i][0], coords[i][1], coords[i][2], coords[i][3]);
return nbSteps;
}
DimImg
QuadTreeBuilder::setParents (DimImg &parentId,
const DimSideImg &x, const DimSideImg &y, const DimSideImg &w, const DimSideImg &h,
const DimSideImg &imgW, const DimSideImg &imgH, DimImg level) const {
const DimSideImg &x, const DimSideImg &y, const DimSideImg &width, const DimSideImg &height,
const DimSideImg &imgWidth, const DimSideImg &imgHeight, DimImg level) const {
DEF_LOG ("setParents", "parentId: " << parentId << " x: " << x << " y: " << y << " w: " << w << " h: " << h);
DimImg localId = --parentId;
if (w > 2 && h > 2) {
DimSideImg dw1 = w >> 1;
DimSideImg dh1 = h >> 1;
DimSideImg dw2 = (w >> 1) + (w & 1);
DimSideImg dh2 = (h >> 1) + (h & 1);
DimSideImg coords [4][4] = {
{x , y , dw1, dh1},
{x + dw1, y , dw2, dh1},
{x , y + dh1, dw1, dh2},
{x + dw1, y + dh1, dw2, dh2}
};
childCount[localId+2] = 4;
for (int i = 0; i < 4; i++)
compParents[setParents (parentId, coords[i][0], coords[i][1], coords[i][2], coords[i][3], imgW, imgH, level+1)] = localId;
} else
for (DimSideImg i = x; i < w + x; i++)
for (DimSideImg j = y; j < h + y; j++) {
DimSideImg id = i + j * imgW;
if (width <= 2 && height <= 2) {
for (DimSideImg i = x; i < width + x; i++)
for (DimSideImg j = y; j < height + y; j++) {
DimSideImg id = i + j * imgWidth;
leafParents[id] = localId;
childCount[localId+2]++;
}
return localId;
}
DimSideImg dw1 = width >> 1;
DimSideImg dh1 = height >> 1;
DimSideImg dw2 = (width >> 1) + (width & 1);
DimSideImg dh2 = (height >> 1) + (height & 1);
DimSideImg coords [4][4] = {
{x , y , dw1, dh1},
{x + dw1, y , dw2, dh1},
{x , y + dh1, dw1, dh2},
{x + dw1, y + dh1, dw2, dh2}
};
childCount[localId+2] = 4;
for (int i = 0; i < 4; i++)
compParents[setParents (parentId, coords[i][0], coords[i][1], coords[i][2], coords[i][3], imgWidth, imgHeight, level+1)] = localId;
return localId;
}

View File

@ -2,101 +2,90 @@
using namespace otb::triskele;
Tree::Tree (const DimImg &leafC, const DimSideImg &width, const DimSideImg &height)
: size (width, height),
leafCount (leafC),
nodeCount (leafCount),
Tree::Tree (const DimSideImg &width, const DimSideImg &height)
: Tree ((DimImg)width * (DimImg)height)
{
size = Size (width, height);
}
Tree::Tree (const DimImg &leafCount)
: size (),
leafCount (0),
nodeCount (0),
leafParents (nullptr),
compParents (nullptr),
children (nullptr),
childCount (nullptr),
newCompIndex (nullptr),
state (State::Void)
{
init();
book (leafCount);
clear ();
}
Tree::Tree (const DimSideImg &width, const DimSideImg &height)
: Tree (width * height, width, height)
{}
Tree::Tree (const DimSideImg &leafC)
: Tree (leafC, 0, 0)
{}
Tree::~Tree () { reset (); }
void
Tree::resize (const DimImg &newLeafCount, const DimSideImg &w, const DimSideImg &h) {
leafCount = newLeafCount;
nodeCount = 0;
size = Size (w, h);
init ();
Tree::~Tree () {
free ();
}
void
Tree::resize (const DimSideImg &w, const DimSideImg &h) {
resize ((DimImg)w * (DimImg)h, w, h);
Tree::clear () {
nodeCount = leafCount;
if (!leafCount)
return;
childCount[0] = childCount[1] = 0;
// XXX fill//
std::fill_n (leafParents, leafCount*2, DimImg_MAX);
#ifdef SMART_LOG
std::fill_n (children, (leafCount-1)*2, 0);
std::fill_n (childCount, leafCount+1, 0);
#endif
}
void
Tree::resize (const DimImg &newLeafCount) {
resize (newLeafCount, 0, 0);
Tree::resize (const DimSideImg &width, const DimSideImg &height) {
resize ((DimImg)width * (DimImg)height);
size = Size (width, height);
}
void
Tree::init () {
reset ();
book ();
state = State::Initialized;
Tree::resize (const DimImg &leafCount) {
size = NullSize;
book (leafCount);
clear ();
}
void
Tree::reset () {
delete[] leafParents;
Tree::free () {
if (leafParents)
delete[] leafParents;
leafParents = compParents = nullptr;
delete[] children;
delete[] childCount;
if (children)
delete[] children;
if (childCount)
delete[] childCount;
children = childCount = nullptr;
}
void
Tree::book () {
Tree::book (const DimImg &leafCount) {
if (this->leafCount == leafCount) {
clear ();
return;
}
free ();
if (!leafCount)
return;
this->leafCount = leafCount;
leafParents = new DimNodeId[leafCount*2];
compParents = leafParents + leafCount;
std::fill_n (leafParents, leafCount*2, leafCount*2);
children = new DimNodeId[(leafCount-1)*2];
childCount = new DimNodeId[leafCount+2];
std::fill_n (children, (leafCount-1)*2, leafCount*2);
std::fill_n (childCount, leafCount+2, 0);
clear ();
}
template<typename FuncToApply>
void
Tree::forEachChild (const DimNodeId &idx, const FuncToApply& f) {
std::vector<DimNodeId> childrenNode = getChildren(idx);
for (DimNodeId i = 0; i < childrenNode.size (); ++i)
f (childrenNode[i]);
}
std::vector<DimNodeId>
Tree::getChildren (const DimNodeId &idx) const {
std::vector<DimNodeId> childrenRet;
for (DimNodeId i = childCount[idx]; i < childCount[idx+1]; ++i)
childrenRet.push_back (children[i]);
return childrenRet;
}
#ifdef SMART_LOG
inline void
Tree::printTree (const Size &size, const bool &rec) {

View File

@ -81,21 +81,24 @@ XMLTreeBuilder::exportToFile (const Tree &tree, const std::string &fileName) {
if (tree.getSize().height != 0)
treeNode->SetAttribute ("height", tree.getSize ().height);
// Construct the tree
// Construct the tree
writeNodeChildren (tree, tree.getAbsRoot (), treeNode);
doc.SaveFile (fileName.c_str ());
}
void
XMLTreeBuilder::writeNodeChildren (const Tree &tree, const DimNodeId &idx, TiXmlElement *node) {
if (idx < tree.getLeafCount ()) {
XMLTreeBuilder::writeNodeChildren (const Tree &tree, const DimNodeId &id, TiXmlElement *node) {
if (id < tree.getLeafCount ()) {
TiXmlElement *leafNode = new TiXmlElement ("Leaf");
node->LinkEndChild (leafNode);
leafNode->SetAttribute ("id", idx);
} else {
TiXmlElement *nodeNode = new TiXmlElement ("Node");
node->LinkEndChild (nodeNode);
for (int id : tree.getChildren (idx - tree.getLeafCount ()))
writeNodeChildren (tree, id, nodeNode);
leafNode->SetAttribute ("id", id);
return;
}
TiXmlElement *nodeNode = new TiXmlElement ("Node");
node->LinkEndChild (nodeNode);
tree.forEachChild (id - tree.getLeafCount (),
[&tree, &nodeNode] (const DimNodeId &childId) {
writeNodeChildren (tree, childId, nodeNode);
});
}

View File

@ -8,11 +8,11 @@
#include "QuadTree/QuadTreeBuilder.hpp"
#include "XMLTree/XMLTreeBuilder.hpp"
#include "IImage.hpp"
//#include "ArrayTree/Border.hpp"
//#include "ArrayTree/GraphWalker.hpp"
//#include "ArrayTree/Leader.hpp"
//#include "ArrayTree/Weight.hpp"
//#include "ArrayTree/ArrayTreeBuilder.hpp" XXX
#include "ArrayTree/Border.hpp"
#include "ArrayTree/GraphWalker.hpp"
#include "ArrayTree/Leader.hpp"
#include "ArrayTree/Weight.hpp"
//#include "ArrayTree/ArrayTreeBuilder.hpp"
int
main (int argc, char** argv) {
@ -21,7 +21,7 @@ main (int argc, char** argv) {
IImage<uint32_t> imgInt ("test.png");
imgInt.readImage ();
std::cout << "Value of 0: " << imgInt.getValue(0) << std::endl;
Tree tree;
Tree tree;
//otb::BuildTree::buildTree(tree, otb::DAPTreeBuilder());
return 0;
}