diff --git a/Code/ObjectDetection/otbLabeledSampleLocalizationGenerator.h b/Code/ObjectDetection/otbLabeledSampleLocalizationGenerator.h index 662cc16272138e68441d2581ed009c45d24cd195..76404b2b055ba058b118c3e65094c9926a6a76a4 100644 --- a/Code/ObjectDetection/otbLabeledSampleLocalizationGenerator.h +++ b/Code/ObjectDetection/otbLabeledSampleLocalizationGenerator.h @@ -33,15 +33,15 @@ namespace otb * This generator produces a unique vector data containing labeled positions * extracted from inputs. * - * Input points are transmited to the output. In addition, 'no class' + * Input points are transmitted to the output. In addition, 'no class' * points are randomly picked inside input polygons making sure * they are at least at a given distance (InhibitionRadius) of every * known points. * - * Classes are specified by the VectorData with a metadata identified by + * Classes are specified by the VectorData with a metadata field identified by * a specific key. This key can be provided by the SetClassKey() method * (using "Class" as a default key). - * Features associated with + * The field is retrieved by GetFieldAsInt(), thus must be int-compatible * */ template <class TVectorData> @@ -80,18 +80,28 @@ public: virtual void Update(); - /** Accessors */ + /** Field name containing the class identifier */ itkGetConstMacro(ClassKey, std::string); itkSetMacro(ClassKey, std::string); - itkGetConstMacro(NoClassIdentifier, std::string); - itkSetMacro(NoClassIdentifier, std::string); + + /** Identifier for the negative samples class */ + itkGetConstMacro(NoClassIdentifier, int); + itkSetMacro(NoClassIdentifier, int); + + /** The density of auto-generated negative samples inside the polygons */ itkGetConstMacro(RandomLocalizationDensity, double); itkSetMacro(RandomLocalizationDensity, double); + + /** The minimum distance between a generated negative sample and positive samples */ itkGetConstMacro(InhibitionRadius, double); itkSetMacro(InhibitionRadius, double); - itkGetConstMacro(PseudoRandom, bool); - itkSetMacro(PseudoRandom, bool); - + + /** Set the seed for random number generator */ + void SetSeed(unsigned int seed) + { + m_RandomGenerator->SetSeed(seed); + } + protected: LabeledSampleLocalizationGenerator(); virtual ~LabeledSampleLocalizationGenerator() {} @@ -99,9 +109,7 @@ protected: /** Triggers the Computation of the sample list */ void GenerateData(void); - /** Create a dictionary containing all differente values of ClassKey - * field */ - void ClassKeyValuesCollector(); + PointVectorType RandomPointsGenerator(DataNodeType * node); private: @@ -111,13 +119,9 @@ private: RandomGeneratorType::Pointer m_RandomGenerator; std::string m_ClassKey; - std::vector<std::string> m_ClassKeyDictionary; - std::string m_NoClassIdentifier; + int m_NoClassIdentifier; double m_RandomLocalizationDensity; double m_InhibitionRadius; - - bool m_PseudoRandom; - }; } // end namespace otb diff --git a/Code/ObjectDetection/otbLabeledSampleLocalizationGenerator.txx b/Code/ObjectDetection/otbLabeledSampleLocalizationGenerator.txx index 1ace87b117db6eb7c381402f796b8ccea3b8909d..8dc611c9aef8d27f0c7c069f72f45cf7de11a28a 100644 --- a/Code/ObjectDetection/otbLabeledSampleLocalizationGenerator.txx +++ b/Code/ObjectDetection/otbLabeledSampleLocalizationGenerator.txx @@ -28,10 +28,9 @@ template<class TVectorData> LabeledSampleLocalizationGenerator<TVectorData> ::LabeledSampleLocalizationGenerator() : m_ClassKey("Class"), - m_NoClassIdentifier("NoClass"), + m_NoClassIdentifier(0), m_RandomLocalizationDensity(.05), - m_InhibitionRadius(5.0), - m_PseudoRandom(false) + m_InhibitionRadius(5.0) { this->SetNumberOfRequiredInputs(1); this->SetNumberOfRequiredOutputs(1); @@ -73,42 +72,6 @@ LabeledSampleLocalizationGenerator<TVectorData> return static_cast<const VectorDataType *>(this->Superclass::GetInput(idx)); } -template <class TVectorData> -void -LabeledSampleLocalizationGenerator<TVectorData> -::ClassKeyValuesCollector() -{ - unsigned int nbInputs = this->GetNumberOfInputs(); - - for (unsigned int i=0; i<nbInputs; i++) - { - typename VectorDataType::ConstPointer vectorData = static_cast<const VectorDataType *>(this->GetInput(i)); - - TreeIteratorType itVector(vectorData->GetDataTree()); - itVector.GoToBegin(); - while (!itVector.IsAtEnd()) - { - std::string tmpString; - if (itVector.Get()->IsPolygonFeature() || itVector.Get()->IsPointFeature()) - { - tmpString = itVector.Get()->GetFieldAsString(this->GetClassKey()); - - bool duplication = true; - for (unsigned j=0; j<m_ClassKeyDictionary.size(); j++) - { - duplication = duplication * (m_ClassKeyDictionary.at(j) != tmpString); - } - - if (duplication == true) - { - m_ClassKeyDictionary.push_back(tmpString); - } - } - ++itVector; - } - } -} - template <class TVectorData> typename LabeledSampleLocalizationGenerator<TVectorData> ::PointVectorType @@ -121,12 +84,6 @@ LabeledSampleLocalizationGenerator<TVectorData> // Euclidean distance typename EuclideanDistanceType::Pointer euclideanDistance = EuclideanDistanceType::New(); - // Enable 'pseudo randomness' - if (this->GetPseudoRandom()) - { - this->m_RandomGenerator->SetSeed((unsigned int)0); - } - // Gathering Information RegionType generatorRegion = node->GetPolygonExteriorRing()->GetBoundingRegion(); typename RegionType::SizeType generatorRegionSize = generatorRegion.GetSize(); @@ -229,8 +186,6 @@ LabeledSampleLocalizationGenerator<TVectorData> { unsigned int nbInputs = this->GetNumberOfInputs(); - this->ClassKeyValuesCollector(); - this->GetOutput(0)->SetMetaDataDictionary(this->GetInput(0)->GetMetaDataDictionary()); // Retrieving root node @@ -241,6 +196,7 @@ LabeledSampleLocalizationGenerator<TVectorData> // Adding the layer to the data tree this->GetOutput(0)->GetDataTree()->Add(document, root); + // Copy all point feature in output VectorData for (unsigned int i=0; i<nbInputs; i++) { typename VectorDataType::ConstPointer vectorData = static_cast<const VectorDataType *>(this->GetInput(i)); @@ -257,6 +213,8 @@ LabeledSampleLocalizationGenerator<TVectorData> } } + // Iterates through the polygon features and generates random point inside the polygon with + // the "NoClass" identifier for (unsigned int i=0; i<nbInputs; i++) { typename VectorDataType::ConstPointer vectorData = static_cast<const VectorDataType *>(this->GetInput(i)); @@ -275,7 +233,7 @@ LabeledSampleLocalizationGenerator<TVectorData> CurrentGeometry->SetNodeId("FEATURE_POINT"); CurrentGeometry->SetNodeType(otb::FEATURE_POINT); CurrentGeometry->SetPoint(*it); - CurrentGeometry->SetFieldAsString(this->GetClassKey(), this->GetNoClassIdentifier()); + CurrentGeometry->SetFieldAsInt(this->GetClassKey(), this->GetNoClassIdentifier()); this->GetOutput(0)->GetDataTree()->Add(CurrentGeometry, document); } } diff --git a/Testing/Code/ObjectDetection/otbLabeledSampleLocalizationGenerator.cxx b/Testing/Code/ObjectDetection/otbLabeledSampleLocalizationGenerator.cxx index a85607269a49003986a697c2e5676cff00a6ffa2..cac3d605d6f33d20da267f842e41d381fea8888e 100644 --- a/Testing/Code/ObjectDetection/otbLabeledSampleLocalizationGenerator.cxx +++ b/Testing/Code/ObjectDetection/otbLabeledSampleLocalizationGenerator.cxx @@ -63,7 +63,11 @@ int otbLabeledSampleLocalizationGenerator(int argc, char* argv[]) generator->PushBackInput(reader1->GetOutput()); generator->PushBackInput(reader2->GetOutput()); - generator->SetPseudoRandom(true); + generator->SetSeed(0); // enable reproducible random number sequence + generator->SetClassKey("Class"); + generator->SetNoClassIdentifier(0); + generator->SetInhibitionRadius(5); + generator->SetRandomLocalizationDensity(0.05); generator->Update();