/** Author: gilles Differences of blockwise averages at different scales on the ROI (a la Viola and Jones)*/#include <mash/heuristic.h>usingnamespaceMash;//------------------------------------------------------------------------------// Declaration of the heuristic class//------------------------------------------------------------------------------classblockwise:publicHeuristic{//_____ Construction / Destruction __________public:blockwise();virtual~blockwise();//_____ Implementation of Heuristic __________public://--------------------------------------------------------------------------// Returns the number of features this heuristic computes//// When this method is called, the 'roi_extent' attribute is initialized//--------------------------------------------------------------------------virtualunsignedintdim();//--------------------------------------------------------------------------// Called once per image, before any computation //// Pre-computes from a full image the data the heuristic will need to compute// features at any coordinates in the image//// When this method is called, the following attributes are initialized:// - roi_extent// - image//--------------------------------------------------------------------------virtualvoidprepareForImage();//--------------------------------------------------------------------------// Called once per image, after any computation //// Frees the memory allocated by the prepareForImage() method//--------------------------------------------------------------------------virtualvoidfinishForImage();//--------------------------------------------------------------------------// Called once per coordinates, before any computation//// Pre-computes the data the heuristic will need to compute features at the// given coordinates//// When this method is called, the following attributes are initialized:// - roi_extent// - image// - coordinates//--------------------------------------------------------------------------virtualvoidprepareForCoordinates();//--------------------------------------------------------------------------// Called once per coordinates, after any computation //// Frees the memory allocated by the prepareForCoordinates() method//--------------------------------------------------------------------------virtualvoidfinishForCoordinates();//--------------------------------------------------------------------------// Computes the specified feature//// When this method is called, the following attributes are initialized:// - roi_extent// - image// - coordinates//--------------------------------------------------------------------------virtualscalar_tcomputeFeature(unsignedintfeature_index);//_____ Attributes __________protected:int**_blocksum;// will contain cumulative sums in (x,y) over the ROI// TODO: Declare all the attributes you'll need here};//------------------------------------------------------------------------------// Creation function of the heuristic//------------------------------------------------------------------------------extern"C"Heuristic*new_heuristic(){returnnewblockwise();}/************************* CONSTRUCTION / DESTRUCTION *************************/blockwise::blockwise(){// TODO: Initialization of the attributes that doesn't depend of anything}blockwise::~blockwise(){// TODO: Cleanup of the allocated memory still remaining}/************************* IMPLEMENTATION OF Heuristic ************************/unsignedintblockwise::dim(){return16*16*5*5*4;}voidblockwise::prepareForImage(){// nothing}voidblockwise::finishForImage(){// nothing}voidblockwise::prepareForCoordinates(){// Compute the coordinates of the top-left pixel of the region of interestunsignedintx0=coordinates.x-roi_extent;unsignedinty0=coordinates.y-roi_extent;unsignedintroi_size=roi_extent*2;// here we put the center of the ROI inbetween pixelsbyte_t**pLines=image->grayLines();// Compute cumulative pixel sums in (x,y) over the ROI_blocksum=newint*[roi_size+1];for(unsignedintx=0;x<=roi_size;++x){intcol_sum=0;_blocksum[x]=newint[roi_size+1];for(unsignedinty=0;y<=roi_size;++y){if(y==0||x==0)_blocksum[x][y]=0;else{col_sum+=pLines[y0+y-1][x0+x-1];_blocksum[x][y]=_blocksum[x-1][y]+col_sum;}}}}voidblockwise::finishForCoordinates(){for(unsignedintx=0;x<=2*roi_extent;++x)delete[]_blocksum[x];delete[]_blocksum;}scalar_tblockwise::computeFeature(unsignedintfeature_index){unsignedintroi_size=roi_extent*2;floatstepsize=roi_extent*2/16;intfeature_type=feature_index%4;intx_size=roi_extent/(1<<((feature_index/4)%5));// the size of the subregion:inty_size=roi_extent/(1<<((feature_index/4)/5)%5);// roi_extent / 2^k , k=0 to 4intx0=stepsize*((((feature_index/4)/5)/5)%16);inty0=stepsize*(((((feature_index/4)/5)/5)/16)%16);if(x_size==0)x_size++;if(y_size==0)y_size++;intxM=(x0+x_size>roi_extent*2)?(roi_extent*2):(x0+x_size);intxm=(x0-x_size>0)?(x0-x_size):0;intyM=(y0+y_size>roi_extent*2)?(roi_extent*2):(y0+y_size);intym=(y0-y_size>0)?(y0-y_size):0;if(feature_type==0)// mean valuereturn(scalar_t)((_blocksum[xM][yM]-_blocksum[xm][yM]-_blocksum[xM][ym]+_blocksum[xm][ym])/(float)(x_size*y_size));if(feature_type==1)// horizontal differencereturn(scalar_t)((_blocksum[xM][yM]-_blocksum[xm][yM]-2*_blocksum[xM][y0]+2*_blocksum[xm][y0]+_blocksum[xM][ym]-_blocksum[xm][ym])/(float)(x_size*y_size));if(feature_type==2)// vertical differencereturn(scalar_t)((_blocksum[xM][yM]-_blocksum[xM][ym]-2*_blocksum[x0][yM]+2*_blocksum[x0][ym]+_blocksum[xm][yM]-_blocksum[xm][ym])/(float)(x_size*y_size));if(feature_type==3)// crossed (checkerboard) differencereturn(scalar_t)((_blocksum[xM][yM]+_blocksum[xM][ym]+_blocksum[xm][yM]+_blocksum[xm][ym]-2*_blocksum[xM][y0]-2*_blocksum[xm][y0]-2*_blocksum[x0][yM]-2*_blocksum[x0][ym]+4*_blocksum[x0][y0])/(float)(x_size*y_size));}