SimpleHoughClusterer.cpp
Go to the documentation of this file.
00001 /*******************************************************************************
00002  *  SimpleHoughClusterer.cpp
00003  *
00004  *  (C) 2007 AG Aktives Sehen <agas@uni-koblenz.de>
00005  *           Universitaet Koblenz-Landau
00006  *
00007  *  Additional information:
00008  *  $Id: $
00009  *******************************************************************************/
00010 
00011 #include "SimpleHoughClusterer.h"
00012 
00013 #include "Workers/Math/vec2.h"
00014 
00015 #include <assert.h>
00016 #include <map>
00017 #include <list>
00018 #include <math.h>
00019 
00020 using namespace std;
00021 
00022 #define THIS SimpleHoughClusterer
00023 
00024 THIS::THIS ( vector< KeyPoint >* keyPoints1, vector< KeyPoint >* keyPoints2, std::list< KeyPointMatch >& matches )
00025 {
00026     m_KeyPoints1 = keyPoints1;
00027     m_KeyPoints2 = keyPoints2;
00028     m_Matches = matches;
00029     m_Log << "SimpleHoughClusterer created\n";
00030     m_Log << "Number of keypoints (scenePoints/objectImagePoints): " << m_KeyPoints1->size() << " / " << m_KeyPoints2->size() << endl;
00031 }
00032 
00033 
00034 THIS::~THIS()
00035 {
00036 }
00037 
00038 
00039 void THIS::eliminateByOrientation ( )
00040 {
00041     m_Log << endl << "-------- Orientation based elimination -----------" << endl;
00042 
00043     int numBins=80;
00044     int windowSize=numBins/16;
00045 
00046     //Turn Angle histogram
00047     vector<double> hist;
00048     hist.assign ( numBins, 0 );
00049 
00050     std::list<KeyPointMatch>::iterator currentMatch=m_Matches.begin();
00051     while ( currentMatch != m_Matches.end() )
00052     {
00053         hist[ int ( ( currentMatch->turnAngle+M_PI ) /M_PI/2.0 * numBins ) % numBins ]++;
00054         currentMatch++;
00055     }
00056 
00057     vector<bool> deleteMap=computeDeleteMap( hist, numBins, windowSize);
00058 
00059     //Delete
00060     currentMatch=m_Matches.begin();
00061     while ( currentMatch != m_Matches.end() )
00062     {
00063         int index=int ( ( currentMatch->turnAngle+M_PI ) /M_PI/2.0 * numBins ) % numBins;
00064         //non-max
00065         if ( deleteMap[ index ] )
00066         {
00067             m_Log << "deleting: " << currentMatch->turnAngle/M_PI*180.0 << "deg " << hist[ index ] << "hist";
00068             currentMatch = m_Matches.erase ( currentMatch );
00069         }
00070         else
00071         {
00072             currentMatch++;
00073         }
00074     }
00075 
00076     m_Log << "\nTurn angles: ";
00077     currentMatch=m_Matches.begin();
00078     while ( currentMatch != m_Matches.end() )
00079     {
00080         m_Log << currentMatch->turnAngle << " ";
00081         currentMatch++;
00082     }
00083     m_Log << "\n--- " << m_Matches.size() << " remaining after orientation based elimination.\n";
00084     m_Log << endl;
00085 }
00086 
00087 
00088 void THIS::eliminateByScale ( )
00089 {
00090     m_Log << endl << "-------- Scale based elimination -----------" << endl;
00091 
00092     int numBins=150;
00093     int windowSize=numBins/15;
00094     int maxOctaves=5;
00095 
00096     //scale quotient histogram
00097     vector<double> hist;
00098     hist.assign ( numBins, 0 );
00099 
00100     std::list<KeyPointMatch>::iterator currentMatch=m_Matches.begin();
00101     while ( currentMatch != m_Matches.end() )
00102     {
00103         int index = ( log2( currentMatch->scaleQuotient ) / (maxOctaves-1) / 2 + 0.5 ) * numBins;
00104         if ( index >= numBins ) { index=numBins-1; }
00105         if ( index < 0 ) { index=0; }
00106 
00107         hist[ index ]++;
00108         currentMatch++;
00109     }
00110 
00111     vector<bool> deleteMap=computeDeleteMap( hist, numBins, windowSize);
00112 
00113     //Delete
00114     currentMatch=m_Matches.begin();
00115     while ( currentMatch != m_Matches.end() )
00116     {
00117         int index = ( log2( currentMatch->scaleQuotient ) / maxOctaves / 2 + 0.5 ) * numBins;
00118         if ( index >= numBins ) { index=numBins-1; }
00119         if ( index < 0 ) { index=0; }
00120 
00121         //non-max
00122         if ( deleteMap[ index ] )
00123         {
00124             m_Log << "deleting: scale quotient=" << currentMatch->scaleQuotient << " log=" << log2(currentMatch->scaleQuotient) << "  histogram entry=" << hist[ index ];
00125             currentMatch = m_Matches.erase ( currentMatch );
00126         }
00127         else
00128         {
00129             currentMatch++;
00130         }
00131     }
00132 
00133     m_Log << "\nScale quotients: ";
00134     currentMatch=m_Matches.begin();
00135     while ( currentMatch != m_Matches.end() )
00136     {
00137         m_Log << currentMatch->scaleQuotient << " ";
00138         currentMatch++;
00139     }
00140     m_Log << "\n--- " << m_Matches.size() << " remaining after scale based elimination:\n";
00141 }
00142 
00143 void THIS::eliminateByPosition ( float maxDistance )
00144 {
00145     float turnAngle = getMeanTurnAngle();
00146     float scaleChange = getMeanScaleQuotient();
00147     Point2D sourceCenter;
00148     Point2D targetCenter;
00149 
00150     bool outlierFound = true;
00151 
00152     while ( outlierFound )
00153     {
00154       getCenters ( targetCenter, sourceCenter );
00155 
00156       outlierFound = false;
00157 
00158       std::list<KeyPointMatch>::iterator currentMatch=m_Matches.begin();
00159       while ( currentMatch != m_Matches.end() )
00160       {
00161           Point2D position1 = (*m_KeyPoints1)[ currentMatch->index1 ].position();
00162           Point2D position2 = (*m_KeyPoints2)[ currentMatch->index2 ].position();
00163 
00164           position2 -= sourceCenter.toVector();
00165           position2.rotate ( turnAngle );
00166           position2 *= scaleChange;
00167           position2 += targetCenter.toVector();
00168 
00169           float distance = position1.distance ( position2 );
00170           float meanScale = ( (*m_KeyPoints1)[ currentMatch->index1 ].scale+ (*m_KeyPoints2)[ currentMatch->index2 ].scale) / 2.0;
00171           distance /= meanScale;
00172 
00173           if ( distance > maxDistance )
00174           {
00175               m_Log << " deleting " << currentMatch->index1 << "->" << currentMatch->index2 << "(" << distance << ")  ";
00176               currentMatch = m_Matches.erase ( currentMatch );
00177               outlierFound = true;
00178           }
00179           else
00180           {
00181               currentMatch++;
00182           }
00183       }
00184     }
00185     m_Log << "\n--- " << m_Matches.size() << " remaining after position based elimination:\n";
00186 }
00187 
00188 
00189 vector<bool> THIS::computeDeleteMap( vector<double> hist, int numBins, int windowSize )
00190 {
00191   m_Log << "original histogram: ";
00192   for ( int i=0; i<numBins; i++ )
00193   {
00194     m_Log << hist[i] << " ";
00195   }
00196   m_Log << endl;
00197 
00198     //calc sliding window mean
00199   float windowSum=0;
00200   vector<double> hist2=hist;
00201   for ( int i=0; i<windowSize; i++ )
00202   {
00203         //cout << i << " ";
00204     windowSum+=hist2[i];
00205   }
00206   for ( int i=0; i<numBins; i++ )
00207   {
00208     hist[ ( i+ ( windowSize/2 ) ) % numBins ]=windowSum;
00209     windowSum-=hist2[i];
00210     windowSum+=hist2[ ( i+windowSize ) % numBins ];
00211   }
00212 
00213   m_Log << "    mean histogram: ";
00214   for ( int i=0; i<numBins; i++ )
00215   {
00216     m_Log << hist[i] << " ";
00217   }
00218   m_Log << endl;
00219 
00220     //find max
00221   float max=0;
00222   for ( int i=0; i<numBins; i++ )
00223   {
00224     if ( hist[i] > max ) max=hist[i];
00225   }
00226   m_Log << "           maximum: " << max << endl;
00227 
00228     //determine what to keep (elements which are near a maximum)
00229   vector<bool> deleteMap;
00230   deleteMap.assign ( numBins, true );
00231   for ( int i=0; i<numBins; i++ )
00232   {
00233     for ( int j=-windowSize/2; j<=windowSize/2; j++ )
00234     {
00235       if ( hist[ ( numBins+i+j ) %numBins] >= max )
00236       {
00237         deleteMap[i]=false;
00238         break;
00239       }
00240     }
00241   }
00242 
00243   m_Log << "            delete: ";
00244   for ( int i=0; i<numBins; i++ )
00245   {
00246     m_Log << deleteMap[i] << " ";
00247   }
00248   m_Log << endl;
00249   return deleteMap;
00250 }
00251 
00252 
00253 float THIS::getMeanTurnAngle() const
00254 {
00255     vector<float> turnAngles;
00256     turnAngles.reserve ( m_Matches.size() );
00257 
00258     std::list< KeyPointMatch >::const_iterator currentMatch=m_Matches.begin();
00259     while ( currentMatch != m_Matches.end() )
00260     {
00261         turnAngles.push_back ( currentMatch->turnAngle );
00262         currentMatch++;
00263     }
00264     float mean=Math::meanAngle ( turnAngles );
00265     return mean;
00266 }
00267 
00268 
00269 float THIS::getMeanScaleQuotient() const
00270 {
00271     vector<float> scaleQuotients;
00272     scaleQuotients.reserve ( m_Matches.size() );
00273 
00274     std::list< KeyPointMatch >::const_iterator currentMatch=m_Matches.begin();
00275     while ( currentMatch != m_Matches.end() )
00276     {
00277         scaleQuotients.push_back ( currentMatch->scaleQuotient );
00278         currentMatch++;
00279     }
00280     float mean=Math::mean ( scaleQuotients );
00281     return mean;
00282 }
00283 
00284 
00285 void THIS::getCenters ( Point2D& center1, Point2D& center2 )
00286 {
00287   double numPoints = double ( m_Matches.size() );
00288 
00289   std::list< KeyPointMatch >::iterator currentMatch=m_Matches.begin();
00290   while ( currentMatch != m_Matches.end() )
00291   {
00292     unsigned index1 = currentMatch->index1;
00293     unsigned index2 = currentMatch->index2;
00294 
00295     center1 += (*m_KeyPoints1)[index1].position().toVector();
00296     center2 += (*m_KeyPoints2)[index2].position().toVector();
00297 
00298     currentMatch++;
00299   }
00300 
00301   center1 = Point2D ( center1.x() / numPoints, center1.y() / numPoints );
00302   center2 = Point2D ( center2.x() / numPoints, center2.y() / numPoints );
00303 }
00304 
00305 
00306 string THIS::getLog()
00307 {
00308   return m_Log.str();
00309 }
00310 
00311 
00312 #undef THIS


or_libs
Author(s): Viktor Seib
autogenerated on Tue Jan 7 2014 11:24:03