From aa6a578004bddb5b0bb07b780483fda0ecc6cb5e Mon Sep 17 00:00:00 2001 From: Leonardo Florez-Valencia Date: Mon, 20 Apr 2015 16:26:51 -0500 Subject: [PATCH] Light compensation algorithm added --- appli/examples/CMakeLists.txt | 2 + appli/examples/example_LightCompensation.cxx | 57 ++++++++++++ appli/examples/example_ParallelImageMean.cxx | 52 +++++++++++ .../Algorithms/LightCompensationFilter.h | 67 ++++++++++++++ .../Algorithms/LightCompensationFilter.hxx | 88 +++++++++++++++++++ .../Extensions/Algorithms/ParallelImageMean.h | 72 +++++++++++++++ .../Algorithms/ParallelImageMean.hxx | 65 ++++++++++++++ 7 files changed, 403 insertions(+) create mode 100644 appli/examples/example_LightCompensation.cxx create mode 100644 appli/examples/example_ParallelImageMean.cxx create mode 100644 lib/cpPlugins/Extensions/Algorithms/LightCompensationFilter.h create mode 100644 lib/cpPlugins/Extensions/Algorithms/LightCompensationFilter.hxx create mode 100644 lib/cpPlugins/Extensions/Algorithms/ParallelImageMean.h create mode 100644 lib/cpPlugins/Extensions/Algorithms/ParallelImageMean.hxx diff --git a/appli/examples/CMakeLists.txt b/appli/examples/CMakeLists.txt index c986abe..93bc0d8 100644 --- a/appli/examples/CMakeLists.txt +++ b/appli/examples/CMakeLists.txt @@ -32,6 +32,8 @@ SET( example_ImageGaussianModelEstimator example_ReadQuadEdgeMeshWithoutPlugins example_RenderQuadEdgeMeshWithoutPlugins + example_ParallelImageMean + example_LightCompensation ) FOREACH(prog ${NOPLUGINS_EXAMPLES_PROGRAMS}) ADD_EXECUTABLE( diff --git a/appli/examples/example_LightCompensation.cxx b/appli/examples/example_LightCompensation.cxx new file mode 100644 index 0000000..44062ed --- /dev/null +++ b/appli/examples/example_LightCompensation.cxx @@ -0,0 +1,57 @@ +#include +#include +#include + +#include +#include +#include + +#include + +// ------------------------------------------------------------------------- +const unsigned int Dim = 2; +typedef itk::RGBPixel< unsigned char > TPixel; +typedef itk::Image< TPixel, Dim > TImage; + +// ------------------------------------------------------------------------- +int main( int argc, char* argv[] ) +{ + if( argc < 3 ) + { + std::cerr + << "Usage: " << argv[ 0 ] + << " input_image output_image" + << std::endl; + return( 1 ); + + } // fi + std::string input_image_fn = argv[ 1 ]; + std::string output_image_fn = argv[ 2 ]; + + // Read image + itk::ImageFileReader< TImage >::Pointer input_image_reader = + itk::ImageFileReader< TImage >::New( ); + input_image_reader->SetFileName( input_image_fn ); + try + { + input_image_reader->Update( ); + } + catch( itk::ExceptionObject& err ) + { + std::cerr << "Error caught: " << err << std::endl; + return( 1 ); + + } // yrt + TImage::Pointer input_image = input_image_reader->GetOutput( ); + + cpPlugins::Extensions::Algorithms:: + LightCompensationFilter< TImage >::Pointer filter = + cpPlugins::Extensions::Algorithms:: + LightCompensationFilter< TImage >::New( ); + filter->SetInput( input_image ); + filter->Update( ); + + return( 0 ); +} + +// eof - $RCSfile$ diff --git a/appli/examples/example_ParallelImageMean.cxx b/appli/examples/example_ParallelImageMean.cxx new file mode 100644 index 0000000..a01c163 --- /dev/null +++ b/appli/examples/example_ParallelImageMean.cxx @@ -0,0 +1,52 @@ +#include +#include +#include + +#include +#include +#include + +#include + +// ------------------------------------------------------------------------- +const unsigned int Dim = 2; +typedef itk::RGBPixel< unsigned char > TPixel; +typedef itk::Image< TPixel, Dim > TImage; + +// ------------------------------------------------------------------------- +int main( int argc, char* argv[] ) +{ + if( argc < 2 ) + { + std::cerr << "Usage: " << argv[ 0 ] << " image" << std::endl; + return( 1 ); + + } // fi + std::string image_fn = argv[ 1 ]; + + // Read image + itk::ImageFileReader< TImage >::Pointer image_reader = + itk::ImageFileReader< TImage >::New( ); + image_reader->SetFileName( image_fn ); + try + { + image_reader->Update( ); + } + catch( itk::ExceptionObject& err ) + { + std::cerr << "Error caught: " << err << std::endl; + return( 1 ); + + } // yrt + TImage::Pointer image = image_reader->GetOutput( ); + + // Compute mean + cpPlugins::Extensions::Algorithms::ParallelImageMean< TImage >::Pointer mean = + cpPlugins::Extensions::Algorithms::ParallelImageMean< TImage >::New( ); + mean->Execute( image, image->GetRequestedRegion( ) ); + std::cout << "Mean: " << mean->GetMean( ) << std::endl; + + return( 0 ); +} + +// eof - $RCSfile$ diff --git a/lib/cpPlugins/Extensions/Algorithms/LightCompensationFilter.h b/lib/cpPlugins/Extensions/Algorithms/LightCompensationFilter.h new file mode 100644 index 0000000..596b5fa --- /dev/null +++ b/lib/cpPlugins/Extensions/Algorithms/LightCompensationFilter.h @@ -0,0 +1,67 @@ +// ------------------------------------------------------------------------- +// @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co) +// ------------------------------------------------------------------------- + +#ifndef __CPPLUGINS__EXTENSIONS__ALGORITHMS__LIGHTCOMPENSATIONFILTER__H__ +#define __CPPLUGINS__EXTENSIONS__ALGORITHMS__LIGHTCOMPENSATIONFILTER__H__ + +#include +#include + +namespace cpPlugins +{ + namespace Extensions + { + namespace Algorithms + { + /** + */ + template< class I > + class LightCompensationFilter + : public itk::InPlaceImageFilter< I, I > + { + public: + typedef LightCompensationFilter Self; + typedef itk::InPlaceImageFilter< I, I > Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + typedef I TImage; + typedef typename I::RegionType TRegion; + + typedef cpPlugins::Extensions::Algorithms::ParallelImageMean< I > TMeanCalculator; + typedef typename TMeanCalculator::TMean TMean; + + public: + itkNewMacro( Self ); + itkTypeMacro( LightCompensationFilter, itkInPlaceImageFilter ); + + itkGetConstMacro( Mean, TMean ); + + protected: + LightCompensationFilter( ); + virtual ~LightCompensationFilter( ); + + private: + virtual void BeforeThreadedGenerateData( ); + virtual void ThreadedGenerateData( + const TRegion& region, itk::ThreadIdType id + ); + virtual void AfterThreadedGenerateData( ); + + protected: + TMean m_Mean; + TMean m_Coefficient; + }; + + } // ecapseman + + } // ecapseman + +} // ecapseman + +#include + +#endif // __CPPLUGINS__EXTENSIONS__ALGORITHMS__LIGHTCOMPENSATIONFILTER__H__ + +// eof - $RCSfile$ diff --git a/lib/cpPlugins/Extensions/Algorithms/LightCompensationFilter.hxx b/lib/cpPlugins/Extensions/Algorithms/LightCompensationFilter.hxx new file mode 100644 index 0000000..71dc0f6 --- /dev/null +++ b/lib/cpPlugins/Extensions/Algorithms/LightCompensationFilter.hxx @@ -0,0 +1,88 @@ +// ------------------------------------------------------------------------- +// @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co) +// ------------------------------------------------------------------------- + +#ifndef __CPPLUGINS__EXTENSIONS__ALGORITHMS__LIGHTCOMPENSATIONFILTER__HXX__ +#define __CPPLUGINS__EXTENSIONS__ALGORITHMS__LIGHTCOMPENSATIONFILTER__HXX__ + +#include +#include +#include + +// ------------------------------------------------------------------------- +template< class I > +cpPlugins::Extensions::Algorithms::LightCompensationFilter< I >:: +LightCompensationFilter( ) + : Superclass( ) +{ + this->SetNumberOfRequiredInputs( 1 ); + this->InPlaceOff( ); +} + +// ------------------------------------------------------------------------- +template< class I > +cpPlugins::Extensions::Algorithms::LightCompensationFilter< I >:: +~LightCompensationFilter( ) +{ +} + +// ------------------------------------------------------------------------- +template< class I > +void cpPlugins::Extensions::Algorithms::LightCompensationFilter< I >:: +BeforeThreadedGenerateData( ) +{ + I* input = const_cast< I* >( this->GetInput( ) ); + + typename TMeanCalculator::Pointer mc = TMeanCalculator::New( ); + mc->Execute( input, input->GetRequestedRegion( ) ); + this->m_Mean = mc->GetMean( ); + + double gm = this->m_Mean[ 0 ] + this->m_Mean[ 1 ] + this->m_Mean[ 2 ]; + gm /= double( 3 ); + this->m_Coefficient = this->m_Mean; + this->m_Coefficient.Fill( gm ); + this->m_Coefficient[ 0 ] /= this->m_Mean[ 0 ]; + this->m_Coefficient[ 1 ] /= this->m_Mean[ 1 ]; + this->m_Coefficient[ 2 ] /= this->m_Mean[ 2 ]; +} + +// ------------------------------------------------------------------------- +template< class I > +void cpPlugins::Extensions::Algorithms::LightCompensationFilter< I >:: +ThreadedGenerateData( const TRegion& region, itk::ThreadIdType id ) +{ + typedef itk::NumericTraits< typename I::PixelType > _TPixelTraits; + typedef typename _TPixelTraits::ValueType _TPixelChannel; + typedef itk::NumericTraits< _TPixelChannel > _TChannelTraits; + static const double max_value = double( _TChannelTraits::max( ) ); + + itk::ImageRegionConstIterator< I > iIt( this->GetInput( ), region ); + itk::ImageRegionIterator< I > oIt( this->GetOutput( ), region ); + + iIt.GoToBegin( ); + oIt.GoToBegin( ); + for( ; !iIt.IsAtEnd( ); ++iIt, ++oIt ) + { + double r = double( iIt.Get( )[ 0 ] ) * this->m_Coefficient[ 0 ]; + double g = double( iIt.Get( )[ 1 ] ) * this->m_Coefficient[ 1 ]; + double b = double( iIt.Get( )[ 2 ] ) * this->m_Coefficient[ 2 ]; + if( r > max_value ) r = max_value; + if( g > max_value ) g = max_value; + if( b > max_value ) b = max_value; + oIt.Get( ).Set( + _TPixelChannel( r ), _TPixelChannel( g ), _TPixelChannel( b ) + ); + + } // rof +} + +// ------------------------------------------------------------------------- +template< class I > +void cpPlugins::Extensions::Algorithms::LightCompensationFilter< I >:: +AfterThreadedGenerateData( ) +{ +} + +#endif // __CPPLUGINS__EXTENSIONS__ALGORITHMS__LIGHTCOMPENSATIONFILTER__HXX__ + +// eof - $RCSfile$ diff --git a/lib/cpPlugins/Extensions/Algorithms/ParallelImageMean.h b/lib/cpPlugins/Extensions/Algorithms/ParallelImageMean.h new file mode 100644 index 0000000..c171d1a --- /dev/null +++ b/lib/cpPlugins/Extensions/Algorithms/ParallelImageMean.h @@ -0,0 +1,72 @@ +// ------------------------------------------------------------------------- +// @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co) +// ------------------------------------------------------------------------- + +#ifndef __CPPLUGINS__EXTENSIONS__ALGORITHMS__PARALLELIMAGEMEAN__H__ +#define __CPPLUGINS__EXTENSIONS__ALGORITHMS__PARALLELIMAGEMEAN__H__ + +#include +#include +#include +#include + +namespace cpPlugins +{ + namespace Extensions + { + namespace Algorithms + { + /** + */ + template< class I > + class ParallelImageMean + : public itk::DomainThreader< itk::ThreadedImageRegionPartitioner< I::ImageDimension >, I > + { + public: + // Standard ITK typedefs. + typedef itk::DomainThreader< itk::ThreadedImageRegionPartitioner< I::ImageDimension >, I > Superclass; + typedef ParallelImageMean Self; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + typedef typename Superclass::DomainType DomainType; + + typedef itk::Array< double > TMean; + + protected: + typedef itk::NumericTraits< typename I::PixelType > _TPixelTraits; + + + public: + itkNewMacro( Self ); + itkTypeMacro( ParallelImageMean, itkDomainThreader ); + + itkGetConstMacro( Mean, TMean ); + + protected: + ParallelImageMean( ); + virtual ~ParallelImageMean( ); + + private: + virtual void BeforeThreadedExecution( ); + virtual void ThreadedExecution( + const DomainType& region, const itk::ThreadIdType id + ); + virtual void AfterThreadedExecution( ); + + protected: + itk::Array< double > m_Mean; + unsigned long m_N; + }; + + } // ecapseman + + } // ecapseman + +} // ecapseman + +#include + +#endif // __CPPLUGINS__EXTENSIONS__ALGORITHMS__PARALLELIMAGEMEAN__H__ + +// eof - $RCSfile$ diff --git a/lib/cpPlugins/Extensions/Algorithms/ParallelImageMean.hxx b/lib/cpPlugins/Extensions/Algorithms/ParallelImageMean.hxx new file mode 100644 index 0000000..bb066e1 --- /dev/null +++ b/lib/cpPlugins/Extensions/Algorithms/ParallelImageMean.hxx @@ -0,0 +1,65 @@ +// ------------------------------------------------------------------------- +// @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co) +// ------------------------------------------------------------------------- + +#ifndef __CPPLUGINS__EXTENSIONS__ALGORITHMS__PARALLELIMAGEMEAN__HXX__ +#define __CPPLUGINS__EXTENSIONS__ALGORITHMS__PARALLELIMAGEMEAN__HXX__ + +#include + +// ------------------------------------------------------------------------- +template< class I > +cpPlugins::Extensions::Algorithms::ParallelImageMean< I >:: +ParallelImageMean( ) + : Superclass( ) +{ +} + +// ------------------------------------------------------------------------- +template< class I > +cpPlugins::Extensions::Algorithms::ParallelImageMean< I >:: +~ParallelImageMean( ) +{ +} + +// ------------------------------------------------------------------------- +template< class I > +void cpPlugins::Extensions::Algorithms::ParallelImageMean< I >:: +BeforeThreadedExecution( ) +{ + this->m_Mean.SetSize( _TPixelTraits::GetLength( ) ); + this->m_Mean.Fill( double( 0 ) ); + this->m_N = 0; +} + +// ------------------------------------------------------------------------- +template< class I > +void cpPlugins::Extensions::Algorithms::ParallelImageMean< I >:: +ThreadedExecution( const DomainType& region, const itk::ThreadIdType id ) +{ + itk::ImageRegionConstIterator< I > i( this->m_Associate, region ); + for( i.GoToBegin( ); !i.IsAtEnd( ); ++i ) + { + for( unsigned int d = 0; d < _TPixelTraits::GetLength( ); ++d ) + { + this->m_Mean.SetElement( + d, this->m_Mean.GetElement( d ) + double( i.Get( )[ d ] ) + ); + this->m_N++; + + } // rof + + } // rof +} + +// ------------------------------------------------------------------------- +template< class I > +void cpPlugins::Extensions::Algorithms::ParallelImageMean< I >:: +AfterThreadedExecution( ) +{ + this->m_Mean /= double( this->m_N ); +} + +#endif // __CPPLUGINS__EXTENSIONS__ALGORITHMS__PARALLELIMAGEMEAN__HXX__ + +// eof - $RCSfile$ -- 2.47.1