Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
otb
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
David Youssefi
otb
Commits
b6defe65
Commit
b6defe65
authored
12 years ago
by
Arnaud Jaen
Browse files
Options
Downloads
Patches
Plain Diff
DOC: Update the StreamingMeanShiftSegmentation example.
parent
0f9ce884
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
Examples/Segmentation/CMakeLists.txt
+10
-0
10 additions, 0 deletions
Examples/Segmentation/CMakeLists.txt
Examples/Segmentation/StreamingMeanShiftSegmentation.cxx
+155
-66
155 additions, 66 deletions
Examples/Segmentation/StreamingMeanShiftSegmentation.cxx
with
165 additions
and
66 deletions
Examples/Segmentation/CMakeLists.txt
+
10
−
0
View file @
b6defe65
...
@@ -424,7 +424,17 @@ ADD_TEST(seTeStreamingMeanShiftSegmentationTest ${EXE_TESTS}
...
@@ -424,7 +424,17 @@ ADD_TEST(seTeStreamingMeanShiftSegmentationTest ${EXE_TESTS}
# ${TEMP}/seTeStreamingMeanShiftSegmentationTest.shp
# ${TEMP}/seTeStreamingMeanShiftSegmentationTest.shp
StreamingMeanShiftSegmentationTest
StreamingMeanShiftSegmentationTest
${
INPUTDATA
}
/QB_Toulouse_Ortho_PAN.tif
${
INPUTDATA
}
/QB_Toulouse_Ortho_PAN.tif
${
INPUTDATA
}
/QB_Toulouse_Ortho_PAN_Mask.tif
${
TEMP
}
/seTeStreamingMeanShiftSegmentationTest.shp
${
TEMP
}
/seTeStreamingMeanShiftSegmentationTest.shp
NewLayer
100
5
15.
100
1
#filter small object
50
#minimum size of object
1
#Simplify Flag
0.2
#Simplification tolerance
)
)
...
...
This diff is collapsed.
Click to expand it.
Examples/Segmentation/StreamingMeanShiftSegmentation.cxx
+
155
−
66
View file @
b6defe65
...
@@ -22,44 +22,59 @@
...
@@ -22,44 +22,59 @@
// Software Guide : BeginLatex
// Software Guide : BeginLatex
//
//
// The following example illustrates how to segment images
// The following example illustrates how to segment very large images
// using the \doxygen{otb}{StreamingVectorizedSegmentation}.
// using the \doxygen{otb}{StreamingVectorizedSegmentation}. This filter is
// The \doxygen{otb}{MeanShiftImageFilter} is used to segment each tile of the image.
// templated over the segmentation filter that will be used to segment each tile
// The labeled output image of each tile is then polygonized and stored into a \doxygen{otb}{VectorData}
// of the input image. In this example we will use the \doxygen{otb}{MeanShiftVectorImageFilter}.
// The method used for polygonize is GDALPolygonize.
// The labeled output image of each tile is then vectorized (using a filter based on GDALPolygonize)
// and stored into a \doxygen{otb}{ogr}{Layer} within the \doxygen{otb}{ogr}{DataSource}
// set as input. Finally a fusion filter, \doxygen{otb}{FusionOGRTileFilter}, is used to merge polygons
// at tile border.
//
//
//
First we include the segmentation filter (Here it is the MeanShiftFilter) and
//
Let's take a look at the code.
//
the StreamingVectorizedSegmentation
header
.
//
First we include all the needed
header
s
// Software Guide : EndLatex
// Software Guide : EndLatex
#include
<iostream>
#include
<iostream>
// Software Guide : BeginCodeSnippet
// Software Guide : BeginCodeSnippet
#include
"otbStreamingVectorizedSegmentationOGR.h"
#include
"otbStreamingVectorizedSegmentationOGR.h"
#include
"otbMeanShiftSegmentationFilter.h"
#include
"otbMeanShiftVectorImageFilter.h"
#include
"otbOGRDataSourceWrapper.h"
#include
"otbFusionOGRTileFilter.h"
// Software Guide : EndCodeSnippet
// Software Guide : EndCodeSnippet
#include
"otbVectorImage.h"
#include
"otbVectorImage.h"
#include
"otbImageFileReader.h"
#include
"otbImageFileReader.h"
#include
"otbVectorDataFileWriter.h"
#include
"otbVectorData.h"
#include
"otbOGRDataSourceWrapper.h"
int
main
(
int
argc
,
char
*
argv
[])
int
main
(
int
argc
,
char
*
argv
[])
{
{
if
(
argc
<
2
)
if
(
argc
!=
13
)
{
{
std
::
cerr
<<
"Missing Parameters "
<<
std
::
endl
;
std
::
cerr
<<
"Usage: "
<<
argv
[
0
];
std
::
cerr
<<
"Usage: "
<<
argv
[
0
];
std
::
cerr
<<
" inputImage maskImage outputVec layerName TileDimension"
std
::
cerr
<<
<<
"spatialRadius rangeRadius minObjectSize filterSmallObj minSize"
" inputImage outputVectorData "
<<
"SimplifyFlag Tolerance"
<<
std
::
endl
;
<<
std
::
endl
;
return
EXIT_FAILURE
;
return
1
;
}
}
const
char
*
imageName
=
argv
[
1
];
const
char
*
maskName
=
argv
[
2
];
const
char
*
dataSourceName
=
argv
[
3
];
const
char
*
layerName
=
argv
[
4
];
const
unsigned
int
tileSize
=
atoi
(
argv
[
5
]);
const
unsigned
int
spatialRadius
=
atoi
(
argv
[
6
]);
const
double
rangeRadius
=
atof
(
argv
[
7
]);
const
unsigned
int
minimumObjectSize
=
atoi
(
argv
[
8
]);
const
bool
filterSmallObj
=
atoi
(
argv
[
9
]);
const
unsigned
int
minSize
=
atoi
(
argv
[
10
]);
const
bool
simplify
=
atoi
(
argv
[
11
]);
const
double
tolerance
=
atof
(
argv
[
12
]);
const
std
::
string
fieldName
(
"DN"
);
// Software Guide : BeginLatex
// Software Guide : BeginLatex
//
//
// We now declare the image and pixel types
to
use as input of the MeanShiftFilter.
// We now declare the image and pixel types use
d
as input of the MeanShiftFilter.
// Software Guide : EndLatex
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
// Software Guide : BeginCodeSnippet
...
@@ -72,37 +87,26 @@ int main(int argc, char *argv[])
...
@@ -72,37 +87,26 @@ int main(int argc, char *argv[])
typedef
otb
::
VectorData
<
double
,
2
>
VectorDataType
;
typedef
otb
::
VectorData
<
double
,
2
>
VectorDataType
;
// Software Guide : EndCodeSnippet
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Next we declare the output VectorData type that will contain all the polygons.
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef
otb
::
VectorData
<
double
,
2
>
VectorDataType
;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
// Software Guide : BeginLatex
//
//
// Then the mean shift segmentation filter is declared using the Image type declared previsouly.
// Then the mean shift segmentation filter is declared using the Image type declared previsouly.
// The StreamingVectorizedSegmentation is templated over the mean shift filter, the input image type and the output vector data type
// The StreamingVectorizedSegmentation is templated over the mean shift filter, the input image type and the output vector data type
// Software Guide : EndLatex
// Software Guide : EndLatex
// Typedefs
// Software Guide : BeginCodeSnippet
// Software Guide : BeginCodeSnippet
//typedef otb::MeanShiftSmoothingImageFilter<ImageType, ImageType> MeanShiftImageFilterType;
//typedef otb::MeanShiftSmoothingImageFilter<ImageType, ImageType> MeanShiftImageFilterType;
typedef
otb
::
MeanShiftSegmentationFilter
<
ImageType
,
LabelImageType
,
ImageType
>
MeanShiftSegmentationFilterType
;
typedef
otb
::
MeanShiftVectorImageFilter
<
ImageType
,
ImageType
,
LabelImageType
>
SegmentationFilterType
;
typedef
otb
::
StreamingVectorizedSegmentationOGR
<
ImageType
,
SegmentationFilterType
>
StreamingVectorizedSegmentationType
;
typedef
otb
::
StreamingVectorizedSegmentationOGR
<
ImageType
,
MeanShiftSegmentationFilterType
>
StreamingVectorizedSegmentationType
;
// Software Guide : EndCodeSnippet
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
// Software Guide : BeginLatex
//
//
// Finaly we define a Reader on the input image and a writer for the VectorData.
// Finaly we define a Reader on the input image and a mask reader.
// All pixels in the mask with a value of 0 will not be considered suitable for vectorization.
// Software Guide : EndLatex
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
// Software Guide : BeginCodeSnippet
typedef
otb
::
ImageFileReader
<
ImageType
>
ReaderType
;
typedef
otb
::
ImageFileReader
<
ImageType
>
ReaderType
;
typedef
otb
::
VectorDataFileWriter
<
VectorData
Type
>
Writ
erType
;
typedef
otb
::
ImageFileReader
<
LabelImage
Type
>
MaskRead
erType
;
// Software Guide : EndCodeSnippet
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
// Software Guide : BeginLatex
...
@@ -110,51 +114,136 @@ int main(int argc, char *argv[])
...
@@ -110,51 +114,136 @@ int main(int argc, char *argv[])
// Now we have declared all type needed for the pipeline, we instantiate the different filters,
// Now we have declared all type needed for the pipeline, we instantiate the different filters,
// Software Guide : EndLatex
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
// Software Guide : BeginCodeSnippet
ReaderType
::
Pointer
reader
=
ReaderType
::
New
();
ReaderType
::
Pointer
reader
=
ReaderType
::
New
();
MaskReaderType
::
Pointer
maskReader
=
MaskReaderType
::
New
();
StreamingVectorizedSegmentationType
::
Pointer
filter
=
StreamingVectorizedSegmentationType
::
New
();
StreamingVectorizedSegmentationType
::
Pointer
filter
=
StreamingVectorizedSegmentationType
::
New
();
//WriterType::Pointer writer = WriterType::New();
// Software Guide : EndCodeSnippet
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
// Software Guide : BeginLatex
//
//
// And we connect the pipeline and set parameters for the mean shift filter.
// The instanciation of the DataSource is slightly different as usual.
// In fact the \code{New()} method on a \doxygen{otb}{ogr}{DataSource} can be called with or without parameters.
// Without parameters, the \code{New()} method instanciate a "Memory" DataSource, which means all the data are stored in memory.
// This is not useful in case of large scale segmentation as it will result in millions of polygons kept in memory ...
// However the \code{New()} method can also take a filename (\code{std::String}) parameter. Then either the file already exists
// and the corresponding ogr driver is used to open the file, or it doesn't exists and then it is created.
// Here we used a non existing filename to create a new file in writing mode.
// Software Guide : EndLatex
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
// Software Guide : BeginCodeSnippet
reader
->
SetFileName
(
argv
[
1
]);
otb
::
ogr
::
DataSource
::
Pointer
ogrDS
=
otb
::
ogr
::
DataSource
::
New
(
dataSourceName
,
otb
::
ogr
::
DataSource
::
Modes
::
write
);
reader
->
GenerateOutputInformation
();
// Software Guide : EndCodeSnippet
filter
->
SetInput
(
reader
->
GetOutput
());
otb
::
ogr
::
DataSource
::
Pointer
ogrDS
=
otb
::
ogr
::
DataSource
::
New
(
argv
[
2
],
otb
::
ogr
::
DataSource
::
Modes
::
write
);
filter
->
SetOGRDataSource
(
ogrDS
);
//filter->GetStreamer()->SetNumberOfLinesStrippedStreaming(atoi(argv[3]));
filter
->
GetStreamer
()
->
SetAutomaticTiledStreaming
();
const
std
::
string
fieldName
(
"DN"
);
// Software Guide : BeginLatex
//
// Now we set the parameters to the segmentation filter.The \doxygen{otb}{MeanShiftVectorImageFilter}
// required three parameters, the spatial radius, the range radius and the minimum object size.
// We use the \code{GetSegmentationFilter()} method on the \doxygen{otb}{StreamingVectorizedSegmentation}
// to get a pointer to the segmentation filter.
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
filter
->
GetSegmentationFilter
()
->
SetSpatialRadius
(
spatialRadius
);
filter
->
GetSegmentationFilter
()
->
SetRangeRadius
(
rangeRadius
);
filter
->
GetSegmentationFilter
()
->
SetMinimumRegionSize
(
minimumObjectSize
);
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Then we set parameters to the \doxygen{otb}{StreamingVectorizedSegmentation} filter.
// These parameters are :
// \begin{itemize}
// \item tile size : use \code{SetTileDimensionTiledStreaming()} for square tile or \code{SetNumberOfLinesStrippedStreaming()}
// for Strip.
// \item layer name : name of the layer that will be created in the input \doxygen{otb}{ogr}{DataSource}.
// \item field name : name of the field that will contained the label values. (default is "DN").
// \item start label : first label. Each polygons have a unique label (incremented by one).
// \item option to filter small polygons (default to false).
// \item minimum object size : in case filter small polygons option is True
// \item simplify option : simplification of polygon vertex (default to false).This can reduced very efficiently the size
// of the output file with no real impact on the results.
// \item simplification tolerance
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
filter
->
GetStreamer
()
->
SetTileDimensionTiledStreaming
(
tileSize
);
filter
->
SetLayerName
(
layerName
);
filter
->
SetFieldName
(
fieldName
);
filter
->
SetFieldName
(
fieldName
);
filter
->
SetLayerName
(
"Layer"
);
filter
->
SetStartLabel
(
1
);
filter
->
SetStartLabel
(
1
);
filter
->
SetUse8Connected
(
false
);
filter
->
SetFilterSmallObject
(
filterSmallObj
);
filter
->
SetMinimumObjectSize
(
minSize
);
filter
->
SetSimplify
(
simplify
);
filter
->
SetSimplificationTolerance
(
tolerance
);
// Software Guide : EndCodeSnippet
//filter->GetSegmentationFilter()->SetSpatialRadius(10);
//filter->GetSegmentationFilter()->SetRangeRadius(15);
//filter->GetSegmentationFilter()->SetMinimumRegionSize(400);
filter
->
GetSegmentationFilter
()
->
SetSpatialBandwidth
(
10
);
filter
->
GetSegmentationFilter
()
->
SetRangeBandwidth
(
15
);
filter
->
SetFilterSmallObject
(
true
);
filter
->
SetMinimumObjectSize
(
400
);
filter
->
Initialize
();
// Software Guide : BeginLatex
//
// Finally we connect the pipeline
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
reader
->
SetFileName
(
imageName
);
reader
->
GenerateOutputInformation
();
maskReader
->
SetFileName
(
maskName
);
maskReader
->
UpdateOutputInformation
();
filter
->
SetInput
(
reader
->
GetOutput
());
filter
->
SetInputMask
(
maskReader
->
GetOutput
());
filter
->
SetOGRDataSource
(
ogrDS
);
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// And call the \code{Initialize()} method (needed to create the output layer in the datasource)
// before calling the \code{Update()} method.
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
filter
->
Initialize
();
filter
->
Update
();
filter
->
Update
();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The segmentation is done, but as it works tile by tile, we need to fusion polygons at tile border.
// We use the \doxygen{otb}{FusionOGRTileFilter}. This filter uses a simple fusion strategy.
// Polygons that have the largest intersection over a tile are fusioned. Each polygon can be fusioned
// only once per tile border (row and column).
// Let's look at the code for fusioning.
// As usual we declared and instanciate the \doxygen{otb}{FusionOGRTileFilter}.
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef
otb
::
FusionOGRTileFilter
<
ImageType
>
FusionFilterType
;
FusionFilterType
::
Pointer
fusionFilter
=
FusionFilterType
::
New
();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
// Next we set the input image and the input \doxygen{otb}{ogr}{DataSource}.
// The image is internally used in the filter to compute coordinates of streaming tiles.
// The DataSource is the one containing the segmentation results.
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
fusionFilter
->
SetInput
(
reader
->
GetOutput
());
fusionFilter
->
SetOGRDataSource
(
ogrDS
);
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
// We set the name of the layer containing segmentation results which is the same that we used
// for the \doxygen{otb}{StreamingVectorizedSegmentation} filter. We also set the size of the
// tile used, which may be different from the one we set in the \doxygen{otb}{StreamingVectorizedSegmentation} filter
// but can be retrieved using the \code{GetStreamSize()} method.
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
fusionFilter
->
SetStreamSize
(
filter
->
GetStreamSize
());
fusionFilter
->
SetLayerName
(
layerName
);
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
// Finally we call the \code{GenerateData()} method to launch the processing.
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
fusionFilter
->
GenerateData
();
//writer->SetFileName(argv[2]);
//writer->SetInput(filter->GetOutputVectorData());
//writer->Update();
// Software Guide : EndCodeSnippet
// Software Guide : EndCodeSnippet
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment