/** Author: Francois Fleuret This heuristic computes the average level of gray over 1000 boxes picked at random when dim() is called (i.e. the 1000 boxes remain the same for all images and sub-windows). */#include <mash/heuristic.h>#include <stdlib.h>usingnamespaceMash;structRectangle{intxmin,ymin,xmax,ymax;};//------------------------------------------------------------------------------// Declaration of the heuristic class//------------------------------------------------------------------------------classBoxedAverages:publicHeuristic{public:BoxedAverages();virtual~BoxedAverages();public:virtualunsignedintdim();virtualvoidprepareForImage();virtualvoidfinishForImage();virtualvoidprepareForCoordinates();virtualvoidfinishForCoordinates();virtualscalar_tcomputeFeature(unsignedintfeature_index);protected:staticconstintnb_features=1000;int*_integral_image;int_image_width,_image_height;Rectangle*_rectangles;};extern"C"Heuristic*new_heuristic(){returnnewBoxedAverages();}BoxedAverages::BoxedAverages(){_rectangles=0;}BoxedAverages::~BoxedAverages(){delete[]_rectangles;}unsignedintBoxedAverages::dim(){_rectangles=newRectangle[nb_features];for(intn=0;n<nb_features;n++){do{_rectangles[n].xmin=-roi_extent+int(drand48()*(2*roi_extent+1));_rectangles[n].ymin=-roi_extent+int(drand48()*(2*roi_extent+1));_rectangles[n].xmax=-roi_extent+int(drand48()*(2*roi_extent+1));_rectangles[n].ymax=-roi_extent+int(drand48()*(2*roi_extent+1));}while(_rectangles[n].xmax<=_rectangles[n].xmin||_rectangles[n].ymax<=_rectangles[n].ymin);}returnnb_features;}voidBoxedAverages::prepareForImage(){byte_t**pixels=image->grayLines();_image_width=image->width();_image_height=image->height();_integral_image=newint[_image_width*_image_height];for(inty=0;y<_image_height;y++){for(intx=0;x<_image_width;x++){if(y==0||x==0){_integral_image[x+_image_width*y]=0;}else{_integral_image[x+_image_width*y]=pixels[x][y]+_integral_image[(x-1)+_image_width*y]+_integral_image[x+_image_width*(y-1)]-_integral_image[(x-1)+_image_width*(y-1)];}}}}voidBoxedAverages::finishForImage(){delete[]_integral_image;}voidBoxedAverages::prepareForCoordinates(){}voidBoxedAverages::finishForCoordinates(){}scalar_tBoxedAverages::computeFeature(unsignedintfeature_index){intxmin=coordinates.x+_rectangles[feature_index].xmin;intymin=coordinates.y+_rectangles[feature_index].ymin;intxmax=coordinates.x+_rectangles[feature_index].xmax;intymax=coordinates.y+_rectangles[feature_index].ymax;if(xmin<0)xmin=0;if(xmax>=_image_width)xmax=_image_width-1;if(ymin<0)ymin=0;if(ymax>=_image_height)ymax=_image_height-1;if(xmax>xmin&&ymax>ymin){returnscalar_t(+_integral_image[xmin+_image_width*ymin]+_integral_image[xmax+_image_width*ymax]-_integral_image[xmax+_image_width*ymin]-_integral_image[xmin+_image_width*ymax]);}else{return0.0;}}