void ComputeMeanAndVariance(Array2d<double>& data,Array2dC<double>& avg,Array2d<double>& cov,const bool subtractMean) { avg.Create(1,data.ncol); avg.Zero(); cov.Create(data.ncol,data.ncol); cov.Zero(); for(int i=0;i<data.nrow;i++) { for(int j=0;j<data.ncol;j++) avg.buf[j] += data.p[i][j]; for(int j=0;j<data.ncol;j++) for(int k=0;k<data.ncol;k++) cov.p[j][k] += data.p[i][j]*data.p[i][k]; } const double r = 1.0/data.nrow; for(int i=0;i<data.ncol;i++) avg.buf[i] *= r; if(subtractMean) { for(int i=0;i<data.ncol;i++) for(int j=0;j<data.ncol;j++) cov.p[i][j] = cov.p[i][j]*r-avg.buf[i]*avg.buf[j]; } else { for(int i=0;i<data.ncol;i++) for(int j=0;j<data.ncol;j++) cov.p[i][j] = cov.p[i][j]*r; } }
// The function that does the real detection int DetectionScanner::FastScan(IntImage<double>& original,std::vector<CRect>& results,const int stepsize) { if(original.nrow<height+5 || original.ncol<width+5) return 0; const int hd = height/xdiv; const int wd = width/ydiv; InitImage(original); results.clear(); hist.Create(1,baseflength*(xdiv-EXT)*(ydiv-EXT)); NodeDetector* node = cascade->nodes[1]; double** pc = node->classifier.p; int oheight = original.nrow, owidth = original.ncol; CRect rect; while(image.nrow>=height && image.ncol>=width) { InitIntegralImages(stepsize); for(int i=2; i+height<image.nrow-2; i+=stepsize) { const double* sp = scores.p[i]; for(int j=2; j+width<image.ncol-2; j+=stepsize) { if(sp[j]<=0) continue; int* p = hist.buf; hist.Zero(); for(int k=0; k<xdiv-EXT; k++) { for(int t=0; t<ydiv-EXT; t++) { for(int x=i+k*hd+1; x<i+(k+1+EXT)*hd-1; x++) { int* ctp = ct.p[x]; for(int y=j+t*wd+1; y<j+(t+1+EXT)*wd-1; y++) p[ctp[y]]++; } p += baseflength; } } double score = node->thresh; for(int k=0; k<node->classifier.nrow; k++) score += pc[k][hist.buf[k]]; if(score>0) { rect.top = i*oheight/image.nrow; rect.bottom = (i+height)*oheight/image.nrow; rect.left = j*owidth/image.ncol; rect.right = (j+width)*owidth/image.ncol; results.push_back(rect); } } } ResizeImage(); } return 0; }