From 7499b5b8273824db426afae1153c2883494b263b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Merciol?= Date: Mon, 16 Jul 2018 14:10:48 +0200 Subject: [PATCH] =?UTF-8?q?Gestion=20des=20pixels=20isol=C3=A9=20en=20cas?= =?UTF-8?q?=20de=20pixels=20"nodata"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MakefileNoOTB | 7 ++- documentation/GitInfos.org | 19 ++++-- include/ArrayTree/ArrayTreeBuilder.tpp | 80 ++++++++++++++++++++----- include/ArrayTree/Border.hpp | 81 -------------------------- include/Border.hpp | 80 +++++++++++++++++++++++++ include/{ArrayTree => }/Border.tpp | 5 ++ include/Tree.hpp | 5 +- src/PerfArrayTreeBuilder.cpp | 4 +- src/TestArrayTreeBuilder.cpp | 30 ++++++---- src/Tree.cpp | 14 ++--- src/apGenerator.cpp | 2 +- 11 files changed, 201 insertions(+), 126 deletions(-) delete mode 100644 include/ArrayTree/Border.hpp create mode 100644 include/Border.hpp rename include/{ArrayTree => }/Border.tpp (97%) diff --git a/MakefileNoOTB b/MakefileNoOTB index b2a0771..715c5e3 100644 --- a/MakefileNoOTB +++ b/MakefileNoOTB @@ -21,9 +21,14 @@ PRF_SRC = $(patsubst %, $(CPP_DIR)/%.cpp, $(PRF_PRG)) PRF_OUT = $(patsubst %, $(OUT_DIR)/%, $(PRF_PRG)) ## FLAGS ############################### +# fast and no control DFLAGS = -O2 -DNDEBUG -DNO_OTB -DINTEL_TBB_THREAD -DBOOST_DISABLE_ASSERTS +# fast but control #DFLAGS = -O2 -DNDEBUG -DNO_OTB -DINTEL_TBB_THREAD -#DFLAGS = -g -DENABLE_LOG -DNO_OTB # -DTHREAD_DISABLE -DENABLE_SMART_LOG +# debut multi-threaded +#DFLAGS = -g -DENABLE_LOG -DNO_OTB +# debut one thread +#DFLAGS = -g -DENABLE_LOG -DNO_OTB -DTHREAD_DISABLE -DENABLE_SMART_LOG IFLAGS = $(DFLAGS) -MMD -I$(HPP_DIR) -I/usr/include/gdal LFLAGS = -L$(LIB_DIR) -ltriskele -lstdc++ -lpthread -lboost_system -lboost_chrono -lboost_thread -lboost_program_options -lboost_date_time -lboost_serialization -lboost_filesystem -lboost_unit_test_framework -lgdal -ltbb CC = g++ diff --git a/documentation/GitInfos.org b/documentation/GitInfos.org index f48e6f1..6f9d50c 100644 --- a/documentation/GitInfos.org +++ b/documentation/GitInfos.org @@ -2,12 +2,13 @@ Note aux développeurs ** La TODO list - - vérifier min et max - - vérifier coupure - - vérifier alpha-tree + - refaire le tableau des exemples de traces + - vérifier min et max apla tos + - vérifier coupure (avec sens de la monotonie) - faire un omega-tree + - faire les features-profiles (L, mean, SD, A, MOI) - vérifier production windows - + - faire des tests de perf pour algo parallèle ** Infos concernant le pattern de git de Triskele @@ -56,8 +57,16 @@ Triskele suit partiellement le [[https://nvie.com/posts/a-successful-git-branchi # editer les fichiers en confli $ git commit -a $ git push - # Puis mettre à jour la branch si conflit + # Puis mettre à jour la branch develop si conflit $ git checkout develop $ git merge master # Il est possible d'annuler le traitement en cas de conflit $ git merge --abort + +- Etiquetage de version + # Choisir la branch master + git checkout master + # Donner un nom majeru.mineur.AAMMJJ + git tag 1.0.180610 + # valider sur le serveur + git push --tags diff --git a/include/ArrayTree/ArrayTreeBuilder.tpp b/include/ArrayTree/ArrayTreeBuilder.tpp index 99e8403..ad318c2 100644 --- a/include/ArrayTree/ArrayTreeBuilder.tpp +++ b/include/ArrayTree/ArrayTreeBuilder.tpp @@ -143,7 +143,6 @@ ArrayTreeBuilder::buildTree (Tree &tree, const WeightFunct &wei << tree.printTree (2*leafCount-1)); // merge sub-tree auto startMerge = high_resolution_clock::now (); - DimImg compCount = compTops [0]; DimImg *topC = NULL; DimImg compBase = vertexMaxBounds[tileCount]; if (boundCount) { @@ -186,6 +185,52 @@ ArrayTreeBuilder::buildTree (Tree &tree, const WeightFunct &wei }); } + // SMART_LOG ("compWeights:" << endl + // << printMap (compWeights, size, 0) << endl << endl + // << tree.printTree (2*leafCount-1)); + if (graphWalker.border.exists ()) { + // merge comp forest + DimImg rootId = 0; + for (unsigned int tileId = 0; tileId < tileCount; tileId++) + if (compTops [tileId] != compBases [tileId]) { + rootId = findRoot (compTops [tileId] - 1); + break; + } + + LOG ("merge forest: " << printComp (rootId)); + for (unsigned int tileId = 0; tileId < tileCount; ++tileId) + for (DimImg compId = compBases [tileId]; compId < compTops [tileId]; ++compId) + if (compParents [compId] == DimImg_MAX) { + connectComp (compId, rootId, weightFunct); + rootId = findRoot (rootId); + LOG ("merge top: compId:" << printComp (compId) << " nr:" << printComp (rootId)); + } + + // merge pixels forest + vector lonelyPixelsCount (tileCount, 0); + vector topsWeight (tileCount, compWeights [rootId]); + dealThreadRange (tileCount, coreCount, [this, &tiles, &rootId, &weightFunct, &lonelyPixelsCount, &topsWeight] (const DimImg &tileId) { + WeightT &topWeight (topsWeight [tileId]); + DimImg &lonelyPixelCount (lonelyPixelsCount [tileId]); + graphWalker.forEachVertexIdx (tiles [tileId], [this, &rootId, &lonelyPixelCount, &topWeight, &weightFunct] (const DimImg &leafId) { + if (leafParents [leafId] == DimImg_MAX) { + WeightT pixelWeight (weightFunct.getWeight (leafId)); + leafParents [leafId] = rootId; + lonelyPixelCount++; + if (weightFunct.isWeightInf (topWeight, pixelWeight)) + topWeight = pixelWeight; + } + }); + }); + for (unsigned int tileId = 0; tileId < tileCount; ++tileId) { + childCount [rootId] += lonelyPixelsCount [tileId]; + if (weightFunct.isWeightInf (compWeights [rootId], topsWeight [tileId])) + compWeights [rootId] = topsWeight [tileId]; + // XXX on ne reprend pas la fraterie inférieur car plus d'appel à findMultiChildrenTop + LOG ("merge pixels: tileId:" << tileId << " lonely:" << lonelyPixelsCount [tileId] << " root:" << printComp (rootId)); + } + } + SMART_LOG ("compWeights:" << endl << printMap (compWeights, size, 0) << endl << endl << tree.printTree (2*leafCount-1)); @@ -196,7 +241,7 @@ ArrayTreeBuilder::buildTree (Tree &tree, const WeightFunct &wei SMART_LOG ("reuse leaders:" << endl << printMap (newCompId, size, 0) << endl << endl); - compCount = updateNewId (compBases, compTops, weightFunct); + DimImg maxTop = updateNewId (compBases, compTops, weightFunct); SMART_LOG ("updateNewId:" << endl << printMap (newCompId, size, 0) << endl << endl); @@ -207,15 +252,15 @@ ArrayTreeBuilder::buildTree (Tree &tree, const WeightFunct &wei << printMap (newCompId, size, 0) << endl << endl); leaders.free (); - while (compCount > 1 && childCount[compCount-1] == 1) { - --compCount; - compParents [compCount-1] = DimImg_MAX; - SMART_LOG ("reduce lonely root:" << printComp (compCount) << endl); + while (maxTop > 1 && childCount[maxTop-1] == 1) { + --maxTop; + compParents [maxTop-1] = DimImg_MAX; + SMART_LOG ("reduce lonely root:" << printComp (maxTop) << endl); } - setNodeCount (tree, leafCount+compCount); + setNodeCount (tree, leafCount+maxTop); LOG ("nodeCount:" << tree.getNodeCount()); - // DimEdge root = compCount-1; - // compParents[root] = root; + // DimEdge rootId = maxTop-1; + // compParents[rootId] = rootId; SMART_LOG ("compWeights:" << endl << printMap (compWeights, size, 0) << endl << endl); @@ -275,8 +320,12 @@ ArrayTreeBuilder::buildParents (Edge *edges, const Wei SMART_LOG ("pa:" << pa << " pb:" << pb << " la:" << la << " lb:" << lb); SMART_LOG ("ra:" << printComp (ra) << " rb:" << printComp (rb)); - if (la == lb) + if (la == lb) { + leaders.link (pa, la); + leaders.link (pb, la); + SMART_LOG ("la=lb"); continue; + } if (ra == DimImg_MAX) { swap (la, lb); swap (ra, rb); @@ -299,9 +348,9 @@ ArrayTreeBuilder::buildParents (Edge *edges, const Wei leader = lb; } } else if (ra == rb) { - // XXX + SMART_LOG ("ra=rb **** XXXX ****"); BOOST_ASSERT (false); - continue; + leader = la; } else if (compWeights[ra] == compWeights [rb]) { // ra.weight = rb.weight // XXX ?= curEdge.weight if (childCount [ra] < childCount [rb]) { @@ -327,7 +376,7 @@ ArrayTreeBuilder::buildParents (Edge *edges, const Wei leaders.link (pa, leader); leaders.link (pb, leader); - SMART_LOG (" leader:" << leader << " ra:" << printComp (ra) << " rb:" << printComp (rb)); + SMART_LOG (" leader:" << leader << " ra:" << printComp (ra) << " rb:" << printComp (rb) << " nr:" << printComp (findRoot (leafParents [la]))); } SMART_LOG ("topParent:" << topParent); @@ -431,7 +480,7 @@ ArrayTreeBuilder::connectLeaf (DimImg a, DimImg b, const Weight unlinkParent (parA); ++childCount[parB]; leafParents[a] = parB; - SMART_LOG ("parA: " << printComp (parA) << " parB: " << printComp (parB)); + SMART_LOG ("link a: " << a << " parB: " << printComp (parB)); } // eqW0 | eqW1 | eqW2 SMART_LOG ("eqW0 | eqW1 | eqW2: connect"); @@ -455,8 +504,7 @@ ArrayTreeBuilder::connect3Comp (DimImg newComp, DimImg topA, Di swap (topA, topB); BOOST_ASSERT (findTopComp (topB, weightFunct) == topB); BOOST_ASSERT (weightFunct.isWeightInf (compWeights[newComp], compWeights[topB])); - compParents[newComp] = topB; - ++childCount[topB]; + addChild (topB, compParents[newComp]); SMART_LOG ("topB: " << printComp (topB)); connectComp (topA, topB, weightFunct); } diff --git a/include/ArrayTree/Border.hpp b/include/ArrayTree/Border.hpp deleted file mode 100644 index c164d36..0000000 --- a/include/ArrayTree/Border.hpp +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef _OTB_TRISKELE_ARRAY_TREE_BORDER_HPP -#define _OTB_TRISKELE_ARRAY_TREE_BORDER_HPP - -#include - -#include "triskeleBase.hpp" -#include "triskeleArrayTreeBase.hpp" - -namespace otb { - namespace triskele { - namespace arrayTree { - - /** Border */ - class Border { - public: - /*! Retourne le nombre de pixels à l'aide de la taille */ - static inline DimImg getPixelsCount (const Size &size); - - /*! Retourne la taille que doit faire le tableau simplifié */ - 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 */ - 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 */ - inline bool isBorder (const Point &p) const; - - /*! Supprime toutes les occurences de bordure à l'index idx */ - 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 */ - inline void clearBorder (const Point &p); - - /*! Rajoute une occurence de bordure à l'index indiqué */ - 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 */ - inline void setBorder (const Point &p); - - /*! Construit par défault sans aucune bordure */ - inline Border (); - - /*! Construit Border, les valeurs de map dépendent de defaultVal */ - inline Border (const Size &size, bool defaultVal); - inline Border (const Border &border, const Rect &tile); - inline ~Border (); - - inline void reset (bool defaultVal); - - inline const Size &getSize () const; - - /*! Compte le nombre de pixels considérés comme de la bordure */ - inline DimImg borderCount (); - - private: - /*! Nombre de pixels dans l'image */ - DimImg pixelsCount; - - /*! Taille du tableau "simplifié" des pixels */ - DimImg mapLength; - - /*! Dimensions de l'image */ - Size size; - - /*! Tableau "simplifié" des pixels */ - vector map; - - bool defaultVal; - - inline void createMap (); - - friend inline ostream &operator << (ostream &out, const Border &border); - }; - -#include "Border.tpp" - - } //arrayTree - } // triskele -} // otb - -#endif // _OTB_TRISKELE_ARRAY_TREE_BORDER_HPP diff --git a/include/Border.hpp b/include/Border.hpp new file mode 100644 index 0000000..41af2ab --- /dev/null +++ b/include/Border.hpp @@ -0,0 +1,80 @@ +#ifndef _OTB_TRISKELE_BORDER_HPP +#define _OTB_TRISKELE_BORDER_HPP + +#include + +#include "triskeleBase.hpp" +//#include "triskeleArrayTreeBase.hpp" + +namespace triskele { + + /** Border */ + class Border { + public: + /*! Retourne le nombre de pixels à l'aide de la taille */ + static inline DimImg getPixelsCount (const Size &size); + + /*! Retourne la taille que doit faire le tableau simplifié */ + static inline DimImg getMapLength (DimImg pixelsCount); + + /*! Indique qu'une carte de borfure est présente (donc potentiellement des pixels de bordures). */ + inline bool exists () const; + + /*! 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 */ + 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 */ + inline bool isBorder (const Point &p) const; + + /*! Supprime toutes les occurences de bordure à l'index idx */ + 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 */ + inline void clearBorder (const Point &p); + + /*! Rajoute une occurence de bordure à l'index indiqué */ + 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 */ + inline void setBorder (const Point &p); + + /*! Construit par défault sans aucune bordure */ + inline Border (); + + /*! Construit Border, les valeurs de map dépendent de defaultVal */ + inline Border (const Size &size, bool defaultVal); + inline Border (const Border &border, const Rect &tile); + inline ~Border (); + + inline void reset (bool defaultVal); + + inline const Size &getSize () const; + + /*! Compte le nombre de pixels considérés comme de la bordure */ + inline DimImg borderCount (); + + private: + /*! Nombre de pixels dans l'image */ + DimImg pixelsCount; + + /*! Taille du tableau "simplifié" des pixels */ + DimImg mapLength; + + /*! Dimensions de l'image */ + Size size; + + /*! Tableau "simplifié" des pixels */ + vector map; + + bool defaultVal; + + inline void createMap (); + + friend inline ostream &operator << (ostream &out, const Border &border); + }; + +#include "Border.tpp" + +} // triskele + +#endif // _OTB_TRISKELE_BORDER_HPP diff --git a/include/ArrayTree/Border.tpp b/include/Border.tpp similarity index 97% rename from include/ArrayTree/Border.tpp rename to include/Border.tpp index e095146..7c5bb74 100644 --- a/include/ArrayTree/Border.tpp +++ b/include/Border.tpp @@ -10,6 +10,11 @@ Border::getMapLength (DimImg pixelsCount) { return (pixelsCount+7)/8; } +inline bool +Border::exists () const { + return map.size (); +} + inline bool Border::isBorder (DimImg idx) const { BOOST_ASSERT (idx < pixelsCount); diff --git a/include/Tree.hpp b/include/Tree.hpp index 344fd0d..51f2ca9 100644 --- a/include/Tree.hpp +++ b/include/Tree.hpp @@ -9,6 +9,7 @@ #include "triskeleBase.hpp" #include "triskeleDebug.hpp" +#include "Border.hpp" namespace otb { namespace triskele { @@ -121,8 +122,8 @@ namespace otb { bool compareTo (const Tree &tree, bool testChildren = false) const; - void checkSpare () const; - void check () const; + void checkSpare (const Border& border) const; + void check (const Border& border) const; // XXX void checkWeightCurve (bool incr) const; // nice ostream diff --git a/src/PerfArrayTreeBuilder.cpp b/src/PerfArrayTreeBuilder.cpp index 50ab63d..597cac3 100644 --- a/src/PerfArrayTreeBuilder.cpp +++ b/src/PerfArrayTreeBuilder.cpp @@ -5,6 +5,7 @@ #include "triskeleDebug.hpp" #include "triskeleBase.hpp" +#include "Border.hpp" #include "Tree.hpp" #include "TreeStats.hpp" #include "TreeBuilder.hpp" @@ -12,7 +13,6 @@ #include "AttributeProfiles.hpp" #include "ArrayTree/triskeleArrayTreeBase.hpp" #include "ArrayTree/triskeleSort.hpp" -#include "ArrayTree/Border.hpp" #include "ArrayTree/GraphWalker.hpp" #include "ArrayTree/Leader.hpp" #include "ArrayTree/Weight.hpp" @@ -33,7 +33,7 @@ perf (const Raster &raster, const GraphWalker &graphWalker, const TreeTy Tree tree (coreCount); WeightAttributes weightAttributes (tree); atb.buildTree (tree, weightAttributes); - tree.check (); + tree.check (graphWalker.border); } // ======================================== diff --git a/src/TestArrayTreeBuilder.cpp b/src/TestArrayTreeBuilder.cpp index 9813d60..6d745b7 100644 --- a/src/TestArrayTreeBuilder.cpp +++ b/src/TestArrayTreeBuilder.cpp @@ -5,6 +5,7 @@ #include "triskeleDebug.hpp" #include "triskeleBase.hpp" +#include "Border.hpp" #include "Tree.hpp" #include "TreeStats.hpp" #include "TreeBuilder.hpp" @@ -12,7 +13,6 @@ #include "AttributeProfiles.hpp" #include "ArrayTree/triskeleArrayTreeBase.hpp" #include "ArrayTree/triskeleSort.hpp" -#include "ArrayTree/Border.hpp" #include "ArrayTree/GraphWalker.hpp" #include "ArrayTree/Leader.hpp" #include "ArrayTree/Weight.hpp" @@ -23,9 +23,9 @@ using namespace otb::triskele; using namespace otb::triskele::arrayTree; -const unsigned int nbTest = 1000; -const TreeType treeType = ALPHA; // TOS; // MIN; // MAX; -const unsigned int coreCount = 4; +const unsigned int nbTest = 1; // 1000; +const TreeType treeType = MIN; // ALPHA; // TOS; // MIN; // MAX; +const unsigned int coreCount = 2; typedef uint16_t PixelT; typedef uint16_t WeightT; @@ -92,7 +92,7 @@ PixelT pixelsB3 [] = { //) parents[0]:0 parentId:6 level child:0 parent:0 parent 5, 1, 7, 2, 4, 1, 6, 6, 4, 6, 1, 5 }; -PixelT pixelsC1 [] = { //A) childIdx:26 parentId:1 parentIdx:25 rootId:9 +PixelT pixelsC1_6x4 [] = { //A) childIdx:26 parentId:1 parentIdx:25 rootId:9 6, 1, 7, 7, 3, 3, 0, 3, 0, 0, 6, 4, 3, 3, 4, 6, 7, 4, @@ -208,23 +208,31 @@ PixelT pixelsT7_12x8 [] = { // ======================================== void test () { //Size size (6, 4); - //Size size (18, 12); + // Size size (18, 12); Size size (12, 8); Border border (size, false); + border.setBorder (1); + //border.setBorder (12); + border.setBorder (13); + border.setBorder (24); + border.setBorder (25); + GraphWalker graphWalker (border); int leafCount = graphWalker.vertexMaxCount (); // ==================== + // PixelT *pixels = pixelsC1_6x4; + // PixelT *pixels = pixelsT1_18x12; // PixelT *pixels = pixelsT2_12x8; // PixelT *pixels = pixelsT3_12x8; // PixelT *pixels = pixelsT4_12x8; - // PixelT *pixels = pixelsT5_12x8; + PixelT *pixels = pixelsT5_12x8; // PixelT *pixels = pixelsT6_12x8; // PixelT *pixels = pixelsT7_12x8; - PixelT *pixels = new PixelT [leafCount]; - for (int i = 0; i < leafCount; ++i) - pixels[i] = std::rand() % 8; + // PixelT *pixels = new PixelT [leafCount]; + // for (int i = 0; i < leafCount; ++i) + // pixels[i] = std::rand() % 8; // ==================== Raster raster (size); @@ -246,7 +254,7 @@ void test () { Tree tree (coreCount); WeightAttributes weightAttributes (tree); atb.buildTree (tree, weightAttributes); - tree.check (); + tree.check (border); AttributeProfiles attributeProfiles (tree); atb.setAttributProfiles (attributeProfiles); diff --git a/src/Tree.cpp b/src/Tree.cpp index 761c5b1..88d648f 100644 --- a/src/Tree.cpp +++ b/src/Tree.cpp @@ -1,5 +1,5 @@ #include "Tree.hpp" -#include "ArrayTree/Border.hpp" +#include "Border.hpp" #include "ArrayTree/GraphWalker.hpp" using namespace otb::triskele; @@ -170,8 +170,7 @@ Tree::compareTo (const Tree &tree, bool testChildren) const { // ======================================== void -Tree::checkSpare () const { - Border border; // default = no border +Tree::checkSpare (const Border &border) const { GraphWalker graphWalker (border); vector tiles; vector boundaries; @@ -229,11 +228,12 @@ Tree::checkSpare () const { } void -Tree::check () const { +Tree::check (const Border& border) const { + GraphWalker graphWalker (border); DimImg compCount = getCompCount (); BOOST_ASSERT (compCount < leafCount); // check parents - forEachLeaf ([this, &compCount] (const DimImg &leafId) { + graphWalker.forEachVertexIdx ([this, &compCount] (const DimImg &leafId) { // XXX si border => leafParents [leafId] == DimImg_MAX BOOST_ASSERT (leafParents[leafId] < compCount); }); @@ -297,8 +297,8 @@ Tree::check () const { BOOST_ASSERT (children[childId-1] < children[childId]); } }); - for (DimImg child = 0; child < nodeCount-1; ++child) - BOOST_ASSERT (childrenMap [child] != DimImg_MAX); + for (DimNodeId child = 0; child < nodeCount-1; ++child) + BOOST_ASSERT (childrenMap [child] != DimImg_MAX || (child < leafCount && border.isBorder (child))); } } diff --git a/src/apGenerator.cpp b/src/apGenerator.cpp index c2de193..094620a 100644 --- a/src/apGenerator.cpp +++ b/src/apGenerator.cpp @@ -3,6 +3,7 @@ #include "triskeleDebug.hpp" #include "triskeleBase.hpp" +#include "Border.hpp" #include "Appli/Option.hpp" #include "Tree.hpp" #include "TreeStats.hpp" @@ -13,7 +14,6 @@ #include "ArrayTree/triskeleArrayTreeBase.hpp" #include "ArrayTree/triskeleSort.hpp" -#include "ArrayTree/Border.hpp" #include "ArrayTree/GraphWalker.hpp" #include "ArrayTree/Leader.hpp" #include "ArrayTree/Weight.hpp"