Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
Main Repositories
otb
Commits
68c43d05
Commit
68c43d05
authored
Feb 17, 2016
by
Guillaume Pasero
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'masked_iterator_decorator' into develop
parents
16fc6cd6
8686293f
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
783 additions
and
1 deletion
+783
-1
Modules/Core/Common/include/otbSubsampledImageRegionConstIterator.txx
.../Common/include/otbSubsampledImageRegionConstIterator.txx
+1
-1
Modules/Filtering/ImageManipulation/include/otbMaskedIteratorDecorator.h
...ng/ImageManipulation/include/otbMaskedIteratorDecorator.h
+132
-0
Modules/Filtering/ImageManipulation/include/otbMaskedIteratorDecorator.txx
.../ImageManipulation/include/otbMaskedIteratorDecorator.txx
+237
-0
Modules/Filtering/ImageManipulation/otb-module.cmake
Modules/Filtering/ImageManipulation/otb-module.cmake
+1
-0
Modules/Filtering/ImageManipulation/test/CMakeLists.txt
Modules/Filtering/ImageManipulation/test/CMakeLists.txt
+17
-0
Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx
...ImageManipulation/test/otbImageManipulationTestDriver.cxx
+4
-0
Modules/Filtering/ImageManipulation/test/otbMaskedIteratorDecorator.cxx
...ing/ImageManipulation/test/otbMaskedIteratorDecorator.cxx
+391
-0
No files found.
Modules/Core/Common/include/otbSubsampledImageRegionConstIterator.txx
View file @
68c43d05
...
...
@@ -316,7 +316,7 @@ SubsampledImageRegionConstIterator<TImage>
{
// Get the index of the first pixel on the span (row)
IndexType ind = this->m_Image->ComputeIndex(static_cast<IndexValueType>(this->m_Offset));
IndexType& startIndex = this->m_Region.GetIndex();
const
IndexType& startIndex = this->m_Region.GetIndex();
// Deccrement along a row, then wrap at the beginning of the region row.
bool done;
...
...
Modules/Filtering/ImageManipulation/include/otbMaskedIteratorDecorator.h
0 → 100644
View file @
68c43d05
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef otbMaskedIteratorDecorator_h
#define otbMaskedIteratorDecorator_h
#include "itkMacro.h"
namespace
otb
{
/** \class MaskedIteratorDecorator
* \brief Decorate an iterator to ignore masked pixels
*
* An iterator that dispatches its operations on both an image and a mask using
* two iterators of the same type. It skips over pixels where the value of the
* mask is zero. There is a limitation that the image and the mask must both be
* of the same type.
*
* \ingroup ImageIterator
* \ingroup OTBCommon
*/
template
<
typename
TIteratorType
,
typename
TMaskIteratorType
=
TIteratorType
>
class
MaskedIteratorDecorator
{
public:
typedef
MaskedIteratorDecorator
<
TIteratorType
,
TMaskIteratorType
>
Self
;
typedef
typename
TMaskIteratorType
::
ImageType
MaskType
;
typedef
typename
TIteratorType
::
ImageType
ImageType
;
typedef
typename
ImageType
::
IndexType
IndexType
;
typedef
typename
ImageType
::
RegionType
RegionType
;
typedef
typename
ImageType
::
PixelType
PixelType
;
typedef
typename
MaskType
::
PixelType
MaskPixelType
;
// Run-time type information
itkTypeMacroNoParent
(
MaskedIteratorDecorator
);
/** Constructors forward arguments to both iterators
* Beware that the iterator is in a undefinite state after construction
* GoToBegin() or GoToEnd() should be called */
MaskedIteratorDecorator
(
MaskType
*
mask
,
ImageType
*
image
,
const
RegionType
&
region
);
/** Current iterator index. Wraps the underlying iterator GetIndex() */
IndexType
GetIndex
()
const
;
/** Move to the first valid iteration position. Note that this is different
* from the underlying iterators GoToBegin because their first pixels might be
* masked */
void
GoToBegin
();
/** Move one pixel past the last valid iteration index */
void
GoToEnd
();
/** True if the iterator is at the beginning */
bool
IsAtBegin
()
const
;
/** True if the iterator is at the end */
bool
IsAtEnd
()
const
;
/** Advance to the next valid iteration position. That is the next non masked
* position of the image iterator */
Self
&
operator
++
();
/** Move to the previous valid iteration position. That is the previous non
* masked position of the image iterator */
Self
&
operator
--
();
/** Set the image pixel value */
//void Set(const PixelType& value) const;
/** Get the image pixel value */
const
PixelType
&
Value
(
void
)
const
;
// Can't wrap all methods because iterator interface is open ended
// So provide access to inner iterators:
/** Underlying mask iterator accessor */
TMaskIteratorType
&
GetMaskIterator
();
/** Underlying mask iterator const accessor */
const
TMaskIteratorType
&
GetMaskIterator
()
const
;
/** Underlying image iterator accessor */
TIteratorType
&
GetImageIterator
();
/** Underlying image iterator const accessor */
const
TIteratorType
&
GetImageIterator
()
const
;
const
bool
&
HasMask
()
const
;
private:
/** Private method to compute the begin iterator position taking into account
the mask. Called by the constructor. */
void
ComputeMaskedBegin
();
private:
// Inner iterators on the image and mask
TMaskIteratorType
m_ItMask
;
TIteratorType
m_ItImage
;
// flag to check if mask is present
bool
m_UseMask
;
// Unmasked bounds
TMaskIteratorType
m_StartMask
;
TIteratorType
m_StartImage
;
};
}
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbMaskedIteratorDecorator.txx"
#endif
#endif
Modules/Filtering/ImageManipulation/include/otbMaskedIteratorDecorator.txx
0 → 100644
View file @
68c43d05
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef otbMaskedIteratorDecorator_hxx
#define otbMaskedIteratorDecorator_hxx
#include "otbMaskedIteratorDecorator.h"
#include "itkMacro.h"
namespace otb
{
template <typename TIteratorType, typename TMaskIteratorType>
MaskedIteratorDecorator<TIteratorType,TMaskIteratorType>
::MaskedIteratorDecorator( MaskType* mask,
ImageType* image,
const RegionType& region)
{
m_ItImage = TIteratorType(image,region);
if (mask == NULL)
{
m_UseMask = false;
}
else
{
if (image->GetLargestPossibleRegion() != mask->GetLargestPossibleRegion())
{
itkGenericExceptionMacro("Input image and mask have different largest regions : mask is discarded!");
}
else
{
m_UseMask = true;
m_ItMask = TMaskIteratorType(mask,region);
m_StartMask = TMaskIteratorType(mask,region);
m_StartImage = TIteratorType(image,region);
}
}
}
template <typename TIteratorType, typename TMaskIteratorType>
typename MaskedIteratorDecorator<TIteratorType,TMaskIteratorType>::IndexType
MaskedIteratorDecorator<TIteratorType,TMaskIteratorType>
::GetIndex() const
{
return m_ItImage.GetIndex();
}
template <typename TIteratorType, typename TMaskIteratorType>
void
MaskedIteratorDecorator<TIteratorType,TMaskIteratorType>
::GoToBegin()
{
if (m_UseMask)
{
this->ComputeMaskedBegin();
}
else
{
m_ItImage.GoToBegin();
}
}
template <typename TIteratorType, typename TMaskIteratorType>
void
MaskedIteratorDecorator<TIteratorType,TMaskIteratorType>
::GoToEnd()
{
if (m_UseMask)
{
// make sure masked begin is computed as next calls might be operator--()
// and IsAtBegin() (for a reverse iteration)
this->ComputeMaskedBegin();
m_ItMask.GoToEnd();
}
m_ItImage.GoToEnd();
}
template <typename TIteratorType, typename TMaskIteratorType>
bool
MaskedIteratorDecorator<TIteratorType,TMaskIteratorType>
::IsAtBegin() const
{
if (m_UseMask)
{
return m_ItMask == m_StartMask || m_ItImage == m_StartImage;
}
return m_ItImage.IsAtBegin();
}
template <typename TIteratorType, typename TMaskIteratorType>
bool
MaskedIteratorDecorator<TIteratorType,TMaskIteratorType>
::IsAtEnd() const
{
if (m_UseMask)
{
return m_ItMask.IsAtEnd() || m_ItImage.IsAtEnd();
}
return m_ItImage.IsAtEnd();
}
// Wrap the underlying iterators to skip masked pixels
template <typename TIteratorType, typename TMaskIteratorType>
MaskedIteratorDecorator<TIteratorType,TMaskIteratorType>&
MaskedIteratorDecorator<TIteratorType,TMaskIteratorType>
::operator++()
{
if (m_UseMask)
{
do
{
++m_ItMask;
++m_ItImage;
} while (m_ItMask.Value() == 0 && !this->IsAtEnd());
}
else
{
++m_ItImage;
}
return *this;
}
// Wrap the underlying iterators to skip masked pixels
template <typename TIteratorType, typename TMaskIteratorType>
MaskedIteratorDecorator<TIteratorType,TMaskIteratorType>&
MaskedIteratorDecorator<TIteratorType,TMaskIteratorType>
::operator--()
{
if (m_UseMask)
{
do
{
--m_ItMask;
--m_ItImage;
} while (m_ItMask.Value() == 0 && !this->IsAtBegin());
}
else
{
--m_ItImage;
}
return *this;
}
/*
template <typename TIteratorType, typename TMaskIteratorType>
void MaskedIteratorDecorator<TIteratorType,TMaskIteratorType>::Set(const PixelType& value) const
{
m_ItImage.Set(value);
}
*/
template <typename TIteratorType, typename TMaskIteratorType>
const typename MaskedIteratorDecorator<TIteratorType,TMaskIteratorType>::PixelType&
MaskedIteratorDecorator<TIteratorType,TMaskIteratorType>
::Value(void) const
{
return m_ItImage.Value();
}
template <typename TIteratorType, typename TMaskIteratorType>
TMaskIteratorType&
MaskedIteratorDecorator<TIteratorType,TMaskIteratorType>
::GetMaskIterator()
{
return m_ItMask;
}
template <typename TIteratorType, typename TMaskIteratorType>
const TMaskIteratorType&
MaskedIteratorDecorator<TIteratorType,TMaskIteratorType>
::GetMaskIterator() const
{
return m_ItMask;
}
template <typename TIteratorType, typename TMaskIteratorType>
TIteratorType&
MaskedIteratorDecorator<TIteratorType,TMaskIteratorType>
::GetImageIterator()
{
return m_ItImage;
}
template <typename TIteratorType, typename TMaskIteratorType>
const TIteratorType&
MaskedIteratorDecorator<TIteratorType,TMaskIteratorType>
::GetImageIterator() const
{
return m_ItImage;
}
template <typename TIteratorType, typename TMaskIteratorType>
const bool&
MaskedIteratorDecorator<TIteratorType,TMaskIteratorType>
::HasMask() const
{
return m_UseMask;
}
// Compute begin iterator position taking into account the mask
template <typename TIteratorType, typename TMaskIteratorType>
void
MaskedIteratorDecorator<TIteratorType,TMaskIteratorType>
::ComputeMaskedBegin()
{
// We must search for the first index where the image is not masked
// Start searching at the begining
m_ItMask.GoToBegin();
m_ItImage.GoToBegin();
// Advance to the first non-masked position, or the end
while (m_ItMask.Value() == 0 && !m_ItMask.IsAtEnd() && !m_ItImage.IsAtEnd())
{
++m_ItMask;
++m_ItImage;
}
m_StartMask.SetIndex(m_ItMask.GetIndex());
m_StartImage.SetIndex(m_ItImage.GetIndex());
}
} // namespace otb
#endif
Modules/Filtering/ImageManipulation/otb-module.cmake
View file @
68c43d05
...
...
@@ -7,6 +7,7 @@ data.")
otb_module
(
OTBImageManipulation
DEPENDS
OTBBoostAdapters
OTBCommon
OTBITK
OTBImageBase
...
...
Modules/Filtering/ImageManipulation/test/CMakeLists.txt
View file @
68c43d05
...
...
@@ -76,6 +76,7 @@ otbTwoNRIBandsImageToNComplexBandsImage.cxx
otbChangeNoDataValueFilter.cxx
otbImageToNoDataMaskFilter.cxx
otbChangeInformationImageFilter.cxx
otbMaskedIteratorDecorator.cxx
)
add_executable
(
otbImageManipulationTestDriver
${
OTBImageManipulationTests
}
)
...
...
@@ -716,3 +717,19 @@ otb_add_test(NAME bfTvChangeInformationImageFilter COMMAND otbImageManipulation
otbChangeInformationImageFilter
${
INPUTDATA
}
/WV2_PAN_ROI_1000_100.tif
)
otb_add_test
(
NAME bfTuMaskedIteratorDecoratorNew COMMAND otbImageManipulationTestDriver
otbMaskedIteratorDecoratorNew
)
otb_add_test
(
NAME bfTvMaskedIteratorDecoratorNominal COMMAND otbImageManipulationTestDriver
otbMaskedIteratorDecoratorNominal
)
otb_add_test
(
NAME bfTvMaskedIteratorDecoratorDegenerate COMMAND otbImageManipulationTestDriver
otbMaskedIteratorDecoratorDegenerate
)
otb_add_test
(
NAME bfTvMaskedIteratorDecoratorExtended COMMAND otbImageManipulationTestDriver
otbMaskedIteratorDecoratorExtended
)
Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx
View file @
68c43d05
...
...
@@ -82,4 +82,8 @@ void RegisterTests()
REGISTER_TEST
(
otbChangeNoDataValueFilter
);
REGISTER_TEST
(
otbImageToNoDataMaskFilter
);
REGISTER_TEST
(
otbChangeInformationImageFilter
);
REGISTER_TEST
(
otbMaskedIteratorDecoratorNew
);
REGISTER_TEST
(
otbMaskedIteratorDecoratorNominal
);
REGISTER_TEST
(
otbMaskedIteratorDecoratorDegenerate
);
REGISTER_TEST
(
otbMaskedIteratorDecoratorExtended
);
}
Modules/Filtering/ImageManipulation/test/otbMaskedIteratorDecorator.cxx
0 → 100644
View file @
68c43d05
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include <set>
#include "otbImage.h"
#include "otbVectorImage.h"
#include "itkImageRegionIterator.h"
#include "itkImageRegionReverseIterator.h"
#include "itkImageRandomIteratorWithIndex.h"
#include "itkImageScanlineIterator.h"
#include "itkImageRandomNonRepeatingIteratorWithIndex.h"
#include "otbSubsampledImageRegionIterator.h"
#include "otbMaskedIteratorDecorator.h"
// Generate a test image of specified size and value
template
<
typename
ImageType
>
typename
ImageType
::
Pointer
GetTestImage
(
itk
::
SizeValueType
fillSize
,
const
typename
ImageType
::
PixelType
&
value
,
unsigned
int
nbBand
=
1
)
{
typename
ImageType
::
Pointer
image
=
ImageType
::
New
();
typename
ImageType
::
SizeType
size
;
size
.
Fill
(
fillSize
);
typename
ImageType
::
RegionType
region
;
region
.
SetSize
(
size
);
image
->
SetNumberOfComponentsPerPixel
(
nbBand
);
image
->
SetRegions
(
region
);
image
->
Allocate
();
image
->
FillBuffer
(
value
);
return
image
;
}
// Fill half of the pixels with a value
// Used for generating a test mask
template
<
typename
ImageType
>
void
FillHalf
(
typename
ImageType
::
Pointer
image
,
const
typename
ImageType
::
RegionType
&
region
,
const
typename
ImageType
::
PixelType
&
value
)
{
itk
::
ImageRegionIterator
<
ImageType
>
it
(
image
,
region
);
unsigned
int
count
=
0
;
for
(
it
.
GoToBegin
();
!
it
.
IsAtEnd
();
++
it
,
++
count
)
{
if
(
count
%
2
==
0
)
{
it
.
Set
(
value
);
}
}
}
// Test template instanciation
int
otbMaskedIteratorDecoratorNew
(
int
itkNotUsed
(
argc
),
char
*
itkNotUsed
(
argv
)
[])
{
typedef
otb
::
Image
<
double
,
2
>
ImageType
;
ImageType
::
Pointer
image
=
GetTestImage
<
ImageType
>
(
10
,
10
);
ImageType
::
Pointer
mask
=
GetTestImage
<
ImageType
>
(
10
,
0
);
ImageType
::
RegionType
region
(
image
->
GetLargestPossibleRegion
());
otb
::
MaskedIteratorDecorator
<
itk
::
ImageRegionIterator
<
ImageType
>
>
it
(
mask
,
image
,
region
);
return
EXIT_SUCCESS
;
}
// ---------------------- Initialization code ----------------------------------
template
<
typename
IteratorType
>
void
InitializeIterator
(
IteratorType
&
,
typename
IteratorType
::
RegionType
)
{
// by default : nothing to do
}
// specialization for otb::SubsampledImageRegionIterator<otb::Image<double, 2> >
template
<
>
void
InitializeIterator
<
otb
::
SubsampledImageRegionIterator
<
otb
::
Image
<
double
,
2
>
>
>
(
otb
::
SubsampledImageRegionIterator
<
otb
::
Image
<
double
,
2
>
>&
it
,
typename
otb
::
SubsampledImageRegionIterator
<
otb
::
Image
<
double
,
2
>
>::
RegionType
)
{
it
.
SetSubsampleFactor
(
2
);
}
// -------------------------- ForwardTest --------------------------------------
// Function to test the forward iteration interface
template
<
typename
IteratorType
,
typename
MaskIteratorType
>
int
ForwardTest
(
typename
MaskIteratorType
::
ImageType
::
Pointer
mask
,
typename
IteratorType
::
ImageType
::
Pointer
image
,
typename
IteratorType
::
ImageType
::
RegionType
region
)
{
otb
::
MaskedIteratorDecorator
<
IteratorType
,
MaskIteratorType
>
it
(
mask
,
image
,
region
);
// specific initialization code
InitializeIterator
<
IteratorType
>
(
it
.
GetImageIterator
(),
region
);
if
(
it
.
HasMask
())
{
InitializeIterator
<
MaskIteratorType
>
(
it
.
GetMaskIterator
(),
region
);
}
it
.
GoToBegin
();
if
(
!
it
.
IsAtBegin
())
{
return
1
;}
unsigned
int
loopCount
=
0
;
for
(;
!
it
.
IsAtEnd
();
++
it
)
{
if
(
loopCount
!=
0
&&
it
.
IsAtBegin
())
{
return
2
;}
if
(
it
.
IsAtEnd
())
{
return
3
;}
//it.Set(it.Value() * 0.42);
loopCount
+=
1
;
}
if
(
!
it
.
IsAtEnd
())
{
return
4
;}
return
0
;
}
// -------------------------- ReverseTest --------------------------------------
// Test reverse iteration interface
template
<
typename
IteratorType
,
typename
MaskIteratorType
>
int
ReverseTest
(
typename
MaskIteratorType
::
ImageType
::
Pointer
mask
,
typename
IteratorType
::
ImageType
::
Pointer
image
,
typename
IteratorType
::
ImageType
::
RegionType
region
)
{
otb
::
MaskedIteratorDecorator
<
IteratorType
,
MaskIteratorType
>
it
(
mask
,
image
,
region
);
// specific initialization code
InitializeIterator
<
IteratorType
>
(
it
.
GetImageIterator
(),
region
);
if
(
it
.
HasMask
())
{
InitializeIterator
<
MaskIteratorType
>
(
it
.
GetMaskIterator
(),
region
);
}
it
.
GoToEnd
();
if
(
!
it
.
IsAtEnd
())
{
return
1
;}
bool
beginReached
=
false
;
while
(
!
it
.
IsAtBegin
())
{
--
it
;
if
(
it
.
IsAtEnd
())
{
return
2
;}
if
(
beginReached
)
{
return
3
;
}
if
(
it
.
IsAtBegin
())
{
beginReached
=
true
;
}
}
if
(
!
it
.
IsAtBegin
())
{
return
4
;}
return
0
;
}
// -------------------------- BijectiveTest --------------------------------------
// Check bijection between iterated and non masked
// i.e all locations where mask value != 0 are in the iteration (injection)
// and mask value != 0 at all iteration locations (surjection)
// Templated to test decoration of different iterator types
template
<
typename
IteratorType
,
typename
MaskIteratorType
>
int
BijectiveTest
(
typename
MaskIteratorType
::
ImageType
::
Pointer
mask
,
typename
IteratorType
::
ImageType
::
Pointer
image
,
typename
IteratorType
::
ImageType
::
RegionType
region
)
{
otb
::
MaskedIteratorDecorator
<
IteratorType
,
MaskIteratorType
>
itDecorated
(
mask
,
image
,
region
);
IteratorType
it
(
image
,
region
);