00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "HoughClusterer.h"
00012
00013 #include "Architecture/Config/Config.h"
00014 #include "Architecture/Singleton/Clock.h"
00015 #include "HoughIndexCalculator.h"
00016 #include "Workers/Math/vec2.h"
00017
00018 #include <ros/ros.h>
00019 #include <algorithm>
00020 #include <assert.h>
00021 #include <map>
00022 #include <list>
00023 #include <math.h>
00024 #include <cstring>
00025
00026 #include <fstream>
00027
00028 using namespace std;
00029
00030 #define THIS HoughClusterer
00031
00032 THIS::THIS( vector< KeyPoint >* sceneKeyPoints, vector< KeyPoint >* objectImageKeyPoints, Point2D center, int imageWidth, int imageHeight)
00033 {
00034 m_Log << endl << "-------- Hough Transform Clustering -----------\n\n";
00035
00036 m_SceneKeyPoints = sceneKeyPoints;
00037
00038 m_ObjectImageKeyPoints = objectImageKeyPoints;
00039 m_Center = center;
00040
00041 m_ImageWidth = imageWidth;
00042 m_ImageHeight = imageHeight;
00043
00044
00045 m_ScaleBins = Config::getInt( "ObjectRecognition.HoughClustering.iScaleBins" );
00046 m_OrientationBins = Config::getInt( "ObjectRecognition.HoughClustering.iOrientationBins" );
00047 m_XLocationBins = Config::getInt( "ObjectRecognition.HoughClustering.iXLocationBins" );
00048 m_YLocationBins = Config::getInt( "ObjectRecognition.HoughClustering.iYLocationBins" );
00049
00050 m_Log << "HoughClusterer [" << m_ScaleBins<< "*"<< m_OrientationBins << "*"<< m_XLocationBins <<"*"<<m_YLocationBins<< "]"<< " created -> ";
00051
00052 int startTime = Clock::getInstance()->getTimestamp();
00053 m_HoughAccumulator = new HoughAccumulator();
00054 m_Log << "building accumulator took " << Clock::getInstance()->getTimestamp() - startTime << " ms \n\n";
00055 }
00056
00057
00058 void THIS::setNNMatches(std::list< KeyPointMatch > nnrMatches)
00059 {
00060 m_Log << "Filling accumulator with " << nnrMatches.size() << " matches \n";
00061
00062 int startTime = Clock::getInstance()->getTimestamp();
00063
00064 std::list< KeyPointMatch >::iterator it;
00065 it = nnrMatches.begin();
00066 while(it!=nnrMatches.end())
00067 {
00068 incrAccumulatorValue(m_SceneKeyPoints->at(it->index1), m_ObjectImageKeyPoints->at(it->index2),*it);
00069 ++it;
00070 }
00071
00072 m_Log << "-> filling accumulator took " << Clock::getInstance()->getTimestamp() - startTime << " ms \n\n";
00073 }
00074
00075 vector< std::list< KeyPointMatch> > THIS::clusterAccumulator()
00076 {
00077 m_Log << "Clustering Accumulator = " << "( + -> keep, - -> delete, x -> out of bounds -> index/value )\n\n";
00078
00079 int startTime = Clock::getInstance()->getTimestamp();
00080
00081 vector< std::list< KeyPointMatch> > newMatches;
00082
00083 if(Config::getInt( "ObjectRecognition.HoughClustering.iAccumulatorSearchStrategy")==0)
00084 {
00085 newMatches = m_HoughAccumulator->getClusteredMatches();
00086 }
00087 else
00088 {
00089 ROS_INFO_STREAM("Find maximum in accumulator");
00090 newMatches = m_HoughAccumulator->getMaximumMatches();
00091 }
00092
00093 m_Log << m_HoughAccumulator->getLog();
00094 m_Log << " -> clustering and re-filling took " << ( Clock::getInstance()->getTimestamp() - startTime ) << " ms \n\n";
00095 m_Log << "Number of clusters after hough clustering: " << newMatches.size() << endl;
00096
00097 startTime = Clock::getInstance()->getTimestamp();
00098 m_Log << "Sorting matches in descending order took " << ( Clock::getInstance()->getTimestamp() - startTime ) << " ms \n\n";
00099
00100 return newMatches;
00101 }
00102
00103 void THIS::incrAccumulatorValue(KeyPoint scenePoint, KeyPoint objectPoint, KeyPointMatch match)
00104 {
00105
00106
00107 int scaleIndexFloor;
00108 int scaleIndexCeil;
00109
00110 double scaleQuotient = scenePoint.scale/objectPoint.scale;
00111 HoughIndexCalculator::calculateScaleIndex(scaleQuotient, scaleIndexFloor, scaleIndexCeil);
00112
00113
00114
00115 int orientationFloor;
00116 int orientationCeil;
00117
00118 double orientationQuotient = Math::minTurnAngle(scenePoint.orientation, objectPoint.orientation);
00119 HoughIndexCalculator::calculateOrientationIndex(orientationQuotient, orientationFloor, orientationCeil);
00120
00121
00122
00123 int xDistanceFloor;
00124 int xDistanceCeil;
00125
00126 int yDistanceFloor;
00127 int yDistanceCeil;
00128
00129 HoughIndexCalculator::calculatePositionIndex(scenePoint, objectPoint, m_Center, m_ImageWidth, m_ImageHeight, xDistanceFloor, xDistanceCeil, yDistanceFloor, yDistanceCeil);
00130
00131
00132
00133
00134
00135 int successCounter = 0;
00136
00137 if(m_HoughAccumulator->incrAccumulatorValue(scaleIndexFloor,orientationFloor,xDistanceFloor,yDistanceFloor, match))
00138 successCounter++;
00139 if(m_HoughAccumulator->incrAccumulatorValue(scaleIndexFloor,orientationFloor,xDistanceFloor,yDistanceCeil, match))
00140 successCounter++;
00141 if(m_HoughAccumulator->incrAccumulatorValue(scaleIndexFloor,orientationFloor,xDistanceCeil,yDistanceFloor, match))
00142 successCounter++;
00143 if(m_HoughAccumulator->incrAccumulatorValue(scaleIndexFloor,orientationFloor,xDistanceCeil,yDistanceCeil, match))
00144 successCounter++;
00145 if(m_HoughAccumulator->incrAccumulatorValue(scaleIndexFloor,orientationCeil,xDistanceFloor,yDistanceFloor, match))
00146 successCounter++;
00147 if(m_HoughAccumulator->incrAccumulatorValue(scaleIndexFloor,orientationCeil,xDistanceFloor,yDistanceCeil, match))
00148 successCounter++;
00149 if(m_HoughAccumulator->incrAccumulatorValue(scaleIndexFloor,orientationCeil,xDistanceCeil,yDistanceFloor, match))
00150 successCounter++;
00151 if(m_HoughAccumulator->incrAccumulatorValue(scaleIndexFloor,orientationCeil,xDistanceCeil,yDistanceCeil, match))
00152 successCounter++;
00153 if(m_HoughAccumulator->incrAccumulatorValue(scaleIndexCeil,orientationFloor,xDistanceFloor,yDistanceFloor, match))
00154 successCounter++;
00155 if(m_HoughAccumulator->incrAccumulatorValue(scaleIndexCeil,orientationFloor,xDistanceFloor,yDistanceCeil, match))
00156 successCounter++;
00157 if(m_HoughAccumulator->incrAccumulatorValue(scaleIndexCeil,orientationFloor,xDistanceCeil,yDistanceFloor, match))
00158 successCounter++;
00159 if(m_HoughAccumulator->incrAccumulatorValue(scaleIndexCeil,orientationFloor,xDistanceCeil,yDistanceCeil, match))
00160 successCounter++;
00161 if(m_HoughAccumulator->incrAccumulatorValue(scaleIndexCeil,orientationCeil,xDistanceFloor,yDistanceFloor, match))
00162 successCounter++;
00163 if(m_HoughAccumulator->incrAccumulatorValue(scaleIndexCeil,orientationCeil,xDistanceFloor,yDistanceCeil, match))
00164 successCounter++;
00165 if(m_HoughAccumulator->incrAccumulatorValue(scaleIndexCeil,orientationCeil,xDistanceCeil,yDistanceFloor, match))
00166 successCounter++;
00167 if(m_HoughAccumulator->incrAccumulatorValue(scaleIndexCeil,orientationCeil,xDistanceCeil,yDistanceCeil, match))
00168 successCounter++;
00169
00170 if(successCounter==0)
00171 {
00172 m_Log << "Incrementing match at scale "<< scaleQuotient << " orientation " << orientationQuotient << " posX "<< scenePoint.x << " posY "<< scenePoint.y << " failed." << endl;
00173 }
00174 }
00175
00176 bool THIS::getAccumulatorValue(KeyPoint scenePoint, KeyPoint objectPoint, unsigned int& value)
00177 {
00178
00179
00180 int scaleIndexFloor;
00181 int scaleIndexCeil;
00182
00183 double scaleQuotient = scenePoint.scale/objectPoint.scale;
00184 HoughIndexCalculator::calculateScaleIndex(scaleQuotient, scaleIndexFloor, scaleIndexCeil);
00185
00186
00187
00188 int orientationFloor;
00189 int orientationCeil;
00190
00191 double orientationQuotient = Math::minTurnAngle(scenePoint.orientation, objectPoint.orientation);
00192 HoughIndexCalculator::calculateOrientationIndex(orientationQuotient, orientationFloor, orientationCeil);
00193
00194
00195
00196 int xDistanceFloor;
00197 int xDistanceCeil;
00198
00199 int yDistanceFloor;
00200 int yDistanceCeil;
00201
00202 HoughIndexCalculator::calculatePositionIndex(scenePoint, objectPoint, m_Center, m_ImageWidth, m_ImageHeight, xDistanceFloor, xDistanceCeil, yDistanceFloor, yDistanceCeil);
00203
00204 std::vector<int> accumulatorValues;
00205
00206 unsigned int val;
00207
00208 if(m_HoughAccumulator->getAccumulatorValue(scaleIndexFloor,orientationFloor,xDistanceFloor,yDistanceFloor,val))
00209 accumulatorValues.push_back(val);
00210
00211 if(m_HoughAccumulator->getAccumulatorValue(scaleIndexFloor,orientationFloor,xDistanceFloor,yDistanceFloor,val))
00212 accumulatorValues.push_back(val);
00213
00214 if(m_HoughAccumulator->getAccumulatorValue(scaleIndexFloor,orientationFloor,xDistanceFloor,yDistanceCeil,val))
00215 accumulatorValues.push_back(val);
00216
00217 if(m_HoughAccumulator->getAccumulatorValue(scaleIndexFloor,orientationFloor,xDistanceCeil,yDistanceFloor,val))
00218 accumulatorValues.push_back(val);
00219
00220 if(m_HoughAccumulator->getAccumulatorValue(scaleIndexFloor,orientationFloor,xDistanceCeil,yDistanceCeil,val))
00221 accumulatorValues.push_back(val);
00222
00223 if(m_HoughAccumulator->getAccumulatorValue(scaleIndexFloor,orientationCeil,xDistanceFloor,yDistanceFloor,val))
00224 accumulatorValues.push_back(val);
00225
00226 if(m_HoughAccumulator->getAccumulatorValue(scaleIndexFloor,orientationCeil,xDistanceFloor,yDistanceCeil,val))
00227 accumulatorValues.push_back(val);
00228
00229 if(m_HoughAccumulator->getAccumulatorValue(scaleIndexFloor,orientationCeil,xDistanceCeil,yDistanceFloor,val))
00230 accumulatorValues.push_back(val);
00231
00232 if(m_HoughAccumulator->getAccumulatorValue(scaleIndexFloor,orientationCeil,xDistanceCeil,yDistanceCeil,val))
00233 accumulatorValues.push_back(val);
00234
00235 if(m_HoughAccumulator->getAccumulatorValue(scaleIndexCeil,orientationFloor,xDistanceFloor,yDistanceFloor,val))
00236 accumulatorValues.push_back(val);
00237
00238 if(m_HoughAccumulator->getAccumulatorValue(scaleIndexCeil,orientationFloor,xDistanceFloor,yDistanceCeil,val))
00239 accumulatorValues.push_back(val);
00240
00241 if(m_HoughAccumulator->getAccumulatorValue(scaleIndexCeil,orientationFloor,xDistanceCeil,yDistanceFloor,val))
00242 accumulatorValues.push_back(val);
00243
00244 if(m_HoughAccumulator->getAccumulatorValue(scaleIndexCeil,orientationFloor,xDistanceCeil,yDistanceCeil,val))
00245 accumulatorValues.push_back(val);
00246
00247 if(m_HoughAccumulator->getAccumulatorValue(scaleIndexCeil,orientationCeil,xDistanceFloor,yDistanceFloor,val))
00248 accumulatorValues.push_back(val);
00249
00250 if(m_HoughAccumulator->getAccumulatorValue(scaleIndexCeil,orientationCeil,xDistanceFloor,yDistanceCeil,val))
00251 accumulatorValues.push_back(val);
00252
00253 if(m_HoughAccumulator->getAccumulatorValue(scaleIndexCeil,orientationCeil,xDistanceCeil,yDistanceFloor,val))
00254 accumulatorValues.push_back(val);
00255
00256 if(m_HoughAccumulator->getAccumulatorValue(scaleIndexCeil,orientationCeil,xDistanceCeil,yDistanceCeil,val))
00257 accumulatorValues.push_back(val);
00258
00259 if(accumulatorValues.size()==0)
00260 {
00261 value = 0;
00262 m_Log << "Reading match "<< scaleQuotient << " " << orientationQuotient << " "<< scenePoint.x << " "<< scenePoint.y << " failed. \n";
00263 return false;
00264 }
00265 else
00266 {
00267 value = *std::max_element(accumulatorValues.begin(), accumulatorValues.end());
00268 return true;
00269 }
00270 }
00271
00272 float THIS::getVariance()
00273 {
00274 return m_HoughAccumulator->getVariance();
00275 }
00276
00277 void THIS::getImage( cv::Mat& target )
00278 {
00279 m_HoughAccumulator->getImage(target);
00280 }
00281
00282
00283 string THIS::getLog()
00284 {
00285 return m_Log.str();
00286 }
00287
00288
00289 THIS::~THIS()
00290 {
00291 delete m_HoughAccumulator;
00292 }
00293
00294 #undef THIS