TestSetGenerator.cpp
Go to the documentation of this file.
1 
19 
21 
22 TestSetGenerator::TestSetGenerator(boost::shared_ptr<AbstractTopologyEvaluator> pEvaluator, boost::shared_ptr<SceneModel::Topology> pFullyMeshedTopology, const std::vector<std::string>& pObjectTypes):
23  mEvaluator(pEvaluator), mFullyMeshedTopology(pFullyMeshedTopology), mTypes(pObjectTypes),
24  mPrintHelper('+')
25 {
26  ros::NodeHandle nodeHandle("~");
27 
28  // Try to get the valid test set source database filename:
29  if(!nodeHandle.getParam("valid_test_set_db_filename", mValidTestSetDbFilename))
30  throw std::runtime_error("Please specifiy parameter valid_test_set_db_filename when starting this node.");
31  // Try to get the invalid test set source database filename:
32  if(!nodeHandle.getParam("invalid_test_set_db_filename", mInvalidTestSetDbFilename))
33  throw std::runtime_error("Please specifiy parameter invalid_test_set_db_filename when starting this node.");
34  // Try to get the valid test set target database filename:
35  if(!nodeHandle.getParam("write_valid_test_sets_filename", mWriteValidTestSetsFilename))
36  throw std::runtime_error("Please specifiy parameter write_valid_test_sets_filename when starting this node.");
37  // Try to get the invalid test set target database filename:
38  if(!nodeHandle.getParam("write_invalid_test_sets_filename", mWriteInvalidTestSetsFilename))
39  throw std::runtime_error("Please specifiy parameter write_invalid_test_sets_filename when starting this node.");
40 
41  // Try to get the probability for each object that, in a newly generated test set, this object is missing.
42  if(!nodeHandle.getParam("object_missing_in_test_set_probability", mObjectMissingInTestSetProbability))
43  throw std::runtime_error("Please specify parameter object_missing_in_test_set_probability when starting this node.");
44 }
45 
47 { }
48 
49 void TestSetGenerator::generateTestSets(std::vector<boost::shared_ptr<ISM::ObjectSet>> pExamplesList, unsigned int pTestSetCount)
50 {
51  mSceneId = pExamplesList[0]->mIdentifier;
52 
53  // if the file names are empty: generate new test sets.
55  {
56  std::vector<boost::shared_ptr<TestSet>> randomTestSets = generateRandomSets(pExamplesList, pTestSetCount);
57 
58  // if requested, simulate occlusion:
60  randomTestSets = simulateOcclusion(randomTestSets);
61 
62  validateSets(randomTestSets);
63 
68  }
69  else // get the test sets from the databases. Might be more than pTestSetCount.
70  {
73  }
74 
75  mEvaluator->setValidTestSets(mValidTestSets); // update with newfound valid test sets
76  mEvaluator->setInvalidTestSets(mInvalidTestSets); // initialize properly
77 }
78 
80 {
81  // Use fully meshed topology to calculate probabilities:
82  // set all tests as valid (so that fully meshed topology, which cannot have false positives, gets its evaluation result set already)
83  mEvaluator->setValidTestSets(pTestSets);
84  mEvaluator->setInvalidTestSets(std::vector<boost::shared_ptr<TestSet>>());
85  double recognitionThreshold = mEvaluator->getRecognitionThreshold(); // save actual recognition threshold.
86  mEvaluator->setRecognitionThreshold(-1); // so every test set gets recognized
87 
88  ROS_INFO_STREAM("Recognizing test sets with fully meshed topology.");
89  mEvaluator->evaluate(mFullyMeshedTopology, true);
90  if (mFullyMeshedTopology->getFalsePositives() != 0)
91  throw std::runtime_error("In TestSetGenerator::validateSets(): Error when evaluating fully meshed topology: has false positives, should have none");
92 
93  if (!mEvaluator->getInvalidTestSets().empty())
94  throw std::runtime_error("In TestSetGenerator::validateSets(): Error when evaluating fully meshed topology: found invalid test sets when those should not have been initialized yet.");
95 
96  double maxProbability = 0;
97  double minProbability = 2; // Minumum probability greater than zero. Set higher than possible maximum so it will be lowered in each case, and if invalid probability 2 is returned, this indicates that no probability > 0 was found.
98  unsigned int zeroSets = 0;
99  for (boost::shared_ptr<TestSet> testSet: pTestSets)
100  {
101  double probability = testSet->getFullyMeshedProbability();
102  if (probability > maxProbability) maxProbability = probability;
103  if (probability == 0) zeroSets++;
104  else if (probability < minProbability) minProbability = probability; // set lowest non-zero probability as new minimum
105  }
106 
107  std::vector<boost::shared_ptr<TestSet>> validTestSets;
108  std::vector<boost::shared_ptr<TestSet>> invalidTestSets;
109 
110  for (unsigned int i = 0; i < pTestSets.size(); i++)
111  {
112  if (pTestSets[i]->getFullyMeshedProbability() > recognitionThreshold)
113  validTestSets.push_back(pTestSets[i]);
114  else invalidTestSets.push_back(pTestSets[i]);
115  }
116 
117  mPrintHelper.addLine("Test set creation complete.");
118  mPrintHelper.addLine("Maximum probability: " + boost::lexical_cast<std::string>(maxProbability));
119  if (minProbability == 2)
120  minProbability = std::numeric_limits<double>::quiet_NaN();
121  mPrintHelper.addLine("Minimum probability greater than zero: " + boost::lexical_cast<std::string>(minProbability));
122  mPrintHelper.addLine("Recognition threshold: " + boost::lexical_cast<std::string>(recognitionThreshold));
123  mPrintHelper.addLine("Found " + boost::lexical_cast<std::string>(validTestSets.size()) + " valid and " + boost::lexical_cast<std::string>(invalidTestSets.size()) + " invalid test sets.");
124  mPrintHelper.addLine(boost::lexical_cast<std::string>(zeroSets) + " test sets have probability 0.");
126 
127  mEvaluator->setRecognitionThreshold(recognitionThreshold); // set actual recognition threshold again
128 
129  mValidTestSets = validTestSets;
130  mInvalidTestSets = invalidTestSets;
131 }
132 
133 void TestSetGenerator::setPoseOfObjectRelativeToReference(ISM::ObjectPtr pObject, ISM::ObjectPtr pReference)
134 {
135  ISM::PosePtr newPose;
136  pObject->pose->convertPoseIntoFrame(pReference->pose, newPose);
137  pObject->pose = newPose;
138 }
139 
140 std::vector<boost::shared_ptr<TestSet>> TestSetGenerator::loadTestSetsFromFile(const std::string& pFilename)
141 {
142  ROS_INFO_STREAM("Loading test sets from file " << pFilename);
143  // compare ISM CombinatorialTrainer
144  try
145  {
146  std::vector<boost::shared_ptr<TestSet>> testSets;
147 
148  ISM::TableHelperPtr localTableHelper(new ISM::TableHelper(pFilename));
149  std::vector<std::string> patternNames = localTableHelper->getRecordedPatternNames();
150  if (std::find(patternNames.begin(), patternNames.end(), mSceneId) == patternNames.end())
151  ROS_INFO_STREAM("In TestSetGenerator::loadTestSetsFromFile(" << pFilename + "): scene id " << mSceneId << " is not a valid pattern in the database.");
152  else {
153  std::vector<ISM::ObjectSetPtr> loadedTestSets;
154  loadedTestSets = localTableHelper->getRecordedPattern(mSceneId)->objectSets;
155 
156  for (ISM::ObjectSetPtr loadedTestSet: loadedTestSets)
157  {
158  boost::shared_ptr<TestSet> testSet(new TestSet());
159  for (ISM::ObjectPtr object: loadedTestSet->objects)
160  testSet->mObjectSet->insert(object);
161  testSets.push_back(testSet);
162  }
163  }
164  ROS_INFO_STREAM("Loaded " << testSets.size() << " test sets.");
165 
166  return testSets;
167  }
168  catch (soci::soci_error& e)
169  {
170  throw std::runtime_error("In TestSetGenerator::loadTestSetsFromFile(): soci error while trying to write to database file.\nProbably the file path does not exist.");
171  }
172 }
173 
174 void TestSetGenerator::writeTestSetsToFile(const std::string& pFilename, const std::vector<boost::shared_ptr<TestSet>>& pTestSets)
175 {
176  ROS_INFO_STREAM("Writing test sets to file " << pFilename);
177  if (!pTestSets.empty())
178  {
179  try
180  {
181  ISM::TableHelperPtr localTableHelper(new ISM::TableHelper(pFilename));
182  localTableHelper->createTablesIfNecessary();
183  localTableHelper->insertRecordedPattern(mSceneId);
184  for (boost::shared_ptr<TestSet> testSet: pTestSets)
185  localTableHelper->insertRecordedObjectSet(testSet->mObjectSet, mSceneId);
186  }
187  catch (soci::soci_error& e)
188  {
189  throw std::runtime_error("In TestSetGenerator::writeTestSetsToFile(): soci error while trying to write to database file " + pFilename
190  + "\nProbably the file path does not exist.");
191  }
192  }
193  ROS_INFO_STREAM("Wrote " << pTestSets.size() << " test sets.");
194 }
195 
196 std::vector<boost::shared_ptr<TestSet>> TestSetGenerator::simulateOcclusion(std::vector<boost::shared_ptr<TestSet>> pCompleteTestSets)
197 {
199  return pCompleteTestSets;
200 
201  ROS_INFO_STREAM("Simulating occlusion by removing random object observations from test sets.");
202 
203  unsigned int removed = 0;
204 
205  std::random_device rd;
206  boost::mt19937 eng; // Mersenne Twister
207  eng.seed(rd());
208  boost::uniform_int<> dist(0,RAND_MAX); // Normal Distribution
209  boost::variate_generator<boost::mt19937,boost::uniform_int<>> gen(eng,dist); // Variate generator
210 
211  if (mObjectMissingInTestSetProbability < 0 || mObjectMissingInTestSetProbability > 1)
212  throw std::runtime_error("parameter object_missing_in_test_set_probability should be in interval [0,1].");
213 
214  for (boost::shared_ptr<TestSet> testSet: pCompleteTestSets)
215  {
216  // The first object in each test set is treated as the reference object, which is not allowed to be occluded, so i starts at 1.
217  // This also prevents empty test sets.
218  unsigned int i = 1;
219  unsigned int occurs;
220 
221  while (i < testSet->mObjectSet->objects.size())
222  {
223  occurs = gen() % (int) ((double) 1.0 / mObjectMissingInTestSetProbability); // only with a certain probability: object i occurs
224 
225  if (occurs != 0) // if object i does occur, move to next one
226  i++;
227  else
228  {
229  testSet->mObjectSet->objects.erase(testSet->mObjectSet->objects.begin() + i); // otherwise erase it from test set.
230  removed++;
231  }
232  }
233  }
234  ROS_INFO_STREAM("Removed " << removed << " object observations.");
235  return pCompleteTestSets;
236 }
237 
238 }
std::vector< boost::shared_ptr< TestSet > > mValidTestSets
std::vector< boost::shared_ptr< TestSet > > simulateOcclusion(std::vector< boost::shared_ptr< TestSet >> pCompleteTestSets)
boost::shared_ptr< SceneModel::Topology > mFullyMeshedTopology
bool find(const std::vector< double > &in, double toFind)
Definition: validator.cpp:128
void setPoseOfObjectRelativeToReference(ISM::ObjectPtr pObject, ISM::ObjectPtr pReference)
void generateTestSets(std::vector< boost::shared_ptr< ISM::ObjectSet >> pExamplesList, unsigned int pTestSetCount)
void addLine(const std::string &pLine)
Definition: PrintHelper.h:48
void validateSets(std::vector< boost::shared_ptr< TestSet >> pTestSets)
TestSetGenerator(boost::shared_ptr< AbstractTopologyEvaluator > pEvaluator, boost::shared_ptr< SceneModel::Topology > pFullyMeshedTopology, const std::vector< std::string > &pObjectTypes)
void writeTestSetsToFile(const std::string &pFilename, const std::vector< boost::shared_ptr< TestSet >> &pTestSets)
double recognitionThreshold
#define ROS_INFO_STREAM(args)
std::vector< std::string > testSets
bool getParam(const std::string &key, std::string &s) const
boost::shared_ptr< AbstractTopologyEvaluator > mEvaluator
std::vector< boost::shared_ptr< TestSet > > loadTestSetsFromFile(const std::string &pFilename)
std::vector< boost::shared_ptr< TestSet > > mInvalidTestSets
virtual std::vector< boost::shared_ptr< TestSet > > generateRandomSets(std::vector< boost::shared_ptr< ISM::ObjectSet >> pExamplesList, unsigned int pTestSetCount)=0


asr_psm
Author(s): Braun Kai, Gehrung Joachim, Heizmann Heinrich, Meißner Pascal
autogenerated on Fri Nov 15 2019 04:00:08