Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Cresson Remi
LSGRM
Commits
9493484b
Commit
9493484b
authored
Aug 24, 2016
by
remicres
Browse files
ENH: Fully modularized! Now require GRM Module
parent
bb65d2e0
Changes
19
Show whitespace changes
Inline
Side-by-side
app/CMakeLists.txt
View file @
9493484b
...
...
@@ -2,4 +2,4 @@ cmake_minimum_required (VERSION 2.8)
OTB_CREATE_APPLICATION
(
NAME LSGRM
SOURCES otbLSGRM.cxx
LINK_LIBRARIES OTBCommon
)
LINK_LIBRARIES OTBCommon
OTBGRM
)
app/otbLSGRM.cxx
View file @
9493484b
...
...
@@ -58,10 +58,10 @@ private:
AddParameter
(
ParameterType_OutputImage
,
"out"
,
"Ouput Label Image"
);
SetDefaultOutputPixelType
(
"out"
,
ImagePixelType_uint32
);
// AddParameter(ParameterType_Choice, "criterion", "Homogeneity criterion to use");
// AddChoice("criterion.bs", "Baatz & Schape");
// AddChoice("criterion.ed", "Euclidean Distance");
// AddChoice("criterion.fls", "Full Lambda Schedule");
// AddParameter(ParameterType_Choice, "criterion", "Homogeneity criterion to use");
// AddChoice("criterion.bs", "Baatz & Schape");
// AddChoice("criterion.ed", "Euclidean Distance");
// AddChoice("criterion.fls", "Full Lambda Schedule");
AddParameter
(
ParameterType_Float
,
"threshold"
,
"Threshold for the criterion"
);
...
...
@@ -167,16 +167,8 @@ private:
otbAppLogFATAL
(
"Unknow input tiling mode!"
);
}
// MPI configuration
#ifdef OTB_USE_MPI
if
(
myrank
==
0
)
std
::
cout
<<
"Number of MPI process : "
<<
nprocs
<<
std
::
endl
;
controller
.
SetNumberOfProcess
(
nprocs
);
controller
.
SetProcessRank
(
myrank
);
#endif
// Specific parameters
ls
rm
::
BaatzParam
params
;
g
rm
::
BaatzParam
params
;
params
.
m_SpectralWeight
=
GetParameterFloat
(
"cw"
);
params
.
m_ShapeWeight
=
GetParameterFloat
(
"sw"
);
controller
.
SetSpecificParameters
(
params
);
...
...
@@ -197,11 +189,25 @@ private:
labelImage
->
SetSpacing
(
inputImage
->
GetSpacing
());
SetParameterOutputImage
<
UInt32ImageType
>
(
"out"
,
labelImage
);
// Get temporary files list
m_TemporaryFilesList
=
controller
.
GetTemporaryFilesList
();
}
void
AfterExecuteAndWriteOutputs
()
{
// Delete temporary files
for
(
unsigned
int
i
=
0
;
i
<
m_TemporaryFilesList
.
size
()
;
i
++
)
{
if
(
remove
(
m_TemporaryFilesList
.
at
(
i
).
c_str
()
)
!=
0
)
{
otbAppLogWARNING
(
"Error deleting file "
<<
m_TemporaryFilesList
.
at
(
i
)
);
}
}
}
private:
std
::
vector
<
std
::
string
>
m_TemporaryFilesList
;
};
// app class
}
// end of namespace wrapper
...
...
include/lpContour.cpp
deleted
100644 → 0
View file @
bb65d2e0
#include "lpContour.h"
namespace
lp
{
void
ContourOperations
::
MergeContour
(
Contour
&
mergedContour
,
BoundingBox
&
mergedBBox
,
Contour
&
contour1
,
Contour
&
contour2
,
BoundingBox
&
bbox1
,
BoundingBox
&
bbox2
,
const
CellIndex
cid1
,
const
CellIndex
cid2
,
const
std
::
size_t
gridSizeX
)
{
// First step consists of building the bounding box resulting from the fusion
// of the bounding boxes bbox1 and bbox2
mergedBBox
=
MergeBoundingBoxes
(
bbox1
,
bbox2
);
// Create the associate matrix indicating where the cells are located
// inside the bbox
std
::
vector
<
bool
>
cellMatrix
(
mergedBBox
.
m_W
*
mergedBBox
.
m_H
,
false
);
// Fill the cell matrix with the cells from both contours
{
CellLists
borderCells
;
// Fill with the cells of contour 1
GenerateBorderCells
(
borderCells
,
contour1
,
cid1
,
gridSizeX
);
for
(
auto
&
cell
:
borderCells
)
cellMatrix
[
GridToBBox
(
cell
,
mergedBBox
,
gridSizeX
)]
=
true
;
borderCells
.
clear
();
// Fill with the cells of contour 2
GenerateBorderCells
(
borderCells
,
contour2
,
cid2
,
gridSizeX
);
for
(
auto
&
cell
:
borderCells
)
cellMatrix
[
GridToBBox
(
cell
,
mergedBBox
,
gridSizeX
)]
=
true
;
}
// Create the new contour
CreateNewContour
(
mergedContour
,
GridToBBox
(
cid1
,
mergedBBox
,
gridSizeX
),
cellMatrix
,
mergedBBox
.
m_W
,
mergedBBox
.
m_H
);
}
void
ContourOperations
::
CreateNewContour
(
Contour
&
newContour
,
const
CellIndex
cidx
,
const
std
::
vector
<
bool
>&
cellMatrix
,
const
std
::
size_t
bboxWidth
,
const
std
::
size_t
bboxHeight
)
{
// The first move is always 1
Push1
(
newContour
);
// Previous move
short
prevMove
=
1
;
// Local pixel id
CellIndex
currIdx
=
cidx
;
// Table containing id neighbors
long
int
neighbors
[
8
];
for
(;;)
{
// Compute neighbor'ids
EIGHTNeighborhood
(
neighbors
,
currIdx
,
bboxWidth
,
bboxHeight
);
if
(
prevMove
==
1
)
{
if
(
neighbors
[
1
]
!=
-
1
&&
cellMatrix
[
neighbors
[
1
]])
{
Push0
(
newContour
);
currIdx
=
currIdx
+
1
-
bboxWidth
;
prevMove
=
0
;
}
else
if
(
neighbors
[
2
]
!=
-
1
&&
cellMatrix
[
neighbors
[
2
]])
{
Push1
(
newContour
);
currIdx
++
;
prevMove
=
1
;
}
else
{
Push2
(
newContour
);
prevMove
=
2
;
}
}
else
if
(
prevMove
==
2
)
{
if
(
neighbors
[
3
]
!=
-
1
&&
cellMatrix
[
neighbors
[
3
]])
{
Push1
(
newContour
);
currIdx
=
currIdx
+
bboxWidth
+
1
;
prevMove
=
1
;
}
else
if
(
neighbors
[
4
]
!=
-
1
&&
cellMatrix
[
neighbors
[
4
]])
{
Push2
(
newContour
);
currIdx
+=
bboxWidth
;
prevMove
=
2
;
}
else
{
Push3
(
newContour
);
prevMove
=
3
;
}
}
else
if
(
prevMove
==
3
)
{
if
(
neighbors
[
5
]
!=
-
1
&&
cellMatrix
[
neighbors
[
5
]])
{
Push2
(
newContour
);
currIdx
=
currIdx
-
1
+
bboxWidth
;
prevMove
=
2
;
}
else
if
(
neighbors
[
6
]
!=
-
1
&&
cellMatrix
[
neighbors
[
6
]])
{
Push3
(
newContour
);
currIdx
-=
1
;
prevMove
=
3
;
}
else
{
Push0
(
newContour
);
prevMove
=
0
;
}
}
else
{
assert
(
prevMove
==
0
);
if
(
neighbors
[
7
]
!=
-
1
&&
cellMatrix
[
neighbors
[
7
]])
{
Push3
(
newContour
);
currIdx
=
currIdx
-
bboxWidth
-
1
;
prevMove
=
3
;
}
else
if
(
neighbors
[
0
]
!=
-
1
&&
cellMatrix
[
neighbors
[
0
]])
{
Push0
(
newContour
);
currIdx
-=
bboxWidth
;
prevMove
=
0
;
}
else
{
if
(
currIdx
==
cidx
)
break
;
else
{
Push1
(
newContour
);
prevMove
=
1
;
}
}
}
}
}
void
ContourOperations
::
GenerateBorderCells
(
CellLists
&
borderCells
,
const
Contour
&
contour
,
const
CellIndex
startCellId
,
const
std
::
size_t
gridSizeX
)
{
// Add the first pixel to the border list
borderCells
.
insert
(
startCellId
);
if
(
contour
.
size
()
>
8
)
{
// Intialize the first move at prev
short
curr
,
prev
=
GetMove10
(
GetMove2
(
0
,
contour
));
// Declare the current pixel index
CellIndex
idx
=
startCellId
;
// Explore the contour
for
(
ContourIndex
cidx
=
1
;
cidx
<
contour
.
size
()
/
2
;
cidx
++
)
{
curr
=
GetMove10
(
GetMove2
(
cidx
,
contour
));
assert
(
curr
>=
0
&&
curr
<
4
);
if
(
curr
==
0
)
{
// Impossible case is prev = 2;
assert
(
prev
!=
2
);
//*
//*
if
(
prev
==
0
)
{
idx
-=
gridSizeX
;
borderCells
.
insert
(
idx
);
}
// *
// **
if
(
prev
==
1
)
{
idx
=
idx
+
1
-
gridSizeX
;
borderCells
.
insert
(
idx
);
}
}
else
if
(
curr
==
1
)
{
// Impossible case
assert
(
prev
!=
3
);
// **
if
(
prev
==
1
)
{
idx
++
;
borderCells
.
insert
(
idx
);
}
//*
//**
if
(
prev
==
2
)
{
idx
=
idx
+
1
+
gridSizeX
;
borderCells
.
insert
(
idx
);
}
}
else
if
(
curr
==
2
)
{
// Impossible case
assert
(
prev
!=
0
);
// *
// *
if
(
prev
==
2
)
{
idx
+=
gridSizeX
;
borderCells
.
insert
(
idx
);
}
// **
// *
if
(
prev
==
3
)
{
idx
=
idx
-
1
+
gridSizeX
;
borderCells
.
insert
(
idx
);
}
}
else
{
// Impossible case
assert
(
prev
!=
1
);
if
(
prev
==
0
)
{
idx
=
idx
-
1
-
gridSizeX
;
borderCells
.
insert
(
idx
);
}
if
(
prev
==
3
)
{
idx
--
;
borderCells
.
insert
(
idx
);
}
}
prev
=
curr
;
}
}
}
CellIndex
ContourOperations
::
BBoxToGrid
(
const
CellIndex
bboxId
,
const
BoundingBox
&
bbox
,
const
std
::
size_t
gridSizeX
)
{
CellIndex
bbX
=
bboxId
%
bbox
.
m_W
;
CellIndex
bbY
=
bboxId
/
bbox
.
m_W
;
CellIndex
gridX
=
bbox
.
m_UX
+
bbX
;
CellIndex
gridY
=
bbox
.
m_UY
+
bbY
;
CellIndex
gridId
=
gridY
*
gridSizeX
+
gridX
;
return
gridId
;
}
CellIndex
ContourOperations
::
GridToBBox
(
const
CellIndex
gridId
,
const
BoundingBox
&
bbox
,
const
std
::
size_t
gridSizeX
)
{
CellIndex
gridX
=
gridId
%
gridSizeX
;
CellIndex
gridY
=
gridId
/
gridSizeX
;
CellIndex
bbX
=
gridX
-
bbox
.
m_UX
;
CellIndex
bbY
=
gridY
-
bbox
.
m_UY
;
CellIndex
bbId
=
bbY
*
bbox
.
m_W
+
bbX
;
return
bbId
;
}
void
ContourOperations
::
EIGHTNeighborhood
(
long
int
*
neighborhood
,
const
CellIndex
id
,
const
std
::
size_t
width
,
const
std
::
size_t
height
)
{
const
unsigned
int
x
=
id
%
width
;
const
unsigned
int
y
=
id
/
width
;
/* top */
neighborhood
[
0
]
=
(
y
>
0
?
(
id
-
width
)
:
-
1
);
/* top right */
neighborhood
[
1
]
=
(
(
y
>
0
&&
x
<
(
width
-
1
)
)
?
(
id
-
width
+
1
)
:
-
1
);
/* right */
neighborhood
[
2
]
=
(
x
<
(
width
-
1
)
?
(
id
+
1
)
:
-
1
);
/* bottom right */
neighborhood
[
3
]
=
(
(
x
<
(
width
-
1
)
&&
y
<
(
height
-
1
)
)
?
(
id
+
1
+
width
)
:
-
1
);
/* bottom */
neighborhood
[
4
]
=
(
y
<
(
height
-
1
)
?
(
id
+
width
)
:
-
1
);
/* bottom left */
neighborhood
[
5
]
=
(
(
y
<
(
height
-
1
)
&&
x
>
0
)
?
(
id
+
width
-
1
)
:
-
1
);
/* left */
neighborhood
[
6
]
=
(
x
>
0
?
(
id
-
1
)
:
-
1
);
/* top left */
neighborhood
[
7
]
=
(
(
x
>
0
&&
y
>
0
)
?
(
id
-
width
-
1
)
:
-
1
);
}
BoundingBox
ContourOperations
::
MergeBoundingBoxes
(
const
BoundingBox
&
bb1
,
const
BoundingBox
&
bb2
)
{
std
::
size_t
min_ux
,
min_uy
,
max_xw
,
max_yh
;
BoundingBox
bb
;
min_ux
=
std
::
min
(
bb1
.
m_UX
,
bb2
.
m_UX
);
min_uy
=
std
::
min
(
bb1
.
m_UY
,
bb2
.
m_UY
);
max_xw
=
std
::
max
(
bb1
.
m_UX
+
bb1
.
m_W
,
bb2
.
m_UX
+
bb2
.
m_W
);
max_yh
=
std
::
max
(
bb1
.
m_UY
+
bb1
.
m_H
,
bb2
.
m_UY
+
bb2
.
m_H
);
bb
.
m_UX
=
min_ux
;
bb
.
m_UY
=
min_uy
;
bb
.
m_W
=
max_xw
-
min_ux
;
bb
.
m_H
=
max_yh
-
min_uy
;
return
bb
;
}
Move
ContourOperations
::
GetMove2
(
ContourIndex
idx
,
const
Contour
&
contour
)
{
return
Move
(
2
*
contour
[
2
*
idx
]
+
contour
[
idx
*
2
+
1
]);
}
short
ContourOperations
::
GetMove10
(
const
Move
&
m
)
{
return
(
m
[
0
]
*
2
+
m
[
1
]);
}
void
ContourOperations
::
Push0
(
Contour
&
contour
)
{
contour
.
push_back
(
0
);
contour
.
push_back
(
0
);
}
void
ContourOperations
::
Push1
(
Contour
&
contour
)
{
contour
.
push_back
(
1
);
contour
.
push_back
(
0
);
}
void
ContourOperations
::
Push2
(
Contour
&
contour
)
{
contour
.
push_back
(
0
);
contour
.
push_back
(
1
);
}
void
ContourOperations
::
Push3
(
Contour
&
contour
)
{
contour
.
push_back
(
1
);
contour
.
push_back
(
1
);
}
}
// end of namespace lp
include/lpContour.h
deleted
100644 → 0
View file @
bb65d2e0
#ifndef __LP_CONTOUR_H
#define __LP_CONTOUR_H
#include <cassert>
#include <iostream>
#include <bitset>
#include <vector>
#include <utility>
#include <unordered_set>
#include <unordered_map>
#include <boost/dynamic_bitset.hpp>
namespace
lp
{
/* Move along a contour: 4 possibles: top (0), right(1), bottom (2), left(3). */
using
Move
=
std
::
bitset
<
2
>
;
/* A contour is a list of moves represented by a pair of bits*/
using
Contour
=
boost
::
dynamic_bitset
<>
;
using
ContourIndex
=
boost
::
dynamic_bitset
<>::
size_type
;
/* Index of a cell in the grid */
using
CellIndex
=
std
::
size_t
;
/* List of cell indices */
using
CellLists
=
std
::
unordered_set
<
CellIndex
>
;
struct
BoundingBox
{
std
::
size_t
m_UX
;
std
::
size_t
m_UY
;
std
::
size_t
m_W
;
std
::
size_t
m_H
;
};
class
ContourOperations
{
public:
/* Methods to fill a contour. */
static
void
Push0
(
Contour
&
contour
);
// Push a move to the top.
static
void
Push1
(
Contour
&
contour
);
// Push a move to the right.
static
void
Push2
(
Contour
&
contour
);
// Push a move to the bottom.
static
void
Push3
(
Contour
&
contour
);
// Push a move to the left.
/* Methods to access to elements of a contour. */
static
Move
GetMove2
(
ContourIndex
idx
,
const
Contour
&
contour
);
// Retrieve a move
static
short
GetMove10
(
const
Move
&
m
);
// Transform the move into a 10 base number (0,1,2 or 3).
/* Main methods */
static
void
MergeContour
(
Contour
&
mergedContour
,
BoundingBox
&
mergedBoundingBox
,
Contour
&
contour1
,
Contour
&
contour2
,
BoundingBox
&
bbox1
,
BoundingBox
&
bbox2
,
const
CellIndex
cid1
,
const
CellIndex
cid2
,
const
std
::
size_t
gridSizeX
);
static
void
GenerateBorderCells
(
CellLists
&
borderCells
,
// From a contour, the smallest id of the cell
const
Contour
&
contour
,
// belonging to the shape and the size of the grid,
const
CellIndex
startCellId
,
// this method returns the ids of the border cells
const
std
::
size_t
gridSizeX
);
// of the shape.
static
void
CreateNewContour
(
Contour
&
newContour
,
const
CellIndex
startCellId
,
const
std
::
vector
<
bool
>&
cellMatrix
,
const
std
::
size_t
bboxWidth
,
const
std
::
size_t
bboxHeight
);
/* Utilities methods */
static
BoundingBox
MergeBoundingBoxes
(
const
BoundingBox
&
bb1
,
// Given 2 bounding boxes return the bounding
const
BoundingBox
&
bb2
);
// which is the union.
static
void
EIGHTNeighborhood
(
long
int
*
neighborhood
,
// return 8-neighbors of cell id.
const
CellIndex
id
,
const
std
::
size_t
width
,
const
std
::
size_t
height
);
static
CellIndex
BBoxToGrid
(
const
CellIndex
bboxId
,
const
BoundingBox
&
bbox
,
const
std
::
size_t
gridSizeX
);
static
CellIndex
GridToBBox
(
const
CellIndex
gridId
,
// Return the coordinates of the cell
const
BoundingBox
&
bbox
,
// in the bounding box reference.
const
std
::
size_t
gridSizeX
);
};
}
// end of namespace lp
#include "lpContour.cpp"
#endif
include/lsgrmController.h
View file @
9493484b
...
...
@@ -47,6 +47,7 @@ public:
void
SetTilingModeAuto
(){
m_TilingMode
=
LSGRM_TILING_AUTO
;};
typename
LabelImageType
::
Pointer
GetLabeledClusteredOutput
();
std
::
vector
<
std
::
string
>
GetTemporaryFilesList
();
itkGetMacro
(
Margin
,
unsigned
int
);
...
...
include/lsgrmController.txx
View file @
9493484b
...
...
@@ -77,8 +77,10 @@ void Controller<TSegmenter>::RunSegmentation()
// Update the given number of iterations
numberOfIterationsRemaining -= m_NumberOfFirstIterations;
#ifdef OTB_USE_MPI
// Gathering useful variables
GatherUsefulVariables(accumulatedMemory, isFusion);
#endif
// Time monitoring
ShowTime(t);
...
...
@@ -104,9 +106,10 @@ void Controller<TSegmenter>::RunSegmentation()
// Update the given number of iterations
numberOfIterationsRemaining -= numberOfIterationsForPartialSegmentations;
#ifdef OTB_USE_MPI
// Gathering useful variables
GatherUsefulVariables(accumulatedMemory, isFusion);
#endif
// Time monitoring
ShowTime(t);
}
...
...
@@ -131,7 +134,7 @@ void Controller<TSegmenter>::RunSegmentation()
m_InputImage->GetNumberOfComponentsPerPixel(),
numberOfIterationsRemaining);
ShowTime(t);
//
ShowTime(t);
}
else // accumulatedMemory > m_Memory
...
...
@@ -156,7 +159,7 @@ void Controller<TSegmenter>::RunSegmentation()
template<class TSegmenter>
unsigned int Controller<TSegmenter>::GetNodeMemory()
{
// Create a
unique nod
e
// Create a
n*n imag
e
const unsigned int n = 100;
typename ImageType::Pointer onePixelImage = ImageType::New();
typename ImageType::IndexType start;
...
...
@@ -167,12 +170,17 @@ unsigned int Controller<TSegmenter>::GetNodeMemory()
onePixelImage->SetRegions(region);
onePixelImage->SetNumberOfComponentsPerPixel(m_InputImage->GetNumberOfComponentsPerPixel());
onePixelImage->Allocate();
// Instanciate and initialize a segmenter
TSegmenter segmenter;
segmenter.SetInput(onePixelImage);
ls
rm::GraphOperations<TSegmenter>::InitNodes(onePixelImage,segmenter,FOUR);
g
rm::GraphOperations<TSegmenter>::InitNodes(onePixelImage,segmenter,FOUR);
// Get the memory occupied by the graph, normalize it by n*n
unsigned int memory = segmenter.GetGraphMemory() / (n*n);
itkDebugMacro(<<"Size of a node is " << memory);
return memory;
}
...
...
@@ -268,8 +276,8 @@ void Controller<TSegmenter>::GetAutomaticConfiguration()
{
#ifdef OTB_USE_MPI
// We want number of tiles which is a multiple of the number of MPI processes
if (nbOfTiles % layoutNCol == 0 && // Is it a multiple of the nb of
...
Tiles?
nbOfTiles % otb::MPIConfig::Instance()->GetNbProcs() == 0)
// ...nProcs?
if (nbOfTiles % layoutNCol == 0 && // Is it a multiple of the nb of Tiles
and nProcs
?
nbOfTiles % otb::MPIConfig::Instance()->GetNbProcs() == 0)
#else
if (nbOfTiles % layoutNCol == 0) // Is it a multiple of the nb of Tiles?
#endif
...
...
@@ -358,4 +366,19 @@ Controller<TSegmenter>::GetLabeledClusteredOutput()
{
return m_LabelImage;
}
template <class TSegmenter>
std::vector<std::string> Controller<TSegmenter>::GetTemporaryFilesList()
{
std::vector<std::string> list;