diff --git a/Code/BasicFilters/otbBandMathImageFilter.h b/Code/BasicFilters/otbBandMathImageFilter.h index f22a3ab543c7b3c2d9b436645509ea30ae90aca8..4490f7ee5534b6d81ba698e3f191d5be1b6b154b 100644 --- a/Code/BasicFilters/otbBandMathImageFilter.h +++ b/Code/BasicFilters/otbBandMathImageFilter.h @@ -55,6 +55,20 @@ namespace otb * following expression is valid : * "ndvi(b1,b2)*b3" * + * As an additional functionality, the filter also granted access to + * indexes information under special virtual bands named idxX, idxY + * for the images indexes and idxPhyX,idxPhyY for the physical + * indexes. + * It allows the user to perform, for example a spatial processing + * aiming to suppress a determined area : + * "if(sqrt((idxPhyX-105.3)*(idxPhyX-105.3)+ + * (idxPhyY-207.1)*(idxPhyY-207.1))>100, b1, 0)" + * This expression replace the physical zone around the point of + * physical index (105.3;207.1) by a black area + * This functionality assumes that all the band involved have the same + * spacing and origin. + * + * * \sa Parser * * \ingroup Streamed @@ -83,6 +97,9 @@ public: typedef typename ImageType::ConstPointer ImagePointer; typedef typename ImageType::RegionType ImageRegionType; typedef typename ImageType::PixelType PixelType; + typedef typename ImageType::IndexType IndexType; + typedef typename ImageType::PointType OrigineType; + typedef typename ImageType::SpacingType SpacingType; typedef Parser ParserType; /** Set the nth filter input with or without a specified associated variable name */ @@ -121,6 +138,10 @@ private : std::vector<ParserType::Pointer> m_VParser; std::vector< std::vector<double> > m_AImage; std::vector< std::string > m_VVarName; + unsigned int m_NbVar; + + SpacingType m_Spacing; + OrigineType m_Origin; long m_UnderflowCount; long m_OverflowCount; diff --git a/Code/BasicFilters/otbBandMathImageFilter.txx b/Code/BasicFilters/otbBandMathImageFilter.txx index 590426636e67b21518b839b7fecca843f927729f..195b3c7a6a1743b61bf84612c435c13573adbdb3 100644 --- a/Code/BasicFilters/otbBandMathImageFilter.txx +++ b/Code/BasicFilters/otbBandMathImageFilter.txx @@ -80,10 +80,15 @@ void BandMathImageFilter<TImage> { this->SetInput(idx, const_cast<TImage *>( image )); unsigned int nbInput = this->GetNumberOfInputs(); - m_VVarName.resize(nbInput); + m_VVarName.resize(nbInput+4); std::ostringstream varName; varName << "b" << nbInput; - m_VVarName[idx] = varName.str(); + m_VVarName[idx] = varName.str(); + + m_VVarName[idx+1] = "idxX"; + m_VVarName[idx+2] = "idxY"; + m_VVarName[idx+3] = "idxPhyX"; + m_VVarName[idx+4] = "idxPhyY"; } template <class TImage> @@ -91,8 +96,13 @@ void BandMathImageFilter<TImage> ::SetNthInput(unsigned int idx, const ImageType * image, const std::string& varName) { this->SetInput(idx, const_cast<TImage *>( image )); - m_VVarName.resize(this->GetNumberOfInputs()); + m_VVarName.resize(this->GetNumberOfInputs()+4); m_VVarName[idx] = varName; + + m_VVarName[idx+1] = "idxX"; + m_VVarName[idx+2] = "idxY"; + m_VVarName[idx+3] = "idxPhyX"; + m_VVarName[idx+4] = "idxPhyY"; } template <class TImage> @@ -102,7 +112,6 @@ void BandMathImageFilter<TImage> m_VVarName[idx] = varName; } - template <typename TImage> TImage * BandMathImageFilter<TImage> ::GetNthInput(unsigned int idx) @@ -141,13 +150,21 @@ void BandMathImageFilter<TImage> typename std::vector< std::vector<PixelType> >::iterator itVImage; unsigned int nbThreads = this->GetNumberOfThreads(); unsigned int nbInputImages = this->GetNumberOfInputs(); + unsigned int nbAccessIndex = 4; //to give access to image and physical index unsigned int i, j; unsigned int inputSize[2]; - + std::vector< std::string > tmpIdxVarNames; + + tmpIdxVarNames.resize(nbAccessIndex); + tmpIdxVarNames.at(0) = "idxX"; + tmpIdxVarNames.at(1) = "idxY"; + tmpIdxVarNames.at(2) = "idxPhyX"; + tmpIdxVarNames.at(3) = "idxPhyY"; + // Check if input image dimensions matches inputSize[0] = this->GetNthInput(0)->GetLargestPossibleRegion().GetSize(0); inputSize[1] = this->GetNthInput(0)->GetLargestPossibleRegion().GetSize(1); - + for(unsigned int p = 1; p < nbInputImages; p++) { if((inputSize[0] != this->GetNthInput(p)->GetLargestPossibleRegion().GetSize(0)) @@ -160,14 +177,20 @@ void BandMathImageFilter<TImage> << this->GetNthInput(p)->GetLargestPossibleRegion().GetSize(1) << "]"); } } - - //Allocate and initialize the thread temporaries + + // Store images specs + m_Spacing = this->GetNthInput(0)->GetSpacing(); + m_Origin = this->GetNthInput(0)->GetOrigin(); + + // Allocate and initialize the thread temporaries m_ThreadUnderflow.SetSize(nbThreads); m_ThreadUnderflow.Fill(0); m_ThreadOverflow.SetSize(nbThreads); m_ThreadOverflow.Fill(0); m_VParser.resize(nbThreads); m_AImage.resize(nbThreads); + m_NbVar = nbInputImages+nbAccessIndex; + m_VVarName.resize(m_NbVar); for(itParser = m_VParser.begin(); itParser < m_VParser.end(); itParser++) { @@ -176,12 +199,19 @@ void BandMathImageFilter<TImage> for(i = 0; i < nbThreads; i++) { - m_AImage.at(i).resize(nbInputImages); + m_AImage.at(i).resize(m_NbVar); m_VParser.at(i)->SetExpr(m_Expression); + for(j=0; j < nbInputImages; j++) { m_VParser.at(i)->DefineVar(m_VVarName.at(j), &(m_AImage.at(i).at(j))); } + + for(j=nbInputImages; j < nbInputImages+nbAccessIndex; j++) + { + m_VVarName.at(j) = tmpIdxVarNames.at(j-nbInputImages); + m_VParser.at(i)->DefineVar(m_VVarName.at(j), &(m_AImage.at(i).at(j))); + } } } @@ -241,6 +271,17 @@ void BandMathImageFilter<TImage> { m_AImage.at(threadId).at(j) = static_cast<double>(Vit.at(j).Get()); } + + // Image Indexes + for(j=0; j < 2; j++) + { + m_AImage.at(threadId).at(nbInputImages+j) = static_cast<double>(Vit.at(0).GetIndex()[j]); + } + for(j=0; j < 2; j++) + { + m_AImage.at(threadId).at(nbInputImages+2+j) = static_cast<double>(m_Origin[j]) + +static_cast<double>(Vit.at(0).GetIndex()[j]) * static_cast<double>(m_Spacing[j]) ; + } try { diff --git a/Code/Testing/otbTestHelper.cxx b/Code/Testing/otbTestHelper.cxx index 0bd9820d4243017e530e01dc14119050f767d0c3..419a68fb65cb9e39108486c3fce873739b4dcedb 100644 --- a/Code/Testing/otbTestHelper.cxx +++ b/Code/Testing/otbTestHelper.cxx @@ -38,6 +38,7 @@ #include "cpl_conv.h" #include "cpl_string.h" #include "cpl_multiproc.h" +#include "ogr_api.h" #define otbPrintDiff(comment, refStr, testStr) \ std::cout << " ---- '" << comment << "' checking ---------------------------" << std::endl; \ @@ -733,8 +734,8 @@ int TestHelper::RegressionTestOgrFile(const char *testOgrFilename, const char *b { const char *ref_pszDataSource = baselineOgrFilename; const char *test_pszDataSource = testOgrFilename; - const char *ref_pszWHERE = NULL; - const char *test_pszWHERE = NULL; + //const char *ref_pszWHERE = NULL; + //const char *test_pszWHERE = NULL; int bReadOnly = FALSE; int nbdiff(0); /* -------------------------------------------------------------------- */ @@ -742,10 +743,10 @@ int TestHelper::RegressionTestOgrFile(const char *testOgrFilename, const char *b /* -------------------------------------------------------------------- */ OGRDataSource *ref_poDS = NULL; OGRSFDriver * ref_poDriver = NULL; - OGRGeometry * ref_poSpatialFilter = NULL; + //OGRGeometry * ref_poSpatialFilter = NULL; OGRDataSource *test_poDS = NULL; OGRSFDriver * test_poDriver = NULL; - OGRGeometry * test_poSpatialFilter = NULL; + //OGRGeometry * test_poSpatialFilter = NULL; OGRRegisterAll(); @@ -844,8 +845,7 @@ int TestHelper::RegressionTestOgrFile(const char *testOgrFilename, const char *b } //Check Layer inforamtion - ogrReportOnLayer(ref_poLayer, ref_pszWHERE, ref_poSpatialFilter, test_poLayer, test_pszWHERE, test_poSpatialFilter, - nbdiff); + ogrReportOnLayer(ref_poLayer, NULL, NULL, test_poLayer, NULL, NULL, nbdiff); //If no difference, check the feature if (nbdiff == 0) @@ -876,7 +876,7 @@ int TestHelper::RegressionTestOgrFile(const char *testOgrFilename, const char *b itkGenericExceptionMacro(<< "Impossible to create ASCII file <" << ref_filename << ">."); } DumpOGRFeature(ref_f, ref_poFeature); - delete ref_poFeature; + OGRFeature::DestroyFeature( ref_poFeature ); fclose(ref_f); FILE *test_f(NULL); @@ -886,7 +886,7 @@ int TestHelper::RegressionTestOgrFile(const char *testOgrFilename, const char *b itkGenericExceptionMacro(<< "Impossible to create ASCII file <" << test_filename << ">."); } DumpOGRFeature(test_f, test_poFeature); - delete test_poFeature; + OGRFeature::DestroyFeature( test_poFeature ); fclose(test_f); //Check ASCII comparaison @@ -906,24 +906,11 @@ int TestHelper::RegressionTestOgrFile(const char *testOgrFilename, const char *b /* -------------------------------------------------------------------- */ /* Close down. */ /* -------------------------------------------------------------------- */ - /* CSLDestroy( papszArgv ); - CSLDestroy( papszLayers ); - CSLDestroy( papszOptions );*/ - delete ref_poDS; - if (ref_poSpatialFilter) delete ref_poSpatialFilter; - delete test_poDS; - if (test_poSpatialFilter) delete test_poSpatialFilter; - - delete OGRSFDriverRegistrar::GetRegistrar(); - - OSRCleanup(); - CPLFinderClean(); - VSICleanupFileManager(); - CPLFreeConfig(); - CPLCleanupTLS(); + OGRDataSource::DestroyDataSource( ref_poDS ); + OGRDataSource::DestroyDataSource( test_poDS ); + OGRCleanupAll(); return (nbdiff != 0) ? 1 : 0; - } void TestHelper::DumpOGRFeature(FILE* fpOut, OGRFeature* feature, char** papszOptions) diff --git a/Examples/BasicFilters/BandMathFilterExample.cxx b/Examples/BasicFilters/BandMathFilterExample.cxx index 2602b1b4a370b58a217cf07fee87c95324d5a39b..e7df354c4a29483f862437acba98a9207ed3c699 100755 --- a/Examples/BasicFilters/BandMathFilterExample.cxx +++ b/Examples/BasicFilters/BandMathFilterExample.cxx @@ -28,13 +28,15 @@ // // This filter is based on the mathematical parser library muParser. // The built in functions and operators list is available at: -// \url{http://muparser.sourceforge.net/mup_features.html} \\ +// \url{http://muparser.sourceforge.net/mup_features.html}. +// // In order to use this filter, at least one input image is to be // set. An associated variable name can be specified or not by using // the corresponding SetNthInput method. For the nth input image, if // no associated variable name has been specified, a default variable // name is given by concatenating the letter "b" (for band) and the -// corresponding input index. \\ +// corresponding input index. +// // The next step is to set the expression according to the variable // names. For example, in the default case with three input images the // following expression is valid : "(b1+b2)*b3". @@ -151,7 +153,8 @@ int main( int argc, char* argv[]) // // Now we can define the mathematical expression to perform on the layers (b1, b2,b3,b4). // The filter takes advantage of the parsing capabilities of the muParser library and -// allows to set the expression as on a digital calculator. \\ +// allows to set the expression as on a digital calculator. +// // The expression below returns 255 if the ratio $(NIR-RED)/(NIR+RED)$ is greater than 0.4 and 0 if not. // // Software Guide : EndLatex diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt index d6c079a32b5b9c53d3811d39ac32bd94233edd1e..a0d3096332cfca1454cf771c762175d069d1bcc0 100644 --- a/RELEASE_NOTES.txt +++ b/RELEASE_NOTES.txt @@ -1,4 +1,4 @@ -OTB-v.3.6.0 - Changes since version 3.4.0 (2010/??/??) +OTB-v.3.6.0 - Changes since version 3.4.0 (2010/10/07) ----------------------------------------- * Monteverdi diff --git a/Testing/Code/BasicFilters/CMakeLists.txt b/Testing/Code/BasicFilters/CMakeLists.txt index 669c2d4b81c4b1f90380f1ec1909dd6aa80f18ff..8f2ed23db01c3987b596ea4327399e93747e7f0a 100644 --- a/Testing/Code/BasicFilters/CMakeLists.txt +++ b/Testing/Code/BasicFilters/CMakeLists.txt @@ -1767,6 +1767,12 @@ ADD_TEST(bfTuBandMathImageFilter ${BASICFILTERS_TESTS13} ADD_TEST(bfTvBandMathImageFilter ${BASICFILTERS_TESTS13} otbBandMathImageFilter) +ADD_TEST(bfTvBandMathImageFilterWithIdx ${BASICFILTERS_TESTS13} + otbBandMathImageFilterWithIdx + ${TEMP}/bfTvBandMathImageFilterWithIdx1.tif + ${TEMP}/bfTvBandMathImageFilterWithIdx2.tif +) + ADD_TEST(bfTvComplexToIntensityFilterTest ${BASICFILTERS_TESTS13} otbComplexToIntensityFilterTest) diff --git a/Testing/Code/BasicFilters/otbBandMathImageFilter.cxx b/Testing/Code/BasicFilters/otbBandMathImageFilter.cxx index 6fe92c69c33425d8ca6aca52cbaacc90f305a231..dc02e71901eee8d631f19a86e392ab54c877d5ee 100644 --- a/Testing/Code/BasicFilters/otbBandMathImageFilter.cxx +++ b/Testing/Code/BasicFilters/otbBandMathImageFilter.cxx @@ -26,6 +26,7 @@ #include "otbMath.h" #include "otbImage.h" #include "otbBandMathImageFilter.h" +#include "otbStreamingImageFileWriter.h" int otbBandMathImageFilterNew( int argc, char* argv[]) { @@ -180,3 +181,99 @@ int otbBandMathImageFilter( int argc, char* argv[]) return EXIT_SUCCESS; } + + +int otbBandMathImageFilterWithIdx( int argc, char* argv[]) +{ + const char * outfname1 = argv[1]; + const char * outfname2 = argv[2]; + + typedef double PixelType; + //typedef float PixelType; + typedef otb::Image<PixelType, 2> ImageType; + typedef otb::BandMathImageFilter<ImageType> FilterType; + typedef otb::StreamingImageFileWriter<ImageType> WriterType; + + unsigned int i; + const unsigned int N = 100; + unsigned int FAIL_FLAG = 0; + + ImageType::SizeType size; + size.Fill(N); + ImageType::IndexType index; + index.Fill(0); + ImageType::RegionType region; + region.SetSize(size); + region.SetIndex(index); + ImageType::PointType origin; + origin[0] = -25; + origin[1] = -25; + ImageType::SpacingType spacing; + spacing[0] = 0.5; + spacing[1] = 0.5; + + ImageType::Pointer image1 = ImageType::New(); + ImageType::Pointer image2 = ImageType::New(); + ImageType::Pointer image3 = ImageType::New(); + + image1->SetLargestPossibleRegion( region ); + image1->SetBufferedRegion( region ); + image1->SetRequestedRegion( region ); + image1->Allocate(); + + image2->SetLargestPossibleRegion( region ); + image2->SetBufferedRegion( region ); + image2->SetRequestedRegion( region ); + image2->Allocate(); + + image3->SetLargestPossibleRegion( region ); + image3->SetBufferedRegion( region ); + image3->SetRequestedRegion( region ); + image3->Allocate(); + + typedef itk::ImageRegionIteratorWithIndex<ImageType> IteratorType; + IteratorType it1(image1, region); + IteratorType it2(image2, region); + IteratorType it3(image3, region); + + image1->SetOrigin(origin); + image1->SetSpacing(spacing); + image2->SetOrigin(origin); + image2->SetSpacing(spacing); + image3->SetOrigin(origin); + image3->SetSpacing(spacing); + + for (it1.GoToBegin(), it2.GoToBegin(), it3.GoToBegin(); !it1.IsAtEnd(); ++it1, ++it2, ++it3) + { + ImageType::IndexType i1 = it1.GetIndex(); + ImageType::IndexType i2 = it2.GetIndex(); + ImageType::IndexType i3 = it3.GetIndex(); + + it1.Set( i1[0] + i1[1] -50 ); + it2.Set( i2[0] * i2[1] ); + it3.Set( i3[0] + i3[1] * i3[1] ); + } + + + FilterType::Pointer filter = FilterType::New(); + std::cout << "Number Of Threads : " << filter->GetNumberOfThreads() << std::endl; + + + filter->SetNthInput(0, image1); + filter->SetNthInput(1, image2); + filter->SetNthInput(2, image3); + + filter->SetExpression("if(sqrt(idxX*idxX+idxY*idxY) < 50, b2,b3)"); + WriterType::Pointer writer = WriterType::New(); + writer->SetInput(filter->GetOutput()); + writer->SetFileName(outfname1); + writer->Update(); + + filter->SetExpression("if(sqrt(idxPhyX*idxPhyX+idxPhyY*idxPhyY) < 25, b2, b3)"); + WriterType::Pointer writer2 = WriterType::New(); + writer2->SetInput(filter->GetOutput()); + writer2->SetFileName(outfname2); + writer2->Update(); + + return EXIT_SUCCESS; +} diff --git a/Testing/Code/BasicFilters/otbBasicFiltersTests13.cxx b/Testing/Code/BasicFilters/otbBasicFiltersTests13.cxx index 9974b1467b3f5b5de287472f0a6bae03bf378bc9..1ef57badec0dc2d39e4bed489484b395979f520b 100644 --- a/Testing/Code/BasicFilters/otbBasicFiltersTests13.cxx +++ b/Testing/Code/BasicFilters/otbBasicFiltersTests13.cxx @@ -28,5 +28,6 @@ void RegisterTests() { REGISTER_TEST(otbBandMathImageFilterNew); REGISTER_TEST(otbBandMathImageFilter); + REGISTER_TEST(otbBandMathImageFilterWithIdx); REGISTER_TEST(otbComplexToIntensityFilterTest); } diff --git a/Utilities/otbsvm/svm.cxx b/Utilities/otbsvm/svm.cxx index 6109c871dd728253784439764b4b9a3fa95c554e..dd5ae3d2d5c8db1684c4b982b377cc88eae335cf 100644 --- a/Utilities/otbsvm/svm.cxx +++ b/Utilities/otbsvm/svm.cxx @@ -3338,11 +3338,7 @@ int svm_check_probability_model(const svm_model *model) GenericKernelFunctorBase::GenericKernelFunctorBase(const GenericKernelFunctorBase& copy) { - if (this != ©) - { - this->operator=(copy); - } - + *this = copy; } GenericKernelFunctorBase& @@ -3644,22 +3640,20 @@ add(const svm_node *px, const svm_node *py) const // **************************************************************************************** ComposedKernelFunctor::ComposedKernelFunctor(const ComposedKernelFunctor& copy) - { - //this->GenericKernelFunctorBase::GenericKernelFunctorBase(copy); - Superclass::GenericKernelFunctorBase(static_cast<GenericKernelFunctorBase>(copy)); - this->m_KernelFunctorList = copy.m_KernelFunctorList; - this->m_HaveToBeDeletedList = copy.m_HaveToBeDeletedList; - this->m_PonderationList = copy.m_PonderationList; - } +{ + *this = copy; +} ComposedKernelFunctor& ComposedKernelFunctor::operator=(const ComposedKernelFunctor& copy) { - //this->GenericKernelFunctorBase::operator=( copy ); - Superclass::operator=( static_cast<GenericKernelFunctorBase>(copy) ); - this->m_KernelFunctorList = copy.m_KernelFunctorList; + // Call Superclass::operator= + static_cast<Superclass&>(*this) = static_cast<const Superclass&>(copy); + + // Copy Self attributes + this->m_KernelFunctorList = copy.m_KernelFunctorList; this->m_HaveToBeDeletedList = copy.m_HaveToBeDeletedList; - this->m_PonderationList = copy.m_PonderationList; + this->m_PonderationList = copy.m_PonderationList; return *this; } diff --git a/Utilities/otbsvm/svm.h b/Utilities/otbsvm/svm.h index 6a160a88fadd780f61f2011ed5994120d9b1a149..e97eded539a220631f0c143d9b3d529d19a63bf4 100644 --- a/Utilities/otbsvm/svm.h +++ b/Utilities/otbsvm/svm.h @@ -234,12 +234,9 @@ public: } } }; - /** Recopy constructor */ + + /** Recopy constructor */ ComposedKernelFunctor( const ComposedKernelFunctor& copy ); - /* ComposedKernelFunctor( const ComposedKernelFunctor& c ) : GenericKernelFunctorBase(c), */ -/* m_KernelFunctorList(c.m_KernelFunctorList) */ -/* m_HaveToBeDeletedList(c.m_HaveToBeDeletedList) */ -/* m_PonderationList(c.m_PonderationList) {}; */ ComposedKernelFunctor& operator=(const ComposedKernelFunctor& copy); typedef std::vector<GenericKernelFunctorBase *> KernelListType;