/** Author: Charles Dubout (charles.dubout@idiap.ch) * * Haar transform heuristic. Compute the 2D haar transform of the region of * interest (all levels), padding the ROI with zeros so that the size is a * power of two. */#include <mash/heuristic.h>#include <cmath>#include <vector>usingnamespaceMash;//------------------------------------------------------------------------------/// The 'Haar' heuristic class//------------------------------------------------------------------------------classHaarHeuristic:publicHeuristic{//_____ Implementation of Heuristic __________public:virtualunsignedintdim();virtualvoidprepareForCoordinates();virtualscalar_tcomputeFeature(unsignedintfeature_index);private:// Compute the 1D haar transformstaticvoidhaar1(scalar_t*features,unsignedintw);// Compute the 2D haar transformstaticvoidhaar2(scalar_t*features,unsignedintw);// Round up to the next highest power of 2staticunsignedintroundUp(unsignedintx);// The transformed version of the region of intereststd::vector<scalar_t>features_;};//------------------------------------------------------------------------------/// Creation function of the heuristic//------------------------------------------------------------------------------extern"C"Heuristic*new_heuristic(){returnnewHaarHeuristic();}/************************* IMPLEMENTATION OF Heuristic ************************/unsignedintHaarHeuristic::dim(){// We have has many features than pixels in the region of interest (rounded// to the next highest power of 2)unsignedintroi_size=roi_extent*2+1;unsignedintextended_size=roundUp(roi_size);returnextended_size*extended_size;}voidHaarHeuristic::prepareForCoordinates(){// Compute the coordinates of the top-left pixel of the region of interestunsignedintx0=coordinates.x-roi_extent;unsignedinty0=coordinates.y-roi_extent;// Compute the size of the region of interestunsignedintroi_size=roi_extent*2+1;unsignedintextended_size=roundUp(roi_size);// Get the pixels values of the region of interestbyte_t**pLines=image->grayLines();// Resize the features to the correct dimensionfeatures_.clear();features_.resize(dim());// Fill the feature imagefor(unsignedinty=0;y<roi_size;++y){for(unsignedintx=0;x<roi_size;++x){features_[y*extended_size+x]=pLines[y][x];}}haar2(&features_[0],extended_size);}scalar_tHaarHeuristic::computeFeature(unsignedintfeature_index){returnfeatures_[feature_index];}// Compute the 1D haar transformvoidHaarHeuristic::haar1(scalar_t*features,unsignedintw){constscalar_tinvSqrt2=0.707106781187;std::vector<scalar_t>temp(w);for(unsignedinti=0;i<(w/2);++i){temp[i]=(features[2*i]+features[2*i+1])*invSqrt2;temp[i+(w/2)]=(features[2*i]-features[2*i+1])*invSqrt2;}for(unsignedinti=0;i<w;++i){features[i]=temp[i];}}// Compute the 2D haar transformvoidHaarHeuristic::haar2(scalar_t*features,unsignedintw){std::vector<scalar_t>temp(w);unsignedintz=w;while(z>1){// Do 1D haar transforms along the rowsfor(unsignedinti=0;i<z;++i){haar1(features+i*w,z);}// Do 1D haar transforms along the columnsfor(unsignedinti=0;i<z;++i){for(unsignedintj=0;j<w;++j){temp[j]=features[i+j*w];}haar1(&temp[0],z);for(unsignedintj=0;j<w;++j){features[i+j*w]=temp[j];}}z>>=1;}}// Round up to the next highest power of 2unsignedintHaarHeuristic::roundUp(unsignedintx){// Assume x is 32-bits--x;x|=x>>1;x|=x>>2;x|=x>>4;x|=x>>8;x|=x>>16;return++x;}