diff --git a/Code/OBIA/otbLabelImageToOGRDataSourceFilter.h b/Code/OBIA/otbLabelImageToOGRDataSourceFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..36887dbced61849388d30a96c24af2bbef3ce5ad --- /dev/null +++ b/Code/OBIA/otbLabelImageToOGRDataSourceFilter.h @@ -0,0 +1,110 @@ +/*========================================================================= + + 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 __otbLabelImageToOGRDataSourceFilter_h +#define __otbLabelImageToOGRDataSourceFilter_h + +#include "itkProcessObject.h" +#include "itkDataObjectDecorator.h" +#include "itkDataObject.h" + +namespace otb +{ + +class OGRDataSourceWrapper; + +/** \class LabelImageToOGRDataSourceFilter + * \brief this class uses GDALPolygonize method to transform a Label image into + * a OGRDataSource. It is a non-streamed version. + * + * + * \sa StreamingLabelImageToOGRDataSourceFilter (streamed version) + * \ingroup OBIA + * + * + */ + +template <class TInputImage> +class ITK_EXPORT LabelImageToOGRDataSourceFilter : + public itk::ProcessObject +{ +public: + + /** typedef for the classes standards. */ + typedef LabelImageToOGRDataSourceFilter Self; + typedef itk::ProcessObject Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Method for management of the object factory. */ + itkNewMacro(Self); + + /** Return the name of the class. */ + itkTypeMacro(LabelImageToOGRDataSourceFilter, ProcessObject); + + /** Definition of the input image */ + typedef TInputImage InputImageType; + typedef typename InputImageType::PixelType InputPixelType; + typedef typename InputImageType::IndexType InputIndexType; + typedef typename InputImageType::SizeType SizeType; + typedef typename InputImageType::RegionType RegionType; + typedef typename InputImageType::SpacingType SpacingType; + typedef typename InputImageType::PointType OriginType; + typedef typename InputImageType::IndexType IndexType; + + typedef itk::DataObjectDecorator<OGRDataSourceWrapper> OGRDataSourceObjectType; + + /** Set/Get the input image of this process object. */ + virtual void SetInput(const InputImageType *input); + virtual const InputImageType * GetInput(void); + + itkSetMacro(FieldName, std::string); + itkGetMacro(FieldName, std::string); + + const OGRDataSourceObjectType * GetOutput(); + +protected: + LabelImageToOGRDataSourceFilter(); + virtual ~LabelImageToOGRDataSourceFilter() {} + + virtual void GenerateInputRequestedRegion(); + + /** Generate Data method*/ + virtual void GenerateData(); + + /** DataObject pointer */ + typedef itk::DataObject::Pointer DataObjectPointer; + + virtual DataObjectPointer MakeOutput(unsigned int idx); + +private: + LabelImageToOGRDataSourceFilter(const Self &); //purposely not implemented + void operator =(const Self&); //purposely not implemented + + std::string m_FieldName; + + +}; + + +} // end namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbLabelImageToOGRDataSourceFilter.txx" +#endif + +#endif diff --git a/Code/OBIA/otbLabelImageToOGRDataSourceFilter.txx b/Code/OBIA/otbLabelImageToOGRDataSourceFilter.txx new file mode 100644 index 0000000000000000000000000000000000000000..d89a0d8368700375d543bafb5bb8e6decc8c6dab --- /dev/null +++ b/Code/OBIA/otbLabelImageToOGRDataSourceFilter.txx @@ -0,0 +1,252 @@ +/*========================================================================= + + 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 __otbLabelImageToOGRDataSourceFilter_txx +#define __otbLabelImageToOGRDataSourceFilter_txx + +#include "otbLabelImageToOGRDataSourceFilter.h" +#include "otbGdalDataTypeBridge.h" + + +//gdal libraries +#include "gdal.h" +#include "gdal_priv.h" +#include "cpl_conv.h" +#include "gdal_alg.h" +#include "ogrsf_frmts.h" + +#include <typeinfo> +namespace otb +{ + +class OGRDataSourceWrapper : public itk::Object +{ + +public: + typedef OGRDataSourceWrapper Self; + typedef itk::Object Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(OGRDataSourceWrapper, itk::Object); + + void SetDataSource (OGRDataSource* datasource) + { + m_DataSource = datasource; + } + /** Easy access to the internal OGRDataSource object. + * Don't close it, it will be automatic */ + OGRDataSource* GetDataSource() const + { + return m_DataSource; + } + +protected : + OGRDataSourceWrapper() + : m_DataSource(NULL) + { + } + + ~OGRDataSourceWrapper() + { + if (m_DataSource) + { + OGRDataSource::DestroyDataSource(m_DataSource); + } + } + +private: + OGRDataSource* m_DataSource; +}; // end of OGRDataSourceWrapper + + +template <class TInputImage> +LabelImageToOGRDataSourceFilter<TInputImage> +::LabelImageToOGRDataSourceFilter() : m_FieldName("DN") +{ + this->SetNumberOfRequiredInputs(1); + this->SetNumberOfRequiredOutputs(1); + + GDALAllRegister(); + OGRRegisterAll(); + + this->ProcessObject::SetNthOutput(0, this->MakeOutput(0) ); +} + + +template <class TInputImage> +typename LabelImageToOGRDataSourceFilter<TInputImage>::DataObjectPointer +LabelImageToOGRDataSourceFilter<TInputImage> +::MakeOutput(unsigned int itkNotUsed(idx)) +{ + return static_cast< DataObjectPointer >(OGRDataSourceObjectType::New().GetPointer()); +} + +template <class TInputImage> +const typename LabelImageToOGRDataSourceFilter<TInputImage>::OGRDataSourceObjectType * +LabelImageToOGRDataSourceFilter<TInputImage> +::GetOutput() +{ + return static_cast< const OGRDataSourceObjectType * >( + this->ProcessObject::GetOutput(0)); +} + +template <class TInputImage> +void +LabelImageToOGRDataSourceFilter<TInputImage> +::SetInput(const InputImageType *input) +{ + this->Superclass::SetNthInput(0, const_cast<InputImageType *>(input)); +} + +template <class TInputImage> +const typename LabelImageToOGRDataSourceFilter<TInputImage> +::InputImageType * +LabelImageToOGRDataSourceFilter<TInputImage> +::GetInput(void) +{ + if (this->GetNumberOfInputs() < 1) + { + return 0; + } + + return static_cast<const InputImageType *>(this->Superclass::GetInput(0)); +} + +template <class TInputImage> +void +LabelImageToOGRDataSourceFilter<TInputImage> +::GenerateInputRequestedRegion(void) +{ + // call the superclass' implementation of this method + Superclass::GenerateInputRequestedRegion(); + + // get pointers to the inputs + typename InputImageType::Pointer input = + const_cast<InputImageType *> (this->GetInput()); + + if ( !input ) + { + return; + } + + // The input is necessarily the largest possible region. + // For a streamed implementation, use the StreamingLineSegmentDetector filter + input->SetRequestedRegionToLargestPossibleRegion(); +} + + +template <class TInputImage> +void +LabelImageToOGRDataSourceFilter<TInputImage> +::GenerateData(void) +{ + if (this->GetInput()->GetRequestedRegion() != this->GetInput()->GetLargestPossibleRegion()) + { + itkExceptionMacro(<< "Not streamed filter. ERROR : requested region is not the largest possible region."); + } + + typename InputImageType::Pointer inImage = const_cast<InputImageType *>(this->GetInput()); + + SizeType size = this->GetInput()->GetLargestPossibleRegion().GetSize(); + + unsigned int nbBands = this->GetInput()->GetNumberOfComponentsPerPixel(); + unsigned int bytePerPixel = sizeof(InputPixelType); + + /** Convert Input image into a OGRLayer using GDALPolygonize */ + // buffer casted in unsigned long cause under Win32 the adress + // don't begin with 0x, the adress in not interpreted as + // hexadecimal but alpha numeric value, then the conversion to + // integer make us pointing to an non allowed memory block => Crash. + std::ostringstream stream; + stream << "MEM:::" + << "DATAPOINTER=" << (unsigned long)(this->GetInput()->GetBufferPointer()) << "," + << "PIXELS=" << size[0] << "," + << "LINES=" << size[1] << "," + << "BANDS=" << nbBands << "," + << "DATATYPE=" << GDALGetDataTypeName(GdalDataTypeBridge::GetGDALDataType<InputPixelType>()) << "," + << "PIXELOFFSET=" << bytePerPixel * nbBands << "," + << "LINEOFFSET=" << bytePerPixel * nbBands * size[0] << "," + << "BANDOFFSET=" << bytePerPixel; + + GDALDataset * dataset = static_cast<GDALDataset *> (GDALOpen(stream.str().c_str(), GA_ReadOnly)); + + //Set input Projection ref and Geo transform to the dataset. + dataset->SetProjection(this->GetInput()->GetProjectionRef().c_str()); + + unsigned int projSize = this->GetInput()->GetGeoTransform().size(); + double geoTransform[6]; + + //Set the geo transform of the input image (if any) + // Reporting origin and spacing of the buffered region + // the spacing is unchanged, the origin is relative to the buffered region + IndexType bufferIndexOrigin = this->GetInput()->GetBufferedRegion().GetIndex(); + OriginType bufferOrigin; + this->GetInput()->TransformIndexToPhysicalPoint(bufferIndexOrigin, bufferOrigin); + geoTransform[0] = bufferOrigin[0]; + geoTransform[3] = bufferOrigin[1]; + geoTransform[1] = this->GetInput()->GetSpacing()[0]; + geoTransform[5] = this->GetInput()->GetSpacing()[1]; + // FIXME: Here component 1 and 4 should be replaced by the orientation parameters + if (projSize == 0) + { + geoTransform[2] = 0.; + geoTransform[4] = 0.; + } + else + { + geoTransform[2] = this->GetInput()->GetGeoTransform()[2]; + geoTransform[4] = this->GetInput()->GetGeoTransform()[4]; + } + dataset->SetGeoTransform(geoTransform); + + //Create the output layer for GDALPolygonize(). + const char * driverName = "Memory"; + OGRSFDriver * ogrDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driverName); + OGRDataSource * dataSource = ogrDriver->CreateDataSource("Shape",NULL); + + OGRLayer * outputLayer = dataSource->CreateLayer("toto",NULL,wkbMultiPolygon,NULL); + + OGRFieldDefn field(m_FieldName.c_str(),OFTInteger); + outputLayer->CreateField(&field, true); + + //Call GDALPolygonize() + GDALPolygonize(dataset->GetRasterBand(1), NULL, outputLayer, 0, NULL, NULL, NULL); + + + OGRDataSourceObjectType * decoratedOutput = + static_cast< OGRDataSourceObjectType * >( + this->ProcessObject::GetOutput(0)); + + typename OGRDataSourceWrapper::Pointer dataSourceWrapper = OGRDataSourceWrapper::New(); + dataSourceWrapper->SetDataSource(dataSource); + decoratedOutput->Set(dataSourceWrapper); + + //Clear memory + GDALClose(dataset); + + +} + + +} // end namespace otb + +#endif diff --git a/Code/OBIA/otbPersistentImageToOGRDataFilter.h b/Code/OBIA/otbPersistentImageToOGRDataFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..1662b705ffbd4c9ee77be343c2e7e8ae15079e00 --- /dev/null +++ b/Code/OBIA/otbPersistentImageToOGRDataFilter.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. + + Some parts of this code are derived from ITK. See ITKCopyright.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 __otbPersistentImageToOGRDataFilter_h +#define __otbPersistentImageToOGRDataFilter_h + +#include "otbPersistentImageFilter.h" + +#include "otbLabelImageToOGRDataSourceFilter.h" +#include "itkDataObjectDecorator.h" + +#include "itkMacro.h" + +class OGRDataSource; + +namespace otb +{ + +/** \class PersistentImageToOGRDataFilter + * \brief Perform vectorization in a persistent way. + * + * This filter is a generic PersistentImageFilter, which encapsulate any filter + * which produces OGR data from an input Image. + * + * + * \sa PersistentImageFilter + * + */ +template<class TImage> +class ITK_EXPORT PersistentImageToOGRDataFilter : + public PersistentImageFilter<TImage, TImage> +{ +public: + /** Standard Self typedef */ + typedef PersistentImageToOGRDataFilter Self; + typedef PersistentImageFilter<TImage, TImage> Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Runtime information support. */ + itkTypeMacro(PersistentImageToOGRDataFilter, PersistentImageFilter); + + typedef TImage InputImageType; + typedef typename InputImageType::Pointer InputImagePointer; + typedef typename InputImageType::RegionType RegionType; + typedef typename InputImageType::SizeType SizeType; + typedef typename InputImageType::IndexType IndexType; + typedef typename InputImageType::PixelType PixelType; + typedef typename InputImageType::InternalPixelType InternalPixelType; + + + typedef itk::DataObjectDecorator<OGRDataSourceWrapper> OGRDataSourceObjectType; + typedef typename OGRDataSourceObjectType::Pointer OGRDataSourceObjectPointerType; + + + /** Smart Pointer type to a DataObject. */ + typedef itk::DataObject::Pointer DataObjectPointer; + + void AllocateOutputs(); + + virtual void Reset(void); + + virtual void Synthetize(void); + + virtual void Initialize(void); + + /** Specify the name of the output shapefile to write. */ + void SetFileName(const std::string & filename); + itkGetStringMacro(FileName); + +protected: + PersistentImageToOGRDataFilter(); + virtual ~PersistentImageToOGRDataFilter(); + + void PrintSelf(std::ostream& os, itk::Indent indent) const; + + virtual void GenerateData(); + + +private: + PersistentImageToOGRDataFilter(const Self &); //purposely not implemented + void operator =(const Self&); //purposely not implemented + + virtual OGRDataSourceObjectPointerType ProcessTile() = 0; + + std::string m_FileName; + unsigned int m_TileNum; + OGRDataSource * m_DataSource; + +}; // end of class +} // end namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbPersistentImageToOGRDataFilter.txx" +#endif + +#endif diff --git a/Code/OBIA/otbPersistentImageToOGRDataFilter.txx b/Code/OBIA/otbPersistentImageToOGRDataFilter.txx new file mode 100644 index 0000000000000000000000000000000000000000..813891d66c43678bfe8fd678f1a492c06b610f94 --- /dev/null +++ b/Code/OBIA/otbPersistentImageToOGRDataFilter.txx @@ -0,0 +1,178 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + Some parts of this code are derived from ITK. See ITKCopyright.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 __otbPersistentImageToOGRDataFilter_txx +#define __otbPersistentImageToOGRDataFilter_txx + +#include "otbPersistentImageToOGRDataFilter.h" +#include "ogrsf_frmts.h" + +namespace otb +{ + + + + +template<class TImage> +PersistentImageToOGRDataFilter<TImage> +::PersistentImageToOGRDataFilter() : m_FileName(""), m_TileNum(0) +{ + // OGR factory registration + OGRRegisterAll(); +} + +template<class TImage> +PersistentImageToOGRDataFilter<TImage> +::~PersistentImageToOGRDataFilter() +{ + if (m_DataSource != NULL) + { + OGRDataSource::DestroyDataSource(m_DataSource); + } +} + +template<class TImage> +void +PersistentImageToOGRDataFilter<TImage> +::AllocateOutputs() +{ + // Nothing that needs to be allocated for the outputs : the output is not meant to be used +} + +template<class TImage> +void +PersistentImageToOGRDataFilter<TImage> +::Reset() +{ + +} + +template<class TImage> +void +PersistentImageToOGRDataFilter<TImage> +::Synthetize() +{ + +} + +template<class TImage> +void +PersistentImageToOGRDataFilter<TImage> +::Initialize() +{ + if (m_DataSource != NULL) + { + OGRDataSource::DestroyDataSource(m_DataSource); + } + + std::string projectionRefWkt = this->GetInput()->GetProjectionRef(); + bool projectionInformationAvailable = !projectionRefWkt.empty(); + OGRSpatialReference * oSRS = NULL; + if (projectionInformationAvailable) + { + oSRS = static_cast<OGRSpatialReference *>(OSRNewSpatialReference(projectionRefWkt.c_str())); + } + OGRSFDriver * ogrDriver; + //OGRSFDriverRegistrar::Open(this->m_FileName.c_str(), FALSE, &ogrDriver); + ogrDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName("ESRI Shapefile"); + m_DataSource = ogrDriver->CreateDataSource(this->m_FileName.c_str(), NULL); + m_DataSource->CreateLayer("titi", oSRS ,wkbMultiPolygon, NULL); + + OGRFieldDefn field("DN",OFTInteger); + m_DataSource->GetLayer(0)->CreateField(&field, true); + + std::cout<<"bon ok "<<std::endl; +} + +template<class TImage> +void +PersistentImageToOGRDataFilter<TImage> +::SetFileName(const std::string & filename) +{ + m_FileName = filename; + this->Initialize(); +} + +template<class TImage> +void +PersistentImageToOGRDataFilter<TImage> +::GenerateData() +{ + // call the processing function for this tile + OGRDataSourceObjectPointerType currentTileVD = this->ProcessTile(); + OGRLayer * poSrcLayer = currentTileVD->Get()->GetDataSource()->GetLayer(0); + + std::ostringstream stream; + stream << m_TileNum; + + //m_DataSource->CopyLayer(tileLayer,stream.str().c_str(),NULL); + //create the layer corresponding to the tile processed ! + OGRLayer * poDstLayer; + poDstLayer = m_DataSource->GetLayer(0); + + + //poDstLayer = m_DataSource->CreateLayer(stream.str().c_str(),poSrcLayer->GetSpatialRef() ,poSrcLayer->GetGeomType(), NULL); + //Copy features + poSrcLayer->ResetReading(); + OGRFieldDefn * layerDefn = poSrcLayer->GetLayerDefn()->GetFieldDefn(0); + /*std::cout<<"ouaip "<< layerDefn->GetNameRef() <<std::endl; + poDstLayer->CreateField(layerDefn, true); + std::cout<<"create field ok"<<std::endl;*/ + unsigned int nbFeatures = poSrcLayer->GetFeatureCount(true); + //std::cout<<"nb Features : "<<nbFeatures <<std::endl; + unsigned int i = 0; + OGRFeature *poFeature; + while (i<nbFeatures) + { + OGRFeature *poDstFeature = NULL; + poFeature = poSrcLayer->GetNextFeature(); + + if( poFeature == NULL ) + break; + + poDstFeature = OGRFeature::CreateFeature( poDstLayer->GetLayerDefn() ); + poDstFeature->SetFrom( poFeature, TRUE ); + + poDstLayer->CreateFeature( poDstFeature ); + + OGRFeature::DestroyFeature( poDstFeature ); + OGRFeature::DestroyFeature( poFeature ); + + i++; + } + + +// OGRDataSource::DestroyDataSource(currentTileVD->Get()->GetDataSource()); + + + m_TileNum++; + +} + +template<class TImage> +void +PersistentImageToOGRDataFilter<TImage> +::PrintSelf(std::ostream& os, itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); +} + +} // end namespace otb +#endif diff --git a/Code/OBIA/otbStreamingVectorizedSegmentation.h b/Code/OBIA/otbStreamingVectorizedSegmentation.h index 3e14264f23894795dcb780eb8e832c43686987e8..f964b70cff26f32b0edbcfcb2d4ee8fa627347aa 100644 --- a/Code/OBIA/otbStreamingVectorizedSegmentation.h +++ b/Code/OBIA/otbStreamingVectorizedSegmentation.h @@ -39,6 +39,8 @@ #include "otbPersistentImageToVectorDataFilter.h" #include "otbMeanShiftImageFilter.h" +#include "otbMeanShiftVectorImageFilter.h" +#include "itkMacro.h" namespace otb @@ -68,6 +70,18 @@ class LabeledOutputAccessor<MeanShiftImageFilter<TInputImage, TOutputImage, TLab itkStaticConstMacro(LabeledOutputIndex, unsigned int, 2); }; +/** + * \class LabeledOutputAccessor + * \brief Specialized class to get the index of the labeled output image in mean shift vector image filter. + */ +template <class TInputImage, class TOutputImage, class TLabeledImage> +class LabeledOutputAccessor<MeanShiftVectorImageFilter<TInputImage, TOutputImage, TLabeledImage> > +{ + public: + typedef typename MeanShiftImageFilter<TInputImage, TOutputImage, TLabeledImage>::LabeledOutputType LabelImageType; + itkStaticConstMacro(LabeledOutputIndex, unsigned int, 2); +}; + /** \class PersistentStreamingLabelImageToVectorDataFilter * \brief this class uses GDALPolygonize method to transform a Label image into a VectorData. @@ -115,8 +129,6 @@ public: itkSetMacro(FieldName, std::string); itkGetMacro(FieldName, std::string); - - void SetStartLabel(const LabelPixelType & label) { m_StartLabel = label; @@ -142,6 +154,8 @@ private: LabelPixelType m_StartLabel; typename SegmentationFilterType::Pointer m_SegmentationFilter; + unsigned int m_TileNumber; + }; @@ -208,6 +222,11 @@ public: return this->GetFilter()->GetStartLabel(); } + void SetFileName(const std::string & fileName) + { + this->GetFilter()->SetFileName(fileName); + } + protected: /** Constructor */ StreamingVectorizedSegmentation() {} diff --git a/Code/OBIA/otbStreamingVectorizedSegmentation.txx b/Code/OBIA/otbStreamingVectorizedSegmentation.txx index 10f75a151f87dfbb951519636e0c6b1a03d739bb..27ccc93951d7b53cd7614ef82d5b9ec7e02d4f12 100644 --- a/Code/OBIA/otbStreamingVectorizedSegmentation.txx +++ b/Code/OBIA/otbStreamingVectorizedSegmentation.txx @@ -26,6 +26,8 @@ #include "otbVectorDataTransformFilter.h" #include "itkAffineTransform.h" +#include "itkTimeProbe.h" + namespace otb { @@ -34,6 +36,7 @@ PersistentStreamingLabelImageToVectorDataFilter<TImageType, TOutputVectorData, T ::PersistentStreamingLabelImageToVectorDataFilter() : m_FieldName("DN"), m_TileMaxLabel(0), m_StartLabel(0) { m_SegmentationFilter = SegmentationFilterType::New(); + m_TileNumber = 1; } template <class TImageType, class TOutputVectorData, class TSegmentationFilter> @@ -67,12 +70,23 @@ typename PersistentStreamingLabelImageToVectorDataFilter<TImageType, TOutputVect PersistentStreamingLabelImageToVectorDataFilter<TImageType, TOutputVectorData, TSegmentationFilter> ::ProcessTile() { + std::cout<< "tile number : " << m_TileNumber <<std::endl; + m_TileNumber = m_TileNumber + 1; + itk::TimeProbe tileChrono; + tileChrono.Start(); + + + itk::TimeProbe chrono; + chrono.Start(); // Apply an ExtractImageFilter to avoid problems with filters asking for the LargestPossibleRegion typedef itk::ExtractImageFilter<InputImageType, InputImageType> ExtractImageFilterType; typename ExtractImageFilterType::Pointer extract = ExtractImageFilterType::New(); extract->SetInput( this->GetInput() ); extract->SetExtractionRegion( this->GetInput()->GetBufferedRegion() ); extract->Update(); + + chrono.Stop(); + //std::cout<< "extract took " << chrono.GetTotal() << " sec"<<std::endl; // WARNING: itk::ExtractImageFilter does not copy the MetadataDictionnary extract->GetOutput()->SetMetaDataDictionary(this->GetInput()->GetMetaDataDictionary()); @@ -81,16 +95,36 @@ PersistentStreamingLabelImageToVectorDataFilter<TImageType, TOutputVectorData, T typename LabelImageToVectorDataFilterType::Pointer labelImageToVectorDataFilter = LabelImageToVectorDataFilterType::New(); + + /*typename SegmentationFilterType::Pointer segFilter = SegmentationFilterType::New(); + segFilter->SetInput(extract->GetOutput()); + segFilter->GetFunctor().SetExpression("distance<40"); + segFilter->Update();*/ + + itk::TimeProbe chrono1; + chrono1.Start(); m_SegmentationFilter->SetInput(extract->GetOutput()); - m_SegmentationFilter->UpdateOutputInformation(); + //m_SegmentationFilter->ResetPipeline(); + //m_SegmentationFilter->Modified(); + m_SegmentationFilter->UpdateLargestPossibleRegion(); m_SegmentationFilter->Update(); + chrono1.Stop(); + std::cout<< "segmentation took " << chrono1.GetTotal() << " sec"<<std::endl; + + itk::TimeProbe chrono2; + chrono2.Start(); + //labelImageToVectorDataFilter->SetInput(dynamic_cast<LabelImageType *>(segFilter->GetOutputs().at(labelImageIndex).GetPointer())); labelImageToVectorDataFilter->SetInput(dynamic_cast<LabelImageType *>(m_SegmentationFilter->GetOutputs().at(labelImageIndex).GetPointer())); labelImageToVectorDataFilter->SetFieldName(m_FieldName); labelImageToVectorDataFilter->Update(); - + chrono2.Stop(); + std::cout<< "vectorization took " << chrono2.GetTotal() << " sec"<<std::endl; + //Relabel the vector data + itk::TimeProbe chrono3; + chrono3.Start(); typename TreeNodeType::Pointer rootNode = const_cast<TreeNodeType *>(labelImageToVectorDataFilter->GetOutput()->GetDataTree()->GetRoot()); ChildrenListType childList = rootNode->GetChildrenList()[0]->GetChildrenList(); @@ -120,7 +154,13 @@ PersistentStreamingLabelImageToVectorDataFilter<TImageType, TOutputVectorData, T } m_TileMaxLabel = m_TileMaxLabel + fieldValueVector.size(); + + chrono3.Stop(); + //std::cout<< "relabel took " << chrono3.GetTotal() << " sec"<<std::endl; + + tileChrono.Stop(); + std::cout<< "tile processing took " << tileChrono.GetTotal() << " sec"<<std::endl; // return the VectorData in image physical coordinates return labelImageToVectorDataFilter->GetOutput(); } diff --git a/Code/OBIA/otbStreamingVectorizedSegmentationOGR.h b/Code/OBIA/otbStreamingVectorizedSegmentationOGR.h new file mode 100644 index 0000000000000000000000000000000000000000..5dc387206209ec85db7a9f207e052d83355d93f4 --- /dev/null +++ b/Code/OBIA/otbStreamingVectorizedSegmentationOGR.h @@ -0,0 +1,239 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + Some parts of this code are derived from ITK. See ITKCopyright.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 __otbStreamingVectorizedSegmentationOGR_h +#define __otbStreamingVectorizedSegmentationOGR_h + +#include <vector> + +#include "itkImageRegion.h" +#include "otbVectorData.h" +#include "itkPreOrderTreeIterator.h" + +#include "itkDataObject.h" +#include "itkDataObjectDecorator.h" +#include "itkSimpleDataObjectDecorator.h" + +#include "otbLabelImageToVectorDataFilter.h" +#include "itkExtractImageFilter.h" + +#include "otbPersistentImageFilter.h" +#include "otbPersistentFilterStreamingDecorator.h" +#include "otbPersistentImageToOGRDataFilter.h" + +#include "otbMeanShiftImageFilter.h" +#include "otbMeanShiftVectorImageFilter.h" +#include "itkMacro.h" + + +namespace otb +{ + +/** + * \class LabeledOutputAccessor + * \brief Accessor to the index of the labeled output image of the Template Filter. + */ +template <class TFilter> +class LabeledOutputAccessor +{ + public: + typedef typename TFilter::OutputImageType LabelImageType; + itkStaticConstMacro(LabeledOutputIndex, unsigned int, 0); +}; + +/** + * \class LabeledOutputAccessor + * \brief Specialized class to get the index of the labeled output image in mean shift filter. + */ +template <class TInputImage, class TOutputImage, class TLabeledImage, class TBufferConverter> +class LabeledOutputAccessor<MeanShiftImageFilter<TInputImage, TOutputImage, TLabeledImage, TBufferConverter> > +{ + public: + typedef typename MeanShiftImageFilter<TInputImage, TOutputImage, TLabeledImage, TBufferConverter>::LabeledOutputType LabelImageType; + itkStaticConstMacro(LabeledOutputIndex, unsigned int, 2); +}; + +/** + * \class LabeledOutputAccessor + * \brief Specialized class to get the index of the labeled output image in mean shift vector image filter. + */ +template <class TInputImage, class TOutputImage, class TLabeledImage> +class LabeledOutputAccessor<MeanShiftVectorImageFilter<TInputImage, TOutputImage, TLabeledImage> > +{ + public: + typedef typename MeanShiftImageFilter<TInputImage, TOutputImage, TLabeledImage>::LabeledOutputType LabelImageType; + itkStaticConstMacro(LabeledOutputIndex, unsigned int, 2); +}; + + +/** \class PersistentStreamingLabelImageToOGRDataFilter + * \brief this class uses GDALPolygonize method to transform a Label image into a VectorData. + * + * This filter is a generic PersistentImageFilter, which encapsulate + * the LabelImageToVectorData filter. + * + * \sa PersistentImageToOGRDataFilter + * + */ +template <class TImageType, class TSegmentationFilter> +class PersistentStreamingLabelImageToOGRDataFilter + : public otb::PersistentImageToOGRDataFilter<TImageType> +{ +public: + /** Standard Self typedef */ + typedef PersistentStreamingLabelImageToOGRDataFilter Self; + typedef PersistentImageToOGRDataFilter<TImageType> Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + typedef typename Superclass::InputImageType InputImageType; + typedef typename Superclass::InputImagePointer InputImagePointerType; + + + typedef TSegmentationFilter SegmentationFilterType; + typedef typename LabeledOutputAccessor<SegmentationFilterType>::LabelImageType LabelImageType; + typedef typename LabelImageType::PixelType LabelPixelType; + + typedef otb::LabelImageToOGRDataSourceFilter<LabelImageType> LabelImageToOGRDataSourceFilterType; + typedef typename LabelImageToOGRDataSourceFilterType::OGRDataSourceObjectType OGRDataSourceObjectType; + typedef typename OGRDataSourceObjectType::Pointer OGRDataSourceObjectPointerType; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Runtime information support. */ + itkTypeMacro(PersistentStreamingLabelImageToOGRDataFilter, PersistentImageToOGRDataFilter); + + itkGetObjectMacro(SegmentationFilter, SegmentationFilterType); + + itkSetMacro(FieldName, std::string); + itkGetMacro(FieldName, std::string); + + void SetStartLabel(const LabelPixelType & label) + { + m_StartLabel = label; + m_TileMaxLabel = label; + } + itkGetMacro(StartLabel, LabelPixelType); + +protected: + PersistentStreamingLabelImageToOGRDataFilter(); + + virtual ~PersistentStreamingLabelImageToOGRDataFilter(); + + void GenerateInputRequestedRegion(); + +private: + PersistentStreamingLabelImageToOGRDataFilter(const Self &); //purposely not implemented + void operator =(const Self&); //purposely not implemented + + virtual OGRDataSourceObjectPointerType ProcessTile(); + + std::string m_FieldName; + LabelPixelType m_TileMaxLabel; + LabelPixelType m_StartLabel; + typename SegmentationFilterType::Pointer m_SegmentationFilter; + + unsigned int m_TileNumber; + + +}; + +template <class TImageType, class TSegmentationFilter> +class ITK_EXPORT StreamingVectorizedSegmentationOGR : +public PersistentFilterStreamingDecorator<PersistentStreamingLabelImageToOGRDataFilter<TImageType, TSegmentationFilter> > +{ + +public: + /** Standard Self typedef */ + typedef StreamingVectorizedSegmentationOGR Self; + typedef PersistentFilterStreamingDecorator + <PersistentStreamingLabelImageToOGRDataFilter<TImageType, TSegmentationFilter> > Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Type macro */ + itkNewMacro(Self); + + /** Creation through object factory macro */ + itkTypeMacro(StreamingVectorizedSegmentationOGR, PersistentFilterStreamingDecorator); + + typedef TSegmentationFilter SegmentationFilterType; + typedef TImageType InputImageType; + typedef typename PersistentStreamingLabelImageToOGRDataFilter<TImageType, TSegmentationFilter>::LabelPixelType LabelPixelType; + + void SetInput(InputImageType * input) + { + this->GetFilter()->SetInput(input); + } + const InputImageType * GetInput() + { + return this->GetFilter()->GetInput(); + } + + SegmentationFilterType * GetSegmentationFilter() + { + return this->GetFilter()->GetSegmentationFilter(); + } + + void SetFieldName(const std::string & field) + { + this->GetFilter()->SetFieldName(field); + } + + const std::string & GetFieldName() + { + return this->GetFilter()->GetFieldName(); + } + + void SetStartLabel(const LabelPixelType & label) + { + this->GetFilter()->SetStartLabel(label); + } + + const LabelPixelType & GetStartLabel() + { + return this->GetFilter()->GetStartLabel(); + } + + void SetFileName(const std::string & fileName) + { + this->GetFilter()->SetFileName(fileName); + } + +protected: + /** Constructor */ + StreamingVectorizedSegmentationOGR() {} + /** Destructor */ + virtual ~StreamingVectorizedSegmentationOGR() {} + +private: + StreamingVectorizedSegmentationOGR(const Self &); //purposely not implemented + void operator =(const Self&); //purposely not implemented +}; + + +} + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbStreamingVectorizedSegmentationOGR.txx" +#endif + +#endif diff --git a/Code/OBIA/otbStreamingVectorizedSegmentationOGR.txx b/Code/OBIA/otbStreamingVectorizedSegmentationOGR.txx new file mode 100644 index 0000000000000000000000000000000000000000..3fccafaeae1d4e50552807fcc566efd13741dc13 --- /dev/null +++ b/Code/OBIA/otbStreamingVectorizedSegmentationOGR.txx @@ -0,0 +1,166 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + Some parts of this code are derived from ITK. See ITKCopyright.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 __otbStreamingVectorizedSegmentationOGR_txx +#define __otbStreamingVectorizedSegmentationOGR_txx + +#include "otbStreamingVectorizedSegmentationOGR.h" + +#include "otbVectorDataTransformFilter.h" +#include "itkAffineTransform.h" + +#include "itkTimeProbe.h" + +namespace otb +{ + +template <class TImageType, class TSegmentationFilter> +PersistentStreamingLabelImageToOGRDataFilter<TImageType, TSegmentationFilter> +::PersistentStreamingLabelImageToOGRDataFilter() : m_FieldName("DN"), m_TileMaxLabel(0), m_StartLabel(0) +{ + m_SegmentationFilter = SegmentationFilterType::New(); + m_TileNumber = 1; +} + +template <class TImageType, class TSegmentationFilter> +PersistentStreamingLabelImageToOGRDataFilter<TImageType, TSegmentationFilter> +::~PersistentStreamingLabelImageToOGRDataFilter() +{ +} + +template <class TImageType, class TSegmentationFilter> +void +PersistentStreamingLabelImageToOGRDataFilter<TImageType, TSegmentationFilter> +::GenerateInputRequestedRegion() +{ + Superclass::GenerateInputRequestedRegion(); + + if (this->GetInput()) + { + InputImagePointerType input = const_cast<InputImageType *> (this->GetInput()); + + typename InputImageType::RegionType region = this->GetOutput()->GetRequestedRegion(); + + region.PadByRadius(1); + region.Crop(input->GetLargestPossibleRegion()); + + input->SetRequestedRegion(region); + } +} + +template <class TImageType, class TSegmentationFilter> +typename PersistentStreamingLabelImageToOGRDataFilter<TImageType, TSegmentationFilter>::OGRDataSourceObjectPointerType +PersistentStreamingLabelImageToOGRDataFilter<TImageType, TSegmentationFilter> +::ProcessTile() +{ + std::cout<< "tile number : " << m_TileNumber <<std::endl; + m_TileNumber = m_TileNumber + 1; + itk::TimeProbe tileChrono; + tileChrono.Start(); + + + itk::TimeProbe chrono; + chrono.Start(); + // Apply an ExtractImageFilter to avoid problems with filters asking for the LargestPossibleRegion + typedef itk::ExtractImageFilter<InputImageType, InputImageType> ExtractImageFilterType; + typename ExtractImageFilterType::Pointer extract = ExtractImageFilterType::New(); + extract->SetInput( this->GetInput() ); + extract->SetExtractionRegion( this->GetInput()->GetBufferedRegion() ); + extract->Update(); + + chrono.Stop(); + //std::cout<< "extract took " << chrono.GetTotal() << " sec"<<std::endl; + + // WARNING: itk::ExtractImageFilter does not copy the MetadataDictionnary + extract->GetOutput()->SetMetaDataDictionary(this->GetInput()->GetMetaDataDictionary()); + + const unsigned int labelImageIndex = LabeledOutputAccessor<SegmentationFilterType>::LabeledOutputIndex; + + typename LabelImageToOGRDataSourceFilterType::Pointer labelImageToOGRDataFilter = + LabelImageToOGRDataSourceFilterType::New(); + + + itk::TimeProbe chrono1; + chrono1.Start(); + m_SegmentationFilter->SetInput(extract->GetOutput()); + //m_SegmentationFilter->ResetPipeline(); + //m_SegmentationFilter->Modified(); + m_SegmentationFilter->UpdateLargestPossibleRegion(); + m_SegmentationFilter->Update(); + + chrono1.Stop(); + std::cout<< "segmentation took " << chrono1.GetTotal() << " sec"<<std::endl; + + itk::TimeProbe chrono2; + chrono2.Start(); + //labelImageToVectorDataFilter->SetInput(dynamic_cast<LabelImageType *>(segFilter->GetOutputs().at(labelImageIndex).GetPointer())); + labelImageToOGRDataFilter->SetInput(dynamic_cast<LabelImageType *>(m_SegmentationFilter->GetOutputs().at(labelImageIndex).GetPointer())); + labelImageToOGRDataFilter->SetFieldName(m_FieldName); + labelImageToOGRDataFilter->Update(); + + chrono2.Stop(); + std::cout<< "vectorization took " << chrono2.GetTotal() << " sec"<<std::endl; + + //Relabel the vector data + /*itk::TimeProbe chrono3; + chrono3.Start(); + typename TreeNodeType::Pointer rootNode = const_cast<TreeNodeType *>(labelImageToVectorDataFilter->GetOutput()->GetDataTree()->GetRoot()); + ChildrenListType childList = rootNode->GetChildrenList()[0]->GetChildrenList(); + + std::vector<int> fieldValueVector; + for (typename ChildrenListType::iterator it = childList.begin(); it != childList.end(); ++it) + { + typename OutputVectorDataType::DataNodePointerType dataNode = (*it)->Get(); + fieldValueVector.push_back(dataNode->GetFieldAsInt(m_FieldName)); + } + std::sort(fieldValueVector.begin(), fieldValueVector.end()); + std::map<int,int> relabelMap; + unsigned int i = 0; + unsigned int ind = 0; + for(i = 0; i < fieldValueVector.size(); i++) + { + if (relabelMap.find(fieldValueVector.at(i)) == relabelMap.end()) + { + relabelMap[fieldValueVector.at(i)] = static_cast<int>(ind); + ind = ind + 1; + } + } + for (typename ChildrenListType::iterator it = childList.begin(); it != childList.end(); ++it) + { + typename OutputVectorDataType::DataNodePointerType dataNode = (*it)->Get(); + int newLabel = relabelMap[dataNode->GetFieldAsInt(m_FieldName)] + m_TileMaxLabel; + dataNode->SetFieldAsInt(m_FieldName, newLabel); + } + + m_TileMaxLabel = m_TileMaxLabel + fieldValueVector.size(); + + chrono3.Stop(); + //std::cout<< "relabel took " << chrono3.GetTotal() << " sec"<<std::endl; + + + tileChrono.Stop(); + std::cout<< "tile processing took " << tileChrono.GetTotal() << " sec"<<std::endl;*/ + // return the VectorData in image physical coordinates + return const_cast<OGRDataSourceObjectType *>(labelImageToOGRDataFilter->GetOutput()); +} + + +} // end namespace otb +#endif diff --git a/Testing/Code/OBIA/CMakeLists.txt b/Testing/Code/OBIA/CMakeLists.txt index 295ac8ab62cf3595e1b5b36c711148b919fc268a..f0f6e9d343051bad2648bcac20b65d322c936aed 100644 --- a/Testing/Code/OBIA/CMakeLists.txt +++ b/Testing/Code/OBIA/CMakeLists.txt @@ -240,15 +240,46 @@ ADD_TEST(obTuStreamingVectorizedSegmentationNew ${OBIA_TESTS1} otbStreamingVectorizedSegmentationNew) ADD_TEST(obTvStreamingVectorizedSegmentation ${OBIA_TESTS1} - --compare-ogr ${EPSILON_8} - ${BASELINE_FILES}/obTvStreamingVectorizedSegmentationOutput.sqlite - ${TEMP}/obTvStreamingVectorizedSegmentationOutput.sqlite + #--compare-ogr ${EPSILON_8} + #${BASELINE_FILES}/obTvStreamingVectorizedSegmentationOutput.sqlite + #${TEMP}/obTvStreamingVectorizedSegmentationOutput.sqlite otbStreamingVectorizedSegmentation - ${INPUTDATA}/QB_Toulouse_Ortho_PAN.tif - ${TEMP}/obTvStreamingVectorizedSegmentationOutput.sqlite - 100 + #${INPUTDATA}/QB_Toulouse_Ortho_PAN.tif + /home2/arnaud/ORFEO-TOOLBOX/images/TLSE_ORTHO_P_8bits/IMG_PHR1A_P_001/IMG_PHR1A_P_201006181052297_ORT_IPU_20111109_7807-001_R1C1.TIF + #/media/otbnas/otb/OTB-LargeInput/QUICKBIRD/TOULOUSE/000000128955_01_P001_MUL/02APR01105228-M1BS-000000128955_01_P001.TIF + ${TEMP}/obTvStreamingVectorizedSegmentationOutput2.shp + 2048 + #100 + ) + +ADD_TEST(obTuLabelImageToOGRDataSourceFilterNew ${OBIA_TESTS1} + otbLabelImageToOGRDataSourceFilterNew) + +ADD_TEST(obTvLabelImageToOGRDataSourceFilter ${OBIA_TESTS1} + #--compare-ogr ${NOTOL} + #${BASELINE_FILES}/obTuLabelImageToOGRDataSourceFilter.shp + #${TEMP}/obTuLabelImageToOGRDataSourceFilter.shp + otbLabelImageToOGRDataSourceFilter + ${INPUTDATA}/labelImage_UnsignedChar.tif + ${TEMP}/obTuLabelImageToOGRDataSourceFilter.shp + ) + +# ------- otb::StreamingVectorizedSegmentation ------------- +ADD_TEST(obTuStreamingVectorizedSegmentationOGRNew ${OBIA_TESTS1} + otbStreamingVectorizedSegmentationOGRNew) + +ADD_TEST(obTvStreamingVectorizedSegmentationOGR ${OBIA_TESTS1} + #--compare-ogr ${EPSILON_8} + #${BASELINE_FILES}/obTvStreamingVectorizedSegmentationOutput.sqlite + #${TEMP}/obTvStreamingVectorizedSegmentationOutput.sqlite + otbStreamingVectorizedSegmentationOGR + #${INPUTDATA}/QB_Toulouse_Ortho_PAN.tif + /home2/arnaud/ORFEO-TOOLBOX/images/TLSE_ORTHO_P_8bits/IMG_PHR1A_P_001/IMG_PHR1A_P_201006181052297_ORT_IPU_20111109_7807-001_R1C1.TIF + #/media/otbnas/otb/OTB-LargeInput/QUICKBIRD/TOULOUSE/000000128955_01_P001_MUL/02APR01105228-M1BS-000000128955_01_P001.TIF + ${TEMP}/obTvStreamingVectorizedSegmentationOutputOGR.shp + 2048 + #100 ) - # OBIATests2 (need PQXX) IF(OTB_USE_PQXX) @@ -313,6 +344,8 @@ otbHooverInstanceFilterToAttributeImage.cxx otbLabelImageToVectorDataFilterNew.cxx otbLabelImageToVectorDataFilter.cxx otbStreamingVectorizedSegmentation.cxx +otbLabelImageToOGRDataSourceFilter.cxx +otbStreamingVectorizedSegmentationOGR.cxx ) IF(OTB_USE_PQXX) diff --git a/Testing/Code/OBIA/otbLabelImageToOGRDataSourceFilter.cxx b/Testing/Code/OBIA/otbLabelImageToOGRDataSourceFilter.cxx new file mode 100644 index 0000000000000000000000000000000000000000..14bc6a1ab2cdee76d652f9fd1e6d20005f65b425 --- /dev/null +++ b/Testing/Code/OBIA/otbLabelImageToOGRDataSourceFilter.cxx @@ -0,0 +1,72 @@ +/*========================================================================= + + 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 "otbLabelImageToOGRDataSourceFilter.h" +#include "otbImage.h" +#include "otbImageFileReader.h" +#include "otbVectorDataFileWriter.h" + +int otbLabelImageToOGRDataSourceFilterNew(int argc, char * argv[]) +{ + const unsigned int Dimension = 2; + typedef unsigned short LabelType; + typedef otb::Image<LabelType, Dimension> InputLabelImageType; + + typedef otb::LabelImageToOGRDataSourceFilter<InputLabelImageType> FilterType; + + FilterType::Pointer filter = FilterType::New(); + + + return EXIT_SUCCESS; +} + + +int otbLabelImageToOGRDataSourceFilter(int argc, char * argv[]) +{ + if (argc != 3) + { + std::cerr << "Usage: " << argv[0]; + std::cerr << " inputLabelImageFile outputVectorfile(shp)" << std::endl; + return EXIT_FAILURE; + } + const char * infname = argv[1]; + const char * outfname = argv[2]; + + + const unsigned int Dimension = 2; + typedef unsigned short LabelType; + typedef otb::Image<LabelType, Dimension> InputLabelImageType; + + typedef otb::LabelImageToOGRDataSourceFilter<InputLabelImageType> FilterType; + typedef otb::ImageFileReader<InputLabelImageType> LabelImageReaderType; + + + FilterType::Pointer filter = FilterType::New(); + LabelImageReaderType::Pointer reader = LabelImageReaderType::New(); + + reader->SetFileName(infname); + + filter->SetInput(reader->GetOutput()); + filter->Update(); + + std::cout<<"layer name : "<<filter->GetOutput()->Get()->GetDataSource()->GetLayer(0)->GetName()<<std::endl; + std::cout<<"layer nb features : "<<filter->GetOutput()->Get()->GetDataSource()->GetLayer(0)->GetFeatureCount()<<std::endl; + + return EXIT_SUCCESS; +} diff --git a/Testing/Code/OBIA/otbOBIATests1.cxx b/Testing/Code/OBIA/otbOBIATests1.cxx index d1254ae3accad9c546b171bf7213111f2f60d2db..84e1a66168723f58b75a09a94bb011f7619bd046 100644 --- a/Testing/Code/OBIA/otbOBIATests1.cxx +++ b/Testing/Code/OBIA/otbOBIATests1.cxx @@ -64,4 +64,8 @@ REGISTER_TEST(otbLabelImageToVectorDataFilterNew); REGISTER_TEST(otbLabelImageToVectorDataFilter); REGISTER_TEST(otbStreamingVectorizedSegmentationNew); REGISTER_TEST(otbStreamingVectorizedSegmentation); +REGISTER_TEST(otbLabelImageToOGRDataSourceFilterNew); +REGISTER_TEST(otbLabelImageToOGRDataSourceFilter); +REGISTER_TEST(otbStreamingVectorizedSegmentationOGRNew); +REGISTER_TEST(otbStreamingVectorizedSegmentationOGR); } diff --git a/Testing/Code/OBIA/otbStreamingVectorizedSegmentation.cxx b/Testing/Code/OBIA/otbStreamingVectorizedSegmentation.cxx index 7cf45b280d66bf0e41e25a7094afc836690cd57c..b29d7852fe91881474720368dc490cf6522b4924 100644 --- a/Testing/Code/OBIA/otbStreamingVectorizedSegmentation.cxx +++ b/Testing/Code/OBIA/otbStreamingVectorizedSegmentation.cxx @@ -16,12 +16,14 @@ =========================================================================*/ -#include "otbImage.h" +#include "otbVectorImage.h" #include "otbStreamingVectorizedSegmentation.h" #include "otbImageFileReader.h" #include "otbVectorDataFileWriter.h" #include "otbVectorData.h" -#include "otbMeanShiftImageFilter.h" +#include "otbMeanShiftVectorImageFilter.h" +#include "itkConnectedComponentFunctorImageFilter.h" +#include "otbConnectedComponentMuParserFunctor.h" #include "otbPersistentImageToVectorDataFilter.h" #include "otbPersistentFilterStreamingDecorator.h" @@ -52,11 +54,15 @@ int otbStreamingVectorizedSegmentation(int argc, char * argv[]) const std::string fieldName("DN"); // Typedefs - typedef otb::Image<InputPixelType, Dimension> ImageType; + typedef otb::VectorImage<InputPixelType, Dimension> ImageType; typedef otb::VectorData<double, 2> VectorDataType; typedef otb::Image<unsigned int, Dimension> LabelImageType; - typedef otb::MeanShiftImageFilter<ImageType, ImageType, LabelImageType> MeanShiftImageFilterType; - typedef otb::StreamingVectorizedSegmentation<ImageType, VectorDataType, MeanShiftImageFilterType> StreamingVectorizedSegmentationType; + typedef otb::MeanShiftVectorImageFilter<ImageType, ImageType, LabelImageType> MeanShiftImageFilterType; + + typedef otb::Functor::ConnectedComponentMuParserFunctor<ImageType::PixelType> FunctorType; + typedef itk::ConnectedComponentFunctorImageFilter<ImageType, LabelImageType, FunctorType, LabelImageType > SegmentationFilterType; + typedef otb::StreamingVectorizedSegmentation<ImageType, VectorDataType, SegmentationFilterType> StreamingVectorizedSegmentationType; + //typedef otb::StreamingVectorizedSegmentation<ImageType, VectorDataType, MeanShiftImageFilterType> StreamingVectorizedSegmentationType; typedef otb::ImageFileReader<ImageType> ReaderType; typedef otb::VectorDataFileWriter<VectorDataType> WriterType; @@ -68,19 +74,25 @@ int otbStreamingVectorizedSegmentation(int argc, char * argv[]) reader->SetFileName(argv[1]); reader->GenerateOutputInformation(); filter->SetInput(reader->GetOutput()); - filter->GetStreamer()->SetNumberOfLinesStrippedStreaming(atoi(argv[3])); - //filter->GetStreamer()->SetTileDimensionTiledStreaming(atoi(argv[3])); + //filter->GetStreamer()->SetNumberOfLinesStrippedStreaming(atoi(argv[3])); + filter->GetStreamer()->SetTileDimensionTiledStreaming(atoi(argv[3])); filter->SetFieldName(fieldName); filter->SetStartLabel(1); - filter->GetSegmentationFilter()->SetSpatialRadius(10); + /*filter->GetSegmentationFilter()->SetSpatialRadius(10); filter->GetSegmentationFilter()->SetRangeRadius(15); - filter->GetSegmentationFilter()->SetMinimumRegionSize(400); + filter->GetSegmentationFilter()->SetMinimumRegionSize(400);*/ + filter->GetSegmentationFilter()->GetFunctor().SetExpression("distance<40"); + + filter->SetFileName(argv[2]); filter->Update(); + std::cout<< "begin writing ...." <<std::endl; + writer->SetFileName(argv[2]); writer->SetInput(filter->GetOutputVectorData()); writer->Update(); + std::cout<< "end writing ...." <<std::endl; return EXIT_SUCCESS; } diff --git a/Testing/Code/OBIA/otbStreamingVectorizedSegmentationOGR.cxx b/Testing/Code/OBIA/otbStreamingVectorizedSegmentationOGR.cxx new file mode 100644 index 0000000000000000000000000000000000000000..bf6bde307e7866c3b26cd101ccf2aa0738d1a886 --- /dev/null +++ b/Testing/Code/OBIA/otbStreamingVectorizedSegmentationOGR.cxx @@ -0,0 +1,88 @@ +/*========================================================================= + + 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 "otbVectorImage.h" +#include "otbStreamingVectorizedSegmentationOGR.h" +#include "otbImageFileReader.h" + +#include "otbMeanShiftVectorImageFilter.h" +#include "itkConnectedComponentFunctorImageFilter.h" +#include "otbConnectedComponentMuParserFunctor.h" + +#include "otbPersistentImageToOGRDataFilter.h" +#include "otbPersistentFilterStreamingDecorator.h" + +int otbStreamingVectorizedSegmentationOGRNew(int argc, char * argv[]) +{ + typedef float InputPixelType; + const unsigned int Dimension = 2; + + /** Typedefs */ + typedef otb::Image<InputPixelType, Dimension> ImageType; + typedef otb::MeanShiftImageFilter<ImageType, ImageType> MeanShiftImageFilterType; + typedef otb::StreamingVectorizedSegmentationOGR<ImageType, MeanShiftImageFilterType>::FilterType StreamingVectorizedSegmentationOGRType; + + StreamingVectorizedSegmentationOGRType::Pointer filter = StreamingVectorizedSegmentationOGRType::New(); + + std::cout << filter << std::endl; + + return EXIT_SUCCESS; +} + +int otbStreamingVectorizedSegmentationOGR(int argc, char * argv[]) +{ + + typedef float InputPixelType; + const unsigned int Dimension = 2; + const std::string fieldName("DN"); + + // Typedefs + typedef otb::VectorImage<InputPixelType, Dimension> ImageType; + typedef otb::Image<unsigned int, Dimension> LabelImageType; + typedef otb::MeanShiftVectorImageFilter<ImageType, ImageType, LabelImageType> MeanShiftImageFilterType; + + typedef otb::Functor::ConnectedComponentMuParserFunctor<ImageType::PixelType> FunctorType; + typedef itk::ConnectedComponentFunctorImageFilter<ImageType, LabelImageType, FunctorType, LabelImageType > SegmentationFilterType; + typedef otb::StreamingVectorizedSegmentationOGR<ImageType, SegmentationFilterType> StreamingVectorizedSegmentationOGRType; + //typedef otb::StreamingVectorizedSegmentationOGR<ImageType, VectorDataType, MeanShiftImageFilterType> StreamingVectorizedSegmentationOGRType; + + typedef otb::ImageFileReader<ImageType> ReaderType; + + + ReaderType::Pointer reader = ReaderType::New(); + StreamingVectorizedSegmentationOGRType::Pointer filter = StreamingVectorizedSegmentationOGRType::New(); + + + reader->SetFileName(argv[1]); + reader->GenerateOutputInformation(); + filter->SetInput(reader->GetOutput()); + //filter->GetStreamer()->SetNumberOfLinesStrippedStreaming(atoi(argv[3])); + filter->GetStreamer()->SetTileDimensionTiledStreaming(atoi(argv[3])); + filter->SetFieldName(fieldName); + filter->SetStartLabel(1); + /*filter->GetSegmentationFilter()->SetSpatialRadius(10); + filter->GetSegmentationFilter()->SetRangeRadius(15); + filter->GetSegmentationFilter()->SetMinimumRegionSize(400);*/ + filter->GetSegmentationFilter()->GetFunctor().SetExpression("distance<40"); + + filter->SetFileName(argv[2]); + + filter->Update(); + + return EXIT_SUCCESS; +}