Commit a95aca44 authored by Emmanuel Christophe's avatar Emmanuel Christophe
Browse files

MRG

parents f0ce622d 4b1c58c1
......@@ -432,7 +432,9 @@ ADD_TEST( utKmlprintgeometry ${UTILITIES_TESTS}
# ${TEMP}/utkmlprintgeometry.txt
)
ADD_TEST(ijObjectLabelAttributeValuesTest ${UTILITIES_TESTS}
ijObjectLabelAttributeValuesTest
)
# ------- Fichiers sources CXX -----------------------------------
SET(UtilitiesTests_SRCS
ossimIntegrationTest.cxx
......@@ -463,6 +465,7 @@ kmlprintgeometry.cc
kmlhellofeatures.cc
kmlprint.cc
siftfast.cpp
ijObjectLabelAttributeValuesTest.cxx
)
IF(OTB_COMPILE_JPEG2000)
......@@ -560,4 +563,7 @@ ENDIF(UNIX)
# TARGET_LINK_LIBRARIES (otb6SMainWithCallFunction m)
# ENDIF(UNIX)
#--- ijObjectLabel --#
ENDIF( NOT OTB_DISABLE_CXX_TESTING AND BUILD_TESTING )
#include "itkImageFileReader.h"
#include "itkShapeLabelObject.h"
#include "itkLabelMap.h"
#include "itkLabelImageToStatisticsLabelMapFilter.h"
#include "itkSimpleFilterWatcher.h"
bool eq( double a, double b, double precision=0.00001 )
{
return std::abs( ( a - b ) / a ) < precision;
}
int ijObjectLabelAttributeValues(int argc, char * argv[])
{
const int dim = 3;
typedef unsigned char PixelType;
typedef itk::Image< PixelType, dim > ImageType;
if( argc != 3)
{
std::cerr << "usage: " << argv[0] << " input1 input2" << std::endl;
// std::cerr << " : " << std::endl;
exit(1);
}
typedef itk::ImageFileReader< ImageType > ReaderType;
ReaderType::Pointer reader1 = ReaderType::New();
reader1->SetFileName( argv[1] );
ReaderType::Pointer reader2 = ReaderType::New();
reader2->SetFileName( argv[2] );
typedef itk::LabelImageToStatisticsLabelMapFilter< ImageType, ImageType > ConverterType;
ConverterType::Pointer converter = ConverterType::New();
converter->SetInput( reader1->GetOutput() );
converter->SetFeatureImage( reader2->GetOutput() );
converter->SetComputeFeretDiameter( true );
converter->SetComputePerimeter( true );
itk::SimpleFilterWatcher watcher(converter, "filter");
converter->Update();
typedef ConverterType::OutputImageType LabelMapType;
LabelMapType::Pointer labelMap = converter->GetOutput();
typedef LabelMapType::LabelObjectType LabelObjectType;
const LabelObjectType * ball = labelMap->GetLabelObject( 1 );
assert( eq(3.0, ball->GetCentroid()[0]) );
assert( eq(3.0, ball->GetCentroid()[1]) );
assert( eq(6.0, ball->GetCentroid()[2]) );
assert( eq(120.95, ball->GetPhysicalSize()) );
assert( 60475 == ball->GetSize() );
assert( eq(1.01639344262, ball->GetRegionElongation()) );
assert( eq(0.52426940382, ball->GetSizeRegionRatio()) );
assert( 141 == ball->GetSizeOnBorder() );
assert( eq(2.82, ball->GetPhysicalSizeOnBorder()) );
assert( eq(116.327, ball->GetPerimeter()) );
assert( eq(6.1903150162168652, ball->GetFeretDiameter()) );
assert( eq(118.274/116.327, ball->GetRoundness()) );
assert( eq(1.85995, ball->GetBinaryPrincipalMoments()[0]) );
assert( eq(1.85995, ball->GetBinaryPrincipalMoments()[1]) );
assert( eq(1.92809, ball->GetBinaryPrincipalMoments()[2]) );
assert( eq(1.01815, ball->GetBinaryElongation()) );
assert( eq(3.06789, ball->GetEquivalentRadius()) );
assert( eq(118.274, ball->GetEquivalentPerimeter()) );
assert( eq(6.09908, ball->GetEquivalentEllipsoidSize()[0]) );
assert( eq(6.09908, ball->GetEquivalentEllipsoidSize()[1]) );
assert( eq(6.20981, ball->GetEquivalentEllipsoidSize()[2]) );
assert( 0 == ball->GetRegion().GetIndex()[0] );
assert( 0 == ball->GetRegion().GetIndex()[1] );
assert( 15 == ball->GetRegion().GetIndex()[2] );
assert( 61 == ball->GetRegion().GetSize()[0] );
assert( 61 == ball->GetRegion().GetSize()[1] );
assert( 31 == ball->GetRegion().GetSize()[2] );
// assert( eq(0.577199, ball->GetBinaryPrincipalAxes()[0][0]) );
// assert( eq(0.816603, ball->GetBinaryPrincipalAxes()[0][1]) );
// assert( eq(3.52768e-12, ball->GetBinaryPrincipalAxes()[0][2]) );
//
// assert( eq(-0.816603, ball->GetBinaryPrincipalAxes()[1][0]) );
// assert( eq(0.577199, ball->GetBinaryPrincipalAxes()[1][1]) );
// assert( eq(6.73715e-14, ball->GetBinaryPrincipalAxes()[1][2]) );
//
// assert( eq(-1.98116e-12, ball->GetBinaryPrincipalAxes()[2][0]) );
// assert( eq(-2.9196e-12, ball->GetBinaryPrincipalAxes()[2][1]) );
// assert( eq(1.0, ball->GetBinaryPrincipalAxes()[2][2]) );
const LabelObjectType * ellipsoid = labelMap->GetLabelObject( 2 );
assert( eq(3.0, ellipsoid->GetCentroid()[0]) );
assert( eq(3.0, ellipsoid->GetCentroid()[1]) );
assert( eq(22.0, ellipsoid->GetCentroid()[2]) );
assert( eq(238.018, ellipsoid->GetPhysicalSize()) );
assert( 119009 == ellipsoid->GetSize() );
assert( eq(2.0, ellipsoid->GetRegionElongation()) );
assert( eq(0.524313, ellipsoid->GetSizeRegionRatio()) );
assert( 388 == ellipsoid->GetSizeOnBorder() );
assert( eq(6.79, ellipsoid->GetPhysicalSizeOnBorder()) );
// assert( eq(, ellipsoid->GetPerimeter()) );
// assert( eq(, ellipsoid->GetFeretDiameter()) );
// assert( eq(, ellipsoid->GetRoundness()) );
assert( eq(1.8622, ellipsoid->GetBinaryPrincipalMoments()[0]) );
assert( eq(1.8622, ellipsoid->GetBinaryPrincipalMoments()[1]) );
assert( eq(7.4488, ellipsoid->GetBinaryPrincipalMoments()[2]) );
assert( eq(2.0, ellipsoid->GetBinaryElongation()) );
assert( eq(3.8445, ellipsoid->GetEquivalentRadius()) );
assert( eq(185.734, ellipsoid->GetEquivalentPerimeter()) );
assert( eq(6.10277, ellipsoid->GetEquivalentEllipsoidSize()[0]) );
assert( eq(6.10277, ellipsoid->GetEquivalentEllipsoidSize()[1]) );
assert( eq(12.2055, ellipsoid->GetEquivalentEllipsoidSize()[2]) );
assert( 0 == ellipsoid->GetRegion().GetIndex()[0] );
assert( 0 == ellipsoid->GetRegion().GetIndex()[1] );
assert( 80 == ellipsoid->GetRegion().GetIndex()[2] );
assert( 61 == ellipsoid->GetRegion().GetSize()[0] );
assert( 61 == ellipsoid->GetRegion().GetSize()[1] );
assert( 61 == ellipsoid->GetRegion().GetSize()[2] );
// assert( eq(0.821007, ellipsoid->GetBinaryPrincipalAxes()[0][0]) );
// assert( eq(-0.570918, ellipsoid->GetBinaryPrincipalAxes()[0][1]) );
// assert( eq(5.49736e-14, ellipsoid->GetBinaryPrincipalAxes()[0][2]) );
//
// assert( eq(-0.570918, ellipsoid->GetBinaryPrincipalAxes()[1][0]) );
// assert( eq(-0.821007, ellipsoid->GetBinaryPrincipalAxes()[1][1]) );
// assert( eq(-2.5511e-13, ellipsoid->GetBinaryPrincipalAxes()[1][2]) );
//
// assert( eq(1.9078e-13, ellipsoid->GetBinaryPrincipalAxes()[2][0]) );
// assert( eq(1.78062e-13, ellipsoid->GetBinaryPrincipalAxes()[2][1]) );
// assert( eq(-1.0, ellipsoid->GetBinaryPrincipalAxes()[2][2]) );
const LabelObjectType * disk = labelMap->GetLabelObject( 3 );
assert( eq(3.0, disk->GetCentroid()[0]) );
assert( eq(11.0, disk->GetCentroid()[1]) );
assert( eq(22.0, disk->GetCentroid()[2]) );
assert( eq(5.866, disk->GetPhysicalSize()) );
assert( 2933 == disk->GetSize() );
assert( eq(122.0, disk->GetRegionElongation()) );
assert( eq(0.788229, disk->GetSizeRegionRatio()) );
assert( 22 == disk->GetSizeOnBorder() );
assert( eq(0.33, disk->GetPhysicalSizeOnBorder()) );
// assert( eq(, disk->GetPerimeter()) );
// assert( eq(, disk->GetFeretDiameter()) );
// assert( eq(, disk->GetRoundness()) );
assert( eq(-7.78731e-28, disk->GetBinaryPrincipalMoments()[0]) );
assert( eq(2.33397, disk->GetBinaryPrincipalMoments()[1]) );
assert( eq(9.33589, disk->GetBinaryPrincipalMoments()[2]) );
// assert( NaN == disk->GetBinaryElongation() );
assert( eq(1.1188, disk->GetEquivalentRadius()) );
assert( eq(15.7294, disk->GetEquivalentPerimeter()) );
// assert( eq(1.5874, disk->GetEquivalentEllipsoidSize()[0]) );
// assert( eq(1.5874, disk->GetEquivalentEllipsoidSize()[1]) );
// assert( eq(3.1748, disk->GetEquivalentEllipsoidSize()[2]) );
assert( 30 == disk->GetRegion().GetIndex()[0] );
assert( 80 == disk->GetRegion().GetIndex()[1] );
assert( 80 == disk->GetRegion().GetIndex()[2] );
assert( 1 == disk->GetRegion().GetSize()[0] );
assert( 61 == disk->GetRegion().GetSize()[1] );
assert( 61 == disk->GetRegion().GetSize()[2] );
assert( eq(1.0, disk->GetBinaryPrincipalAxes()[0][0]) );
assert( eq(-2.01391e-17, disk->GetBinaryPrincipalAxes()[0][1]) );
assert( eq(-9.13305e-15, disk->GetBinaryPrincipalAxes()[0][2]) );
assert( eq(-2.01391e-17, disk->GetBinaryPrincipalAxes()[1][0]) );
assert( eq(-1.0, disk->GetBinaryPrincipalAxes()[1][1]) );
assert( eq(4.05913e-14, disk->GetBinaryPrincipalAxes()[1][2]) );
assert( eq(-9.13305e-15, disk->GetBinaryPrincipalAxes()[2][0]) );
assert( eq(-4.05913e-14, disk->GetBinaryPrincipalAxes()[2][1]) );
assert( eq(-1.0, disk->GetBinaryPrincipalAxes()[2][2]) );
// assert( eq(, ball->Get()) );
//
// assert( eq(, ball->Get()[0]) );
// assert( eq(, ball->Get()[1]) );
// assert( eq(, ball->Get()[2]) );
// std::cout << ball->GetBinaryPrincipalAxes() << std::endl;
return 0;
}
......@@ -67,5 +67,6 @@ REGISTER_TEST(kmlhellokmz);
REGISTER_TEST(kmlhelloregion);
REGISTER_TEST(kmlprettykml);
REGISTER_TEST(SiftFast);
REGISTER_TEST(ijObjectLabelAttributeValues);
}
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile: itkAttributeKeepNObjectsLabelMapFilter.h,v $
Language: C++
Date: $Date: 2006/03/28 19:59:05 $
Version: $Revision: 1.6 $
Copyright (c) Insight Software Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm 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 __itkAttributeKeepNObjectsLabelMapFilter_h
#define __itkAttributeKeepNObjectsLabelMapFilter_h
#include "itkInPlaceLabelMapFilter.h"
#include "itkAttributeLabelObject.h"
namespace itk {
/** \class AttributeKeepNObjectsLabelMapFilter
* \brief keep N objects according to their attribute
*
* AttributeKeepNObjectsLabelMapFilter keep the N objects in a label collection image
* with the highest (or lowest) attribute value. The attribute is provide by an
* attribute accessor given in template parameter.
*
* \author Gatan Lehmann. Biologie du Dveloppement et de la Reproduction, INRA de Jouy-en-Josas, France.
*
* \ingroup ImageEnhancement MathematicalMorphologyImageFilters
*/
template<class TImage, class TAttributeAccessor=
typename Functor::AttributeLabelObjectAccessor< typename TImage::LabelObjectType > >
class ITK_EXPORT AttributeKeepNObjectsLabelMapFilter :
public InPlaceLabelMapFilter<TImage>
{
public:
/** Standard class typedefs. */
typedef AttributeKeepNObjectsLabelMapFilter Self;
typedef InPlaceLabelMapFilter<TImage>
Superclass;
typedef SmartPointer<Self> Pointer;
typedef SmartPointer<const Self> ConstPointer;
/** Some convenient typedefs. */
typedef TImage ImageType;
typedef typename ImageType::Pointer ImagePointer;
typedef typename ImageType::ConstPointer ImageConstPointer;
typedef typename ImageType::PixelType PixelType;
typedef typename ImageType::IndexType IndexType;
typedef typename ImageType::LabelObjectType LabelObjectType;
typedef TAttributeAccessor AttributeAccessorType;
typedef typename AttributeAccessorType::AttributeValueType AttributeValueType;
/** ImageDimension constants */
itkStaticConstMacro(ImageDimension, unsigned int,
TImage::ImageDimension);
/** Standard New method. */
itkNewMacro(Self);
/** Runtime information support. */
itkTypeMacro(AttributeKeepNObjectsLabelMapFilter,
InPlaceLabelMapFilter);
#ifdef ITK_USE_CONCEPT_CHECKING
/** Begin concept checking */
/* itkConceptMacro(InputEqualityComparableCheck,
(Concept::EqualityComparable<InputImagePixelType>));
itkConceptMacro(IntConvertibleToInputCheck,
(Concept::Convertible<int, InputImagePixelType>));
itkConceptMacro(InputOStreamWritableCheck,
(Concept::OStreamWritable<InputImagePixelType>));*/
/** End concept checking */
#endif
/**
* Set/Get the ordering of the objects. By default, the ones with the
* highest value are kept. Turming ReverseOrdering to true make this filter
* keep the objects with the smallest values
*/
itkSetMacro( ReverseOrdering, bool );
itkGetConstReferenceMacro( ReverseOrdering, bool );
itkBooleanMacro( ReverseOrdering );
/**
* Set/Get the number of objects to keep
*/
itkSetMacro( NumberOfObjects, unsigned long );
itkGetConstReferenceMacro( NumberOfObjects, unsigned long );
protected:
AttributeKeepNObjectsLabelMapFilter();
~AttributeKeepNObjectsLabelMapFilter() {};
void GenerateData();
void PrintSelf(std::ostream& os, Indent indent) const;
class ReverseComparator
{
public:
bool operator()( const typename LabelObjectType::Pointer & a, const typename LabelObjectType::Pointer & b )
{
return accessor( a ) < accessor( b );
}
AttributeAccessorType accessor;
};
class Comparator
{
public:
bool operator()( const typename LabelObjectType::Pointer & a, const typename LabelObjectType::Pointer & b )
{
return accessor( a ) > accessor( b );
}
AttributeAccessorType accessor;
};
private:
AttributeKeepNObjectsLabelMapFilter(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
bool m_ReverseOrdering;
unsigned long m_NumberOfObjects;
} ; // end of class
} // end namespace itk
#ifndef ITK_MANUAL_INSTANTIATION
#include "itkAttributeKeepNObjectsLabelMapFilter.txx"
#endif
#endif
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile: itkAttributeKeepNObjectsLabelMapFilter.txx,v $
Language: C++
Date: $Date: 2005/08/23 15:09:03 $
Version: $Revision: 1.6 $
Copyright (c) Insight Software Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm 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 __itkAttributeKeepNObjectsLabelMapFilter_txx
#define __itkAttributeKeepNObjectsLabelMapFilter_txx
#include "itkAttributeKeepNObjectsLabelMapFilter.h"
#include "itkProgressReporter.h"
namespace itk {
template <class TImage, class TAttributeAccessor>
AttributeKeepNObjectsLabelMapFilter<TImage, TAttributeAccessor>
::AttributeKeepNObjectsLabelMapFilter()
{
m_ReverseOrdering = false;
m_NumberOfObjects = 1;
}
template <class TImage, class TAttributeAccessor>
void
AttributeKeepNObjectsLabelMapFilter<TImage, TAttributeAccessor>
::GenerateData()
{
// Allocate the output
this->AllocateOutputs();
ImageType * output = this->GetOutput();
typedef typename ImageType::LabelObjectContainerType LabelObjectContainerType;
const LabelObjectContainerType & labelObjectContainer = output->GetLabelObjectContainer();
typedef typename std::vector< typename LabelObjectType::Pointer > VectorType;
ProgressReporter progress( this, 0, 2 * labelObjectContainer.size() );
// get the label objects in a vector, so they can be sorted
VectorType labelObjects;
labelObjects.reserve( labelObjectContainer.size() );
for( typename LabelObjectContainerType::const_iterator it = labelObjectContainer.begin();
it != labelObjectContainer.end();
it++ )
{
labelObjects.push_back( it->second );
progress.CompletedPixel();
}
// instantiate the comparator and sort the vector
if( m_NumberOfObjects < labelObjectContainer.size() )
{
typename VectorType::iterator end = labelObjects.begin() + m_NumberOfObjects;
if( m_ReverseOrdering )
{
ReverseComparator comparator;
std::nth_element( labelObjects.begin(), end, labelObjects.end(), comparator );
}
else
{
Comparator comparator;
std::nth_element( labelObjects.begin(), end, labelObjects.end(), comparator );
}
// progress.CompletedPixel();
// and remove the last objects of the map
for( typename VectorType::const_iterator it = end;
it != labelObjects.end();
it++ )
{
output->RemoveLabelObject( *it );
progress.CompletedPixel();
}
}
}
template <class TImage, class TAttributeAccessor>
void
AttributeKeepNObjectsLabelMapFilter<TImage, TAttributeAccessor>
::PrintSelf(std::ostream& os, Indent indent) const
{
Superclass::PrintSelf(os,indent);
os << indent << "ReverseOrdering: " << m_ReverseOrdering << std::endl;
os << indent << "NumberOfObjects: " << m_NumberOfObjects << std::endl;
}
}// end namespace itk
#endif
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile: itkLabelObject.h,v $
Language: C++
Date: $Date: 2005/01/21 20:13:31 $
Version: $Revision: 1.6 $
Copyright (c) Insight Software Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm 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 __itkAttributeLabelObject_h
#define __itkAttributeLabelObject_h
#include "itkLabelObject.h"
namespace itk
{
namespace Functor {
template< class TLabelObject >
class ITK_EXPORT AttributeLabelObjectAccessor
{
public:
typedef TLabelObject LabelObjectType;
typedef typename LabelObjectType::AttributeValueType AttributeValueType;
inline const AttributeValueType operator()( const LabelObjectType * labelObject )
{
return labelObject->GetAttribute();
}
inline void operator()( LabelObjectType * labelObject, AttributeValueType value )
{
labelObject->SetAttribute( value );
}
};
}
/** \class AttributeLabelObject
* \brief A LabelObject with a generic attribute
*
* \author Gatan Lehmann. Biologie du Dveloppement et de la Reproduction, INRA de Jouy-en-Josas, France.
*
*\sa LabelObject, ShapeLabelObject, StatisticsLabelObject
*
* \ingroup DataRepresentation
*/
template < class TLabel, unsigned int VImageDimension, class TAttributeValue >
class ITK_EXPORT AttributeLabelObject : public LabelObject< TLabel, VImageDimension >
{
public:
/** Standard class typedefs */
typedef AttributeLabelObject Self;
typedef LabelObject< TLabel, VImageDimension > Superclass;
typedef SmartPointer<Self> Pointer;
typedef SmartPointer<const Self> ConstPointer;
typedef WeakPointer<const Self> ConstWeakPointer;
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** Run-time type information (and related methods). */
itkTypeMacro(AttributeLabelObject, LabelObject);
typedef LabelMap< Self > LabelMapType;
itkStaticConstMacro(ImageDimension, unsigned int, VImageDimension);
typedef typename Superclass::IndexType IndexType;
typedef TLabel LabelType;
typedef typename Superclass::LineType LineType;
typedef typename Superclass::LengthType LengthType;
typedef typename Superclass::LineContainerType LineContainerType;
typedef TAttributeValue AttributeValueType;
void SetAttribute( const AttributeValueType & v )
{
m_Attribute = v;
}
const AttributeValueType & GetAttribute() const
{
return m_Attribute;
}
AttributeValueType GetAttribute()
{
return m_Attribute;
}
virtual void CopyDataFrom( const Self * src )
{
Superclass::CopyDataFrom( src );
m_Attribute = src->m_Attribute;