123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361 |
- /**
- * @file LFPatches.cpp
- * @brief simple patch based approach
- * @author Erik Rodner
- * @date 02/06/2008
- */
- #include <core/image/RectangleT.h>
- #include <core/image/ImageTools.h>
- #include <iostream>
- #include <sstream>
- #include "vislearning/features/localfeatures/LFPatches.h"
- #include "vislearning/features/localfeatures/IDRandomSampling.h"
- #include "vislearning/features/localfeatures/IDKLTSampling.h"
- #include "vislearning/features/localfeatures/IDSIFTSampling.h"
- #include "vislearning/image/ImagePyramid.h"
- using namespace OBJREC;
- using namespace std;
- using namespace NICE;
- void LFPatches::setDetector ( const int & _detectormode, const NICE::Config * conf)
- {
- if ( this->id != NULL )
- {
- delete this->id;
- this->id = NULL;
- }
-
- if (_detectormode == 0)
- {
- this->id = new IDRandomSampling(conf, this->numPatches);
- }
- else if (_detectormode == 1)
- {
- this->id = new IDKLTSampling(conf, this->numPatches);
- }
- else if (_detectormode == 2)
- {
- this->id = new IDSIFTSampling(conf);
- }
- else
- {
- this->id = new IDRandomSampling(conf, this->numPatches);
- }
- }
- void LFPatches::setNormalization( const std::string & _normalization_s)
- {
- if (_normalization_s == "n01")
- normalization = NORMALIZE_N01;
- else if (_normalization_s == "stddev")
- normalization = NORMALIZE_STDDEV;
- else if (_normalization_s == "mean")
- normalization = NORMALIZE_MEAN;
- else if (_normalization_s == "none")
- normalization = NORMALIZE_NONE;
- else
- {
- fprintf(stderr, "LFPatches::LFPatches: unknown normalization method\n");
- exit(-1);
- }
- }
- ///////////////////// ///////////////////// /////////////////////
- // CONSTRUCTORS / DESTRUCTORS
- ///////////////////// ///////////////////// /////////////////
- LFPatches::LFPatches()
- {
- this->numPatches = -1;
- this->xsize = 11;
- this->ysize = 11;
- this->maxLevels = 10;
- this->scaleSpacing = sqrt(sqrt(2));
- this->detectormode = 0;
- this->id = NULL;
-
- std::string normalization_s = "n01";
- this->setNormalization ( normalization_s );
-
- //TODO initialization useful here?
- srand(time(NULL));
- }
- LFPatches::LFPatches(const Config *conf, int _numPatches) :
- numPatches(_numPatches)
- {
- this->xsize = conf->gI("Patches", "xsize", 11);
- this->ysize = conf->gI("Patches", "ysize", 11);
- this->maxLevels = conf->gI("Patches", "levels", 10);
- this->scaleSpacing = conf->gD("Patches", "scale_spacing", sqrt(sqrt(2)));
- this->detectormode = conf->gI("Patches", "detector", 0);
- this->setDetector ( this->detectormode, conf );
-
- std::string normalization_s = conf->gS("Patches", "normalization", "n01");
- this->setNormalization ( normalization_s );
- srand(time(NULL));
- }
- LFPatches::~LFPatches()
- {
- if ( this->id != NULL )
- {
- delete this->id;
- this->id = NULL;
- }
- }
- ///////////////////// ///////////////////// /////////////////////
- // FEATURE STUFF
- ///////////////////// ///////////////////// //////////////////
- int LFPatches::getDescSize() const
- {
- return xsize * ysize;
- }
- int LFPatches::extractFeatures(const NICE::Image & img, VVector & features,
- VVector & positions) const
- {
- ImagePyramid imp(img, maxLevels, scaleSpacing, xsize, ysize);
- //imp.show();
- VVector positions_tmp;
- if(positions.size()<=0)
- {
- id->getRandomInterests(imp, positions_tmp,numPatches);
- }
- else
- {
- positions_tmp=positions;
- }
- correctPositions(imp, positions_tmp, positions);
- calcDescriptors(imp, positions, features);
- return features.size();
- }
- void LFPatches::correctPositions(const ImagePyramid & imp, VVector & positions,
- VVector & positions_corrected) const
- {
- positions_corrected.clear();
- int numlevels = imp.getNumLevels();
- for (size_t i = 0; i < positions.size(); i++)
- {
- const NICE::Vector & position = positions[i];
- if ((size_t) position[2] < numlevels)
- {
- const NICE::Image & img = imp.getLevel((size_t) position[2]);
- double xl, yl;
- imp.getLevelCoordinates(position[0], position[1],
- (size_t) position[2], xl, yl);
- int x = (int) xl;
- int y = (int) yl;
- x -= xsize / 2;
- y -= ysize / 2;
- if ((x >= 0) && (y >= 0) && (x <= img.width() - xsize) && (y
- <= img.height() - ysize))
- {
- NICE::Vector position_new(3);
- imp.getOriginalCoordinates(x, y,
- (size_t) position[2], position_new[0], position_new[1]);
- position_new[2] = position[2];
- positions_corrected.push_back(position_new);
- }
- }
- }
- }
- void LFPatches::calcDescriptors(const ImagePyramid & imp, VVector & positions,
- VVector & features) const
- {
- NICE::Vector desc(getDescSize());
- for (VVector::iterator i = positions.begin(); i != positions.end();)
- {
- bool deletePosition = false;
- if (calcDescriptor(imp, *i, desc) < 0)
- {
- deletePosition = true;
- }
- else
- {
- features.push_back(desc);
- }
- if (deletePosition)
- {
- i = positions.erase(i);
- }
- else
- {
- i++;
- }
- }
- }
- int LFPatches::calcDescriptor(const ImagePyramid & imp,
- const NICE::Vector & position, NICE::Vector & desc) const
- {
- const NICE::Image & img = imp.getLevel((size_t) position[2]);
- double xl, yl;
- imp.getLevelCoordinates(position[0], position[1], (uint) position[2], xl,
- yl);
- int x = (int) xl;
- int y = (int) yl;
- if ((x < 0) || (y < 0) || (x > img.width() - xsize) || (y > img.height()
- - ysize))
- {
- return -1;
- }
- double mean = 0.0;
- double stddev = 0.0;
- if (normalization != NORMALIZE_NONE)
- {
- // compute mean
- for (int yi = y; yi < y + ysize; yi++)
- for (int xi = x; xi < x + xsize; xi++)
- mean += img.getPixel(xi, yi);
- mean /= (xsize * ysize);
- if (normalization != NORMALIZE_MEAN)
- {
- // compute stddev
- stddev = 0.0;
- for (int yi = y; yi < y + ysize; yi++)
- for (int xi = x; xi < x + xsize; xi++)
- {
- double d = img.getPixel(xi, yi) - mean;
- stddev += d * d;
- }
- if (stddev < 10e-5)
- return -1;
- stddev /= xsize * ysize;
- stddev = sqrt(stddev);
- }
- }
- if (normalization == NORMALIZE_STDDEV)
- {
- // normalize pixel values
- int k = 0;
- for (int yi = y; yi < y + ysize; yi++)
- for (int xi = x; xi < x + xsize; xi++, k++)
- desc[k] = (img.getPixel(xi, yi) - mean) / stddev + mean;
- }
- else if (normalization == NORMALIZE_N01)
- {
- // normalize pixel values
- int k = 0;
- for (int yi = y; yi < y + ysize; yi++)
- for (int xi = x; xi < x + xsize; xi++, k++)
- desc[k] = (img.getPixel(xi, yi) - mean) / stddev;
- }
- else if (normalization == NORMALIZE_MEAN)
- {
- // normalize pixel values
- int k = 0;
- for (int yi = y; yi < y + ysize; yi++)
- for (int xi = x; xi < x + xsize; xi++, k++)
- desc[k] = (img.getPixel(xi, yi) - mean);
- }
- else
- {
- int k = 0;
- for (int yi = y; yi < y + ysize; yi++)
- for (int xi = x; xi < x + xsize; xi++, k++)
- desc[k] = img.getPixel(xi, yi);
- }
- return 0;
- }
- void LFPatches::visualizeFeatures(NICE::Image & mark,
- const VVector & positions, size_t color) const
- {
- for (size_t i = 0; i < positions.size(); i++)
- {
- const NICE::Vector & pos = positions[i];
- double s = pow(scaleSpacing, pos[2]);
- int x = (int) (pos[0]);
- int y = (int) (pos[1]);
- int w = (int) (s * xsize);
- int h = (int) (s * ysize);
- RectangleT<Ipp8u> rect(Coord(x, y), Coord(x + w, y + w));
- mark.draw(rect, (unsigned char) color);
- }
- }
- void LFPatches::visualize(NICE::Image & img, const NICE::Vector & feature) const
- {
- if (feature.size() != (size_t) xsize * ysize)
- {
- fprintf(stderr, "LFPatches::visualize implementation failure\n");
- exit(-1);
- }
- img.resize(xsize, ysize);
- double max = -numeric_limits<double>::max();
- double min = numeric_limits<double>::max();
- int k = 0;
- for (k = 0; k < xsize * ysize; k++)
- {
- if (feature[k] > max)
- max = feature[k];
- if (feature[k] < min)
- min = feature[k];
- }
- k = 0;
- for (int y = 0; y < ysize; y++)
- for (int x = 0; x < xsize; x++, k++)
- {
- double val = ((feature[k] - min) * 255 / (max - min));
- img.setPixel(x, y, (int) val);
- }
- }
- ///////////////////// INTERFACE PERSISTENT /////////////////////
- // interface specific methods for store and restore
- ///////////////////// INTERFACE PERSISTENT /////////////////////
- void LFPatches::restore ( std::istream & is, int format )
- {
- fthrow ( Exception, "LFPatches::restore not implemented yet." );
- //TODO
- }
- void LFPatches::store ( std::ostream & os, int format ) const
- {
- fthrow ( Exception, "LFPatches::store not implemented yet." );
- //TODO
- }
- void LFPatches::clear ()
- {
- if ( this->id != NULL )
- {
- delete this->id;
- this->id = NULL;
- }
- }
|