123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 |
- /**
- * @file LocalFeatureSift.cpp
- * @brief local feature with sift
- * @author Erik Rodner, Alexander Freytag
- * @date 03/10/2012
- */
- #include <iostream>
- #include "vislearning/features/localfeatures/sift.h"
- #include "vislearning/features/localfeatures/LocalFeatureSift.h"
- using namespace OBJREC;
- using namespace std;
- using namespace NICE;
- ///////////////////// ///////////////////// /////////////////////
- // CONSTRUCTORS / DESTRUCTORS
- ///////////////////// ///////////////////// /////////////////////
- LocalFeatureSift::LocalFeatureSift() : LocalFeature ()
- {
- this->octaves = 6;
- this->levels = 3;
- this->first_octave = -1;
- this->normalizeFeature = true;
- this->magnif = 3;
- this->deletemode = true;
- this->integerValues = true;
- this->usegpu = false;
- }
- LocalFeatureSift::LocalFeatureSift( const NICE::Config * _conf )
- {
- this->initFromConfig( _conf );
- }
- LocalFeatureSift::~LocalFeatureSift()
- {
- }
- void OBJREC::LocalFeatureSift::initFromConfig( const NICE::Config* _conf, const std::string& _confSection )
- {
- //NOTE previous confSection defaultet to LFSiftPP!
- this->octaves = _conf->gI(_confSection, "octaves", 6);
- this->levels = _conf->gI(_confSection, "levels", 3);
- this->first_octave = _conf->gI(_confSection, "first_octave", -1);
- this->normalizeFeature = _conf->gB(_confSection, "normalize_feature", true );
- this->magnif = _conf->gD(_confSection, "magnif", 3 );
- this->deletemode = _conf->gB(_confSection, "deletemode", true );
- this->integerValues = _conf->gB(_confSection, "integer_values", true );
- #ifdef NICE_USELIB_CUDASIFT
- this->usegpu = _conf->gB(_confSection, "use_siftgpu", false );
- #else
- this->usegpu = false;
- #endif
- }
- ///////////////////// ///////////////////// /////////////////////
- // FEATURE STUFF
- ///////////////////// ///////////////////// //////////////////
- void LocalFeatureSift::sortPositions(VVector & positions) const
- {
- // < Key , Val >
- map<double, bool> scales;
- for ( vector< NICE::Vector >::iterator i = positions.begin();
- i != positions.end();i++)
- {
- const NICE::Vector & pos = *i;
- scales[pos[2]] = true;
- }
- VVector newpositions;
- map<double,bool>::iterator iter;
- for ( iter = scales.begin(); iter != scales.end(); ++iter )
- {
- for ( vector< NICE::Vector >::iterator i = positions.begin();
- i != positions.end();i++)
- {
- const NICE::Vector & pos = *i;
- if (pos[2] == iter->first)
- {
- newpositions.push_back(pos);
- }
- }
- }
- positions = newpositions;
- }
- void LocalFeatureSift::computeDesc( const NICE::Image & img, VVector & positions, VVector & descriptors ) const
- {
- if ( usegpu ) {
- try {
- #ifdef NICE_USELIB_CUDASIFT
- withGPU( img, positions, descriptors );
- #endif
- }
- catch ( runtime_error& rte ) {
- cerr << "[err] LocalFeatureSift: " << rte.what() << endl;
- clog << "[log] use SIFTPP implementation:" << endl;
- withPP( img, positions, descriptors );
- }
- }
- else {
- withPP( img, positions, descriptors );
- }
- }
- int LocalFeatureSift::getDescriptors ( const NICE::Image & img, VVector & positions, VVector & descriptors ) const
- {
- sortPositions(positions);
- computeDesc(img, positions, descriptors);
- return 0;
- }
- void LocalFeatureSift::visualizeFeatures ( NICE::Image & mark, const VVector & positions, size_t color ) const
- {
- /* TODO: switch to NICE instead of ICE
- ice::Image mark_ice = ice::NewImg ( mark.width(),
- mark.height(), 255 );
- for ( size_t k = 0 ; k < positions.size() ; k++ )
- {
- const NICE::Vector & pos = positions[k];
- ice::Matrix points ( 0, 2 );
- const int size = 6;
- points.Append ( ice::Vector(-size, -size) );
- points.Append ( ice::Vector(-size, size) );
- points.Append ( ice::Vector(size, size) );
- points.Append ( ice::Vector(size, -size) );
- ice::Trafo tr;
- tr.Scale ( 0, 0, pos[2] );
- tr.Rotate ( 0, 0, pos[3] );
- tr.Shift ( pos[0], pos[1] );
- ice::TransformList(tr, points);
- for ( int j = 0 ; j < points.rows(); j++ )
- {
- if (points[j][0] < 0 )
- points[j][0] = 0;
- if (points[j][0] >= mark_ice->xsize)
- points[j][0] = mark_ice->xsize - 1;
- if (points[j][1] < 0 )
- points[j][1] = 0;
- if (points[j][1] >= mark_ice->ysize)
- points[j][1] = mark_ice->ysize - 1;
- }
- ice::DrawPolygon ( points, color, mark_ice );
- }
- for ( unsigned int y = 0 ; y < mark.height(); y++ )
- for ( unsigned int x = 0 ; x < mark.width(); x++ )
- mark.setPixel(x,y, GetVal(mark_ice,x,y));*/
- }
- void LocalFeatureSift::withPP( const NICE::Image & img, VVector & positions, VVector & descriptors ) const
- {
- int O = octaves ;
- int const S = levels ;
- int const omin = first_octave;
- float const sigman = .5 ; //.5
- float const sigma0 = 1.6 * powf(2.0f, 1.0f / S) ;
- if (O < 1)
- {
- O = std::max(int(std::floor(log2
- (std::min(img.width(),img.height()))) - omin - 3), 1) ;
- }
- const unsigned char *blockimg = (unsigned char*) img.getPixelPointer();
- float *blockimgfl = new float[img.width() * img.height()];
- for ( int k = 0 ; k < img.width() * img.height() ; k++ )
- blockimgfl[k] = blockimg[k];
- VL::Sift sift( blockimgfl, img.width(), img.height(),
- sigman, sigma0, O, S, omin, -1, S+1) ;
- //calling sift.process(.) already done in VL::Sift constructor, so omit the following process function
- //sift.process ( blockimgfl, img.width(), img.height() );
- sift.setMagnification ( magnif );
- sift.setNormalizeDescriptor ( normalizeFeature );
- const int descr_size = 128;
- VL::float_t *descr_pt = new VL::float_t [descr_size];
- VL::float_t angles[4] ;
- NICE::Vector feature (descr_size);
- NICE::Vector pos ( 4 );
- for ( vector< NICE::Vector >::iterator i = positions.begin();
- i != positions.end();)
- {
- const NICE::Vector & pos = *i;
- double x = pos[0];
- double y = pos[1];
- assert(pos[0] < img.width());
- assert(pos[1] < img.height());
- double s = pos[2];
- bool deleteFeature = false;
- VL::Sift::Keypoint kp = sift.getKeypoint (x,y,s);
- double angle = 0.0;
- if ( pos.size() < 4 )
- {
- int nangles = sift.computeKeypointOrientations(angles, kp);
- if ( nangles > 0 )
- {
- angle = angles[0];
- }
- else
- {
- if (deletemode)
- deleteFeature = true;
- else
- angle = 0;
- }
- }
- else
- {
- angle = pos[3];
- }
- if ( ! deleteFeature )
- {
- sift.computeKeypointDescriptor ( descr_pt, kp, angle );
- for ( int j = 0 ; j < descr_size ; j++ )
- // Umwandlung in Integer moegl.
- feature[j] = (integerValues ? (int)(512*descr_pt[j]) : descr_pt[j]);
- descriptors.push_back ( feature );
- i++;
- }
- else
- {
- i = positions.erase(i);
- }
- }
- delete [] blockimgfl;
- delete [] descr_pt;
- }
- #ifdef NICE_USELIB_CUDASIFT
- void LocalFeatureSift::withGPU(const NICE::Image& img, VVector& positions, VVector& descriptors) const
- {
- // fill the parameter for
- char* argv[] = {
- // First octave to detect DOG keypoints
- "-fo" , const_cast<char*> (StringTools::convertToString<int> (first_octave).c_str()),
- // Maximum number of Octaves
- "-no" , const_cast<char*> (StringTools::convertToString<int> (octaves).c_str()),
- // Number of DOG levels in an octave.
- "-d" , const_cast<char*> (StringTools::convertToString<int> (levels).c_str()),
- // Write unnormalized descriptor if specified.
- const_cast<char*> (normalizeFeature ? "" : "-unn"),
- // Descriptor grid size factor (magnif ??)
- "-dw" , const_cast<char*> (StringTools::convertToString<float> (magnif).c_str()),
- // verbose levels
- "-v", "0"
- };
- int argc = sizeof (argv) / sizeof (char*);
- // sift Instanz
- SiftGPU sift;
- // give parameter to sift
- sift.ParseParam (argc, argv);
- // check, whether siftgpu is full supported
- int support = sift.CreateContextGL();
- if( support != SiftGPU::SIFTGPU_FULL_SUPPORTED )
- throw runtime_error( "SiftGPU-support is not given by your device.");
- // set keypoints
- const int numberOfKeypoints = positions.size();
- SiftGPU::SiftKeypoint keys[numberOfKeypoints];
- // copy the NICEKeypoints into SiftKeypoints
- for (int i = 0; i < numberOfKeypoints; i++) {
- keys[i].x = positions[i][0];
- keys[i].y = positions[i][1];
- keys[i].s = positions[i][2];
- keys[i].o = positions[i][3];
- }
- sift.SetKeypointList (numberOfKeypoints, keys);
- // run SIFT
- const int imageWidth = img.width();
- const int imageHeight = img.height();
- const unsigned char* rawImageData = img.getPixelPointer();
- sift.RunSIFT (imageWidth, imageHeight, rawImageData, GL_LUMINANCE, GL_UNSIGNED_BYTE);
- // get descriptors
- const int descr_size = 128;
- const int numberOfDescriptors = sift.GetFeatureNum();
- float desc[descr_size * numberOfDescriptors];
- sift.GetFeatureVector (NULL, desc);
- Vector localDesc (descr_size);
- // copy the SiftDescriptors into NICEDescriptors
- for (int i = 0; i < numberOfDescriptors; i++) {
- for (int j = 0; j < descr_size; j++) {
- localDesc[j] = (integerValues ? (int) (512 * desc[i*descr_size+j]) : desc[i*descr_size+j]);
- }
- descriptors.push_back (localDesc);
- }
- }
- #endif
-
- ///////////////////// INTERFACE PERSISTENT /////////////////////
- // interface specific methods for store and restore
- ///////////////////// INTERFACE PERSISTENT /////////////////////
- void LocalFeatureSift::restore ( std::istream & is, int format )
- {
- //delete everything we knew so far...
- this->clear();
-
-
- if ( is.good() )
- {
-
- std::string tmp;
- is >> tmp; //class name
-
- if ( ! this->isStartTag( tmp, "LocalFeatureSift" ) )
- {
- std::cerr << " WARNING - attempt to restore LocalFeatureSift, but start flag " << tmp << " does not match! Aborting... " << std::endl;
- throw;
- }
-
- bool b_endOfBlock ( false ) ;
-
- while ( !b_endOfBlock )
- {
- is >> tmp; // start of block
-
- if ( this->isEndTag( tmp, "LocalFeatureSift" ) )
- {
- b_endOfBlock = true;
- continue;
- }
-
- tmp = this->removeStartTag ( tmp );
-
- if ( tmp.compare("octaves") == 0 )
- {
- is >> this->octaves;
- is >> tmp; // end of block
- tmp = this->removeEndTag ( tmp );
- }
- else if ( tmp.compare("levels") == 0 )
- {
- is >> this->levels;
- is >> tmp; // end of block
- tmp = this->removeEndTag ( tmp );
- }
- else if ( tmp.compare("first_octave") == 0 )
- {
- is >> this->first_octave;
- is >> tmp; // end of block
- tmp = this->removeEndTag ( tmp );
- }
- else if ( tmp.compare("normalizeFeature") == 0 )
- {
- is >> this->normalizeFeature;
- is >> tmp; // end of block
- tmp = this->removeEndTag ( tmp );
- }
- else if ( tmp.compare("magnif") == 0 )
- {
- is >> this->magnif;
- is >> tmp; // end of block
- tmp = this->removeEndTag ( tmp );
- }
- else if ( tmp.compare("deletemode") == 0 )
- {
- is >> this->deletemode;
- is >> tmp; // end of block
- tmp = this->removeEndTag ( tmp );
- }
- else if ( tmp.compare("integerValues") == 0 )
- {
- is >> this->integerValues;
- is >> tmp; // end of block
- tmp = this->removeEndTag ( tmp );
- }
- else if ( tmp.compare("usegpu") == 0 )
- {
- is >> this->usegpu;
- is >> tmp; // end of block
- tmp = this->removeEndTag ( tmp );
- }
- else
- {
- std::cerr << "WARNING -- unexpected LocalFeatureSift object -- " << tmp << " -- for restoration... aborting" << std::endl;
- throw;
- }
- }
- }
- else
- {
- std::cerr << "LocalFeatureSift::restore -- InStream not initialized - restoring not possible!" << std::endl;
- throw;
- }
- }
- void LocalFeatureSift::store ( std::ostream & os, int format ) const
- {
- if (os.good())
- {
- // show starting point
- os << this->createStartTag( "LocalFeatureSift" ) << std::endl;
-
- os << this->createStartTag( "octaves" ) << std::endl;
- os << this->octaves << std::endl;
- os << this->createEndTag( "octaves" ) << std::endl;
- os << this->createStartTag( "levels" ) << std::endl;
- os << this->levels << std::endl;
- os << this->createEndTag( "levels" ) << std::endl;
-
- os << this->createStartTag( "first_octave" ) << std::endl;
- os << this->first_octave << std::endl;
- os << this->createEndTag( "first_octave" ) << std::endl;
- os << this->createStartTag( "normalizeFeature" ) << std::endl;
- os << this->normalizeFeature << std::endl;
- os << this->createEndTag( "normalizeFeature" ) << std::endl;
-
- os << this->createStartTag( "magnif" ) << std::endl;
- os << this->magnif << std::endl;
- os << this->createEndTag( "magnif" ) << std::endl;
-
- os << this->createStartTag( "deletemode" ) << std::endl;
- os << this->deletemode << std::endl;
- os << this->createEndTag( "deletemode" ) << std::endl;
- os << this->createStartTag( "integerValues" ) << std::endl;
- os << this->integerValues << std::endl;
- os << this->createEndTag( "integerValues" ) << std::endl;
-
- os << this->createStartTag( "usegpu" ) << std::endl;
- os << this->usegpu << std::endl;
- os << this->createEndTag( "usegpu" ) << std::endl;
-
- // done
- os << this->createEndTag( "LocalFeatureSift" ) << std::endl;
- }
- else
- {
- std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
- }
- }
- void LocalFeatureSift::clear ()
- {
- }
|