#include #include "vislearning/features/fpfeatures/PixelPairFeature.h" #include "vislearning/cbaselib/FeaturePool.h" using namespace OBJREC; using namespace std; using namespace NICE; #define BOUND(x,min,max) (((x)<(min))?(min):((x)>(max)?(max):(x))) const int firstColorchannel = 0; const int lastColorchannel = 2; void PixelPairFeature::explode ( FeaturePool & featurePool, bool variableWindow ) const { PixelPairFeature *f = new PixelPairFeature ( *this ); int firstchannel = ( imagetype == CachedExample::I_COLOR ) ? firstColorchannel : 0; int lastchannel = ( imagetype == CachedExample::I_COLOR ) ? lastColorchannel : 0; int wsx = window_size_x / 2; int wsy = window_size_y / 2; int numberOfPairFeatures = ( lastchannel - firstchannel + 1 ) * ( 2 * wsx / step_x ) * ( 2 * wsy / step_y ); numberOfPairFeatures *= numberOfPairFeatures; for ( int _type = PPTYPE_DIFF ; _type < PPTYPE_VALUE ; _type++ ) for ( int _x1 = -wsx ; _x1 < wsx ; _x1 += step_x ) for ( int _y1 = -wsy ; _y1 < wsy ; _y1 += step_y ) for ( int _b1 = firstchannel ; _b1 <= lastchannel ; _b1++ ) for ( int _x2 = -wsx ; _x2 < wsx ; _x2 += step_x ) for ( int _y2 = -wsy ; _y2 < wsy ; _y2 += step_y ) for ( int _b2 = firstchannel ; _b2 <= lastchannel ; _b2++ ) { if ( ( _b1 == _b2 ) && ( _x1 == _x2 ) && ( _y1 == _y2 ) ) continue; f->x1 = _x1; f->y1 = _y1; f->b1 = _b1; f->x2 = _x2; f->y2 = _y2; f->b2 = _b2; f->type = _type; featurePool.addFeature ( f->clone(), 1.0 / ( ( PPTYPE_VALUE - PPTYPE_DIFF ) * numberOfPairFeatures ) ); } f->type = PPTYPE_VALUE; for ( int _x1 = -wsx ; _x1 < wsx ; _x1 += step_x ) for ( int _y1 = -wsy ; _y1 < wsy ; _y1 += step_y ) for ( int _b1 = firstchannel ; _b1 <= lastchannel ; _b1++ ) { f->x1 = _x1; f->y1 = _y1; f->b1 = _b1; featurePool.addFeature ( f->clone(), 1.0 / numberOfPairFeatures ); } delete f; } Feature *PixelPairFeature::clone() const { PixelPairFeature *fp = new PixelPairFeature ( *this ); return fp; } /************* PixelPairFeature **************/ PixelPairFeature::PixelPairFeature ( const Config *conf ) { window_size_x = conf->gI ( "PixelPairFeatures", "window_size_x", 24 ); window_size_y = conf->gI ( "PixelPairFeatures", "window_size_y", 24 ); step_x = conf->gI ( "PixelPairFeatures", "step_x", 1 ); step_y = conf->gI ( "PixelPairFeatures", "step_y", 1 ); bool use_color = conf->gB ( "PixelPairFeatures", "use_color", true ); if ( use_color ) { imagetype = CachedExample::I_COLOR; } else { imagetype = CachedExample::I_GRAYVALUES; } } PixelPairFeature::PixelPairFeature ( int _window_size_x, int _window_size_y, int _step_x, int _step_y, int _imagetype ) { window_size_x = _window_size_x; window_size_y = _window_size_y; x1 = 0; y1 = 0; b1 = firstColorchannel; x2 = 1; y1 = 0; b2 = firstColorchannel; step_x = _step_x; step_y = _step_y; type = PixelPairFeature::PPTYPE_DIFF; imagetype = _imagetype; } PixelPairFeature::~PixelPairFeature() { } double PixelPairFeature::val ( const Example *example ) const { int xl = example->x; int yl = example->y; NICE::MultiChannelImageT & img = example->ce->getIChannel ( imagetype ); int xx1 = x1; int yy1 = y1; int xx2 = x1; int yy2 = x2; int exwidth = example->width; if ( exwidth != 0 ) { int exheight = example->height; xx1 = xx1 * exwidth / window_size_x; yy1 = yy1 * exheight / window_size_y; xx2 = xx2 * exwidth / window_size_x; yy2 = yy2 * exheight / window_size_y; } int xsize = img.width(); int ysize = img.height(); int p1x = BOUND ( xl + xx1, 0, xsize - 1 ); int p1y = BOUND ( yl + yy1, 0, ysize - 1 ); int v1 = img.get(p1x,p1y,b1); if ( type != PPTYPE_VALUE ) { int p2x = BOUND ( xl + xx2, 0, xsize - 1 ); int p2y = BOUND ( yl + yy2, 0, ysize - 1 ); int v2 = img.get(p2x,p2y,b2); if ( type == PPTYPE_DIFF ) return v1 - v2; else if ( type == PPTYPE_ABSDIFF ) return fabs ( v1 -v2 ); else if ( type == PPTYPE_SUM ) return v1 + v2; else exit ( -1 ); } else { return v1; } } void PixelPairFeature::restore ( istream & is, int format ) { is >> type; is >> imagetype; is >> window_size_x; is >> window_size_y; is >> x1; is >> y1; is >> b1; is >> x2; is >> y2; is >> b2; } void PixelPairFeature::store ( ostream & os, int format ) const { os << "PIXELPAIRFEATURE" << " " << type << " " << imagetype << " " << window_size_x << " " << window_size_y << " " << " " << x1 << " " << y1 << " " << b1 << " " << x2 << " " << y2 << " " << b2; } void PixelPairFeature::clear () { // nothing to do in my opinion } #if 0 void PixelPairFeature::calcFeatureValues ( const Examples & examples, vector & examples_selection, FeatureValuesUnsorted & values ) const { for ( vector::const_iterator si = examples_selection.begin(); si != examples_selection.end(); si++ ) { int index = *si; const pair & p = examples[index]; int classno = p.first; const Example & example = p.second; double value = 0.0; int xsize, ysize; int xl = example.x - window_size_x / 2; int yl = example.y - window_size_y / 2; const double *channel1 = example.ce->getChannel ( b1, xsize, ysize ); int p1x = BOUND ( xl + x1, 0, xsize - 1 ); int p1y = BOUND ( yl + y1, 0, ysize - 1 ); long off1 = p1x + p1y * xsize; double v1 = channel1[off1]; if ( type != PPTYPE_VALUE ) { const double *channel2 = example.ce->getChannel ( b2, xsize, ysize ); int p2x = BOUND ( xl + x2, 0, xsize - 1 ); int p2y = BOUND ( yl + y2, 0, ysize - 1 ); long off2 = p2x + p2y * xsize; double v2 = channel2[off2]; if ( type == PPTYPE_DIFF ) value = v1 - v2; else if ( type == PPTYPE_ABSDIFF ) value = fabs ( v1 - v2 ); else if ( type == PPTYPE_SUM ) value = v1 + v2; } else { value = v1; } values.push_back ( quadruplet ( value, classno, index, example.weight ) ); } } #endif #undef BOUND