From a6c49dda1a545bd71532a23c7614d03c6dbbc8e6 Mon Sep 17 00:00:00 2001 From: Jonathan Guinet <jonathan.guinet@c-s.fr> Date: Wed, 4 Jul 2012 19:06:30 +0200 Subject: [PATCH] BUG: Using segmentation application with non valid ESRI WKT returns exception when using vector mode with .shp output. --- Applications/Segmentation/otbSegmentation.cxx | 292 ++++++++++-------- 1 file changed, 158 insertions(+), 134 deletions(-) diff --git a/Applications/Segmentation/otbSegmentation.cxx b/Applications/Segmentation/otbSegmentation.cxx index 6ebb968887..e4ac0388cf 100644 --- a/Applications/Segmentation/otbSegmentation.cxx +++ b/Applications/Segmentation/otbSegmentation.cxx @@ -37,6 +37,8 @@ // Fusion filter #include "otbOGRLayerStreamStitchingFilter.h" +#include "otbGeoInformationConversion.h" + namespace otb { namespace Wrapper @@ -440,87 +442,93 @@ private: otb::ogr::DataSource::Pointer ogrDS; otb::ogr::Layer layer(NULL, false); - OGRSpatialReference oSRS(GetParameterFloatVectorImage("in")->GetProjectionRef().c_str()); + std::string projRef = GetParameterFloatVectorImage("in")->GetProjectionRef(); + + OGRSpatialReference oSRS(projRef.c_str()); - if(segModeType=="vector") + if (segModeType == "vector") { // Retrieve output filename as well as layer names std::string dataSourceName = GetParameterString("mode.vector.out"); + //projection ref conversion to ESRI need to be tested in case of .shp + if ((dataSourceName.find(".shp") != string::npos) && (!projRef.empty())) + { + if (!(otb::GeoInformationConversion::IsESRIValidWKT(projRef))) + { + itkExceptionMacro(<<"Image spatial reference can't be converted to ESRI. Use another output format (kml,SQLite,...) to overcome .shp limitation "); + } + } + // Retrieve the output vector opening mode std::string outmode = GetParameterString("mode.vector.outmode"); std::vector<std::string> options = GetParameterStringList("mode.vector.ogroptions"); // Create the DataSource in the appropriate mode - if(outmode == "ovw") + if (outmode == "ovw") { // Create the datasource ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::Overwrite); // and create the layer since we are in overwrite mode, the // datasource is blank - layer = ogrDS->CreateLayer(GetParameterString("mode.vector.layername"), - &oSRS,wkbMultiPolygon, - options); + layer = ogrDS->CreateLayer(GetParameterString("mode.vector.layername"), &oSRS, wkbMultiPolygon, options); // And create the field - OGRFieldDefn field(this->GetParameterString("mode.vector.fieldname").c_str(),OFTInteger); - layer.CreateField(field,true); + OGRFieldDefn field(this->GetParameterString("mode.vector.fieldname").c_str(), OFTInteger); + layer.CreateField(field, true); } - else if(outmode == "ulovw") - { - // Create the datasource - ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::Update_LayerOverwrite); - - // and create the layer since we are in overwrite mode, the - // datasource is blank - layer = ogrDS->CreateLayer(GetParameterString("mode.vector.layername"), - &oSRS,wkbMultiPolygon, - options); - // And create the field - OGRFieldDefn field(this->GetParameterString("mode.vector.fieldname").c_str(),OFTInteger); - layer.CreateField(field,true); - - } - else if(outmode == "ulu") - { - // Create the datasource - ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::Update_LayerUpdate); - // and create the layer since we are in overwrite mode, the - // datasource is blank - layer = ogrDS->CreateLayer(GetParameterString("mode.vector.layername"), - &oSRS,wkbMultiPolygon, - options); - - // And create the field if necessary - std::string fieldName = this->GetParameterString("mode.vector.fieldname"); - OGRFeatureDefn & ogrFeatureDfn = layer.GetLayerDefn(); - - if (-1 == ogrFeatureDfn.GetFieldIndex(fieldName.c_str())) + else + if (outmode == "ulovw") { - OGRFieldDefn field(fieldName.c_str(),OFTInteger); - layer.CreateField(field,true); - } + // Create the datasource + ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::Update_LayerOverwrite); - } - else if(outmode == "ulco") - { - // Create the datasource - ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::Update_LayerCreateOnly); + // and create the layer since we are in overwrite mode, the + // datasource is blank + layer = ogrDS->CreateLayer(GetParameterString("mode.vector.layername"), &oSRS, wkbMultiPolygon, options); + // And create the field + OGRFieldDefn field(this->GetParameterString("mode.vector.fieldname").c_str(), OFTInteger); + layer.CreateField(field, true); - // and create the layer since we are in overwrite mode, the - // datasource is blank - layer = ogrDS->CreateLayer(GetParameterString("mode.vector.layername"), - &oSRS,wkbMultiPolygon, - options); - // And create the field - OGRFieldDefn field(this->GetParameterString("mode.vector.fieldname").c_str(),OFTInteger); - layer.CreateField(field,true); - } - else - { - otbAppLogFATAL(<<"outmode not handled yet: "<< outmode); - } + } + else + if (outmode == "ulu") + { + // Create the datasource + ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::Update_LayerUpdate); + // and create the layer since we are in overwrite mode, the + // datasource is blank + layer = ogrDS->CreateLayer(GetParameterString("mode.vector.layername"), &oSRS, wkbMultiPolygon, options); + + // And create the field if necessary + std::string fieldName = this->GetParameterString("mode.vector.fieldname"); + OGRFeatureDefn & ogrFeatureDfn = layer.GetLayerDefn(); + + if (-1 == ogrFeatureDfn.GetFieldIndex(fieldName.c_str())) + { + OGRFieldDefn field(fieldName.c_str(), OFTInteger); + layer.CreateField(field, true); + } + + } + else + if (outmode == "ulco") + { + // Create the datasource + ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::Update_LayerCreateOnly); + + // and create the layer since we are in overwrite mode, the + // datasource is blank + layer = ogrDS->CreateLayer(GetParameterString("mode.vector.layername"), &oSRS, wkbMultiPolygon, options); + // And create the field + OGRFieldDefn field(this->GetParameterString("mode.vector.fieldname").c_str(), OFTInteger); + layer.CreateField(field, true); + } + else + { + otbAppLogFATAL(<<"outmode not handled yet: "<< outmode); + } } // The actual stream size used @@ -530,98 +538,114 @@ private: { otbAppLogINFO(<<"Use connected component segmentation."<<std::endl); ConnectedComponentStreamingVectorizedSegmentationOGRType::Pointer - ccVectorizationFilter = ConnectedComponentStreamingVectorizedSegmentationOGRType::New(); + ccVectorizationFilter = ConnectedComponentStreamingVectorizedSegmentationOGRType::New(); if (HasValue("mode.vector.inmask")) { - ccVectorizationFilter->GetSegmentationFilter()->SetMaskImage(this->GetParameterUInt32Image("mode.vector.inmask")); + ccVectorizationFilter->GetSegmentationFilter()->SetMaskImage( + this->GetParameterUInt32Image("mode.vector.inmask")); } - ccVectorizationFilter->GetSegmentationFilter()->GetFunctor().SetExpression( - GetParameterString( - "filter.cc.expr")); - streamSize = GenericApplySegmentation<FloatVectorImageType,ConnectedComponentSegmentationFilterType>(ccVectorizationFilter,this->GetParameterFloatVectorImage("in"),layer, 0); - } - else if (segType == "edison") - { - otbAppLogINFO(<<"Use Edison Mean-shift segmentation."<<std::endl); - - //segmentation parameters - const unsigned int - spatialRadius = static_cast<unsigned int> (this->GetParameterInt("filter.edison.spatialr")); - const float - rangeRadius = static_cast<float> (this->GetParameterFloat("filter.edison.ranger")); - const unsigned int - minimumObjectSize = static_cast<unsigned int> (this->GetParameterInt("filter.edison.minsize")); - const float scale = this->GetParameterFloat("filter.edison.scale"); - - EdisontreamingVectorizedSegmentationOGRType::Pointer - edisonVectorizationFilter = EdisontreamingVectorizedSegmentationOGRType::New(); - - edisonVectorizationFilter->GetSegmentationFilter()->SetSpatialRadius(spatialRadius); - edisonVectorizationFilter->GetSegmentationFilter()->SetRangeRadius(rangeRadius); - edisonVectorizationFilter->GetSegmentationFilter()->SetMinimumRegionSize(minimumObjectSize); - edisonVectorizationFilter->GetSegmentationFilter()->SetScale(scale); - - streamSize = GenericApplySegmentation<FloatVectorImageType,EdisonSegmentationFilterType>(edisonVectorizationFilter, this->GetParameterFloatVectorImage("in"), layer,2); - } - else if (segType == "meanshift") - { - otbAppLogINFO(<<"Use threaded Mean-shift segmentation."<<std::endl); - - MeanShiftVectorizedSegmentationOGRType::Pointer - meanShiftVectorizationFilter = MeanShiftVectorizedSegmentationOGRType::New(); - - //segmentation parameters - const unsigned int - spatialRadius = static_cast<unsigned int> (this->GetParameterInt("filter.meanshift.spatialr")); - const float - rangeRadius = static_cast<float> (this->GetParameterFloat("filter.meanshift.ranger")); - const unsigned int - minimumObjectSize = static_cast<unsigned int> (this->GetParameterInt("filter.meanshift.minsize")); - - const float - threshold = this->GetParameterFloat("filter.meanshift.thres"); - const unsigned int - maxIterNumber = static_cast<unsigned int> (this->GetParameterInt("filter.meanshift.maxiter")); - - meanShiftVectorizationFilter->GetSegmentationFilter()->SetSpatialBandwidth(spatialRadius); - meanShiftVectorizationFilter->GetSegmentationFilter()->SetRangeBandwidth(rangeRadius); - meanShiftVectorizationFilter->GetSegmentationFilter()->SetMaxIterationNumber(maxIterNumber); - meanShiftVectorizationFilter->GetSegmentationFilter()->SetThreshold(threshold); - meanShiftVectorizationFilter->GetSegmentationFilter()->SetMinRegionSize(minimumObjectSize); - - streamSize = this->GenericApplySegmentation<FloatVectorImageType,MeanShiftSegmentationFilterType>(meanShiftVectorizationFilter, this->GetParameterFloatVectorImage("in"), layer, 0); + ccVectorizationFilter->GetSegmentationFilter()->GetFunctor().SetExpression(GetParameterString("filter.cc.expr")); + streamSize = GenericApplySegmentation<FloatVectorImageType, ConnectedComponentSegmentationFilterType> ( + ccVectorizationFilter, + this->GetParameterFloatVectorImage( + "in"), + layer, 0); } - else if(segType == "watershed") - { - otbAppLogINFO(<<"Using watershed segmentation."<<std::endl); + else + if (segType == "edison") + { + otbAppLogINFO(<<"Use Edison Mean-shift segmentation."<<std::endl); + + //segmentation parameters + const unsigned int spatialRadius = static_cast<unsigned int> (this->GetParameterInt("filter.edison.spatialr")); + const float rangeRadius = static_cast<float> (this->GetParameterFloat("filter.edison.ranger")); + const unsigned int + minimumObjectSize = static_cast<unsigned int> (this->GetParameterInt("filter.edison.minsize")); + const float scale = this->GetParameterFloat("filter.edison.scale"); + + EdisontreamingVectorizedSegmentationOGRType::Pointer + edisonVectorizationFilter = EdisontreamingVectorizedSegmentationOGRType::New(); + + edisonVectorizationFilter->GetSegmentationFilter()->SetSpatialRadius(spatialRadius); + edisonVectorizationFilter->GetSegmentationFilter()->SetRangeRadius(rangeRadius); + edisonVectorizationFilter->GetSegmentationFilter()->SetMinimumRegionSize(minimumObjectSize); + edisonVectorizationFilter->GetSegmentationFilter()->SetScale(scale); + + streamSize = GenericApplySegmentation<FloatVectorImageType, EdisonSegmentationFilterType> ( + edisonVectorizationFilter, + this->GetParameterFloatVectorImage( + "in"), + layer, 2); + } + else + if (segType == "meanshift") + { + otbAppLogINFO(<<"Use threaded Mean-shift segmentation."<<std::endl); + + MeanShiftVectorizedSegmentationOGRType::Pointer + meanShiftVectorizationFilter = MeanShiftVectorizedSegmentationOGRType::New(); + + //segmentation parameters + const unsigned int + spatialRadius = static_cast<unsigned int> (this->GetParameterInt("filter.meanshift.spatialr")); + const float rangeRadius = static_cast<float> (this->GetParameterFloat("filter.meanshift.ranger")); + const unsigned int + minimumObjectSize = static_cast<unsigned int> (this->GetParameterInt("filter.meanshift.minsize")); + + const float threshold = this->GetParameterFloat("filter.meanshift.thres"); + const unsigned int + maxIterNumber = static_cast<unsigned int> (this->GetParameterInt("filter.meanshift.maxiter")); + + meanShiftVectorizationFilter->GetSegmentationFilter()->SetSpatialBandwidth(spatialRadius); + meanShiftVectorizationFilter->GetSegmentationFilter()->SetRangeBandwidth(rangeRadius); + meanShiftVectorizationFilter->GetSegmentationFilter()->SetMaxIterationNumber(maxIterNumber); + meanShiftVectorizationFilter->GetSegmentationFilter()->SetThreshold(threshold); + meanShiftVectorizationFilter->GetSegmentationFilter()->SetMinRegionSize(minimumObjectSize); + + streamSize = this->GenericApplySegmentation<FloatVectorImageType, MeanShiftSegmentationFilterType> ( + meanShiftVectorizationFilter, + this->GetParameterFloatVectorImage( + "in"), + layer, 0); + } + else + if (segType == "watershed") + { + otbAppLogINFO(<<"Using watershed segmentation."<<std::endl); - AmplitudeFilterType::Pointer amplitudeFilter = AmplitudeFilterType::New(); + AmplitudeFilterType::Pointer amplitudeFilter = AmplitudeFilterType::New(); - amplitudeFilter->SetInput(this->GetParameterFloatVectorImage("in")); + amplitudeFilter->SetInput(this->GetParameterFloatVectorImage("in")); - GradientMagnitudeFilterType::Pointer gradientMagnitudeFilter = GradientMagnitudeFilterType::New(); - gradientMagnitudeFilter->SetInput(amplitudeFilter->GetOutput()); + GradientMagnitudeFilterType::Pointer gradientMagnitudeFilter = GradientMagnitudeFilterType::New(); + gradientMagnitudeFilter->SetInput(amplitudeFilter->GetOutput()); - StreamingVectorizedWatershedFilterType::Pointer watershedVectorizedFilter = StreamingVectorizedWatershedFilterType::New(); + StreamingVectorizedWatershedFilterType::Pointer + watershedVectorizedFilter = StreamingVectorizedWatershedFilterType::New(); - watershedVectorizedFilter->GetSegmentationFilter()->SetThreshold(GetParameterFloat("filter.watershed.threshold")); - watershedVectorizedFilter->GetSegmentationFilter()->SetLevel(GetParameterFloat("filter.watershed.level")); + watershedVectorizedFilter->GetSegmentationFilter()->SetThreshold( + GetParameterFloat( + "filter.watershed.threshold")); + watershedVectorizedFilter->GetSegmentationFilter()->SetLevel(GetParameterFloat("filter.watershed.level")); - streamSize = this->GenericApplySegmentation<FloatImageType,WatershedSegmentationFilterType>(watershedVectorizedFilter,gradientMagnitudeFilter->GetOutput(), layer,0); - } - else - { - otbAppLogFATAL(<<"non defined filtering method "<<GetParameterInt("filter")<<std::endl); - } + streamSize = this->GenericApplySegmentation<FloatImageType, WatershedSegmentationFilterType> ( + watershedVectorizedFilter, + gradientMagnitudeFilter->GetOutput(), + layer, 0); + } + else + { + otbAppLogFATAL(<<"non defined filtering method "<<GetParameterInt("filter")<<std::endl); + } - if (segModeType == "vector" ) + if (segModeType == "vector") { ogrDS->SyncToDisk(); // Stitching mode - if(IsParameterEnabled("mode.vector.stitch")) + if (IsParameterEnabled("mode.vector.stitch")) { otbAppLogINFO(<<"Segmentation done, stiching polygons ..."); -- GitLab