123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- #include "FeatureLearningClusterBased.h"
- #include <iostream>
- #include <core/image/FilterT.h>
- #include <core/vector/VectorT.h>
- #include <vislearning/baselib/ICETools.h>
- //
- #include <vislearning/features/localfeatures/LFonHSG.h>
- #include <vislearning/features/localfeatures/LFColorSande.h>
- #include <vislearning/features/localfeatures/LFColorWeijer.h>
- #include <vislearning/features/localfeatures/LFReadCache.h>
- #include <vislearning/features/localfeatures/LFWriteCache.h>
- //
- #include <vislearning/math/cluster/KMeans.h>
- #include <vislearning/math/cluster/GMM.h>
- using namespace std;
- using namespace NICE;
- using namespace OBJREC;
- //**********************************************
- //
- // PROTECTED METHODS
- //
- //**********************************************
- void FeatureLearningClusterBased::extractFeaturesFromTrainingImages( const OBJREC::MultiDataset *_md, NICE::VVector & examplesTraining )
- {
- examplesTraining.clear();
-
- int numberOfTrainImage ( 0 );
-
- const LabeledSet *trainFiles = (*_md)["train"];
-
- //run over all training images
- LOOP_ALL_S( *trainFiles )
- {
- EACH_INFO( classno, info );
- std::string filename = info.img();
-
- NICE::ColorImage img( filename );
- if ( showTrainingImages )
- {
- showImage( img, "Input" );
- }
-
- //variables to store feature informatio
- NICE::VVector features;
- NICE::VVector cfeatures;
- NICE::VVector positions;
- //compute features
- Globals::setCurrentImgFN ( filename );
- if (featureExtractor == NULL)
- std::cerr << "feature Extractor is NULL" << std::endl;
- else
- featureExtractor->extractFeatures ( img, features, positions );
-
- //store feature information in larger data structure
- for ( NICE::VVector::iterator i = features.begin();
- i != features.end();
- i++)
- {
- //normalization :)
- i->normalizeL1();
- examplesTraining.push_back(*i);
- }
-
- //don't waste memory
- features.clear();
- positions.clear();
- numberOfTrainImage++;
- }//Loop over all training images
- }
- void FeatureLearningClusterBased::train ( const OBJREC::MultiDataset *_md )
- {
- //**********************************************
- //
- // EXTRACT FEATURES FROM TRAINING IMAGES
- //
- //**********************************************
-
- std::cerr << " EXTRACT FEATURES FROM TRAINING IMAGES" << std::endl;
-
- NICE::VVector examplesTraining;
- this->extractFeaturesFromTrainingImages( _md, examplesTraining );
-
- //**********************************************
- //
- // CLUSTER FEATURES FROM TRAINING IMAGES
- //
- // THIS GIVES US AN INITIAL CODEBOOK
- //
- //**********************************************
- std::cerr << " CLUSTER FEATURES FROM TRAINING IMAGES" << std::endl;
- //go, go, go...
- prototypes.clear();
- std::vector< double > weights;
- std::vector< int > assignment;
- clusterAlgo->cluster ( examplesTraining, prototypes, weights, assignment);
- weights.clear();
- assignment.clear();
- }
- //**********************************************
- //
- // PUBLIC METHODS
- //
- //**********************************************
- FeatureLearningClusterBased::FeatureLearningClusterBased ( const Config *_conf,
- const MultiDataset *_md, const std::string & _section )
- : FeatureLearningGeneric ( _conf )
- {
- this->section = _section;
-
-
- //feature stuff
- //! which OpponentSIFT implementation to use {NICE, VANDESANDE}
- std::string opSiftImpl;
- opSiftImpl = conf->gS ( "Descriptor", "implementation", "VANDESANDE" );
- //! read features?
- bool readfeat;
- readfeat = conf->gB ( "Descriptor", "read", true );
- //! write features?
- bool writefeat;
- writefeat = conf->gB ( "Descriptor", "write", true );
-
- showTrainingImages = conf->gB( section, "showTrainingImages", false );
-
-
- //! define the initial number of clusters our codebook shall contain
- initialNumberOfClusters = conf->gI(section, "initialNumberOfClusters", 10);
-
- //! define the clustering algorithm to be used
- std::string clusterAlgoString = conf->gS(section, "clusterAlgo", "kmeans");
-
- //! define the distance function to be used
- std::string distFunctionString = conf->gS(section, "distFunction", "euclidian");
-
-
- //**********************************************
- //
- // SET UP VARIABLES AND METHODS
- // - FEATURE TYPE
- // - CLUSTERING ALGO
- // - DISTANCE FUNCTION
- // - ...
- //
- //**********************************************
-
- std::cerr << " SET UP VARIABLES AND METHODS " << std::endl;
-
- // Welche Opponentsift Implementierung soll genutzt werden ?
- LocalFeatureRepresentation *cSIFT = NULL;
- LocalFeatureRepresentation *writeFeats = NULL;
- LocalFeatureRepresentation *readFeats = NULL;
- this->featureExtractor = NULL;
- if ( opSiftImpl == "NICE" )
- {
- cSIFT = new OBJREC::LFonHSG ( conf, "HSGtrain" );
- }
- else if ( opSiftImpl == "VANDESANDE" )
- {
- cSIFT = new OBJREC::LFColorSande ( conf, "LFColorSandeTrain" );
- }
- else
- {
- fthrow ( Exception, "feattype: %s not yet supported" << opSiftImpl );
- }
- this->featureExtractor = cSIFT;
-
- if ( writefeat )
- {
- // write the features to a file, if there isn't any to read
- writeFeats = new LFWriteCache ( conf, cSIFT );
- this->featureExtractor = writeFeats;
- }
- if ( readfeat )
- {
- // read the features from a file
- if ( writefeat )
- {
- readFeats = new LFReadCache ( conf, writeFeats, -1 );
- }
- else
- {
- readFeats = new LFReadCache ( conf, cSIFT, -1 );
- }
- this->featureExtractor = readFeats;
- }
-
- if (clusterAlgoString.compare("kmeans") == 0)
- {
- clusterAlgo = new OBJREC::KMeans(initialNumberOfClusters);
- }
- else if (clusterAlgoString.compare("GMM") == 0)
- {
- clusterAlgo = new OBJREC::GMM(conf, initialNumberOfClusters);
- }
- else
- {
- std::cerr << "Unknown cluster algorithm selected, use k-means instead" << std::endl;
- clusterAlgo = new OBJREC::KMeans(initialNumberOfClusters);
- }
-
- if (distFunctionString.compare("euclidian") == 0)
- {
- distFunction = new NICE::EuclidianDistance<double>();
- }
- else
- {
- std::cerr << "Unknown vector distance selected, use euclidian instead" << std::endl;
- distFunction = new NICE::EuclidianDistance<double>();
- }
-
- //run the training to initially compute a codebook and stuff like that
- this->train( _md );
-
- //only set feature stuff to NULL, deletion of the underlying object is done in the destructor
- if ( cSIFT != NULL )
- cSIFT = NULL;
- if ( writeFeats != NULL )
- writeFeats = NULL;
- if ( readFeats != NULL )
- readFeats = NULL ;
- }
- FeatureLearningClusterBased::~FeatureLearningClusterBased()
- {
- // clean-up
- if ( clusterAlgo != NULL )
- delete clusterAlgo;
- if ( distFunction != NULL )
- delete distFunction;
- if ( featureExtractor != NULL )
- delete featureExtractor;
- }
- void FeatureLearningClusterBased::learnNewFeatures ( OBJREC::CachedExample *_ce )
- {
- }
- void FeatureLearningClusterBased::evaluateCurrentCodebook ( const std::string & filename )
- {
- NICE::ColorImage img( filename );
- if ( showTrainingImages )
- {
- showImage( img, "Input" );
- }
-
- int xsize ( img.width() );
- int ysize ( img.height() );
-
- //variables to store feature information
- NICE::VVector features;
- NICE::VVector cfeatures;
- NICE::VVector positions;
- //compute features
- Globals::setCurrentImgFN ( filename );
- featureExtractor->extractFeatures ( img, features, positions );
-
- FloatImage noveltyImage ( xsize, ysize );
- noveltyImage.set ( 0.0 );
-
- double maxDist ( 0.0 );
-
- NICE::VVector::const_iterator posIt = positions.begin();
- //store feature information in larger data structure
- for ( NICE::VVector::iterator i = features.begin();
- i != features.end();
- i++, posIt++)
- {
- //normalization :)
- i->normalizeL1();
-
- //loop over codebook representatives
- double minDist ( std::numeric_limits<double>::max() );
- for (NICE::VVector::const_iterator it = prototypes.begin(); it != prototypes.end(); it++)
- {
- //compute distance
- double tmpDist ( distFunction->calculate(*i,*it) );
- if (tmpDist < minDist)
- minDist = tmpDist;
- }
-
- if (minDist > maxDist)
- maxDist = minDist;
- //take minimum distance and store in in a float image
-
- noveltyImage ( (*posIt)[0], (*posIt)[1] ) = minDist;
- }
-
- //gauss-filtering for nicer visualization
- FloatImage noveltyImageGaussFiltered ( xsize, ysize );
- float sigma ( 3.0 );
- FilterT<float, float, float> filter;
- filter.filterGaussSigmaApproximate ( noveltyImage, sigma, &noveltyImageGaussFiltered );
- std::cerr << "maximum distance of Training images: " << maxDist;
- //for suitable visualization of scores between zero (known) and one (unknown)
- // noveltyImageGaussFiltered( 0 , 0 ) = std::max<double>(maxDist, 1.0);
-
- //convert float to RGB
- NICE::ColorImage noveltyImageRGB ( xsize, ysize );
- ICETools::convertToRGB ( noveltyImageGaussFiltered, noveltyImageRGB );
- showImage(noveltyImageRGB, "Novelty Image");
- }
|