Histogram of oriented gradients (orientation discretized in 12 bins) taken at random positions and scales.
Strongly inspired from francoisfleuret/zk_v2.
/** Author: Charles Dubout (charles.dubout@idiap.ch) * * Histogram of oriented gradients (orientation discretized in 12 bins) taken * at random positions and scales. * Strongly inspired from francoisfleuret/zk_v2. */#include <mash/heuristic.h>#include <cmath>#include <cstdlib>#include <vector>usingnamespaceMash;//------------------------------------------------------------------------------/// The 'HoG' heuristic class//------------------------------------------------------------------------------classHoGHeuristic:publicHeuristic{//_____ Implementation of Heuristic __________public:HoGHeuristic();virtualunsignedintdim();virtualvoidprepareForCoordinates();virtualscalar_tcomputeFeature(unsignedintfeature_index);private:// The number of rectanglesstaticconstunsignedintnbRects=1000;// Type of a rectanglestructRect{// Coordinates of the region where to compute the histogramintxMin,yMin,xMax,yMax;// The bin the rectangle is looking atunsignedintbin;};// The rectanglesstd::vector<Rect>rects_;// The 12 integral images used to calculate the HoG'sstd::vector<scalar_t>sats_[12];};//------------------------------------------------------------------------------/// Creation function of the heuristic//------------------------------------------------------------------------------extern"C"Heuristic*new_heuristic(){returnnewHoGHeuristic();}/************************* IMPLEMENTATION OF Heuristic ************************/HoGHeuristic::HoGHeuristic():rects_(nbRects){// Nothing to do}unsignedintHoGHeuristic::dim(){// Compute the size of the region of interestconstintroi_size=roi_extent*2+1;// Initialize the 12 integral imagesfor(unsignedinti=0;i<12;++i){sats_[i].resize(roi_size*roi_size);}// Randomize the nbRects rectangles (4 = minimum size of a rectangle)for(unsignedintr=0;r<nbRects;++r){do{rects_[r].xMin=(std::rand()%roi_size)-(int)roi_extent;rects_[r].yMin=(std::rand()%roi_size)-(int)roi_extent;rects_[r].xMax=(std::rand()%roi_size)-(int)roi_extent;rects_[r].yMax=(std::rand()%roi_size)-(int)roi_extent;}while((rects_[r].xMax<rects_[r].xMin+4)||(rects_[r].yMax<rects_[r].yMin+4));rects_[r].bin=std::rand()%12;}returnnbRects;}voidHoGHeuristic::prepareForCoordinates(){// Compute the coordinates of the top-left pixel of the region of interestconstunsignedintx0=coordinates.x-roi_extent;constunsignedinty0=coordinates.y-roi_extent;// Compute the size of the region of interestconstunsignedintroi_size=roi_extent*2+1;// Get the pixels values of the region of interestbyte_t**pixels=image->grayLines();// Zero out the 12 integral imagesfor(unsignedinti=0;i<12;++i){std::fill(sats_[i].begin(),sats_[i].end(),0);}// Compute the gradient at every pixelfor(unsignedinty=1;y<roi_size-1;++y){for(unsignedintx=1;x<roi_size-1;++x){// Sobel filterscalar_tdx=-(int)pixels[y0+y-1][x0+x-1]-2*(int)pixels[y0+y][x0+x-1]-(int)pixels[y0+y+1][x0+x-1]+(int)pixels[y0+y-1][x0+x+1]+2*(int)pixels[y0+y][x0+x+1]+(int)pixels[y0+y+1][x0+x+1];scalar_tdy=(int)pixels[y0+y-1][x0+x-1]-2*(int)pixels[y0+y-1][x0+x]-(int)pixels[y0+y-1][x0+x+1]+(int)pixels[y0+y+1][x0+x-1]+2*(int)pixels[y0+y+1][x0+x]+(int)pixels[y0+y+1][x0+x+1];// Compute the magnitude and the orientationscalar_tmagnitude=std::sqrt(dx*dx+dy*dy);if(magnitude>0){// In the range [-pi, pi]scalar_ttheta=std::atan2(dy,dx);// Convert theta to the range [0, 12]constscalar_tpi=3.1415926536;theta=theta*6/pi+6;// Just to make sure it's really [0, 12) and not [0, 12]if(theta>=12){theta-=12;}// Bilinear interpolationinttheta0=(int)theta;inttheta1=theta0+1;scalar_talpha=theta-theta0;if(theta1==12){theta1=0;}sats_[theta0][y*roi_size+x]+=(1-alpha)*magnitude;sats_[theta1][y*roi_size+x]+=alpha*magnitude;}}}// Convert the gradient images to integral images// Integral image formula: sat(D) = i(D) + sat(B) + sat(D) - sat(A)for(unsignedinti=0;i<12;++i){for(unsignedinty=1;y<roi_size;++y){for(unsignedintx=1;x<roi_size;++x){sats_[i][y*roi_size+x]+=sats_[i][y*roi_size+x-1]+sats_[i][(y-1)*roi_size+x]-sats_[i][(y-1)*roi_size+x-1];}}}}scalar_tHoGHeuristic::computeFeature(unsignedintfeature_index){// Compute the size of the region of interestconstunsignedintroi_size=roi_extent*2+1;constunsignedintxMin=coordinates.x+rects_[feature_index].xMin;constunsignedintyMin=coordinates.y+rects_[feature_index].yMin;constunsignedintxMax=coordinates.x+rects_[feature_index].xMax;constunsignedintyMax=coordinates.y+rects_[feature_index].yMax;constunsignedintbin=rects_[feature_index].bin;// Integral image formula: sum = sat(A) + sat(C) - sat(B) - sat(D)returnsats_[bin][yMin*roi_size+xMin]+sats_[bin][yMax*roi_size+xMax]-sats_[bin][yMin*roi_size+xMax]-sats_[bin][yMax*roi_size+xMin];}