GradHistChannel::GradHistChannel(const GradMagChannel& GMC) { int w = GMC.getWidth(); int h = GMC.getHeight(); int nChns = GMC.getnChns(); if (nChns != 1) { std::cerr << "Number of channels should be 1 for the Magnitudes!!" << std::endl; } //Parameters, should be configurable int binSize = 4; //equals shrinking int nw = w / binSize; int nh = h / binSize; int nOrientations = 6; bool full = false; int softBin = 0; //It is important that this memory is set to zero to avoid random values in the result histogram = (float*)calloc(nw * nh * nOrientations, sizeof(float)); ; gradHist(GMC.getMagnitude(), GMC.getOrientation(), histogram, h, w, binSize, nOrientations, softBin, full); setChanneldata(histogram, nw, nh, nOrientations); }
// H=gradHist(M,O,[...]) - see gradientHist.m void mGradHist( int nl, mxArray *pl[], int nr, const mxArray *pr[] ) { int h, w, d, hb, wb, nChns, binSize, nOrients, softBin, useHog; bool full; float *M, *O, *H, clipHog; checkArgs(nl,pl,nr,pr,1,3,2,8,&h,&w,&d,mxSINGLE_CLASS,(void**)&M); O = (float*) mxGetPr(pr[1]); if( mxGetM(pr[1])!=h || mxGetN(pr[1])!=w || d!=1 || mxGetClassID(pr[1])!=mxSINGLE_CLASS ) mexErrMsgTxt("M or O is bad."); binSize = (nr>=3) ? (int) mxGetScalar(pr[2]) : 8; nOrients = (nr>=4) ? (int) mxGetScalar(pr[3]) : 9; softBin = (nr>=5) ? (int) mxGetScalar(pr[4]) : 1; useHog = (nr>=6) ? (int) mxGetScalar(pr[5]) : 0; clipHog = (nr>=7) ? (float) mxGetScalar(pr[6]) : 0.2f; full = (nr>=8) ? (bool) (mxGetScalar(pr[7])>0) : false; hb = h/binSize; wb = w/binSize; nChns = useHog== 0 ? nOrients : (useHog==1 ? nOrients*4 : nOrients*3+5); pl[0] = mxCreateMatrix3(hb,wb,nChns,mxSINGLE_CLASS,1,(void**)&H); if( nOrients==0 ) return; if( useHog==0 ) { gradHist( M, O, H, h, w, binSize, nOrients, softBin, full ); } else if(useHog==1) { hog( M, O, H, h, w, binSize, nOrients, softBin, full, clipHog ); } else { fhog( M, O, H, h, w, binSize, nOrients, softBin, clipHog ); } }
void pcl::people::HOG::compute (float *I, float *descriptor) const { // HOG computation: float *M, *O, *G, *H; M = new float[h_ * w_]; O = new float[h_ * w_]; H = new float[(w_ / bin_size_) * (h_ / bin_size_) * n_orients_](); G = new float[(w_ / bin_size_) * (h_ / bin_size_) * n_orients_ *4](); // Compute gradient magnitude and orientation at each location (uses sse): gradMag (I, h_, w_, n_channels_, M, O ); // Compute n_orients gradient histograms per bin_size x bin_size block of pixels: gradHist ( M, O, h_, w_, bin_size_, n_orients_, soft_bin_, H ); // Apply normalizations: normalization ( H, h_, w_, bin_size_, n_orients_, clip_, G ); // Select descriptor of internal part of the image (remove borders): int k = 0; for (int l = 0; l < (n_orients_ * 4); l++) { for (int j = 1; j < (w_ / bin_size_ - 1); j++) { for (int i = 1; i < (h_ / bin_size_ - 1); i++) { descriptor[k] = G[i + j * h_ / bin_size_ + l * (h_ / bin_size_) * (w_ / bin_size_)]; k++; } } } delete[] M; delete[] O; delete[] H; delete[] G; }
// compute HOG features void hog( float *M, float *O, float *H, int h, int w, int binSize, int nOrients, int softBin, bool full, float clip ) { float *N, *R; const int hb=h/binSize, wb=w/binSize, nb=hb*wb; // compute unnormalized gradient histograms R = (float*) wrCalloc(wb*hb*nOrients,sizeof(float)); gradHist( M, O, R, h, w, binSize, nOrients, softBin, full ); // compute block normalization values N = hogNormMatrix( R, nOrients, hb, wb, binSize ); // perform four normalizations per spatial block hogChannels( H, R, N, hb, wb, nOrients, clip, 0 ); wrFree(N); wrFree(R); }
// H=gradHist(M,O,[bin],[nOrients],[softBin],[useHog],[clip])-see gradientHist.m void mGradHist( int nl, mxArray *pl[], int nr, const mxArray *pr[] ) { int h, w, d, hb, wb, bin, nOrients; bool softBin, useHog; float *M, *O, *H, *G, clip; checkArgs(nl,pl,nr,pr,1,3,2,7,&h,&w,&d,mxSINGLE_CLASS,(void**)&M); O = (float*) mxGetPr(pr[1]); if( mxGetM(pr[1])!=h || mxGetN(pr[1])!=w || d!=1 || mxGetClassID(pr[1])!=mxSINGLE_CLASS ) mexErrMsgTxt("M or O is bad."); bin = (nr>=3) ? (int) mxGetScalar(pr[2]) : 8; nOrients = (nr>=4) ? (int) mxGetScalar(pr[3]) : 9; softBin = (nr>=5) ? (bool) (mxGetScalar(pr[4])>0) : true; useHog = (nr>=6) ? (bool) (mxGetScalar(pr[5])>0) : false; clip = (nr>=7) ? (float) mxGetScalar(pr[6]) : 0.2f; hb=h/bin; wb=w/bin; if( useHog==false ) { pl[0] = mxCreateMatrix3(hb,wb,nOrients,mxSINGLE_CLASS,1,(void**)&H); gradHist( M, O, H, h, w, bin, nOrients, softBin ); } else { pl[0] = mxCreateMatrix3(hb,wb,nOrients*4,mxSINGLE_CLASS,1,(void**)&G); H = (float*) mxCalloc(wb*hb*nOrients,sizeof(float)); gradHist( M, O, H, h, w, bin, nOrients, softBin ); hog( H, G, h, w, bin, nOrients, clip ); mxFree(H); } }
/* H = hog( I, [sBin], [oBin] ) - see hog.m */ void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { int h, w, d, hb, wb, nb, hb1, wb1, sBin, oBin; double *I, *M, *H, *HG; float *O; checkArgs(nlhs,plhs,nrhs,prhs,1,1,1,3,&h,&w,&d,&I); sBin = (nrhs>=2) ? (int) mxGetScalar(prhs[1]) : 8; oBin = (nrhs>=3) ? (int) mxGetScalar(prhs[2]) : 9; hb=h/sBin; wb=w/sBin; nb=wb*hb; hb1=hb>2?hb-2:0; wb1=wb>2?wb-2:0; plhs[0] = mxCreateMatrix3( hb1, wb1, oBin*4, mxDOUBLE_CLASS, 0, (void**) &HG); if( hb1==0 || wb1==0 ) return; M = (double*) mxMalloc(h*w*sizeof(double)); O = (float*) mxMalloc(h*w*sizeof(float)); H = (double*) mxCalloc(nb*oBin, sizeof(double)); gradMag( I, M, O, h, w, d ); gradHist( M, O, H, h, w, d, sBin, oBin, true, true ); hog( H, HG, h, w, d, sBin, oBin ); mxFree(M); mxFree(O); mxFree(H); }
// compute FHOG features void fhog( float *M, float *O, float *H, int h, int w, int binSize, int nOrients, int softBin, float clip ) { const int hb=h/binSize, wb=w/binSize, nb=hb*wb, nbo=nb*nOrients; float *N, *R1, *R2; int o, x; // compute unnormalized constrast sensitive histograms R1 = (float*) wrCalloc(wb*hb*nOrients*2,sizeof(float)); gradHist( M, O, R1, h, w, binSize, nOrients*2, softBin, true ); // compute unnormalized contrast insensitive histograms R2 = (float*) wrCalloc(wb*hb*nOrients,sizeof(float)); for( o=0; o<nOrients; o++ ) for( x=0; x<nb; x++ ) R2[o*nb+x] = R1[o*nb+x]+R1[(o+nOrients)*nb+x]; // compute block normalization values N = hogNormMatrix( R2, nOrients, hb, wb, binSize ); // normalized histograms and texture channels hogChannels( H+nbo*0, R1, N, hb, wb, nOrients*2, clip, 1 ); hogChannels( H+nbo*2, R2, N, hb, wb, nOrients*1, clip, 1 ); hogChannels( H+nbo*3, R1, N, hb, wb, nOrients*2, clip, 2 ); wrFree(N); mxFree(R1); wrFree(R2); }