#include "vislearning/features/regionfeatures/RFCsurka.h" #include "vislearning/classifier/fpclassifier/randomforest/FPCRandomForests.h" #include "vislearning/classifier/fpclassifier/logisticregression/FPCSMLR.h" #include "core/image/Filter.h" #include using namespace OBJREC; using namespace std; using namespace NICE; RFCsurka::RFCsurka( const Config *_conf, LocalFeature *_lf ):RFBoV(_conf, _lf) { lf = _lf; string sscales = conf->gS("SIFTTest", "scales", "1+2.0+3.0"); grid = conf->gI("SIFTTest", "grid", 20); sigmaweight = conf->gD ( "RFCsurka", "sigmaweight", 0.2 ); string::size_type pos = 0; string::size_type oldpos = 0; while(pos != string::npos) { pos = sscales.find("+", oldpos); string val; if(pos == string::npos) val = sscales.substr(oldpos); else val = sscales.substr(oldpos, pos-oldpos); double d = atof(val.c_str()); scales.push_back(d); oldpos = pos+1; } gmm = NULL; pca = NULL; fpc = NULL; vec = NULL; } RFCsurka::~RFCsurka() { } void RFCsurka::setPCA(PCA *_pca) { pca = _pca; } void RFCsurka::setGMM(GMM *_gmm) { gmm = _gmm; } void RFCsurka::setClassifier(FeaturePoolClassifier *_fpc) { fpc = _fpc; vec = NULL; nbclasses = fpc->getMaxClassNo ()+1; } void RFCsurka::setClassifier(VecClassifier *_vec) { vec = _vec; fpc = NULL; nbclasses = vec->getMaxClassNo ()+1; } void RFCsurka::extract ( const NICE::Image & img, const RegionGraph &rg, const NICE::Matrix &mask, VVector & feats ) { VVector positions, features; getPositions(rg, mask, positions); lf->getDescriptors(img, positions, features); assert(features.size() == positions.size()); convert(mask, rg, features, feats, positions); } void RFCsurka::extractRGB ( const NICE::ColorImage & cimg, const RegionGraph &rg, const NICE::Matrix &mask, VVector & feats ) { assert(fpc != NULL || vec != NULL); VVector positions, features; getPositions(rg, mask, positions); lf->getDescriptors(cimg, positions, features); assert(features.size() == positions.size()); convert(mask, rg, features, feats, positions); } void RFCsurka::convert(const Matrix &mask, const RegionGraph &rg, VVector &infeats, VVector &outfeats, VVector &positions) { outfeats.reSize(rg.size(),nbclasses); bool usepca = false; bool usegmm = false; if(pca != NULL) usepca = true; if(gmm != NULL) usegmm = true; set scales; map scalesmap; for(int i = 0; i < (int)infeats.size(); i++) { scales.insert(positions[i][2]); } int s = 0; for(set::const_iterator iter = scales.begin(); iter != scales.end(); ++iter, s++) { scalesmap[*iter] = s; } int xsize = mask.rows(); int ysize = mask.cols(); MultiChannelImageT preMap ( xsize,ysize,nbclasses*scales.size(),true ); MultiChannelImageT probabilities ( xsize, ysize, nbclasses, true); preMap.setAll(0.0); probabilities.setAll(0.0); // Die Wahrscheinlichkeitsmaps mit den einzelnen Wahrscheinlichkeiten je Skalierung füllen for(int i = 0; i < (int)infeats.size(); i++) { Vector *feat = new Vector(infeats[i]); Example ex(feat); if(usepca) *ex.vec = pca->getFeatureVector ( *ex.vec, true ); if(usegmm) { Vector probs; gmm->getProbs(*ex.vec, probs); *ex.vec = probs; } ClassificationResult r; if(fpc != NULL) r = fpc->classify ( ex ); else r = vec->classify(*ex.vec); for ( int j = 0 ; j < ( int ) probabilities.numChannels; j++ ) preMap.set ( positions[i][0],positions[i][1],r.scores[j],j+scalesmap[positions[i][2]]*nbclasses); delete ex.vec; ex.vec = NULL; } s = 0; vector sigmavec; for(set::const_iterator iter = scales.begin(); iter != scales.end(); ++iter, s++) { double sigma = sigmaweight*16.0* (*iter); sigmavec.push_back(sigma); } for(int s = 0; s < (int)sigmavec.size(); s++) { double sigma = sigmavec[s]; cerr << "sigma: " << sigma << endl; #pragma omp parallel for for ( int i = 0; i < nbclasses; i++ ) { int pos = i+s*nbclasses; double maxval = preMap.data[pos][0]; double minval = preMap.data[pos][0]; for ( int z = 1; z < xsize*ysize; z++ ) { maxval = std::max ( maxval, preMap.data[pos][z] ); minval = std::min ( minval, preMap.data[pos][z] ); } NICE::FloatImage dblImg( xsize, ysize); NICE::FloatImage gaussImg( xsize, ysize); long int offset = 0; for ( int y = 0; y < ysize; y++ ) { for ( int x = 0; x < xsize; x++, offset++ ) { dblImg.setPixel(x,y,preMap.data[pos][offset]); } } filterGaussSigmaApproximate( dblImg, sigma, &gaussImg ); offset = 0; for ( int y = 0; y < ysize; y++ ) { for ( int x = 0; x < xsize; x++, offset++ ) { preMap.data[pos][offset]=gaussImg.getPixel(x,y); } } } } int scalesize = scales.size(); // Zusammenfassen und auswerten #pragma omp parallel for for ( int x = 0; x < xsize; x++ ) { for ( int y = 0; y < ysize; y++ ) { for ( int j = 0 ; j < ( int ) probabilities.numChannels; j++ ) { double prob = 0.0; for ( int s = 0; s < ( int ) scalesize; s++ ) { prob+=preMap.get ( x,y,j+s*nbclasses ); } double val = prob / ( double ) ( scalesize ); probabilities.set ( x,y,val, j ); } } } // Wahrscheinlichkeiten für Regionen bestimmen for ( int x = 0; x < xsize; x++ ) { for ( int y = 0; y < ysize; y++ ) { for ( int j = 0 ; j < ( int ) probabilities.numChannels; j++ ) { int r = mask(x,y); double val = probabilities.get ( x,y,j ); outfeats[r][j] += val; } } } #pragma omp parallel for for(int i = 0; i < (int)outfeats.size(); i++) { double sum = 0.0; for(int j = 0; j < (int)outfeats[i].size(); j++) { sum += outfeats[i][j]; } for(int j = 0; j < (int)outfeats[i].size(); j++) { outfeats[i][j]/=sum; } } #undef VISSEMSEG #ifdef VISSEMSEG // showImage(img); for ( int j = 0 ; j < ( int ) probabilities.numChannels; j++ ) { cout << "klasse: " << j << endl;//" " << cn.text ( j ) << endl; NICE::Matrix tmp ( probabilities.ysize, probabilities.xsize ); double maxval = 0.0; for ( int y = 0; y < probabilities.ysize; y++ ) for ( int x = 0; x < probabilities.xsize; x++ ) { double val = probabilities.get ( x,y,j ); tmp(y, x) = val; maxval = std::max ( val, maxval ); } NICE::ColorImage imgrgb (probabilities.xsize, probabilities.ysize); ICETools::convertToRGB ( tmp, imgrgb ); cout << "maxval = " << maxval << " for class " << j << endl; //cn.text ( j ) << endl; imgrgb.write("out.ppm"); showImage(imgrgb, "Ergebnis"); } #endif } void RFCsurka::getPositions(const RegionGraph &rg, const NICE::Matrix &mask, VVector &positions) { vector featinreg(rg.size(), 0); int x0 = grid/2; for(int y = 0; y < (int)mask.cols(); y+=grid) { for(int x = x0; x < (int)mask.rows(); x+=grid) { int r = (int)mask(x,y); for(int s = 0; s < (int)scales.size(); s++) { featinreg[r]++; Vector vec(3); vec[0] = x; vec[1] = y; vec[2] = scales[s]; positions.push_back(vec); } } if(x0 == 0) { x0 = grid/2; } else { x0 = 0; } } for(int i = 0; i < (int)featinreg.size(); i++) { if(featinreg[i] == 0) { int x, y; rg[i]->getCentroid(x,y); for(int s = 0; s < (int)scales.size(); s++) { Vector vec(3); vec[0] = x; vec[1] = y; vec[2] = scales[s]; positions.push_back(vec); //FIXME: Achtung es kann in seltenen Fällen vorkommen, dass der Mittelpunkt einer kleinen Region nicht zur Region gehört -> abfangen } } } }