Gestion des pixels isolé en cas de pixels "nodata"

This commit is contained in:
François Merciol 2018-07-16 14:10:48 +02:00
parent 8f504b9db4
commit 7499b5b827
11 changed files with 201 additions and 126 deletions

View File

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

View File

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

View File

@ -143,7 +143,6 @@ ArrayTreeBuilder<WeightT, PixelT>::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<WeightT, PixelT>::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<DimImg> lonelyPixelsCount (tileCount, 0);
vector<WeightT> 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<WeightT, PixelT>::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<WeightT, PixelT>::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<WeightT, PixelT>::buildParents (Edge<WeightT> *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<WeightT, PixelT>::buildParents (Edge<WeightT> *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<WeightT, PixelT>::buildParents (Edge<WeightT> *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<WeightT, PixelT>::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<WeightT, PixelT>::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);
}

View File

@ -1,81 +0,0 @@
#ifndef _OTB_TRISKELE_ARRAY_TREE_BORDER_HPP
#define _OTB_TRISKELE_ARRAY_TREE_BORDER_HPP
#include <algorithm>
#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<uint8_t> 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

80
include/Border.hpp Normal file
View File

@ -0,0 +1,80 @@
#ifndef _OTB_TRISKELE_BORDER_HPP
#define _OTB_TRISKELE_BORDER_HPP
#include <algorithm>
#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<uint8_t> map;
bool defaultVal;
inline void createMap ();
friend inline ostream &operator << (ostream &out, const Border &border);
};
#include "Border.tpp"
} // triskele
#endif // _OTB_TRISKELE_BORDER_HPP

View File

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

View File

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

View File

@ -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<PixelT> &raster, const GraphWalker &graphWalker, const TreeTy
Tree tree (coreCount);
WeightAttributes<PixelT> weightAttributes (tree);
atb.buildTree (tree, weightAttributes);
tree.check ();
tree.check (graphWalker.border);
}
// ========================================

View File

@ -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<PixelT> raster (size);
@ -246,7 +254,7 @@ void test () {
Tree tree (coreCount);
WeightAttributes<PixelT> weightAttributes (tree);
atb.buildTree (tree, weightAttributes);
tree.check ();
tree.check (border);
AttributeProfiles<PixelT> attributeProfiles (tree);
atb.setAttributProfiles (attributeProfiles);

View File

@ -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<Rect> tiles;
vector<Rect> 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)));
}
}

View File

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