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:
Git Merciol 2018-02-18 08:24:25 +01:00
parent cdedd3b7eb
commit ed9141d5c5
26 changed files with 1123 additions and 642 deletions

View File

@ -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> &image;
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"

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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"

View File

@ -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;
}
// ========================================

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
};

View File

@ -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)

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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);
});
}
// ========================================

View File

@ -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;
}
};

View File

@ -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
View 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;
}

View File

@ -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) {

View File

@ -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

View File

@ -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;
}

View File

@ -3,5 +3,8 @@
using namespace triskele;
bool
triskele::debug = false;
unsigned int
Log::indent = 0;