modifié : include/ArrayTree/ArrayTreeBuilder.hpp
modifié : include/ArrayTree/ArrayTreeBuilder.tpp modifié : include/ArrayTree/Border.hpp modifié : include/ArrayTree/GraphWalker.tpp modifié : include/ArrayTree/Leader.hpp modifié : include/ArrayTree/Leader.tpp modifié : include/ArrayTree/Weight.hpp modifié : include/ArrayTree/Weight.tpp modifié : include/ArrayTree/triskeleArrayTreeBase.hpp modifié : include/ArrayTree/triskeleArrayTreeBase.tpp modifié : include/IImage.hpp modifié : include/IImage.tpp modifié : include/Tree.hpp modifié : include/Tree.tpp modifié : include/TreeBuilder.hpp modifié : include/XMLTree/XMLTreeBuilder.hpp modifié : include/triskeleBase.hpp modifié : include/triskeleDealThreads.hpp modifié : include/triskeleDealThreads.tpp modifié : include/triskeleDebug.hpp modifié : include/triskeleGdalGetType.hpp nouveau fichier : src/IImage.cpp modifié : src/QuadTree/QuadTreeBuilder.cpp modifié : src/Tree.cpp modifié : src/testMain.cpp modifié : src/triskeleDebug.cpp
This commit is contained in:
parent
cdedd3b7eb
commit
ed9141d5c5
@ -1,9 +1,9 @@
|
||||
#ifndef _OTB_TRISKELE_ARRAY_TREE_BUILDER_HPP
|
||||
#define _OTB_TRISKELE_ARRAY_TREE_BUILDER_HPP
|
||||
|
||||
#ifdef SMART_LOG
|
||||
#ifdef ENABLE_LOG
|
||||
#include <iostream>
|
||||
#endif // SMART_LOG
|
||||
#endif // ENABLE_LOG
|
||||
|
||||
#include "triskeleSort.hpp"
|
||||
#include "triskeleDealThreads.hpp"
|
||||
@ -20,20 +20,17 @@ namespace otb {
|
||||
template <typename WeightT, typename PixelT>
|
||||
class ArrayTreeBuilder : public TreeBuilder {
|
||||
const unsigned int coreCount;
|
||||
const IImage<PixelT> ℑ
|
||||
const Raster<PixelT> &raster;
|
||||
const GraphWalker &graphWalker;
|
||||
TreeType type;
|
||||
bool countingFlag;
|
||||
Leader leaders;
|
||||
DimNodeId *childCountRec;
|
||||
DimImg *newCompIdx;
|
||||
WeightT *compWeights; // [leafCount]
|
||||
|
||||
|
||||
|
||||
public:
|
||||
ArrayTreeBuilder (const unsigned int &coreCount,
|
||||
IImage<PixelT> &image, const GraphWalker &graphWalker,
|
||||
Raster<PixelT> &raster, const GraphWalker &graphWalker,
|
||||
const TreeType &treeType, const bool &countingSort = true);
|
||||
~ArrayTreeBuilder () {}
|
||||
|
||||
@ -45,13 +42,13 @@ namespace otb {
|
||||
inline void
|
||||
buildTree (Tree &tree, const WeightFunct &weightFunct);
|
||||
|
||||
template<typename WeightFunct>
|
||||
inline void
|
||||
fillAPTree (PixelT *leafAPTree, const WeightFunct &weightFunct);
|
||||
// template<typename WeightFunct>
|
||||
// inline void
|
||||
// fillAPTree (PixelT *leafAPTree, const WeightFunct &weightFunct);
|
||||
|
||||
template<typename WeightFunct>
|
||||
inline void
|
||||
buildTree (Edge<WeightT> *edges, const WeightFunct &weightFunct, const Rect &tile, DimImg &topParent);
|
||||
buildParents (Edge<WeightT> *edges, const WeightFunct &weightFunct, const Rect &tile, DimImg &topParent);
|
||||
|
||||
template<typename WeightFunct>
|
||||
inline void
|
||||
@ -67,13 +64,13 @@ namespace otb {
|
||||
|
||||
template<typename WeightFunct>
|
||||
inline DimImg
|
||||
updateNewIdx (const vector<DimImg> &compBases, const vector<DimImg> &compTops, const WeightFunct &weightFunct);
|
||||
updateNewId (DimImg newCompId[], const vector<DimImg> &compBases, const vector<DimImg> &compTops, const WeightFunct &weightFunct);
|
||||
|
||||
inline void
|
||||
updateNewIdx (const DimImg curComp, DimImg &compCount);
|
||||
updateNewId (DimImg newCompId[], const DimImg curComp, DimImg &compCount);
|
||||
|
||||
inline void
|
||||
compress (const DimImg &compTop);
|
||||
compress (DimImg newCompId[], const DimImg &compTop);
|
||||
|
||||
inline void
|
||||
createParent (DimImg &topParent, const WeightT &weight, DimImg &childA, DimImg &childB);
|
||||
@ -96,7 +93,7 @@ namespace otb {
|
||||
findTopComp (DimImg comp, const WeightT &weight, const WeightFunct &weightFunct);
|
||||
|
||||
inline DimImg
|
||||
findCompMultiChild (DimImg comp);
|
||||
findCompMultiChild (const DimImg newCompId[], DimImg comp);
|
||||
|
||||
inline void
|
||||
buildChildren ();
|
||||
@ -105,14 +102,14 @@ namespace otb {
|
||||
inline void
|
||||
initWeights (const GraphWalker &graphWalker, const WeightFunct &weightFunct);
|
||||
|
||||
#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
|
||||
// #ifdef ENABLE_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"
|
||||
|
@ -1,23 +1,25 @@
|
||||
#ifndef _OTB_TRISKELE_ARRAY_TREE_BUILDER_TPP
|
||||
#define _OTB_TRISKELE_ARRAY_TREE_BUILDER_TPP
|
||||
|
||||
// ========================================
|
||||
template<typename WeightT, typename PixelT>
|
||||
ArrayTreeBuilder<WeightT, PixelT>::ArrayTreeBuilder (const unsigned int &coreCount,
|
||||
IImage<PixelT> &image, const GraphWalker &graphWalker,
|
||||
Raster<PixelT> &raster, const GraphWalker &graphWalker,
|
||||
const TreeType &treeType, const bool &countingSort) :
|
||||
coreCount (coreCount),
|
||||
image (image),
|
||||
raster (raster),
|
||||
graphWalker (graphWalker),
|
||||
type (treeType),
|
||||
countingFlag (countingSort)
|
||||
{
|
||||
}
|
||||
|
||||
// ========================================
|
||||
template<typename WeightT, typename PixelT>
|
||||
inline void
|
||||
ArrayTreeBuilder<WeightT, PixelT>::buildTree (Tree &tree) {
|
||||
tree.resize (graphWalker.vertexMaxCount ());
|
||||
updateAttributes ();
|
||||
// XXX updateAttributes ();
|
||||
if (!leafCount)
|
||||
return;
|
||||
|
||||
@ -25,25 +27,26 @@ ArrayTreeBuilder<WeightT, PixelT>::buildTree (Tree &tree) {
|
||||
childCountRec = childCount + 2;
|
||||
leaders.book (leafCount);
|
||||
// XXX dealThreadFill_n leaders
|
||||
newCompIdx = leaders.getLeaders ();
|
||||
|
||||
switch (type) {
|
||||
case MIN:
|
||||
buildTree<Edge<WeightT> > (tree, MinWeight<PixelT, WeightT> (image.getPixels (), image.getSize ()));
|
||||
// case MIN:
|
||||
// buildTree (tree, MinWeight<PixelT, WeightT> (raster.getPixels (), raster.getSize ()));
|
||||
break;
|
||||
case MAX:
|
||||
buildTree<Edge<WeightT> > (tree, MaxWeight<PixelT, WeightT> (image.getPixels (), image.getSize ()));
|
||||
buildTree (tree, MaxWeight<PixelT, WeightT> (raster.getPixels (), raster.getSize ()));
|
||||
break;
|
||||
case TOS:
|
||||
buildTree<Edge<WeightT> > (tree, MedianWeight<PixelT, WeightT> (image.getPixels (), graphWalker));
|
||||
// case TOS:
|
||||
// buildTree (tree, MedianWeight<PixelT, WeightT> (raster.getPixels (), graphWalker));
|
||||
break;
|
||||
// XXX msg
|
||||
}
|
||||
newCompIdx = NULL;
|
||||
leaders.free ();
|
||||
if (compWeights)
|
||||
delete [] compWeights;
|
||||
compWeights = nullptr;
|
||||
buildChildren ();
|
||||
|
||||
// XXX
|
||||
// if (compWeights)
|
||||
// delete [] compWeights;
|
||||
// compWeights = nullptr;
|
||||
}
|
||||
|
||||
template<typename WeightT, typename PixelT>
|
||||
@ -52,7 +55,9 @@ inline void
|
||||
ArrayTreeBuilder<WeightT, PixelT>::buildTree (Tree &tree, const WeightFunct &weightFunct) {
|
||||
DEF_LOG ("ArrayTreeBuilder::buildTree", "");
|
||||
|
||||
initWeights (graphWalker, weightFunct);
|
||||
//XXX initWeights (graphWalker, weightFunct);
|
||||
|
||||
// buildParents
|
||||
vector<Edge<WeightT> > allEdges (graphWalker.edgeMaxCount ());
|
||||
vector<Rect> tiles;
|
||||
vector<Rect> boundaries;
|
||||
@ -77,9 +82,10 @@ ArrayTreeBuilder<WeightT, PixelT>::buildTree (Tree &tree, const WeightFunct &wei
|
||||
}
|
||||
|
||||
dealThreadRange (tileCount, coreCount, [this, &tileEdges, &weightFunct, &tiles, &compTops] (DimImg threadId) {
|
||||
buildTree (tileEdges [threadId], weightFunct, tiles [threadId], compTops [threadId]);
|
||||
buildParents (tileEdges [threadId], weightFunct, tiles [threadId], compTops [threadId]);
|
||||
});
|
||||
|
||||
// merge sub-tree
|
||||
DimImg compCount = compTops [0];
|
||||
DimImg *topC = NULL;
|
||||
if (boundCount) {
|
||||
@ -122,47 +128,46 @@ ArrayTreeBuilder<WeightT, PixelT>::buildTree (Tree &tree, const WeightFunct &wei
|
||||
});
|
||||
}
|
||||
|
||||
// compress
|
||||
DimImg *newCompId = leaders.getLeaders ();
|
||||
DimImg maxUsed = max (compTops[tileCount-1], topC != NULL ? *topC : 0);
|
||||
dealThreadFill_n (maxUsed, coreCount, newCompIdx, DimImg_MAX);
|
||||
dealThreadFill_n (maxUsed, coreCount, newCompId, DimImg_MAX);
|
||||
|
||||
compCount = updateNewIdx (compBases, compTops, weightFunct);
|
||||
compCount = updateNewId (newCompId, compBases, compTops, weightFunct);
|
||||
|
||||
compress (maxUsed);
|
||||
compress (newCompId, maxUsed);
|
||||
|
||||
newCompIdx = NULL;
|
||||
leaders.free ();
|
||||
|
||||
setNodeCount (tree, leafCount+compCount);
|
||||
LOG ("nodeCount:" << tree.getNodeCount());
|
||||
DimEdge root = compCount-1;
|
||||
compParents[root] = root;
|
||||
|
||||
buildChildren ();
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// template<typename WeightT, typename PixelT>
|
||||
// template<typename WeightFunct>
|
||||
// inline void
|
||||
// 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>::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,
|
||||
ArrayTreeBuilder<WeightT, PixelT>::buildParents (Edge<WeightT> *edges, const WeightFunct &weightFunct,
|
||||
const Rect &tile, DimImg &topParent) {
|
||||
#ifdef SMART_LOG
|
||||
DEF_LOG ("ArrayTreeBuilder::buildTree", " tile:" << tile << " topParent:" << topParent << " counting:" << countingFlag);
|
||||
DEF_LOG ("ArrayTreeBuilder::buildParents", " tile:" << tile << " topParent:" << topParent << " counting:" << countingFlag);
|
||||
#endif
|
||||
|
||||
DimEdge edgeCount = (sizeof (WeightT) < 3 || countingFlag) ?
|
||||
@ -464,9 +469,9 @@ ArrayTreeBuilder<WeightT, PixelT>::connectComp (DimImg topA, DimImg topB, const
|
||||
template<typename WeightT, typename PixelT>
|
||||
template<typename WeightFunct>
|
||||
inline DimImg
|
||||
ArrayTreeBuilder<WeightT, PixelT>::updateNewIdx (const vector<DimImg> &compBases, const vector<DimImg> &compTops,
|
||||
ArrayTreeBuilder<WeightT, PixelT>::updateNewId (DimImg newCompId[], const vector<DimImg> &compBases, const vector<DimImg> &compTops,
|
||||
const WeightFunct &weightFunct) {
|
||||
// DEF_LOG ("ArrayTreeBuilder::updateNewIdx", "");
|
||||
// DEF_LOG ("ArrayTreeBuilder::updateNewId", "");
|
||||
DimImg compCount = compBases[0];
|
||||
vector<DimImg> sizes (compBases.size ());
|
||||
for (DimImg i = 0; i < sizes.size (); ++i)
|
||||
@ -476,26 +481,26 @@ ArrayTreeBuilder<WeightT, PixelT>::updateNewIdx (const vector<DimImg> &compBases
|
||||
[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); });
|
||||
[this, &compBases, &compCount, &newCompId] (const DimImg &vectId, const DimImg &itemId) {
|
||||
updateNewId (newCompId, compBases[vectId]+itemId, compCount); });
|
||||
return compCount;
|
||||
}
|
||||
|
||||
// ----------------------------------------
|
||||
template<typename WeightT, typename PixelT>
|
||||
inline void
|
||||
ArrayTreeBuilder<WeightT, PixelT>::updateNewIdx (const DimImg curComp, DimImg &compCount) {
|
||||
if (newCompIdx[curComp] != DimImg_MAX)
|
||||
ArrayTreeBuilder<WeightT, PixelT>::updateNewId (DimImg newCompId[], const DimImg curComp, DimImg &compCount) {
|
||||
if (newCompId[curComp] != DimImg_MAX)
|
||||
// top already set
|
||||
return;
|
||||
const DimImg &top = findCompMultiChild (curComp);
|
||||
const DimImg &top = findCompMultiChild (newCompId, curComp);
|
||||
if (curComp != top) {
|
||||
// 0 => merge || no more child
|
||||
// 1 => unnecessary node
|
||||
BOOST_ASSERT (curComp != DimImg_MAX);
|
||||
DimImg newTopIdx = newCompIdx[top];
|
||||
DimImg newTopIdx = newCompId[top];
|
||||
if (newTopIdx == DimImg_MAX) {
|
||||
newTopIdx = newCompIdx[top] = compCount++;
|
||||
newTopIdx = newCompId[top] = compCount++;
|
||||
if (top == DimImg_MAX)
|
||||
// XXX arbres non-connexe ?
|
||||
cerr << "coucou top: " << curComp << endl;
|
||||
@ -511,7 +516,7 @@ ArrayTreeBuilder<WeightT, PixelT>::updateNewIdx (const DimImg curComp, DimImg &c
|
||||
const WeightT &newTopWeight = compWeights[top]; // only in case of unnecessary comp
|
||||
for (DimImg sibling = curComp; sibling != top; ) {
|
||||
DimImg nextSibling = compParents[sibling];
|
||||
newCompIdx[sibling] = newTopIdx;
|
||||
newCompId[sibling] = newTopIdx;
|
||||
childCountRec[sibling] = newTopChildCountRec;
|
||||
compParents[sibling] = newTopCompParent;
|
||||
// only in case of unnecessary comp
|
||||
@ -520,34 +525,34 @@ ArrayTreeBuilder<WeightT, PixelT>::updateNewIdx (const DimImg curComp, DimImg &c
|
||||
}
|
||||
return;
|
||||
}
|
||||
newCompIdx[curComp] = compCount++;
|
||||
newCompId[curComp] = compCount++;
|
||||
}
|
||||
|
||||
// ----------------------------------------
|
||||
template<typename WeightT, typename PixelT>
|
||||
inline void
|
||||
ArrayTreeBuilder<WeightT, PixelT>::compress (const DimImg &compTop) {
|
||||
ArrayTreeBuilder<WeightT, PixelT>::compress (DimImg newCompId[], const DimImg &compTop) {
|
||||
|
||||
#ifdef SMART_LOG
|
||||
DEF_LOG ("ArrayTreeBuilder::compress", " compTop:" << compTop);
|
||||
#endif
|
||||
|
||||
dealThreadRange (leafCount, coreCount, [this] (const DimImg &leaf) {
|
||||
dealThreadRange (leafCount, coreCount, [this, &newCompId] (const DimImg &leaf) {
|
||||
DimImg old = leafParents[leaf];
|
||||
if (old != DimImg_MAX)
|
||||
leafParents[leaf] = newCompIdx[old];
|
||||
leafParents[leaf] = newCompId[old];
|
||||
});
|
||||
|
||||
dealThreadRange (compTop, coreCount, [this] (const DimImg &curComp) {
|
||||
dealThreadRange (compTop, coreCount, [this, &newCompId] (const DimImg &curComp) {
|
||||
DimImg old = compParents[curComp];
|
||||
if (old != DimImg_MAX)
|
||||
compParents[curComp] = newCompIdx[old];
|
||||
compParents[curComp] = newCompId[old];
|
||||
});
|
||||
|
||||
// XXX non parallèle
|
||||
for (DimImg curComp = 0; curComp < compTop; ) {
|
||||
DimImg newIdxComp = newCompIdx[curComp];
|
||||
if (newIdxComp == curComp || newIdxComp == DimImg_MAX || newCompIdx[newIdxComp] == newIdxComp) {
|
||||
DimImg newIdxComp = newCompId[curComp];
|
||||
if (newIdxComp == curComp || newIdxComp == DimImg_MAX || newCompId[newIdxComp] == newIdxComp) {
|
||||
++curComp;
|
||||
continue;
|
||||
}
|
||||
@ -559,7 +564,7 @@ ArrayTreeBuilder<WeightT, PixelT>::compress (const DimImg &compTop) {
|
||||
swap (compParents[curComp], compParents[newIdxComp]);
|
||||
swap (compWeights[curComp], compWeights[newIdxComp]);
|
||||
swap (childCountRec[curComp], childCountRec[newIdxComp]);
|
||||
swap (newCompIdx[curComp], newCompIdx[newIdxComp]);
|
||||
swap (newCompId[curComp], newCompId[newIdxComp]);
|
||||
}
|
||||
// XXX YYY curComp ? compTop ?
|
||||
}
|
||||
@ -636,10 +641,10 @@ ArrayTreeBuilder<WeightT, PixelT>::findTopComp (DimImg comp, const WeightT &weig
|
||||
// ----------------------------------------
|
||||
template<typename WeightT, typename PixelT>
|
||||
inline DimImg
|
||||
ArrayTreeBuilder<WeightT, PixelT>::findCompMultiChild (DimImg comp) {
|
||||
ArrayTreeBuilder<WeightT, PixelT>::findCompMultiChild (const DimImg newCompId[], DimImg comp) {
|
||||
BOOST_ASSERT (comp != DimImg_MAX);
|
||||
for (;;) {
|
||||
if (newCompIdx [comp] != DimImg_MAX)
|
||||
if (newCompId [comp] != DimImg_MAX)
|
||||
return comp;
|
||||
const DimImg &parent = compParents[comp];
|
||||
if (parent == DimImg_MAX)
|
||||
@ -684,38 +689,40 @@ ArrayTreeBuilder<WeightT, PixelT>::initWeights (const GraphWalker &graphWalker,
|
||||
|
||||
#ifdef SMART_LOG
|
||||
DEF_LOG ("ArrayTreeBuilder::initCompWeights", "leafCount:" << leafCount);
|
||||
dealThreadFill_n (leafCount, coreCount, compWeights, 0);
|
||||
#endif
|
||||
|
||||
// graphWalker.forEachVertexIdx ([this, &weightFunct] (const DimImg &compIdx){
|
||||
// mapWeights[compIdx] = weightFunct.getWeight (compIdx);
|
||||
// });
|
||||
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);
|
||||
triskele::printMap (cout, compWeights, size) << endl;
|
||||
triskele::printMap (cout, leafParents, doubleSize) << endl;
|
||||
triskele::printMap (cout, rec ? childCountRec : childCount, size) << endl;
|
||||
}
|
||||
template<typename WeightT, typename PixelT>
|
||||
inline void
|
||||
ArrayTreeBuilder<WeightT, PixelT>::printLeaders (const Size &size) {
|
||||
cout << "leaders" << endl;
|
||||
triskele::printMap (cout, newCompIdx, size) << endl;
|
||||
}
|
||||
template<typename WeightT, typename PixelT>
|
||||
inline void
|
||||
ArrayTreeBuilder<WeightT, PixelT>::printNewCompIdx (const Size &size) {
|
||||
cout << "newCompIdx" << endl;
|
||||
triskele::printMap (cout, newCompIdx, size) << endl;
|
||||
}
|
||||
#endif
|
||||
// #ifdef ENABLE_LOG
|
||||
// template<typename WeightT, typename PixelT>
|
||||
// inline void
|
||||
// ArrayTreeBuilder<WeightT, PixelT>::printTree (const Size &size, const bool &rec) {
|
||||
// cout << "tree weight parent " << (rec ? "countRec" : "count children") << endl;
|
||||
// Size doubleSize (size.width, 2*size.height);
|
||||
// triskele::printMap (cout, compWeights, size, (DimNodeId) getCompCount ()) << endl;
|
||||
// triskele::printMap (cout, leafParents, doubleSize) << endl;
|
||||
// triskele::printMap (cout, rec ? childCountRec : childCount, size) << endl;
|
||||
// if (!rec)
|
||||
// printMap (cout, children, doubleSize, nodeCount) << endl << endl;
|
||||
// }
|
||||
// template<typename WeightT, typename PixelT>
|
||||
// inline void
|
||||
// ArrayTreeBuilder<WeightT, PixelT>::printLeaders (const Size &size) {
|
||||
// cout << "leaders" << endl;
|
||||
// triskele::printMap (cout, newCompId, size) << endl;
|
||||
// }
|
||||
// template<typename WeightT, typename PixelT>
|
||||
// inline void
|
||||
// ArrayTreeBuilder<WeightT, PixelT>::printNewCompId (const Size &size) {
|
||||
// cout << "newCompId" << endl;
|
||||
// triskele::printMap (cout, newCompId, size) << endl;
|
||||
// }
|
||||
// #endif
|
||||
|
||||
|
||||
#endif // _OTB_TRISKELE_ARRAY_TREE_BUILDER_TPP
|
||||
|
@ -14,57 +14,40 @@ namespace otb {
|
||||
class Border {
|
||||
public:
|
||||
/*! Retourne le nombre de pixels à l'aide de la taille */
|
||||
static DimImg getPixelsCount (const Size &size) { return DimImg (size.width)*DimImg (size.height); }
|
||||
static inline DimImg getPixelsCount (const Size &size);
|
||||
|
||||
/*! Retourne la taille que doit faire le tableau simplifié */
|
||||
static DimImg getMapLength (DimImg pixelsCount) { return (pixelsCount+7)/8; }
|
||||
static inline DimImg getMapLength (DimImg pixelsCount);
|
||||
|
||||
/*! Vérifie si un index est sur la map ou une bordure, en se basant sur le bit de l'index idx de la map */
|
||||
bool isBorder (DimImg idx) const { return map ? map[idx/8] & (1 << (idx%8)) : false; }
|
||||
inline bool isBorder (DimImg idx) const;
|
||||
|
||||
/*! Vérifie si un point est sur la map ou une bordure en appelant la méthode précédente après avoir converti le point en index */
|
||||
bool isBorder (const Point &p) const { return map ? isBorder (pointToId (size, p)) : false; }
|
||||
inline bool isBorder (const Point &p) const;
|
||||
|
||||
/*! Supprime toutes les occurences de bordure à l'index idx */
|
||||
void clearBorder (DimImg idx) { map[idx/8] &= ~(1 << (idx%8)); }
|
||||
inline void clearBorder (DimImg idx);
|
||||
|
||||
/*! Supprime toutes les occurences de bordure en appelant la méthode précédente après avoir converti le point en index */
|
||||
void clearBorder (const Point &p) { clearBorder (pointToId (size, p)); }
|
||||
inline void clearBorder (const Point &p);
|
||||
|
||||
/*! Rajoute une occurence de bordure à l'index indiqué */
|
||||
void setBorder (DimImg idx) { map[idx/8] |= (1 << (idx%8)); }
|
||||
inline void setBorder (DimImg idx);
|
||||
|
||||
/*! Rajoute une occurence de bordure en appelant la méthode précédente après avoir converti le point en index */
|
||||
void setBorder (const Point &p) { setBorder (pointToId (size, p)); }
|
||||
inline void setBorder (const Point &p);
|
||||
|
||||
/*! Construit par défault sans aucune bordure */
|
||||
Border ()
|
||||
: pixelsCount (0), mapLength (0), size (), map (NULL) {
|
||||
}
|
||||
inline Border ();
|
||||
|
||||
/*! Construit Border, les valeurs de map dépendent de defaultVal */
|
||||
Border (const Size &size, bool defaultVal)
|
||||
: pixelsCount (getPixelsCount (size)), mapLength (getMapLength (pixelsCount)), size (size) {
|
||||
map = new uint8_t [mapLength];
|
||||
reset (defaultVal);
|
||||
}
|
||||
~Border () { if (map) delete [] map; }
|
||||
inline Border (const Size &size, bool defaultVal);
|
||||
inline ~Border ();
|
||||
|
||||
void reset (bool defaultVal) {
|
||||
std::fill_n (map, mapLength, defaultVal ? 0xFF : 0);
|
||||
if (!(mapLength && defaultVal))
|
||||
return;
|
||||
map[mapLength-1] &= 0xFF >> (8-(pixelsCount%8))%8;
|
||||
}
|
||||
inline void reset (bool defaultVal);
|
||||
|
||||
/*! Compte le nombre de pixels considérés comme de la bordure */
|
||||
DimImg borderCount () {
|
||||
DimImg result = 0;
|
||||
for (DimImg i = 0; i < mapLength; ++i)
|
||||
result += bitCount[map[i]];
|
||||
return result;
|
||||
}
|
||||
|
||||
inline DimImg borderCount ();
|
||||
|
||||
private:
|
||||
/*! Nombre de pixels dans l'image */
|
||||
@ -79,7 +62,8 @@ namespace otb {
|
||||
/*! Tableau "simplifié" des pixels */
|
||||
uint8_t *map;
|
||||
};
|
||||
|
||||
|
||||
#include "Border.tpp"
|
||||
|
||||
} //arrayTree
|
||||
} // triskele
|
||||
|
@ -90,7 +90,7 @@ inline DimImg
|
||||
GraphWalker::forEachVertexIdx (const Funct &lambda /*lambda (idx)*/) const {
|
||||
DimImg maxCount = vertexMaxCount ();
|
||||
DimImg vertexCount = 0;
|
||||
for (DimSideImg idx = 0; idx < maxCount; ++idx)
|
||||
for (DimImg idx = 0; idx < maxCount; ++idx)
|
||||
GRAPHWALKER_CALL_LAMBDA_IDX (idx, vertexCount, lambda (idx));
|
||||
return vertexCount;
|
||||
}
|
||||
|
@ -21,8 +21,8 @@ namespace otb {
|
||||
DimImg *leaders;
|
||||
|
||||
public:
|
||||
Leader () : size (0), leaders (NULL) {}
|
||||
~Leader () { free (); }
|
||||
inline Leader ();
|
||||
inline ~Leader ();
|
||||
|
||||
/*! Remet à 0 et redéfinit la taille des tableaux */
|
||||
inline void book (DimImg vertexCount);
|
||||
@ -39,7 +39,7 @@ namespace otb {
|
||||
/*! Rédéfinit les leaders : a et tous les leaders de a ont pour leader r */
|
||||
inline void link (DimImg a, const DimImg &r);
|
||||
|
||||
inline DimImg *getLeaders () { return leaders; }
|
||||
inline DimImg *getLeaders ();
|
||||
};
|
||||
|
||||
#include "Leader.tpp"
|
||||
|
@ -1,6 +1,57 @@
|
||||
#ifndef _OTB_TRISKELE_ARRAY_TREE_LEADER_TPP
|
||||
#define _OTB_TRISKELE_ARRAY_TREE_LEADER_TPP
|
||||
|
||||
// ========================================
|
||||
inline
|
||||
Leader::Leader ()
|
||||
: size (0),
|
||||
leaders (NULL) {
|
||||
}
|
||||
|
||||
inline
|
||||
Leader::~Leader () {
|
||||
free ();
|
||||
}
|
||||
|
||||
// ========================================
|
||||
inline void
|
||||
Leader::book (DimImg vertexCount) {
|
||||
#ifdef SMART_LOG
|
||||
DEF_LOG ("Leader::book", "vertexCount:" << vertexCount);
|
||||
#endif
|
||||
if (vertexCount == size) {
|
||||
reset ();
|
||||
return;
|
||||
}
|
||||
free ();
|
||||
if (!vertexCount)
|
||||
return;
|
||||
size = vertexCount;
|
||||
leaders = new DimImg [vertexCount];
|
||||
reset ();
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
inline void
|
||||
Leader::free () {
|
||||
#ifdef SMART_LOG
|
||||
DEF_LOG ("Leader::free", "");
|
||||
#endif
|
||||
if (leaders)
|
||||
delete [] leaders;
|
||||
leaders = NULL;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
inline void
|
||||
Leader::reset () {
|
||||
if (!size)
|
||||
return;
|
||||
// XXX dealThreadFill_n
|
||||
std::fill_n (leaders, size, DimImg_MAX);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
inline DimImg
|
||||
Leader::find (DimImg a) const {
|
||||
@ -34,42 +85,9 @@ Leader::link (DimImg a, const DimImg &r) {
|
||||
}
|
||||
|
||||
// ========================================
|
||||
inline void
|
||||
Leader::book (DimImg vertexCount) {
|
||||
#ifdef SMART_LOG
|
||||
DEF_LOG ("Leader::book", "vertexCount:" << vertexCount);
|
||||
#endif
|
||||
if (vertexCount == size) {
|
||||
reset ();
|
||||
return;
|
||||
}
|
||||
free ();
|
||||
if (!vertexCount)
|
||||
return;
|
||||
size = vertexCount;
|
||||
leaders = new DimImg [vertexCount];
|
||||
reset ();
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
inline void
|
||||
Leader::reset () {
|
||||
if (!size)
|
||||
return;
|
||||
// XXX dealThreadFill_n
|
||||
std::fill_n (leaders, size, DimImg_MAX);
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
inline void
|
||||
Leader::free () {
|
||||
#ifdef SMART_LOG
|
||||
DEF_LOG ("Leader::free", "");
|
||||
#endif
|
||||
if (leaders)
|
||||
delete [] leaders;
|
||||
leaders = NULL;
|
||||
size = 0;
|
||||
inline DimImg *
|
||||
Leader::getLeaders () {
|
||||
return leaders;
|
||||
}
|
||||
|
||||
// ========================================
|
||||
|
@ -18,65 +18,49 @@ namespace otb {
|
||||
protected:
|
||||
const PixelT *pixels;
|
||||
const Size size;
|
||||
DimNodeId pointIdx (const Point &p) const { return point2idx (size, p); }
|
||||
inline DimNodeId pointIdx (const Point &p) const;
|
||||
PixelT halfPixel, maxPixel;
|
||||
public:
|
||||
const Size &getSize () const { return size; }
|
||||
const PixelT &getValue (const DimImg &idx) const { return pixels[idx]; }
|
||||
const PixelT &getValue (const Point &p) const { return getValue (pointIdx (p)); }
|
||||
bool getDecr () const { return false; }
|
||||
const PixelT &getMaxPixel () const { return maxPixel; }
|
||||
const PixelT &getHalfPixel () const { return halfPixel; }
|
||||
inline const Size &getSize () const;
|
||||
inline const PixelT &getValue (const DimImg &idx) const;
|
||||
inline const PixelT &getValue (const Point &p) const;
|
||||
inline bool getDecr () const;
|
||||
inline const PixelT &getMaxPixel () const;
|
||||
inline const PixelT &getHalfPixel () const;
|
||||
|
||||
PixelT *allocAP (const DimNodeId &nodeCapacity) const { return new PixelT [nodeCapacity]; }
|
||||
inline PixelT *allocAP (const DimNodeId &nodeCapacity) const;
|
||||
|
||||
WeightBase (const PixelT *pixels, const Size &size) : pixels (pixels), size (size) {
|
||||
maxPixel = std::numeric_limits<PixelT>::max ();
|
||||
// only if unsigned
|
||||
halfPixel = maxPixel / 2;
|
||||
if (typeid (PixelT) != typeid (float))
|
||||
halfPixel++;
|
||||
}
|
||||
inline WeightBase (const PixelT *pixels, const Size &size);
|
||||
};
|
||||
|
||||
template <typename PixelT, typename WeightT> struct WeightBase2 : public WeightBase<PixelT> {
|
||||
typedef WeightBase<PixelT> WB;
|
||||
|
||||
WeightBase2 (const PixelT *pixels, const Size &size)
|
||||
: WB (pixels, size) {}
|
||||
inline WeightBase2 (const PixelT *pixels, const Size &size);
|
||||
|
||||
static bool isWeightInf (const WeightT &a, const WeightT &b) { return a < b; }
|
||||
static bool isEdgeInf (const Edge<WeightT> &a, const Edge<WeightT> &b) { return isWeightInf (a.weight, b.weight); }
|
||||
static void sort (Edge<WeightT> *edges, DimEdge count) { std::sort (edges, edges+count, isEdgeInf); }
|
||||
static inline bool isWeightInf (const WeightT &a, const WeightT &b);
|
||||
static inline bool isEdgeInf (const Edge<WeightT> &a, const Edge<WeightT> &b);
|
||||
static inline void sort (Edge<WeightT> *edges, DimEdge count);
|
||||
|
||||
void copyPixelsBound (PixelT *leafAPTree,
|
||||
const DimImg &minVal, const DimImg &maxVal) const {
|
||||
for (DimImg i = minVal; i < maxVal; ++i)
|
||||
leafAPTree[i] = WB::pixels [i];
|
||||
}
|
||||
void weight2valueBound (PixelT *compAPTree, const WeightT *compWeights,
|
||||
const DimImg &minVal, const DimImg &maxVal) const {
|
||||
//memcpy (compAPTree+minVal, compWeights+minVal, maxVal-minVal);
|
||||
for (DimImg compIdx = minVal; compIdx < maxVal; ++compIdx)
|
||||
compAPTree[compIdx] = compWeights[compIdx];
|
||||
}
|
||||
inline void copyPixelsBound (PixelT *leafAPTree,
|
||||
const DimImg &minVal, const DimImg &maxVal) const;
|
||||
inline void weight2valueBound (PixelT *compAPTree, const WeightT *compWeights,
|
||||
const DimImg &minVal, const DimImg &maxVal) const;
|
||||
};
|
||||
|
||||
/*! Structure intégrant la façon dont est géré un poids pour un MinTree */
|
||||
template <typename PixelT, typename WeightT> struct MinWeight : public WeightBase2<PixelT, WeightT> {
|
||||
typedef WeightBase2<PixelT, WeightT> WB;
|
||||
|
||||
bool getDecr () const { return true; }
|
||||
static bool isWeightInf (const WeightT &a, const WeightT &b) { return a > b; }
|
||||
static bool isEdgeInf (const Edge<WeightT> &a, const Edge<WeightT> &b) { return isWeightInf (a.weight, b.weight); }
|
||||
static void sort (Edge<WeightT> *edges, DimEdge count) { std::sort (edges, edges+count, isEdgeInf); }
|
||||
inline bool getDecr () const;
|
||||
static inline bool isWeightInf (const WeightT &a, const WeightT &b);
|
||||
static inline bool isEdgeInf (const Edge<WeightT> &a, const Edge<WeightT> &b);
|
||||
static inline void sort (Edge<WeightT> *edges, DimEdge count);
|
||||
|
||||
MinWeight (const PixelT *pixels, const Size &size)
|
||||
: WB (pixels, size) {}
|
||||
inline MinWeight (const PixelT *pixels, const Size &size);
|
||||
|
||||
WeightT getWeight (const DimImg &idx) const { return WB::getValue (idx); }
|
||||
WeightT getWeight (const Point &a, const Point &b) const { return std::min (getWeight (WB::pointIdx (a)),
|
||||
getWeight (WB::pointIdx (b))); }
|
||||
inline WeightT getWeight (const DimImg &idx) const;
|
||||
inline WeightT getWeight (const Point &a, const Point &b) const;
|
||||
};
|
||||
|
||||
// ========================================
|
||||
@ -84,12 +68,10 @@ namespace otb {
|
||||
template <typename PixelT, typename WeightT> struct MaxWeight : public WeightBase2<PixelT, WeightT> {
|
||||
typedef WeightBase2<PixelT, WeightT> WB;
|
||||
|
||||
MaxWeight (const PixelT *pixels, const Size &size)
|
||||
: WB (pixels, size) {}
|
||||
inline MaxWeight (const PixelT *pixels, const Size &size);
|
||||
|
||||
WeightT getWeight (const DimImg &idx) const { return WB::getValue (idx); }
|
||||
WeightT getWeight (const Point &a, const Point &b) const { return std::max (getWeight (WB::pointIdx (a)),
|
||||
getWeight (WB::pointIdx (b))); }
|
||||
inline WeightT getWeight (const DimImg &idx) const;
|
||||
inline WeightT getWeight (const Point &a, const Point &b) const;
|
||||
};
|
||||
|
||||
// ========================================
|
||||
@ -97,14 +79,10 @@ namespace otb {
|
||||
template <typename PixelT, typename WeightT> struct DiffWeight : public WeightBase2<PixelT, WeightT> {
|
||||
typedef WeightBase2<PixelT, WeightT> WB;
|
||||
|
||||
DiffWeight (const PixelT *pixels, const Size &size)
|
||||
: WB (pixels, size) {}
|
||||
inline DiffWeight (const PixelT *pixels, const Size &size);
|
||||
|
||||
WeightT getWeight (const DimImg &idx) const { return 0; }
|
||||
WeightT getWeight (const Point &a, const Point &b) const {
|
||||
PixelT va = WB::getValue (a), vb = WB::getValue (b);
|
||||
return std::max (va, vb) - std::min (va, vb);
|
||||
}
|
||||
inline WeightT getWeight (const DimImg &idx) const;
|
||||
inline WeightT getWeight (const Point &a, const Point &b) const;
|
||||
};
|
||||
|
||||
// ========================================
|
||||
@ -116,46 +94,24 @@ namespace otb {
|
||||
WeightT thresholdWeight;
|
||||
|
||||
public:
|
||||
bool getDecr () const { return true; }
|
||||
static bool isWeightInf (const WeightT &a, const WeightT &b) { return a > b; }
|
||||
static bool isEdgeInf (const Edge<WeightT> &a, const Edge<WeightT> &b) { return isWeightInf (a.weight, b.weight); }
|
||||
static void sort (Edge<WeightT> *edges, DimEdge count) { std::sort (edges, edges+count, isEdgeInf); }
|
||||
inline bool getDecr () const;
|
||||
static inline bool isWeightInf (const WeightT &a, const WeightT &b);
|
||||
static inline bool isEdgeInf (const Edge<WeightT> &a, const Edge<WeightT> &b);
|
||||
static inline void sort (Edge<WeightT> *edges, DimEdge count);
|
||||
|
||||
const PixelT &getMedian () const { return median; }
|
||||
const PixelT &getThresholdPixel () const { return thresholdPixel; }
|
||||
const WeightT &getThresholdWeight () const { return thresholdWeight; }
|
||||
inline const PixelT &getMedian () const;
|
||||
inline const PixelT &getThresholdPixel () const;
|
||||
inline const WeightT &getThresholdWeight () const;
|
||||
|
||||
WeightT value2weight (const PixelT &val) const {
|
||||
if (median < WB::halfPixel) {
|
||||
if (val >= thresholdPixel)
|
||||
return val;
|
||||
return val < median ? (median-val)*2 - 1 : (val-median)*2;
|
||||
}
|
||||
if (val < thresholdPixel)
|
||||
return WB::maxPixel - val;
|
||||
return val < median ? (median-val)*2 - 1 : (val-median)*2;
|
||||
}
|
||||
PixelT weight2value (const WeightT &weight) const {
|
||||
if (median < WB::halfPixel) {
|
||||
if (weight >= thresholdWeight)
|
||||
return weight;
|
||||
return int (weight) % 2 ? median - 1 - weight/2 : median + weight/2;
|
||||
}
|
||||
if (weight > thresholdWeight)
|
||||
return WB::maxPixel - weight;
|
||||
return int (weight) % 2 ? median - weight/2 : median + weight/2;
|
||||
}
|
||||
inline WeightT value2weight (const PixelT &val) const;
|
||||
inline PixelT weight2value (const WeightT &weight) const;
|
||||
|
||||
inline MedianWeight (const PixelT *pixels, const GraphWalker &graphWalker);
|
||||
|
||||
WeightT getWeight (const DimImg &idx) const { return value2weight (WB::getValue (idx)); }
|
||||
WeightT getWeight (const Point &a, const Point &b) const { return std::min (getWeight (WB::pointIdx (a)),
|
||||
getWeight (WB::pointIdx (b))); }
|
||||
void weight2valueBound (PixelT *compAPTree, const WeightT *compWeights,
|
||||
const DimImg &minVal, const DimImg &maxVal) const {
|
||||
for (DimImg compIdx = minVal; compIdx < maxVal; ++compIdx)
|
||||
compAPTree[compIdx] = weight2value (compWeights[compIdx]);
|
||||
}
|
||||
inline WeightT getWeight (const DimImg &idx) const;
|
||||
inline WeightT getWeight (const Point &a, const Point &b) const;
|
||||
inline void weight2valueBound (PixelT *compAPTree, const WeightT *compWeights,
|
||||
const DimImg &minVal, const DimImg &maxVal) const;
|
||||
};
|
||||
|
||||
} // arrayTree
|
||||
|
@ -1,12 +1,290 @@
|
||||
#ifndef _OTB_TRISKELE_ARRAY_TREE_WEIGHT_TPP
|
||||
#define _OTB_TRISKELE_ARRAY_TREE_WEIGHT_TPP
|
||||
|
||||
// ========================================
|
||||
template <typename PixelT>
|
||||
inline DimNodeId
|
||||
WeightBase<PixelT>::pointIdx (const Point &p) const {
|
||||
return point2idx (size, p);
|
||||
}
|
||||
|
||||
template <typename PixelT>
|
||||
inline const Size &
|
||||
WeightBase<PixelT>::getSize () const {
|
||||
return size;
|
||||
}
|
||||
|
||||
template <typename PixelT>
|
||||
inline const PixelT &
|
||||
WeightBase<PixelT>::getValue (const DimImg &idx) const {
|
||||
return pixels[idx];
|
||||
}
|
||||
|
||||
template <typename PixelT>
|
||||
inline const PixelT &
|
||||
WeightBase<PixelT>::getValue (const Point &p) const {
|
||||
return getValue (pointIdx (p));
|
||||
}
|
||||
|
||||
template <typename PixelT>
|
||||
inline bool
|
||||
WeightBase<PixelT>::getDecr () const {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename PixelT>
|
||||
inline const PixelT &
|
||||
WeightBase<PixelT>::getMaxPixel () const {
|
||||
return maxPixel;
|
||||
}
|
||||
|
||||
template <typename PixelT>
|
||||
inline const PixelT &
|
||||
WeightBase<PixelT>::getHalfPixel () const {
|
||||
return halfPixel;
|
||||
}
|
||||
|
||||
template <typename PixelT>
|
||||
inline PixelT *
|
||||
WeightBase<PixelT>::allocAP (const DimNodeId &nodeCapacity) const {
|
||||
return new PixelT [nodeCapacity];
|
||||
}
|
||||
|
||||
template <typename PixelT>
|
||||
inline
|
||||
WeightBase<PixelT>::WeightBase (const PixelT *pixels, const Size &size)
|
||||
: pixels (pixels),
|
||||
size (size) {
|
||||
maxPixel = std::numeric_limits<PixelT>::max ();
|
||||
// only if unsigned
|
||||
halfPixel = maxPixel / 2;
|
||||
if (typeid (PixelT) != typeid (float))
|
||||
halfPixel++;
|
||||
}
|
||||
|
||||
// ========================================
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline MedianWeight<PixelT, WeightT>::MedianWeight (const PixelT *pixels, const GraphWalker &graphWalker)
|
||||
inline
|
||||
WeightBase2<PixelT, WeightT>::WeightBase2 (const PixelT *pixels, const Size &size)
|
||||
: WB (pixels, size) {
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline bool
|
||||
WeightBase2<PixelT, WeightT>::isWeightInf (const WeightT &a, const WeightT &b) {
|
||||
return a < b;
|
||||
}
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline bool
|
||||
WeightBase2<PixelT, WeightT>::isEdgeInf (const Edge<WeightT> &a, const Edge<WeightT> &b) {
|
||||
return isWeightInf (a.weight, b.weight);
|
||||
}
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline void
|
||||
WeightBase2<PixelT, WeightT>::sort (Edge<WeightT> *edges, DimEdge count) {
|
||||
std::sort (edges, edges+count, isEdgeInf);
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline void
|
||||
WeightBase2<PixelT, WeightT>::copyPixelsBound (PixelT *leafAPTree, const DimImg &minVal, const DimImg &maxVal) const {
|
||||
for (DimImg i = minVal; i < maxVal; ++i)
|
||||
leafAPTree[i] = WB::pixels [i];
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline void
|
||||
WeightBase2<PixelT, WeightT>::weight2valueBound (PixelT *compAPTree, const WeightT *compWeights,
|
||||
const DimImg &minVal, const DimImg &maxVal) const {
|
||||
//memcpy (compAPTree+minVal, compWeights+minVal, maxVal-minVal);
|
||||
for (DimImg compIdx = minVal; compIdx < maxVal; ++compIdx)
|
||||
compAPTree[compIdx] = compWeights[compIdx];
|
||||
}
|
||||
|
||||
// ========================================
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline bool
|
||||
MinWeight<PixelT, WeightT>::getDecr () const {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline bool
|
||||
MinWeight<PixelT, WeightT>::isWeightInf (const WeightT &a, const WeightT &b) {
|
||||
return a > b;
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline bool
|
||||
MinWeight<PixelT, WeightT>::isEdgeInf (const Edge<WeightT> &a, const Edge<WeightT> &b) {
|
||||
return isWeightInf (a.weight, b.weight);
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline void
|
||||
MinWeight<PixelT, WeightT>::sort (Edge<WeightT> *edges, DimEdge count) {
|
||||
std::sort (edges, edges+count, isEdgeInf);
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline
|
||||
MinWeight<PixelT, WeightT>::MinWeight (const PixelT *pixels, const Size &size)
|
||||
: WB (pixels, size) {
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline WeightT
|
||||
MinWeight<PixelT, WeightT>::getWeight (const DimImg &idx) const {
|
||||
return WB::getValue (idx);
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline WeightT
|
||||
MinWeight<PixelT, WeightT>::getWeight (const Point &a, const Point &b) const {
|
||||
return std::min (getWeight (WB::pointIdx (a)),
|
||||
getWeight (WB::pointIdx (b)));
|
||||
}
|
||||
|
||||
// ========================================
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline
|
||||
MaxWeight<PixelT, WeightT>::MaxWeight (const PixelT *pixels, const Size &size)
|
||||
: WB (pixels, size) {
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline WeightT
|
||||
MaxWeight<PixelT, WeightT>::getWeight (const DimImg &idx) const {
|
||||
return WB::getValue (idx);
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline WeightT
|
||||
MaxWeight<PixelT, WeightT>::getWeight (const Point &a, const Point &b) const {
|
||||
return std::max (getWeight (WB::pointIdx (a)),
|
||||
getWeight (WB::pointIdx (b)));
|
||||
}
|
||||
|
||||
// ========================================
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline
|
||||
DiffWeight<PixelT, WeightT>::DiffWeight (const PixelT *pixels, const Size &size)
|
||||
: WB (pixels, size) {
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline WeightT
|
||||
DiffWeight<PixelT, WeightT>::getWeight (const DimImg &idx) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline WeightT
|
||||
DiffWeight<PixelT, WeightT>::getWeight (const Point &a, const Point &b) const {
|
||||
PixelT va = WB::getValue (a), vb = WB::getValue (b);
|
||||
return std::max (va, vb) - std::min (va, vb);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline bool
|
||||
MedianWeight<PixelT, WeightT>::getDecr () const {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline bool
|
||||
MedianWeight<PixelT, WeightT>::isWeightInf (const WeightT &a, const WeightT &b) {
|
||||
return a > b;
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline bool
|
||||
MedianWeight<PixelT, WeightT>::isEdgeInf (const Edge<WeightT> &a, const Edge<WeightT> &b) {
|
||||
return isWeightInf (a.weight, b.weight);
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline void
|
||||
MedianWeight<PixelT, WeightT>::sort (Edge<WeightT> *edges, DimEdge count) {
|
||||
std::sort (edges, edges+count, isEdgeInf);
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline const PixelT &
|
||||
MedianWeight<PixelT, WeightT>::getMedian () const {
|
||||
return median;
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline const PixelT &
|
||||
MedianWeight<PixelT, WeightT>::getThresholdPixel () const {
|
||||
return thresholdPixel;
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline const WeightT &
|
||||
MedianWeight<PixelT, WeightT>::getThresholdWeight () const {
|
||||
return thresholdWeight;
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline WeightT
|
||||
MedianWeight<PixelT, WeightT>::value2weight (const PixelT &val) const {
|
||||
if (median < WB::halfPixel) {
|
||||
if (val >= thresholdPixel)
|
||||
return val;
|
||||
return val < median ? (median-val)*2 - 1 : (val-median)*2;
|
||||
}
|
||||
if (val < thresholdPixel)
|
||||
return WB::maxPixel - val;
|
||||
return val < median ? (median-val)*2 - 1 : (val-median)*2;
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline PixelT
|
||||
MedianWeight<PixelT, WeightT>::weight2value (const WeightT &weight) const {
|
||||
if (median < WB::halfPixel) {
|
||||
if (weight >= thresholdWeight)
|
||||
return weight;
|
||||
return int (weight) % 2 ? median - 1 - weight/2 : median + weight/2;
|
||||
}
|
||||
if (weight > thresholdWeight)
|
||||
return WB::maxPixel - weight;
|
||||
return int (weight) % 2 ? median - weight/2 : median + weight/2;
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline WeightT
|
||||
MedianWeight<PixelT, WeightT>::getWeight (const DimImg &idx) const {
|
||||
return value2weight (WB::getValue (idx));
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline WeightT
|
||||
MedianWeight<PixelT, WeightT>::getWeight (const Point &a, const Point &b) const {
|
||||
return std::min (getWeight (WB::pointIdx (a)),
|
||||
getWeight (WB::pointIdx (b)));
|
||||
}
|
||||
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline void
|
||||
MedianWeight<PixelT, WeightT>::weight2valueBound (PixelT *compAPTree, const WeightT *compWeights,
|
||||
const DimImg &minVal, const DimImg &maxVal) const {
|
||||
for (DimImg compIdx = minVal; compIdx < maxVal; ++compIdx)
|
||||
compAPTree[compIdx] = weight2value (compWeights[compIdx]);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
template <typename PixelT, typename WeightT>
|
||||
inline
|
||||
MedianWeight<PixelT, WeightT>::MedianWeight (const PixelT *pixels, const GraphWalker &graphWalker)
|
||||
: WB (pixels, graphWalker.size) {
|
||||
median = graphWalker.getMedian<WeightT> (*this);
|
||||
thresholdPixel = median < WB::halfPixel ? median * 2 : WB::maxPixel - (WB::maxPixel-median) * 2;
|
||||
thresholdWeight = median < WB::halfPixel ? median * 2 : (WB::maxPixel-median) * 2;
|
||||
}
|
||||
|
||||
// ========================================
|
||||
|
||||
#endif // _OTB_TRISKELE_ARRAY_TREE_WEIGHT_TPP
|
||||
|
@ -47,18 +47,12 @@ namespace otb {
|
||||
/*!
|
||||
* Opérateur de flux sur les connectivités
|
||||
*/
|
||||
inline std::ostream &operator << (std::ostream &out, const Connectivity &c) {
|
||||
BOOST_ASSERT (c >= 0 && c < 4);
|
||||
return out << connectivityName[c];
|
||||
}
|
||||
inline std::ostream &operator << (std::ostream &out, const Connectivity &c);
|
||||
|
||||
/*!
|
||||
* Opérateur de flux sur les TileItem
|
||||
*/
|
||||
inline std::ostream &operator << (std::ostream &out, const TileItem &t) {
|
||||
BOOST_ASSERT (t >= 0 && t < 3);
|
||||
return out << tileItemName[t];
|
||||
}
|
||||
inline std::ostream &operator << (std::ostream &out, const TileItem &t);
|
||||
|
||||
template <typename WeightT> struct Edge {
|
||||
Point points[2];
|
||||
@ -67,51 +61,30 @@ namespace otb {
|
||||
|
||||
/*! Effectue l'échange entre 2 Edge */
|
||||
template <typename WeightT>
|
||||
inline void swapEdge (Edge<WeightT> &a, Edge<WeightT> &b) {
|
||||
Edge<WeightT> c = a;
|
||||
a = b;
|
||||
b = c;
|
||||
}
|
||||
inline void swapEdge (Edge<WeightT> &a, Edge<WeightT> &b);
|
||||
|
||||
/*! Opérateur de flux sur les voisins */
|
||||
template <typename WeightT>
|
||||
inline std::ostream &operator << (std::ostream &out, const Edge<WeightT> &edge) {
|
||||
return out << edge.points[0] << ":" << edge.points[1] << ":" << edge.weight;
|
||||
}
|
||||
inline std::ostream &operator << (std::ostream &out, const Edge<WeightT> &edge);
|
||||
template <typename WeightT>
|
||||
inline std::ostream &printEdge (std::ostream &out, const Edge<WeightT> &edge, const Size &size) {
|
||||
return out << edge.points[0] << ":" << edge.points[1] << ":" << edge.weight << ":"
|
||||
<< point2idx (size, edge.points[0]) << ":" << point2idx (size, edge.points[1]);
|
||||
}
|
||||
inline std::ostream &printEdge (std::ostream &out, const Edge<WeightT> &edge, const Size &size);
|
||||
|
||||
/*! Affiche tous les voisins d'un ensemble */
|
||||
template <typename Edge>
|
||||
inline std::ostream &printEdges (std::ostream &out, const std::vector<Edge> &edges) {
|
||||
for (int i = 0; i < edges.size (); ++i)
|
||||
out << " " << edges [i];
|
||||
return out;
|
||||
}
|
||||
inline std::ostream &printEdges (std::ostream &out, const std::vector<Edge> &edges);
|
||||
|
||||
template <typename Edge>
|
||||
inline std::ostream &printEdges (std::ostream &out, const Edge edges[], const Size &size, const DimEdge edgesCount) {
|
||||
for (int i = 0; i < edgesCount; ++i)
|
||||
printEdge (out, edges[i], size) << std::endl;
|
||||
return out;
|
||||
}
|
||||
inline std::ostream &printEdges (std::ostream &out, const Edge edges[], const Size &size, const DimEdge edgesCount);
|
||||
|
||||
/*! Affiche tous les voisins d'un ensembles à l'aide de leurs coordonnées */
|
||||
template <typename Edge>
|
||||
inline std::ostream &printEdges (std::ostream &out, const std::vector<Edge> &edges, const Size &size) {
|
||||
for (int i = 0; i < edges.size (); ++i)
|
||||
out << " [" << point2idx (size, edges [i].points[0])
|
||||
<< " " << point2idx (size, edges [i].points[1])
|
||||
<< " " << edges [i].weight << "]";
|
||||
return out;
|
||||
}
|
||||
inline std::ostream &printEdges (std::ostream &out, const std::vector<Edge> &edges, const Size &size);
|
||||
|
||||
#include "triskeleArrayTreeBase.tpp"
|
||||
|
||||
} // arrayTree
|
||||
} // triskele
|
||||
} // otb
|
||||
|
||||
|
||||
|
||||
#endif // _OTB_TRISKELE_ARRAY_TREE_BASE_HPP
|
||||
|
@ -0,0 +1,63 @@
|
||||
#ifndef _OTB_TRISKELE_ARRAY_TREE_BASE_TPP
|
||||
#define _OTB_TRISKELE_ARRAY_TREE_BASE_TPP
|
||||
|
||||
inline std::ostream &
|
||||
operator << (std::ostream &out, const Connectivity &c) {
|
||||
BOOST_ASSERT (c >= 0 && c < 4);
|
||||
return out << connectivityName[c];
|
||||
}
|
||||
|
||||
inline std::ostream &
|
||||
operator << (std::ostream &out, const TileItem &t) {
|
||||
BOOST_ASSERT (t >= 0 && t < 3);
|
||||
return out << tileItemName[t];
|
||||
}
|
||||
|
||||
template <typename WeightT>
|
||||
inline void
|
||||
swapEdge (Edge<WeightT> &a, Edge<WeightT> &b) {
|
||||
Edge<WeightT> c = a;
|
||||
a = b;
|
||||
b = c;
|
||||
}
|
||||
|
||||
template <typename WeightT>
|
||||
inline std::ostream &
|
||||
operator << (std::ostream &out, const Edge<WeightT> &edge) {
|
||||
return out << edge.points[0] << ":" << edge.points[1] << ":" << edge.weight;
|
||||
}
|
||||
|
||||
template <typename WeightT>
|
||||
inline std::ostream &
|
||||
printEdge (std::ostream &out, const Edge<WeightT> &edge, const Size &size) {
|
||||
return out << edge.points[0] << ":" << edge.points[1] << ":" << ((uint32_t) edge.weight) << ":"
|
||||
<< point2idx (size, edge.points[0]) << ":" << point2idx (size, edge.points[1]);
|
||||
}
|
||||
|
||||
template <typename Edge>
|
||||
inline std::ostream &
|
||||
printEdges (std::ostream &out, const std::vector<Edge> &edges) {
|
||||
for (int i = 0; i < edges.size (); ++i)
|
||||
out << " " << edges [i];
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename Edge>
|
||||
inline std::ostream &
|
||||
printEdges (std::ostream &out, const Edge edges[], const Size &size, const DimEdge edgesCount) {
|
||||
for (int i = 0; i < edgesCount; ++i)
|
||||
printEdge (out, edges[i], size) << std::endl;
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename Edge>
|
||||
inline std::ostream &
|
||||
printEdges (std::ostream &out, const std::vector<Edge> &edges, const Size &size) {
|
||||
for (int i = 0; i < edges.size (); ++i)
|
||||
out << " [" << point2idx (size, edges [i].points[0])
|
||||
<< " " << point2idx (size, edges [i].points[1])
|
||||
<< " " << edges [i].weight << "]";
|
||||
return out;
|
||||
}
|
||||
|
||||
#endif // _OTB_TRISKELE_ARRAY_TREE_BASE_TPP
|
@ -3,58 +3,78 @@
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <gdal/gdal_priv.h>
|
||||
|
||||
#include "triskeleBase.hpp"
|
||||
#include "triskeleDebug.hpp"
|
||||
#include "triskeleGdalGetType.hpp"
|
||||
|
||||
namespace otb {
|
||||
namespace triskele {
|
||||
namespace triskele {
|
||||
using namespace std;
|
||||
|
||||
template<typename PixelT>
|
||||
class Raster {
|
||||
private:
|
||||
Size size;
|
||||
PixelT *pixels;
|
||||
public:
|
||||
inline void setSize (const Size &size);
|
||||
inline const Size &getSize () const;
|
||||
inline const PixelT *getPixels () const;
|
||||
inline PixelT *getPixels ();
|
||||
inline DimNodeId pointIdx (const Point &p) const;
|
||||
inline PixelT getValue (const DimImg &idx) const;
|
||||
inline PixelT getValue (const Point &point) const;
|
||||
|
||||
inline Raster (const Size &size = NullSize);
|
||||
inline ~Raster ();
|
||||
};
|
||||
|
||||
// ========================================
|
||||
/** Interface Image */
|
||||
class IImage {
|
||||
public:
|
||||
void setFileName (string fileName);
|
||||
inline const string &getFileName () const;
|
||||
inline const Size &getSize () const;
|
||||
inline const DimChanel &getBandCount () const;
|
||||
inline GDALDataType getDataType () const;
|
||||
inline const bool isRead () const;
|
||||
inline const bool isEmpty () const;
|
||||
|
||||
IImage (const std::string &imageFileName = "");
|
||||
~IImage ();
|
||||
|
||||
void readImage ();
|
||||
void createImage (const Size &size, const GDALDataType &dataType, const DimChanel &nbOutputBands);
|
||||
void close ();
|
||||
|
||||
/** Interface Image */
|
||||
template<typename PixelT>
|
||||
class IImage {
|
||||
public:
|
||||
IImage (const std::string &imageFilename) : filename (imageFilename), read (false) {}
|
||||
~IImage () { close(); if (pixels) delete[] pixels; pixels = nullptr; }
|
||||
inline void readBand (Raster<PixelT> &raster, const DimChanel &band) const;
|
||||
template<typename PixelT>
|
||||
inline void readBand (Raster<PixelT> &raster, DimChanel band, const Point &cropOrig, const Size &cropSize) const;
|
||||
template<typename PixelT>
|
||||
inline void writeBand (Raster<PixelT> &raster, DimChanel band) const;
|
||||
|
||||
PixelT *getPixels () { return pixels; }
|
||||
|
||||
PixelT getValue (const DimImg &id) const { return pixels[id]; }
|
||||
PixelT getValue (const Point &point) const { return pixels[pointToId (size, point)]; }
|
||||
|
||||
const std::string &getFilename () const { return filename; }
|
||||
DimImg getPixelsCount () const { return (DimImg)size.width * (DimImg)size.height; }
|
||||
const Size &getSize () const { return size; }
|
||||
GDALDataType getDataType () const { return dataType; }
|
||||
|
||||
void readImage (const Point &cropOrig, const Size &cropSize);
|
||||
void readImage () { readImage (Point(), size); }
|
||||
|
||||
void close ();
|
||||
|
||||
const bool &isRead () const { return read; }
|
||||
bool isEmpty () const { return getPixelsCount () == 0; }
|
||||
|
||||
private:
|
||||
IImage (const IImage &o) = delete;
|
||||
IImage &operator= (const IImage&) = delete;
|
||||
private:
|
||||
IImage (const IImage &o) = delete;
|
||||
IImage &operator= (const IImage&) = delete;
|
||||
|
||||
private:
|
||||
static uint32_t gdalCount;
|
||||
|
||||
std::string filename;
|
||||
Size size;
|
||||
GDALDataType dataType;
|
||||
GDALDataset *gdalInputDataset;
|
||||
PixelT *pixels;
|
||||
bool read;
|
||||
};
|
||||
private:
|
||||
static size_t gdalCount;
|
||||
string fileName;
|
||||
Size size;
|
||||
DimChanel bandCount;
|
||||
GDALDataType dataType;
|
||||
GDALDataset *gdalInputDataset;
|
||||
GDALDataset *gdalOutputDataset;
|
||||
bool read;
|
||||
};
|
||||
|
||||
#include "IImage.tpp"
|
||||
|
||||
} // triskele
|
||||
} // otb
|
||||
} // triskele
|
||||
|
||||
#endif // _OTB_TRISKELE_I_IMAGE_HPP
|
||||
|
@ -1,42 +1,143 @@
|
||||
#ifndef _OTB_TRISKELE_I_IMAGE_TPP
|
||||
#define _OTB_TRISKELE_I_IMAGE_TPP
|
||||
|
||||
// ========================================
|
||||
template<typename PixelT>
|
||||
uint32_t
|
||||
IImage<PixelT>::gdalCount = 0;
|
||||
|
||||
template<typename PixelT>
|
||||
void
|
||||
IImage<PixelT>::readImage (const Point &cropOrig, const Size &cropSize) {
|
||||
DEF_LOG ("IImage::readImage", "filename: " << filename);
|
||||
if (!gdalCount++)
|
||||
GDALAllRegister ();
|
||||
gdalInputDataset = (GDALDataset *) GDALOpen (filename.c_str (), GA_ReadOnly);
|
||||
if (!gdalInputDataset) {
|
||||
dataType = GDT_Unknown;
|
||||
std::cerr << "GDALError: can't define dataset" << std::endl;
|
||||
inline void
|
||||
Raster<PixelT>::setSize (const Size &size) {
|
||||
if (this->size == size)
|
||||
return;
|
||||
}
|
||||
size = Size (gdalInputDataset->GetRasterXSize (), gdalInputDataset->GetRasterYSize ());
|
||||
LOG ("size: " << size);
|
||||
pixels = new PixelT[getPixelsCount ()];
|
||||
LOG ("bandsCount: " << gdalInputDataset->GetRasterCount ());
|
||||
GDALRasterBand &poBand = *gdalInputDataset->GetRasterBand (1);
|
||||
CPLErr err = poBand.RasterIO (GF_Read, cropOrig.x, cropOrig.y, cropSize.width, cropSize.height, pixels, cropSize.width, cropSize.height,
|
||||
toGDALType (getType ((PixelT) 0)), 0, 0);
|
||||
if (err != CE_None)
|
||||
std::cerr << "GDALError: can't acces " << filename << std::endl;
|
||||
if (pixels)
|
||||
delete [] pixels;
|
||||
this->size = size;
|
||||
pixels = new PixelT [DimImg (size.width)*DimImg (size.height)];
|
||||
}
|
||||
|
||||
template<typename PixelT>
|
||||
void
|
||||
IImage<PixelT>::close () {
|
||||
if (gdalInputDataset) {
|
||||
GDALClose (gdalInputDataset);
|
||||
gdalInputDataset = nullptr;
|
||||
if (!--gdalCount)
|
||||
GDALDestroyDriverManager ();
|
||||
}
|
||||
inline const Size &
|
||||
Raster<PixelT>::getSize () const {
|
||||
return size;
|
||||
}
|
||||
|
||||
template<typename PixelT>
|
||||
inline const PixelT *
|
||||
Raster<PixelT>::getPixels () const {
|
||||
return pixels;
|
||||
}
|
||||
|
||||
template<typename PixelT>
|
||||
inline PixelT *
|
||||
Raster<PixelT>::getPixels () {
|
||||
return pixels;
|
||||
}
|
||||
|
||||
template<typename PixelT>
|
||||
inline DimNodeId
|
||||
Raster<PixelT>::pointIdx (const Point &p) const {
|
||||
return point2idx (size, p);
|
||||
}
|
||||
|
||||
template<typename PixelT>
|
||||
inline PixelT
|
||||
Raster<PixelT>::getValue (const DimImg &idx) const {
|
||||
return pixels[idx];
|
||||
}
|
||||
|
||||
template<typename PixelT>
|
||||
inline PixelT
|
||||
Raster<PixelT>::getValue (const Point &point) const {
|
||||
return pixels [pointIdx (point)];
|
||||
}
|
||||
|
||||
|
||||
template<typename PixelT>
|
||||
inline
|
||||
Raster<PixelT>::Raster (const Size &size)
|
||||
: size (NullSize),
|
||||
pixels (nullptr) {
|
||||
setSize (size);
|
||||
}
|
||||
|
||||
template<typename PixelT>
|
||||
inline
|
||||
Raster<PixelT>::~Raster () {
|
||||
if (pixels)
|
||||
delete [] pixels;
|
||||
pixels = nullptr;
|
||||
}
|
||||
|
||||
// ========================================
|
||||
inline void
|
||||
IImage::setFileName (string fileName) {
|
||||
if (this->fileName == fileName)
|
||||
return;
|
||||
this->fileName = fileName;
|
||||
if (read)
|
||||
close ();
|
||||
}
|
||||
|
||||
inline const string &
|
||||
IImage::getFileName () const {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
inline const Size &
|
||||
IImage::getSize () const {
|
||||
return size;
|
||||
}
|
||||
|
||||
inline const DimChanel &
|
||||
IImage::getBandCount () const {
|
||||
return bandCount;
|
||||
}
|
||||
|
||||
inline GDALDataType
|
||||
IImage::getDataType () const {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
inline const bool
|
||||
IImage::isRead () const {
|
||||
return read;
|
||||
}
|
||||
|
||||
inline const bool
|
||||
IImage::isEmpty () const {
|
||||
return size == NullSize;
|
||||
}
|
||||
|
||||
// ========================================
|
||||
template<typename PixelT>
|
||||
inline void
|
||||
IImage::readBand (Raster<PixelT> &raster, const DimChanel &band) const {
|
||||
readBand (raster, band, NullPoint, size);
|
||||
}
|
||||
|
||||
template<typename PixelT>
|
||||
inline void
|
||||
IImage::readBand (Raster<PixelT> &raster, DimChanel band, const Point &cropOrig, const Size &cropSize) const {
|
||||
DEF_LOG ("IImage::readBand", "band: " << band << " crop: " << cropOrig << " - " << cropSize);
|
||||
BOOST_ASSERT (gdalInputDataset);
|
||||
raster.setSize (cropSize);
|
||||
band++; // !!! GDAL bands start at 1 (not 0 :-( )
|
||||
GDALRasterBand &poBand = *gdalInputDataset->GetRasterBand (band);
|
||||
GDALDataType bandType = poBand.GetRasterDataType ();
|
||||
CPLErr err = poBand.RasterIO (GF_Read, cropOrig.x, cropOrig.y, cropSize.width, cropSize.height,
|
||||
raster.getPixels (), cropSize.width, cropSize.height, bandType, 0, 0);
|
||||
if (err != CE_None)
|
||||
cerr << "IImage::readBand: can't acces " << fileName << endl;
|
||||
}
|
||||
|
||||
template<typename PixelT>
|
||||
inline void
|
||||
IImage::writeBand (Raster<PixelT> &raster, DimChanel band) const {
|
||||
DEF_LOG ("IImage::writeBand", "band: " << band);
|
||||
BOOST_ASSERT (gdalOutputDataset);
|
||||
band++; // !!! GDAL layers starts at 1 (not 0 :-( )
|
||||
GDALRasterBand &poBand = *gdalOutputDataset->GetRasterBand (band);
|
||||
CPLErr err = poBand.RasterIO (GF_Write, 0, 0, size.width, size.height, raster.getPixels (), size.width, size.height, dataType, 0, 0);
|
||||
if (err != CE_None)
|
||||
cerr << "IImage::writeBand: can't acces " << fileName << endl;
|
||||
}
|
||||
|
||||
#endif // _OTB_TRISKELE_I_IMAGE_TPP
|
||||
|
@ -16,7 +16,7 @@ namespace otb {
|
||||
|
||||
enum State {
|
||||
Void = 0,
|
||||
Initialized = 1,
|
||||
Initialized = 1 << 0,
|
||||
Constructed = 1 << 1
|
||||
};
|
||||
|
||||
@ -49,48 +49,48 @@ namespace otb {
|
||||
// Constructors, destructor and resize method (does the same as the constructors)
|
||||
|
||||
Tree (const DimSideImg &width, const DimSideImg &height);
|
||||
Tree (const DimImg &leafCount = 0);
|
||||
Tree (const DimImg &leafCount = 0); // XXX
|
||||
~Tree ();
|
||||
|
||||
/*! clear values according to the size defined */
|
||||
void clear ();
|
||||
|
||||
void resize (const DimSideImg &width, const DimSideImg &height);
|
||||
void resize (const DimImg &leafCount);
|
||||
void resize (const DimImg &leafCount); // XXX
|
||||
|
||||
// Setter for nodeCount and size
|
||||
void setNodeCount (const DimImg &newNodeCount) { nodeCount = newNodeCount; }
|
||||
void setSize (const Size &newSize) { size = newSize; }
|
||||
inline void setNodeCount (const DimImg &newNodeCount);
|
||||
inline void setSize (const Size &newSize);
|
||||
|
||||
// Get the tree state and the size
|
||||
State getState () const { return state; }
|
||||
Size getSize () const { return size; }
|
||||
inline State getState () const;
|
||||
inline Size getSize () const;
|
||||
|
||||
// Getters for tree structure
|
||||
DimNodeId getRoot () const { return nodeCount-1; }
|
||||
DimNodeId getAbsRoot () const { return nodeCount-1+leafCount; }
|
||||
DimNodeId getCompCount () const { return nodeCount-leafCount; }
|
||||
inline DimNodeId getRoot () const;
|
||||
inline DimNodeId getAbsRoot () const;
|
||||
inline DimNodeId getCompCount () const;
|
||||
|
||||
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; }
|
||||
inline const DimNodeId &getParent (const DimNodeId &idx) const;
|
||||
inline const DimNodeId &getLeafParent (const DimNodeId &idx) const;
|
||||
inline const DimNodeId &getCompParent (const DimNodeId &idx) const;
|
||||
inline const DimNodeId &getChildrenCount (const DimImg &idx) const;
|
||||
inline const DimSideImg &getLeafCount () const;
|
||||
inline const DimSideImg &getNodeCount () const;
|
||||
|
||||
// Functions to apply to specific entities
|
||||
template<typename FuncToApply>
|
||||
void forEachLeaf (const FuncToApply &f /* f (DimNodeId leafId) */) const;
|
||||
|
||||
template<typename FuncToApply>
|
||||
void forEachComp (const FuncToApply &f /* f (DimNodeId compId) */) const;
|
||||
inline void forEachComp (const FuncToApply &f /* f (DimNodeId compId) */) const;
|
||||
|
||||
template<typename FuncToApply>
|
||||
void forEachChild (const DimNodeId &parentId, const FuncToApply &f /* f (DimNodeId childId) */) const;
|
||||
inline void forEachChild (const DimNodeId &parentId, const FuncToApply &f /* f (DimNodeId childId) */) const;
|
||||
|
||||
#ifdef SMART_LOG
|
||||
#ifdef ENABLE_LOG
|
||||
// Print info about the tree
|
||||
void printTree (const Size &size, const bool &rec);
|
||||
void printTree () const;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -1,15 +1,73 @@
|
||||
#ifndef _OTB_TRISKELE_TREE_TPP
|
||||
#define _OTB_TRISKELE_TREE_TPP
|
||||
|
||||
inline void
|
||||
Tree::setNodeCount (const DimImg &newNodeCount) {
|
||||
nodeCount = newNodeCount;
|
||||
}
|
||||
inline void
|
||||
Tree::setSize (const Size &newSize) {
|
||||
size = newSize;
|
||||
}
|
||||
|
||||
inline State
|
||||
Tree::getState () const {
|
||||
return state;
|
||||
}
|
||||
|
||||
inline Size
|
||||
Tree::getSize () const {
|
||||
return size;
|
||||
}
|
||||
|
||||
inline DimNodeId
|
||||
Tree::getRoot () const {
|
||||
return nodeCount-1;
|
||||
}
|
||||
inline DimNodeId
|
||||
Tree::getAbsRoot () const {
|
||||
return nodeCount-1+leafCount;
|
||||
}
|
||||
inline DimNodeId
|
||||
Tree::getCompCount () const {
|
||||
return nodeCount-leafCount;
|
||||
}
|
||||
|
||||
inline const DimNodeId &
|
||||
Tree::getParent (const DimNodeId &idx) const {
|
||||
return leafParents[idx];
|
||||
}
|
||||
inline const DimNodeId &
|
||||
Tree::getLeafParent (const DimNodeId &idx) const {
|
||||
return leafParents[idx];
|
||||
}
|
||||
inline const DimNodeId &
|
||||
Tree::getCompParent (const DimNodeId &idx) const {
|
||||
return compParents[idx];
|
||||
}
|
||||
inline const DimNodeId &
|
||||
Tree::getChildrenCount (const DimImg &idx) const {
|
||||
return childCount[idx];
|
||||
}
|
||||
inline const DimSideImg &
|
||||
Tree::getLeafCount () const {
|
||||
return leafCount;
|
||||
}
|
||||
inline const DimSideImg &
|
||||
Tree::getNodeCount () const {
|
||||
return nodeCount;
|
||||
}
|
||||
|
||||
|
||||
template<typename FuncToApply>
|
||||
void
|
||||
inline void
|
||||
Tree::forEachLeaf (const FuncToApply &f /* f (DimNodeId leafId) */) const {
|
||||
for (DimNodeId leafId = 0; leafId < leafCount; ++leafId)
|
||||
f (leafId);
|
||||
}
|
||||
|
||||
template<typename FuncToApply>
|
||||
void
|
||||
inline void
|
||||
Tree::forEachComp (const FuncToApply &f /* f (DimNodeId compId) */) const {
|
||||
DimNodeId compCount = nodeCount - leafCount;
|
||||
for (DimNodeId compId = 0; compId < compCount; ++compId)
|
||||
@ -17,7 +75,7 @@ Tree::forEachComp (const FuncToApply &f /* f (DimNodeId compId) */) const {
|
||||
}
|
||||
|
||||
template<typename FuncToApply>
|
||||
void
|
||||
inline void
|
||||
Tree::forEachChild (const DimNodeId &parentId, const FuncToApply &f /* f (DimNodeId childId) */) const {
|
||||
DimNodeId minChild = childCount[parentId], maxChild = childCount[parentId+1];
|
||||
for (DimNodeId childId = minChild; childId < maxChild; ++childId)
|
||||
|
@ -10,44 +10,27 @@ namespace otb {
|
||||
class TreeBuilder {
|
||||
public:
|
||||
|
||||
static void
|
||||
buildTree (Tree &tree, TreeBuilder &builder) { builder.buildTree (tree); }
|
||||
|
||||
static void
|
||||
buildTree (Tree &tree, TreeBuilder &&builder) { builder.buildTree (tree); }
|
||||
|
||||
virtual void
|
||||
buildTree (Tree &tree) { std::cout << "Test" << std::endl; }
|
||||
static inline void buildTree (Tree &tree, TreeBuilder &builder);
|
||||
static inline void buildTree (Tree &tree, TreeBuilder &&builder);
|
||||
virtual inline void buildTree (Tree &tree);
|
||||
|
||||
protected:
|
||||
// Used to set the attributes below with the tree
|
||||
inline void updateAttributes (Tree &tree);
|
||||
inline DimNodeId getCompCount () const;
|
||||
inline void setNodeCount (Tree &tree, DimNodeId nodeCount);
|
||||
|
||||
inline void updateAttributes (Tree &tree) {
|
||||
leafCount = tree.leafCount;
|
||||
nodeCount = tree.nodeCount;
|
||||
leafParents = tree.leafParents;
|
||||
compParents = tree.compParents;
|
||||
children = tree.children;
|
||||
childCount = tree.childCount;
|
||||
}
|
||||
|
||||
DimNodeId getCompCount () const { return nodeCount-leafCount; }
|
||||
inline void setNodeCount (Tree &tree, DimNodeId nodeCount) {
|
||||
tree.setNodeCount (nodeCount);
|
||||
this->nodeCount = nodeCount;
|
||||
}
|
||||
protected:
|
||||
// Attributes corresponding to the tree, used to make the construction easier
|
||||
|
||||
DimImg leafCount, nodeCount;
|
||||
/*! 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;
|
||||
|
||||
};
|
||||
|
||||
#include "TreeBuilder.tpp"
|
||||
|
||||
} // triskele
|
||||
} // otb
|
||||
|
||||
|
@ -1,7 +1,11 @@
|
||||
#ifndef _OTB_TRISKELE_XML_TREE_BUILDER_HPP
|
||||
#define _OTB_TRISKELE_XML_TREE_BUILDER_HPP
|
||||
|
||||
#ifdef NO_OTB
|
||||
#include <tinyxml.h>
|
||||
#else
|
||||
#include <otb_tinyxml.h>
|
||||
#endif
|
||||
|
||||
#include "TreeBuilder.hpp"
|
||||
|
||||
|
@ -11,6 +11,9 @@
|
||||
|
||||
namespace triskele {
|
||||
|
||||
/*! Image band type */
|
||||
typedef uint16_t DimChanel; // hyperspectral > 256
|
||||
|
||||
/*! Image size type */
|
||||
typedef uint32_t DimSideImg;
|
||||
|
||||
@ -25,53 +28,50 @@ namespace triskele {
|
||||
|
||||
struct Point {
|
||||
DimSideImg x, y;
|
||||
Point () : x (0), y (0) {}
|
||||
Point (const DimSideImg &abs, const DimSideImg &ord) : x (abs), y (ord) {}
|
||||
inline Point ();
|
||||
inline Point (const DimSideImg &abs, const DimSideImg &ord);
|
||||
};
|
||||
inline std::ostream &operator << (std::ostream &out, const Point &p) { return out << "(" << p.x << "," << p.y << ")"; }
|
||||
inline bool operator== (const Point &p1, const Point &p2);
|
||||
inline std::ostream &operator << (std::ostream &out, const Point &p);
|
||||
extern Point NullPoint;
|
||||
|
||||
struct Size {
|
||||
DimSideImg width, height;
|
||||
Size () : width (0), height (0) {}
|
||||
Size (const DimSideImg &w, const DimSideImg &h) : width (w), height (h) {}
|
||||
inline Size ();
|
||||
inline Size (const DimSideImg &w, const DimSideImg &h);
|
||||
};
|
||||
inline std::ostream &operator << (std::ostream &out, const Size &s) { return out << "[" << s.width << "," << s.height << "]"; }
|
||||
|
||||
inline DimImg pointToId (const Size &size, const Point &p) { return (DimImg)p.x + (DimImg)p.y * size.width; }
|
||||
|
||||
inline Point idToPoint (const Size &size, const DimImg &id) { return Point(id % size.width, id / size.width); }
|
||||
inline bool operator== (const Size &s1, const Size &s2);
|
||||
inline std::ostream &operator << (std::ostream &out, const Size &s);
|
||||
extern Size NullSize;
|
||||
|
||||
inline DimImg pointToId (const Size &size, const Point &p);
|
||||
inline Point idToPoint (const Size &size, const DimImg &id);
|
||||
|
||||
struct Rect {
|
||||
DimSideImg x, y, width, height;
|
||||
Rect () : x (0), y (0), width (0), height (0) {}
|
||||
Rect (const Rect &rect) : x (rect.x), y (rect.y), width (rect.width), height (rect.height) {}
|
||||
Rect (const Point &orig, const Size &size) : x (orig.x), y (orig.y), width (size.width), height (size.height) {}
|
||||
Rect (const DimSideImg &abs, const DimSideImg &ord, const DimSideImg &w, const DimSideImg &h) :
|
||||
x (abs), y (ord), width (w), height (h) {}
|
||||
inline Rect ();
|
||||
inline Rect (const Rect &rect);
|
||||
inline Rect (const Point &orig, const Size &size);
|
||||
inline Rect (const DimSideImg &abs, const DimSideImg &ord, const DimSideImg &w, const DimSideImg &h);
|
||||
};
|
||||
inline std::ostream &operator << (std::ostream &out, const Rect &r) {
|
||||
return out << "[" << r.x << "," << r.y << " " << r.width << "x" << r.height << "]";
|
||||
}
|
||||
inline bool operator== (const Rect &r1, const Rect &r2);
|
||||
inline std::ostream &operator << (std::ostream &out, const Rect &r);
|
||||
extern Rect NullRect;
|
||||
|
||||
/*! Convertit un point d'un tableau (on peut imaginer une image à 2 dimension) en un index */
|
||||
inline DimImg point2idx (const Size &size, const Point &p) { return DimImg (p.x) + DimImg (p.y)*DimImg (size.width); }
|
||||
inline DimImg point2idx (const Size &size, const Point &p);
|
||||
|
||||
/*! Convertit un index d'un tableau (on peut imaginer une image à 2 dimension) en point correspondant à des coordonnées */
|
||||
inline Point idx2point (const Size &size, const DimImg &idx) { return Point (idx % size.width, idx / size.width); }
|
||||
inline Point idx2point (const Size &size, const DimImg &idx);
|
||||
|
||||
static const DimSideImg printMapMaxSide = 20;
|
||||
|
||||
/*! Affiche le contenu d'un tableau en spécifiant sa taille */
|
||||
template <typename DimImg>
|
||||
inline std::ostream &printMap (std::ostream &out, const DimImg *map, const Size &size) {
|
||||
for (DimSideImg y = 0; y < size.height; ++y) {
|
||||
for (DimSideImg x = 0; x < size.width; ++x, ++map)
|
||||
out << std::setw(3) << *map;
|
||||
out << std::endl;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
inline std::ostream &printMap (std::ostream &out, const DimImg *map, const Size &size, DimNodeId maxValues);
|
||||
|
||||
#include "triskeleBase.tpp"
|
||||
|
||||
} // namespace triskele
|
||||
|
||||
#endif // _OTB_TRISKELE_BASE_HPP
|
||||
|
@ -25,7 +25,10 @@ namespace triskele {
|
||||
inline void
|
||||
dealThread (const DimImg &maxId, unsigned int coreCount, const FunctThreadMinMax &functThreadMinMax/* functThreadMinMax (threadId, minVal, maxVal) */);
|
||||
|
||||
// ----------------------------------------
|
||||
template <typename DimImg, class OutputIterator, class T>
|
||||
inline void
|
||||
dealThreadFill_n (const DimImg &maxId, unsigned int coreCount, OutputIterator first, const T& val);
|
||||
|
||||
template<typename DimImg, typename WeightT, typename WeightFunct, typename CmpFunct, typename CallFunct>
|
||||
inline void
|
||||
callOnSortedSets (const std::vector<DimImg> &sizes,
|
||||
@ -33,143 +36,8 @@ namespace triskele {
|
||||
CmpFunct isWeightInf/* isWeightInf (w1, w2) */,
|
||||
const CallFunct &callIdId/* callIdId (vectId, itemId) */);
|
||||
|
||||
// ========================================
|
||||
template<typename DimImg, typename FunctId>
|
||||
inline void
|
||||
dealThreadRange (const DimImg &maxId, const unsigned int &coreCount, const FunctId &functId/* functId (id) */) {
|
||||
dealThread (maxId, coreCount, [&functId] (const unsigned int &threadId, const DimImg &minVal, const DimImg &maxVal) {
|
||||
for (DimImg id = minVal; id < maxVal; ++id)
|
||||
functId (id);
|
||||
});
|
||||
}
|
||||
#include "triskeleDealThreads.tpp"
|
||||
|
||||
// ----------------------------------------
|
||||
template<typename DimImg, typename FunctThreadId>
|
||||
inline void
|
||||
dealThreadThreadRange (const DimImg &maxId, const unsigned int &coreCount, const FunctThreadId &functThreadId/* functThreadId (threadId, id) */) {
|
||||
dealThread (maxId, coreCount, [&functThreadId] (const unsigned int &threadId, const DimImg &minVal, const DimImg &maxVal) {
|
||||
for (DimImg id = minVal; id < maxVal; ++id)
|
||||
functThreadId (threadId, id);
|
||||
});
|
||||
}
|
||||
|
||||
// ----------------------------------------
|
||||
template<typename DimImg, typename FunctMinMax>
|
||||
inline void
|
||||
dealThreadBound (const DimImg &maxId, const unsigned int &coreCount, const FunctMinMax &functMinMax/* functMinMax (minVal, maxVal) */) {
|
||||
dealThread (maxId, coreCount, [&functMinMax] (const unsigned int &threadId, const DimImg &minVal, const DimImg &maxVal) {
|
||||
functMinMax (minVal, maxVal);
|
||||
});
|
||||
}
|
||||
|
||||
// ----------------------------------------
|
||||
template<typename DimImg>
|
||||
inline std::vector<DimImg>
|
||||
getDealThreadBounds (const DimImg &maxId, const unsigned int &coreCount) {
|
||||
if (!maxId || !coreCount)
|
||||
return std::vector<DimImg> (0);
|
||||
DimImg average = maxId/coreCount;
|
||||
std::vector<DimImg> maxIds (coreCount+1, average);
|
||||
|
||||
for (unsigned int core = 0; core < coreCount; ++core)
|
||||
maxIds[core] = DimImg (core*average);
|
||||
maxIds[coreCount] = maxId;
|
||||
return maxIds;
|
||||
}
|
||||
|
||||
// ----------------------------------------
|
||||
template<typename DimImg, typename FunctThreadMinMax>
|
||||
inline void
|
||||
dealThread (const DimImg &maxId, unsigned int coreCount, const FunctThreadMinMax &functThreadMinMax/* functThreadMinMax (threadId, minVal, maxVal) */) {
|
||||
//DEF_LOG ("dealThreadBound", "coreCount:" << coreCount << " maxId:" << maxId);
|
||||
if (!maxId || !coreCount)
|
||||
return;
|
||||
if (DimImg (coreCount) > maxId)
|
||||
coreCount = (unsigned int) maxId;
|
||||
if (coreCount == 1) {
|
||||
functThreadMinMax (0, 0, maxId);
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<DimImg> maxIds = getDealThreadBounds (maxId, coreCount);
|
||||
boost::thread tasks [coreCount];
|
||||
for (unsigned int idCopyValInThread = 0; idCopyValInThread < coreCount; ++idCopyValInThread) {
|
||||
tasks[idCopyValInThread] = boost::thread ([/*no ref!!!*/idCopyValInThread, &maxIds, &functThreadMinMax] () {
|
||||
functThreadMinMax (idCopyValInThread, maxIds[idCopyValInThread], maxIds[idCopyValInThread+1]);
|
||||
});
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < coreCount; ++i)
|
||||
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
|
||||
callOnSortedSets (const std::vector<DimImg> &sizes,
|
||||
const WeightFunct &getWeight/* getWeight (vectId, itemId) */,
|
||||
CmpFunct isWeightInf/* isWeightInf (w1, w2) */,
|
||||
const CallFunct &callIdId/* callIdId (vectId, itemId) */) {
|
||||
DimImg size = sizes.size ();
|
||||
DEF_LOG ("callOnSortedSets", "size:" << size);
|
||||
if (!size)
|
||||
return;
|
||||
std::vector<DimImg> vectIds (size, 0);
|
||||
std::vector<DimImg> vectCounts (sizes);
|
||||
// get min
|
||||
bool found = false;
|
||||
DimImg minVectIdx = 0;
|
||||
WeightT minWeight = 0;
|
||||
for (DimImg vectId = 0; vectId < size; ++vectId) {
|
||||
if (!vectCounts [vectId])
|
||||
continue;
|
||||
WeightT tmpWeight = getWeight (vectId, 0);
|
||||
if (found && !isWeightInf (tmpWeight, minWeight))
|
||||
continue;
|
||||
minVectIdx = vectId;
|
||||
minWeight = tmpWeight;
|
||||
found = true;
|
||||
}
|
||||
LOG ("found:" << found << " minVectIdx:" << minVectIdx << " minWeight:" << minWeight);
|
||||
// loop
|
||||
for ( ; found; ) {
|
||||
// get next min
|
||||
found = false;
|
||||
DimImg nextMinVectIdx = 0;
|
||||
WeightT nextMinWeight = 0;
|
||||
for (DimImg vectId = minVectIdx; ; ) {
|
||||
if (vectCounts [vectId]) {
|
||||
WeightT tmpWeight = getWeight (vectId, vectIds [vectId]);
|
||||
if (!isWeightInf (minWeight, tmpWeight)) {
|
||||
// minWeight == tmpWeight
|
||||
callIdId (vectId, vectIds [vectId]);
|
||||
++vectIds [vectId];
|
||||
--vectCounts [vectId];
|
||||
continue;
|
||||
}
|
||||
if (!found || isWeightInf (tmpWeight, nextMinWeight)) {
|
||||
nextMinVectIdx = vectId;
|
||||
nextMinWeight = tmpWeight;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
vectId = (vectId+1)%size;
|
||||
if (vectId == minVectIdx)
|
||||
break;
|
||||
}
|
||||
minVectIdx = nextMinVectIdx;
|
||||
minWeight = nextMinWeight;
|
||||
}
|
||||
}
|
||||
|
||||
} // triskele
|
||||
|
||||
|
||||
|
@ -1,14 +1,6 @@
|
||||
#ifndef _TRISKELE_DEAL_THREADS_TPP
|
||||
#define _TRISKELE_DEAL_THREADS_TPP
|
||||
|
||||
// ----------------------------------------
|
||||
template<typename DimImg, typename WeightT, typename WeightFunct, typename CmpFunct, typename CallFunct>
|
||||
inline void
|
||||
callOnSortedSets (const std::vector<DimImg> &sizes,
|
||||
const WeightFunct &getWeight/* getWeight (vectId, itemId) */,
|
||||
CmpFunct isWeightInf/* isWeightInf (w1, w2) */,
|
||||
const CallFunct &callIdId/* callIdId (vectId, itemId) */);
|
||||
|
||||
// ========================================
|
||||
template<typename DimImg, typename FunctId>
|
||||
inline void
|
||||
@ -70,13 +62,27 @@ dealThread (const DimImg &maxId, unsigned int coreCount, const FunctThreadMinMax
|
||||
std::vector<DimImg> maxIds = getDealThreadBounds (maxId, coreCount);
|
||||
boost::thread tasks [coreCount];
|
||||
for (unsigned int idCopyValInThread = 0; idCopyValInThread < coreCount; ++idCopyValInThread) {
|
||||
#ifndef THREAD_DISABLE
|
||||
tasks[idCopyValInThread] = boost::thread ([/*no ref!!!*/idCopyValInThread, &maxIds, &functThreadMinMax] () {
|
||||
#endif
|
||||
functThreadMinMax (idCopyValInThread, maxIds[idCopyValInThread], maxIds[idCopyValInThread+1]);
|
||||
#ifndef THREAD_DISABLE
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef THREAD_DISABLE
|
||||
for (unsigned int i = 0; i < coreCount; ++i)
|
||||
tasks[i].join ();
|
||||
#endif
|
||||
}
|
||||
|
||||
// ========================================
|
||||
template <typename DimImg, class OutputIterator, class T>
|
||||
inline 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);
|
||||
});
|
||||
}
|
||||
|
||||
// ========================================
|
||||
|
@ -5,42 +5,59 @@
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
|
||||
#ifdef SMART_LOG
|
||||
#ifdef DISABLE_LOG
|
||||
|
||||
#ifndef DEF_LOG
|
||||
#define DEF_LOG(name, expr) ::triskele::Log log (name); { std::cerr << expr << std::endl << std::flush; }
|
||||
//#define DEF_LOG_(name) DEF_LOG(name, "") XXXX
|
||||
#define DEF_LOG(name, expr)
|
||||
#endif
|
||||
|
||||
#ifndef LOG
|
||||
#define LOG(expr) { std::cerr << log << "| " << expr << std::endl << std::flush; }
|
||||
#define LOG(expr) {}
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG
|
||||
#define DEBUG(expr) { std::cerr << expr << std::endl << std::flush; }
|
||||
#define DEBUG(expr) {}
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifndef DEF_LOG
|
||||
#define DEF_LOG(name, expr)
|
||||
//#define DEF_LOG_(name) XXXX
|
||||
#define DEF_LOG(name, expr) ::triskele::Log log (name); { if (triskele::debug) cerr << expr << endl << flush; }
|
||||
#endif
|
||||
|
||||
#ifndef LOG
|
||||
#define LOG(expr)
|
||||
#define LOG(expr) { if (triskele::debug) cerr << log << "| " << expr << endl << flush; }
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG
|
||||
#define DEBUG(expr)
|
||||
#define DEBUG(expr) { if (triskele::debug) cerr << expr << endl << flush; }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
namespace triskele {
|
||||
|
||||
extern bool debug;
|
||||
|
||||
using namespace std;
|
||||
|
||||
// =======================================
|
||||
|
||||
inline std::string getLocalTimeStr () {
|
||||
using namespace boost::posix_time;
|
||||
using namespace std;
|
||||
ptime now = second_clock::second_clock::local_time ();
|
||||
stringstream ss;
|
||||
auto date = now.date ();
|
||||
auto time = now.time_of_day ();
|
||||
ss << setfill ('0') << "["
|
||||
<< setw (2) << static_cast<int> (date.month ()) << "/" << setw (2) << date.day ()
|
||||
<< "] " << setw (2)
|
||||
<< time.hours () << ":" << setw (2) << time.minutes ();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// ========================================
|
||||
using namespace std;
|
||||
|
||||
@ -48,10 +65,10 @@ namespace triskele {
|
||||
static unsigned int indent;
|
||||
string functName;
|
||||
public:
|
||||
Log (const string &funct) : functName (funct) { ++indent; cerr << *this << "> "; }
|
||||
~Log () { cerr << *this << "<" << endl << flush; --indent; }
|
||||
Log (const string &functName) : functName (functName) { ++indent; if (triskele::debug) cerr << *this << "> "; }
|
||||
~Log () { if (triskele::debug) cerr << *this << "<" << endl << flush; --indent; }
|
||||
friend inline ostream &operator << (ostream &out, const Log &log) {
|
||||
return out << setw (3) << setw ((log.indent % 20)*2) << "" << log.functName;
|
||||
return out << getLocalTimeStr () << setw (3) << setw ((log.indent % 20)*2) << "" << log.functName;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,8 +1,11 @@
|
||||
#ifndef _OTB_TRISKELE_GDAL_GET_TYPE_HPP
|
||||
#define _OTB_TRISKELE_GDAL_GET_TYPE_HPP
|
||||
|
||||
#ifdef NO_OTB
|
||||
#include <gdal/gdal_priv.h>
|
||||
#else
|
||||
#include <otbGdalDataTypeBridge.h>
|
||||
//#include <gdal/gdal_priv.h>
|
||||
#endif
|
||||
|
||||
namespace otb {
|
||||
namespace triskele {
|
||||
@ -19,39 +22,39 @@ namespace otb {
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
DataType
|
||||
inline DataType
|
||||
getType (Type v) { return DataType::Unknown; };
|
||||
|
||||
template<>
|
||||
DataType
|
||||
inline DataType
|
||||
getType<uint8_t> (uint8_t v) { return DataType::Byte; };
|
||||
|
||||
template<>
|
||||
DataType
|
||||
inline DataType
|
||||
getType<uint16_t> (uint16_t v) { return DataType::UInt16; };
|
||||
|
||||
template<>
|
||||
DataType
|
||||
inline DataType
|
||||
getType<int16_t> (int16_t v) { return DataType::Int16; };
|
||||
|
||||
template<>
|
||||
DataType
|
||||
inline DataType
|
||||
getType<uint32_t> (uint32_t v) { return DataType::UInt32; };
|
||||
|
||||
template<>
|
||||
DataType
|
||||
inline DataType
|
||||
getType<int32_t> (int32_t v) { return DataType::Int32; };
|
||||
|
||||
template<>
|
||||
DataType
|
||||
inline DataType
|
||||
getType<float> (float v) { return DataType::Float; };
|
||||
|
||||
template<>
|
||||
DataType
|
||||
inline DataType
|
||||
getType<double> (double v) { return DataType::Double; };
|
||||
|
||||
// =====================
|
||||
GDALDataType
|
||||
inline GDALDataType
|
||||
toGDALType (DataType type) {
|
||||
switch (type) {
|
||||
case DataType::Byte: return GDT_Byte;
|
||||
|
106
src/IImage.cpp
Normal file
106
src/IImage.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
#include "IImage.hpp"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
using namespace triskele;
|
||||
using namespace std;
|
||||
|
||||
size_t
|
||||
IImage::gdalCount = 0;
|
||||
|
||||
IImage::IImage (const string &imageFileName)
|
||||
: fileName (imageFileName),
|
||||
read (false),
|
||||
gdalInputDataset (nullptr),
|
||||
gdalOutputDataset (nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
IImage::~IImage () {
|
||||
close ();
|
||||
}
|
||||
|
||||
void
|
||||
IImage::readImage () {
|
||||
DEF_LOG ("IImage::readImage", "fileName: " << fileName);
|
||||
BOOST_ASSERT (gdalInputDataset == nullptr);
|
||||
BOOST_ASSERT (gdalOutputDataset == nullptr);
|
||||
close ();
|
||||
if (!gdalCount++)
|
||||
GDALAllRegister ();
|
||||
dataType = GDT_Unknown;
|
||||
gdalInputDataset = (GDALDataset *) GDALOpen (fileName.c_str (), GA_ReadOnly);
|
||||
if (!gdalInputDataset) {
|
||||
cerr << "GDALError: can't define dataset" << endl;
|
||||
return;
|
||||
}
|
||||
size = Size (gdalInputDataset->GetRasterXSize (),
|
||||
gdalInputDataset->GetRasterYSize ());
|
||||
bandCount = gdalInputDataset->GetRasterCount ();
|
||||
LOG ("size: " << size << " x " << bandCount);
|
||||
read = true;
|
||||
|
||||
for (DimChanel band = 0; band < bandCount; ++band) {
|
||||
GDALRasterBand &poBand = *gdalInputDataset->GetRasterBand (band+1);
|
||||
GDALDataType bandType = poBand.GetRasterDataType ();
|
||||
LOG ("band " << band << " " << GDALGetDataTypeName (bandType));
|
||||
if (dataType == GDT_Unknown) {
|
||||
dataType = bandType;
|
||||
continue;
|
||||
}
|
||||
if (dataType != bandType) {
|
||||
dataType = GDT_Unknown;
|
||||
LOG ("Can't parse inconsistant bands");
|
||||
// exit (1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
LOG ("gdalCount: " << gdalCount);
|
||||
}
|
||||
|
||||
void
|
||||
IImage::createImage (const Size &size, const GDALDataType &dataType, const DimChanel &nbBands) {
|
||||
DEF_LOG ("IImage::createImage", "fileName: " << fileName);
|
||||
BOOST_ASSERT (gdalInputDataset == nullptr);
|
||||
BOOST_ASSERT (gdalOutputDataset == nullptr);
|
||||
this->size = size;
|
||||
this->dataType = dataType;
|
||||
if (!gdalCount++)
|
||||
GDALAllRegister ();
|
||||
string fileExtension = boost::filesystem::extension (fileName);
|
||||
boost::algorithm::to_lower (fileExtension);
|
||||
if (!boost::iequals (fileExtension, ".tif") &&
|
||||
!boost::iequals (fileExtension, ".tiff")) {
|
||||
cerr << "!!! Warning !!!" << endl
|
||||
<< "Output image not a TIF file <" << fileName << endl;
|
||||
BOOST_ASSERT (false);
|
||||
}
|
||||
|
||||
GDALDriver *driverTiff = GetGDALDriverManager ()->GetDriverByName ("GTiff");
|
||||
remove (fileName.c_str ());
|
||||
gdalOutputDataset = driverTiff->Create (fileName.c_str (), size.width, size.height, nbBands, dataType, NULL);
|
||||
LOG("gdalCount: " << gdalCount);
|
||||
}
|
||||
|
||||
void
|
||||
IImage::close () {
|
||||
DEF_LOG ("IImage::close", "fileName: " << fileName);
|
||||
if (gdalOutputDataset) {
|
||||
// XXX pour écriture gdalOutputDataset->SetProjection ("WGS84");
|
||||
GDALClose (gdalOutputDataset);
|
||||
gdalOutputDataset = nullptr;
|
||||
if (!--gdalCount)
|
||||
GDALDestroyDriverManager ();
|
||||
}
|
||||
if (gdalInputDataset) {
|
||||
GDALClose (gdalInputDataset);
|
||||
gdalInputDataset = nullptr;
|
||||
if (!--gdalCount)
|
||||
GDALDestroyDriverManager ();
|
||||
}
|
||||
BOOST_ASSERT (gdalCount >= 0);
|
||||
LOG ("gdalCount:" << gdalCount);
|
||||
read = false;
|
||||
}
|
@ -54,7 +54,7 @@ DimImg
|
||||
QuadTreeBuilder::setParents (DimImg &parentId,
|
||||
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);
|
||||
DEF_LOG ("setParents", "parentId: " << parentId << " x: " << x << " y: " << y << " w: " << width << " h: " << height);
|
||||
DimImg localId = --parentId;
|
||||
|
||||
if (width <= 2 && height <= 2) {
|
||||
|
26
src/Tree.cpp
26
src/Tree.cpp
@ -1,6 +1,7 @@
|
||||
#include "Tree.hpp"
|
||||
|
||||
using namespace otb::triskele;
|
||||
using namespace std;
|
||||
|
||||
Tree::Tree (const DimSideImg &width, const DimSideImg &height)
|
||||
: Tree ((DimImg)width * (DimImg)height)
|
||||
@ -33,10 +34,10 @@ Tree::clear () {
|
||||
return;
|
||||
childCount[0] = childCount[1] = 0;
|
||||
// XXX fill//
|
||||
std::fill_n (leafParents, leafCount*2, DimImg_MAX);
|
||||
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);
|
||||
fill_n (children, (leafCount-1)*2, 0);
|
||||
fill_n (childCount, leafCount+1, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -86,17 +87,14 @@ Tree::book (const DimImg &leafCount) {
|
||||
}
|
||||
|
||||
|
||||
#ifdef SMART_LOG
|
||||
inline void
|
||||
Tree::printTree (const Size &size, const bool &rec) {
|
||||
std::cout << "tree level parent " << (rec ? "countRec" : "count") << std::endl;
|
||||
#ifdef ENABLE_LOG
|
||||
void
|
||||
Tree::printTree () const {
|
||||
cout << "tree parent count children" << endl;
|
||||
Size doubleSize (size.width, 2*size.height);
|
||||
printMap (std::cout, leafParents, doubleSize) << std::endl;
|
||||
}
|
||||
|
||||
inline void
|
||||
Tree::printNewCompIndex (const Size &size) {
|
||||
std::cout << "newCompIndex" << std::endl;
|
||||
printMap (std::cout, newCompIndex, size) << std::endl;
|
||||
printMap (cout, leafParents, doubleSize, nodeCount) << endl << endl;
|
||||
printMap (cout, childCount, size, ((DimNodeId) getCompCount ()) + 1) << endl << endl;
|
||||
printMap (cout, children, doubleSize, nodeCount) << endl << endl;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include <iostream>
|
||||
|
||||
#define SMART_LOG
|
||||
#include "triskeleDebug.hpp"
|
||||
#include "triskeleBase.hpp"
|
||||
#include "Appli/Option.hpp"
|
||||
#include "Tree.hpp"
|
||||
#include "TreeBuilder.hpp"
|
||||
#include "QuadTree/QuadTreeBuilder.hpp"
|
||||
@ -19,14 +19,52 @@
|
||||
|
||||
#include "ArrayTree/ArrayTreeBuilder.hpp"
|
||||
|
||||
int
|
||||
main (int argc, char** argv) {
|
||||
using namespace otb::triskele;
|
||||
//using namespace triskele;
|
||||
using namespace otb::triskele;
|
||||
using namespace otb::triskele::arrayTree;
|
||||
|
||||
IImage<uint32_t> imgInt ("test.png");
|
||||
imgInt.readImage ();
|
||||
std::cout << "Value of 0: " << imgInt.getValue(0) << std::endl;
|
||||
template<typename PixelT>
|
||||
inline
|
||||
void prog (const Option &option) {
|
||||
Raster<PixelT> raster;
|
||||
option.inputImage.readBand (raster, option.chanel, option.topLeft, option.size);
|
||||
|
||||
Border border;
|
||||
GraphWalker graphWalker (raster.getSize (), border);
|
||||
//MinWeight<PixelT, PixelT> w (raster.getPixels (), raster.getSize ());
|
||||
ArrayTreeBuilder<PixelT, PixelT> atb (option.treeCoreCount, raster, graphWalker, TreeType::MAX);
|
||||
Tree tree;
|
||||
//otb::BuildTree::buildTree(tree, otb::DAPTreeBuilder());
|
||||
atb.buildTree (tree);
|
||||
|
||||
tree.printTree ();
|
||||
|
||||
cerr << endl << "*** prog ok!" << endl;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char** argv, char** envp) {
|
||||
Option option (argc, argv);
|
||||
DEF_LOG ("main", "");
|
||||
|
||||
switch (option.inputImage.getDataType ()) {
|
||||
case GDT_Byte:
|
||||
prog<uint8_t> (option); break;
|
||||
|
||||
// case GDT_UInt16:
|
||||
// prog<uint16_t> (option); break;
|
||||
// case GDT_Int16:
|
||||
// prog<int16_t> (option); break;
|
||||
// case GDT_UInt32:
|
||||
// prog<uint32_t> (option); break;
|
||||
// case GDT_Int32:
|
||||
// prog<int32_t> (option); break;
|
||||
// case GDT_Float32:
|
||||
// prog<float> (option); break;
|
||||
// case GDT_Float64:
|
||||
// prog<double> (option); break;
|
||||
default :
|
||||
cerr << "unknown type!" << endl; break;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -3,5 +3,8 @@
|
||||
|
||||
using namespace triskele;
|
||||
|
||||
bool
|
||||
triskele::debug = false;
|
||||
|
||||
unsigned int
|
||||
Log::indent = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user