diff --git a/Code/FeatureExtraction/otbImageFittingPolygonListFilter.h b/Code/FeatureExtraction/otbImageFittingPolygonListFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..bff0584dbd3499ea6d736048281c86ae8e12b1cf --- /dev/null +++ b/Code/FeatureExtraction/otbImageFittingPolygonListFilter.h @@ -0,0 +1,114 @@ +/*========================================================================= + +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 __otbImageFittingPolygonListFilter_h +#define __otbImageFittingPolygonListFilter_h + +#include "otbPathListToPathListFilter.h" +#include "otbMacro.h" +#include "itkLineConstIterator.h" + +namespace otb +{ +/** \class ImageFittingPolygonListFilter + * \brief Slightly deform polygon to reach higher enery from the image + * + * <br>Limitations:</br> This filter is currently working with integer position + * for the polygon vertices. It should be optimized for continuous positions. + * + */ +template <class TPath, class TImage> +class ITK_EXPORT ImageFittingPolygonListFilter + : public PathListToPathListFilter<TPath> +{ + public: + /** Standard typedefs */ + typedef ImageFittingPolygonListFilter Self; + typedef PathListToPathListFilter<TPath> Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Type macro */ + itkNewMacro(Self); + + /** Creation through object factory macro */ + itkTypeMacro(ImageFittingPolygonListFilter, PathListToPathListFilter); + + /** Template parameters typedefs */ + typedef typename Superclass::PathType PathType; + typedef typename Superclass::PathListType PathListType; + typedef typename Superclass::PathPointerType PathPointerType; + typedef typename PathListType::Pointer PathListPointerType; + typedef typename PathListType::ConstIterator IteratorType; + typedef typename PathType::VertexType VertexType; + typedef typename PathType::VertexListType VertexListType; + typedef typename VertexListType::ConstIterator VertexListConstIteratorType; + typedef double RealType; + + typedef TImage ImageType; + typedef typename ImageType::Pointer ImagePointerType; + typedef typename ImageType::ConstPointer ImageConstPointerType; + + typedef itk::LineConstIterator<ImageType> LineConstIteratorType; + + /** + * Set the input Likelihood image. + * \param image The Likelihood image. + */ + void SetInputImage(const ImageType * image); + + /** + * Get the input Likelihood image. + * \return The input Likelihood image. + */ + const ImageType * GetInputImage(void); + + /** Set/Get the search radius. */ + itkSetMacro(Radius,unsigned int); + itkGetMacro(Radius,unsigned int); + + /** Set/Get the number of iteration. */ + itkSetMacro(NumberOfIterations,unsigned int); + itkGetMacro(NumberOfIterations,unsigned int); + +protected: + /** Constructor */ + ImageFittingPolygonListFilter(); + /** Destructor */ + virtual ~ImageFittingPolygonListFilter() {}; + /** GenerateData method */ + virtual void GenerateData(); + /** PrintSelf method */ + virtual void PrintSelf(std::ostream& os, itk::Indent indent) const; + + virtual double computeValue(ImageConstPointerType image, VertexType middlePoint, VertexType previousPoint, VertexType nextPoint) const; + + unsigned int m_Radius; + unsigned int m_NumberOfIterations; + +private: + ImageFittingPolygonListFilter(const Self&); //purposely not implemented + void operator=(const Self&); //purposely not implemented + + +}; +}// End namespace otb +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbImageFittingPolygonListFilter.txx" +#endif + +#endif diff --git a/Code/FeatureExtraction/otbImageFittingPolygonListFilter.txx b/Code/FeatureExtraction/otbImageFittingPolygonListFilter.txx new file mode 100644 index 0000000000000000000000000000000000000000..5b0e5d0e41b3035a44d2fb98d0dc1a612e509278 --- /dev/null +++ b/Code/FeatureExtraction/otbImageFittingPolygonListFilter.txx @@ -0,0 +1,273 @@ +/*========================================================================= + +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 __otbImageFittingPolygonListFilter_txx +#define __otbImageFittingPolygonListFilter_txx + +#include "otbImageFittingPolygonListFilter.h" +#include "otbPolyLineImageConstIterator.h" +#include "otbMacro.h" +#include "itkImageRegionConstIteratorWithIndex.h" + +namespace otb +{ +/** + * Constructor + */ +template <class TPath, class TImage> +ImageFittingPolygonListFilter<TPath, TImage> +::ImageFittingPolygonListFilter() +{ + this->SetNumberOfRequiredInputs(2); + this->SetNumberOfInputs(2); + m_Radius=1; + m_NumberOfIterations=1; +} + +template <class TPath, class TImage> +void +ImageFittingPolygonListFilter<TPath, TImage> +::SetInputImage(const ImageType * image) +{ + this->itk::ProcessObject::SetNthInput(1,const_cast<ImageType *>(image)); +} + +template <class TPath, class TImage> +const typename ImageFittingPolygonListFilter<TPath, TImage> +::ImageType * +ImageFittingPolygonListFilter<TPath, TImage> +::GetInputImage(void) +{ + if(this->GetNumberOfInputs()<1) + { + return 0; + } + return static_cast<const ImageType *>(this->itk::ProcessObject::GetInput(1)); +} + + +//FIXME +//There is an issue here with integer and continous indexes +//maybe we should use the itk::LineConstIterator +template <class TPath, class TImage> +void +ImageFittingPolygonListFilter<TPath, TImage> +::GenerateData() +{ + // I/O wiring + ImageConstPointerType inputImagePtr = this->GetInputImage(); + const PathListType * inputPtr = this->GetInput(); + PathListType * outputPtr = this->GetOutput(); + + + typename ImageType::RegionType regionLargest=inputImagePtr->GetLargestPossibleRegion(); + + typedef itk::ImageRegionConstIteratorWithIndex<ImageType> NeighborhoodIteratorType; + + typename ImageType::SizeType size; + size[0]= 2*m_Radius+1; + size[1]= 2*m_Radius+1; + typename ImageType::RegionType region; + region.SetSize(size); + typename ImageType::IndexType start; + + //go through all the polygons in the list + for(IteratorType it = inputPtr->Begin(); it != inputPtr->End(); ++it) + { + PathPointerType polygon = it.Get(); + + if(polygon->GetVertexList()->Size()>2) + { + for (int iteration=0;iteration < m_NumberOfIterations;++iteration) + { + PathPointerType newPolygon = PathType::New(); + VertexListConstIteratorType vertexIt = polygon->GetVertexList()->Begin(); + //We are now going to go through all the vertex, we won't start to process + // first as we need to know the last one for that. + VertexType firstPoint = vertexIt.Value(); + VertexType previousPoint = vertexIt.Value(); + ++vertexIt; + VertexType currentPoint = vertexIt.Value(); + ++vertexIt; + while (vertexIt != polygon->GetVertexList()->End()) + { + VertexType nextPoint=vertexIt.Value(); + + /** try all the possible neighbor for the current point + * to factorize + * */ + { + + start[0] = static_cast<long int>(currentPoint[0]-m_Radius); + start[1] = static_cast<long int>(currentPoint[1]-m_Radius); + region.SetIndex(start); + + NeighborhoodIteratorType nIt(inputImagePtr, region); + double maxValue=0.0; + VertexType maxPoint = currentPoint; + for (nIt.GoToBegin();!nIt.IsAtEnd();++nIt) + { + if(regionLargest.IsInside(nIt.GetIndex())) + { + VertexType middlePoint=static_cast<VertexType>(nIt.GetIndex()); + double currentValue = computeValue(inputImagePtr, middlePoint, previousPoint, nextPoint); + if (currentValue > maxValue) + { + maxValue=currentValue; + maxPoint=middlePoint; + } + } + } + currentPoint=maxPoint; + newPolygon->AddVertex(maxPoint); + } + /** End 'to factorize' */ + + ++vertexIt; + previousPoint=currentPoint; + currentPoint=nextPoint; + + } + //We now need to process the last and the first point + + VertexType nextPoint = firstPoint; + /** try all the possible neighbor for the current point + * to factorize + * */ + { + start[0] = static_cast<long int>(currentPoint[0]-m_Radius); + start[1] = static_cast<long int>(currentPoint[1]-m_Radius); + region.SetIndex(start); + + NeighborhoodIteratorType nIt(inputImagePtr, region); + double maxValue=0.0; + VertexType maxPoint = currentPoint; + for (nIt.GoToBegin();!nIt.IsAtEnd();++nIt) + { + if(regionLargest.IsInside(nIt.GetIndex())) + { + VertexType middlePoint=static_cast<VertexType>(nIt.GetIndex()); + double currentValue = computeValue(inputImagePtr, middlePoint, previousPoint, nextPoint); + if (currentValue > maxValue) + { + maxValue=currentValue; + maxPoint=middlePoint; + } + } + } + currentPoint=maxPoint; + newPolygon->AddVertex(maxPoint); + } + /** End 'to factorize' */ + + previousPoint = currentPoint; + currentPoint= firstPoint; + vertexIt = newPolygon->GetVertexList()->Begin(); + nextPoint=vertexIt.Value(); + + /** try all the possible neighbor for the current point + * to factorize + * */ + { + + start[0] = static_cast<long int>(currentPoint[0]-m_Radius); + start[1] = static_cast<long int>(currentPoint[1]-m_Radius); + region.SetIndex(start); + + NeighborhoodIteratorType nIt(inputImagePtr, region); + double maxValue=0.0; + VertexType maxPoint = currentPoint; + for (nIt.GoToBegin();!nIt.IsAtEnd();++nIt) + { + if(regionLargest.IsInside(nIt.GetIndex())) + { + VertexType middlePoint=static_cast<VertexType>(nIt.GetIndex()); + double currentValue = computeValue(inputImagePtr, middlePoint, previousPoint, nextPoint); + if (currentValue > maxValue) + { + maxValue=currentValue; + maxPoint=middlePoint; + } + } + } + currentPoint=maxPoint; + newPolygon->AddVertex(maxPoint); + } + /** End 'to factorize' */ + + polygon = newPolygon;//prepare the next iteration + } + } + + outputPtr->PushBack(polygon); + + }//going through the polygon list + + +} + +template <class TPath, class TImage> + double + ImageFittingPolygonListFilter<TPath, TImage> + ::computeValue(ImageConstPointerType image, VertexType middlePoint, VertexType previousPoint, VertexType nextPoint) const +{ + typedef typename ImageType::IndexType IndexType; + IndexType middleIndex; + IndexType previousIndex; + IndexType nextIndex; + middleIndex[0]=static_cast<long int>(middlePoint[0]); + middleIndex[1]=static_cast<long int>(middlePoint[1]); + previousIndex[0]=static_cast<long int>(previousPoint[0]); + previousIndex[1]=static_cast<long int>(previousPoint[1]); + nextIndex[0]=static_cast<long int>(nextPoint[0]); + nextIndex[1]=static_cast<long int>(nextPoint[1]); + double currentValue = 0.0; + unsigned int count = 0; + {//compute for first segment + LineConstIteratorType itLine(image, previousIndex, middleIndex); + while (!itLine.IsAtEnd()) + { + currentValue += itLine.Get(); + ++count; + ++itLine; + } + } + {//compute for second segment + LineConstIteratorType itLine(image, nextIndex, middleIndex); + while (!itLine.IsAtEnd()) + { + currentValue += itLine.Get(); + ++count; + ++itLine; + } + } + return currentValue/count; +} + +/** + * PrintSelf Method + */ +template <class TPath, class TImage> +void +ImageFittingPolygonListFilter<TPath, TImage> +::PrintSelf(std::ostream& os, itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); +} + +} // End namespace otb +#endif diff --git a/Code/Visu/otbFixedSizeFullImageWidget.h b/Code/Visu/otbFixedSizeFullImageWidget.h index 4cf705438f9e2a342945c20152935d625f99018d..a22b33a30f5404d7b9ea16f0f291d590d3f4b6e7 100644 --- a/Code/Visu/otbFixedSizeFullImageWidget.h +++ b/Code/Visu/otbFixedSizeFullImageWidget.h @@ -23,7 +23,7 @@ namespace otb { /** \class FixedSizeFullImageWidget - * \brief + * \brief FixedSizeFullImageWidget * */ template <class TPixel> diff --git a/Code/Visu/otbImageViewerBase.h b/Code/Visu/otbImageViewerBase.h index 9af0081bb5583d29ea4ea0ad9f4dbdbf1e851e4e..8cf31240ad95df7cd2a7f952c7944188ae7a2864 100644 --- a/Code/Visu/otbImageViewerBase.h +++ b/Code/Visu/otbImageViewerBase.h @@ -42,7 +42,7 @@ PURPOSE. See the above copyright notices for more information. namespace otb { - /** + /** \class ImageViewerBase * \brief Simple image viewer base class. * * This class is a simple image viewer using fltk gui and opengl drawing. diff --git a/Code/Visu/otbImageViewerBase.txx b/Code/Visu/otbImageViewerBase.txx index 27f6397883077fdcb6122c3b194503e59ca92e8c..9e45489278abc8907723c66021f1635b5f5a9719 100644 --- a/Code/Visu/otbImageViewerBase.txx +++ b/Code/Visu/otbImageViewerBase.txx @@ -1054,8 +1054,9 @@ ImageViewerBase<TPixel,TLabel> { case ScrollWidgetType::RGB: { - if(m_InputImage->GetNumberOfComponentsPerPixel()>2) - { +// if(m_InputImage->GetNumberOfComponentsPerPixel()>2) +// { //NOTE: No reason to prevent a 2 bands image to be displayed in RGB +// and the image is not necessarily loaded at that time. if(m_UseScroll) { m_ScrollWidget->SetViewModel(viewModel); @@ -1108,7 +1109,7 @@ ImageViewerBase<TPixel,TLabel> m_GreenHistogramWidget->SetHistogramColor(green); m_GreenHistogramWidget->SetTextColor(green); break; - } +// } } case ScrollWidgetType::GRAYSCALE: { diff --git a/Code/Visu/otbImageViewerScrollWidget.h b/Code/Visu/otbImageViewerScrollWidget.h index 3c1f74ead23b9973c5e853aa980490ff49abbcd9..3b62e74a1b56853a36a4b47f662472ee595d26e3 100644 --- a/Code/Visu/otbImageViewerScrollWidget.h +++ b/Code/Visu/otbImageViewerScrollWidget.h @@ -28,7 +28,7 @@ namespace otb { template <class TPixel, class TLabel> class ImageViewerBase; -/** +/** \class ImageViewerScrollWidget * \brief Custom scroll image widget. * * This class derives from otb::FixedSizeFullImageWidget, and implements behaviours specific to the image viewer. diff --git a/Code/Visu/otbImageWidgetBase.h b/Code/Visu/otbImageWidgetBase.h index 15902ded9eea0bfa28bb902b59cb8210cd15cc2f..550cbbc021d317245bec3d6601e8e0306f59dec4 100644 --- a/Code/Visu/otbImageWidgetBase.h +++ b/Code/Visu/otbImageWidgetBase.h @@ -29,7 +29,7 @@ namespace otb { /** \class ImageWidgetBase - * \brief + * \brief Base class for ImageWidget * */ template <class TPixel> diff --git a/Code/Visu/otbImageWidgetBase.txx b/Code/Visu/otbImageWidgetBase.txx index 1f6ad40df81ce3384a44938e27dd00187ef193b4..c595bcff9256c58d39311a5c97a913f2739364b8 100644 --- a/Code/Visu/otbImageWidgetBase.txx +++ b/Code/Visu/otbImageWidgetBase.txx @@ -377,7 +377,7 @@ ImageWidgetBase<TPixel> glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_TEXTURE_2D); - glColor4f(1.0,1.0,1.0,0.0); + glColor4f(1.0,1.0,1.0,1.0); GLuint textureOverlay; glGenTextures(1, &textureOverlay); glBindTexture(GL_TEXTURE_2D, textureOverlay); @@ -388,10 +388,10 @@ ImageWidgetBase<TPixel> glBindTexture (GL_TEXTURE_2D, textureOverlay); glBegin (GL_QUADS); int hOffset = this->h() - this->hDisplayed(); - glTexCoord2f (0.0, 1.0); glVertex3f (0.0, 0.0+hOffset, 0.0); - glTexCoord2f (1.0, 1.0); glVertex3f (this->wDisplayed(), 0.0+hOffset, 0.0); - glTexCoord2f (1.0, 0.0); glVertex3f (this->wDisplayed(), this->hDisplayed()+hOffset, 0.0); - glTexCoord2f (0.0, 0.0); glVertex3f (0.0, this->hDisplayed()+hOffset, 0.0); + glTexCoord2f (0.0, 1.0); glVertex3f (0.0, 0.0+hOffset, 1.0); + glTexCoord2f (1.0, 1.0); glVertex3f (this->wDisplayed(), 0.0+hOffset, 1.0); + glTexCoord2f (1.0, 0.0); glVertex3f (this->wDisplayed(), this->hDisplayed()+hOffset, 1.0); + glTexCoord2f (0.0, 0.0); glVertex3f (0.0, this->hDisplayed()+hOffset, 1.0); glEnd (); glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); diff --git a/Testing/Code/FeatureExtraction/CMakeLists.txt b/Testing/Code/FeatureExtraction/CMakeLists.txt index 1a96b798a6ebbde08127cc2759339d56484359e1..16147db51985b2cac75d32dd63de899be25edaba 100644 --- a/Testing/Code/FeatureExtraction/CMakeLists.txt +++ b/Testing/Code/FeatureExtraction/CMakeLists.txt @@ -839,8 +839,10 @@ ADD_TEST(feTvImageToHessianDeterminantImageFilter ${FEATUREEXTRACTION_TESTS9} ${TEMP}/feTvImageToHessianDeterminantImageFilterOutput.tif 1.5 ) - - + +# ------- otb::ImageFittingPolygonListFilter ------------- +ADD_TEST(feTuImageFittingPolygonListFilterNew ${FEATUREEXTRACTION_TESTS9} + otbImageFittingPolygonListFilterNew) # A enrichir SET(BasicFeatureExtraction_SRCS1 @@ -946,6 +948,7 @@ otbImageToSIFTKeyPointSetFilterOutputImage.cxx otbImageToSIFTKeyPointSetFilterOutputAscii.cxx otbImageToHessianDeterminantImageFilterNew.cxx otbImageToHessianDeterminantImageFilter.cxx +otbImageFittingPolygonListFilterNew.cxx ) INCLUDE_DIRECTORIES("${OTBTesting_BINARY_DIR}") diff --git a/Testing/Code/FeatureExtraction/otbFeatureExtractionTests9.cxx b/Testing/Code/FeatureExtraction/otbFeatureExtractionTests9.cxx index 556fbe6f73604c20d62602dd6fd95791651d3c1a..9b4221b808cf1c489e92c082fbe1be9076307aeb 100644 --- a/Testing/Code/FeatureExtraction/otbFeatureExtractionTests9.cxx +++ b/Testing/Code/FeatureExtraction/otbFeatureExtractionTests9.cxx @@ -35,5 +35,6 @@ REGISTER_TEST(otbImageToSIFTKeyPointSetFilterOutputAscii); //REGISTER_TEST(otbImageToSIFTKeyPointSetFilterValid); REGISTER_TEST(otbImageToHessianDeterminantImageFilterNew); REGISTER_TEST(otbImageToHessianDeterminantImageFilter); +REGISTER_TEST(otbImageFittingPolygonListFilterNew); } diff --git a/Testing/Code/FeatureExtraction/otbImageFittingPolygonListFilterNew.cxx b/Testing/Code/FeatureExtraction/otbImageFittingPolygonListFilterNew.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ecc01af65103fdb190484fe2546d2751adc401df --- /dev/null +++ b/Testing/Code/FeatureExtraction/otbImageFittingPolygonListFilterNew.cxx @@ -0,0 +1,37 @@ +/*========================================================================= + + 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 "itkExceptionObject.h" + +#include "otbImageFittingPolygonListFilter.h" +#include "otbPolygon.h" +#include "otbImage.h" +#include <cstdlib> + +int otbImageFittingPolygonListFilterNew(int argc, char * argv[]) +{ + const unsigned int Dimension =2; + typedef otb::Polygon<double> PolygonType; + typedef otb::Image<double,2> ImageType; + + typedef otb::ImageFittingPolygonListFilter<PolygonType,ImageType> FittingPolygonType; + + // Instantiating object + FittingPolygonType::Pointer fittingPolygon = FittingPolygonType::New(); + + return EXIT_SUCCESS; +}