|
@@ -124,7 +124,7 @@ OBJREC::ClusterAlgorithm * setClusterAlgo( const Config * _conf )
|
|
|
{
|
|
|
std::string section ( "clusteringStuff" );
|
|
|
// define the initial number of clusters our codebook shall contain
|
|
|
- int initialNumberOfClusters = _conf->gI(section, "initialNumberOfClusters", 10);
|
|
|
+ int noClusters = _conf->gI(section, "noClusters", 10);
|
|
|
|
|
|
// define the clustering algorithm to be used
|
|
|
std::string clusterAlgoString = _conf->gS(section, "clusterAlgo", "kmeans");
|
|
@@ -133,15 +133,15 @@ OBJREC::ClusterAlgorithm * setClusterAlgo( const Config * _conf )
|
|
|
|
|
|
if (clusterAlgoString.compare("kmeans") == 0)
|
|
|
{
|
|
|
- clusterAlgo = new OBJREC::KMeans(initialNumberOfClusters);
|
|
|
+ clusterAlgo = new OBJREC::KMeans(noClusters);
|
|
|
}
|
|
|
else if (clusterAlgoString.compare("kmedian") == 0)
|
|
|
{
|
|
|
- clusterAlgo = new OBJREC::KMedian(initialNumberOfClusters);
|
|
|
+ clusterAlgo = new OBJREC::KMedian(noClusters);
|
|
|
}
|
|
|
else if (clusterAlgoString.compare("GMM") == 0)
|
|
|
{
|
|
|
- clusterAlgo = new OBJREC::GMM( _conf, initialNumberOfClusters );
|
|
|
+ clusterAlgo = new OBJREC::GMM( _conf, noClusters );
|
|
|
}
|
|
|
else if ( clusterAlgoString.compare("RandomClustering") == 0 )
|
|
|
{
|
|
@@ -195,17 +195,36 @@ int main( int argc, char **argv )
|
|
|
NICE::VVector featuresFromAllTrainingImages;
|
|
|
featuresFromAllTrainingImages.clear();
|
|
|
|
|
|
+ //determine how many training images we actually use to easily allocate the correct amount of memory afterwards
|
|
|
+ int numberOfTrainingImages ( 0 );
|
|
|
+ for(LabeledSet::const_iterator classIt = trainFiles->begin() ; classIt != trainFiles->end() ; classIt++)
|
|
|
+ {
|
|
|
+ numberOfTrainingImages += classIt->second.size();
|
|
|
+ std::cerr << "number of examples for this class: " << classIt->second.size() << std::endl;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
//okay, this is redundant - but I see no way to do it more easy right now...
|
|
|
- std::vector<NICE::VVector> featuresOfImages ( trainFiles->size() );
|
|
|
+ std::vector<NICE::VVector> featuresOfImages ( numberOfTrainingImages );
|
|
|
//this again is somehow redundant, but we need the labels lateron for easy access - change this to a better solution :)
|
|
|
- NICE::VectorT<int> labelsTrain ( trainFiles->size(), 0 );
|
|
|
+ NICE::VectorT<int> labelsTrain ( numberOfTrainingImages, 0 );
|
|
|
|
|
|
//TODO replace the nasty makro by a suitable for-loop to make it omp-ready (parallelization)
|
|
|
int imgCnt ( 0 );
|
|
|
- LOOP_ALL_S( *trainFiles )
|
|
|
+
|
|
|
+ // the corresponding nasty makro: LOOP_ALL_S( *trainFiles )
|
|
|
+ for(LabeledSet::const_iterator classIt = trainFiles->begin() ; classIt != trainFiles->end() ; classIt++)
|
|
|
{
|
|
|
- EACH_INFO( classno, info );
|
|
|
- std::string filename = info.img();
|
|
|
+ for ( std::vector<ImageInfo *>::const_iterator imgIt = classIt->second.begin();
|
|
|
+ imgIt != classIt->second.end();
|
|
|
+ imgIt++, imgCnt++
|
|
|
+ )
|
|
|
+ {
|
|
|
+ // the corresponding nasty makro: EACH_INFO( classno, info );
|
|
|
+ int classno ( classIt->first );
|
|
|
+ const ImageInfo imgInfo = *(*imgIt);
|
|
|
+
|
|
|
+ std::string filename = imgInfo.img();
|
|
|
|
|
|
NICE::ColorImage img( filename );
|
|
|
|
|
@@ -217,7 +236,7 @@ int main( int argc, char **argv )
|
|
|
|
|
|
Globals::setCurrentImgFN ( filename );
|
|
|
featureExtractor->extractFeatures ( img, features, positions );
|
|
|
-
|
|
|
+
|
|
|
//normalization :)
|
|
|
for ( NICE::VVector::iterator i = features.begin();
|
|
|
i != features.end();
|
|
@@ -225,15 +244,16 @@ int main( int argc, char **argv )
|
|
|
{
|
|
|
i->normalizeL1();
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
//collect them all in a larger data structure
|
|
|
featuresFromAllTrainingImages.append( features );
|
|
|
+
|
|
|
//and store it as well in the data struct that additionally keeps the information which features belong to which image
|
|
|
//TODO this can be made more clever!
|
|
|
// featuresOfImages.push_back( features );
|
|
|
featuresOfImages[imgCnt] = features;
|
|
|
labelsTrain[imgCnt] = classno;
|
|
|
- imgCnt++;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
@@ -252,9 +272,10 @@ int main( int argc, char **argv )
|
|
|
std::vector<double> weights;
|
|
|
std::vector<int> assignments;
|
|
|
|
|
|
+ std::cerr << "call cluster of cluster algo " << std::endl;
|
|
|
clusterAlgo->cluster( featuresFromAllTrainingImages, prototypes, weights, assignments );
|
|
|
|
|
|
-
|
|
|
+ std::cerr << "create new codebook with the computed prototypes" << std::endl;
|
|
|
OBJREC::CodebookPrototypes * codebook = new OBJREC::CodebookPrototypes ( prototypes );
|
|
|
|
|
|
|
|
@@ -305,8 +326,11 @@ int main( int argc, char **argv )
|
|
|
// ========================================================================
|
|
|
|
|
|
const LabeledSet *testFiles = md["test"];
|
|
|
+
|
|
|
+ delete featureExtractor;
|
|
|
+ featureExtractor = OBJREC::GenericLFSelection::selectLocalFeatureRep ( conf, "features", OBJREC::GenericLFSelection::TESTING );
|
|
|
|
|
|
- NICE::Matrix confusionMat;
|
|
|
+ NICE::Matrix confusionMat ( trainFiles->size() /* number of classes in training */, testFiles->size() /* number of classes for testing*/, 0.0 );
|
|
|
NICE::Timer t;
|
|
|
|
|
|
ClassificationResults results;
|
|
@@ -364,6 +388,7 @@ int main( int argc, char **argv )
|
|
|
ClassificationResult r = classifier->classify ( histogramOfCurrentImg );
|
|
|
t.stop();
|
|
|
uint classno_estimated = r.classno;
|
|
|
+ r.classno_groundtruth = classno_groundtruth;
|
|
|
|
|
|
//if we like to store the classification results for external post processing, uncomment this
|
|
|
if ( writeClassificationResults )
|