void IntImage::Resize(IntImage &result, REAL ratio) const { result.SetSize(CSize(int(m_iHeight*ratio),int(m_iWidth*ratio))); ratio = 1/ratio; for(int i=0,rh=result.m_iHeight,rw=result.m_iWidth;i<rh;i++) for(int j=0;j<rw;j++) { int x0,y0; REAL x,y,fx0,fx1; x = j*ratio; y = i*ratio; x0 = (int)(x); y0 = (int)(y); //by Jianxin Wu //1. The conversion of float to int in C is towards to 0 point, i.e. the floor function for positive numbers, and ceiling function for negative numbers. //2. We only make use of ratio<1 in this applicaiton, and all numbers involved are positive. //Using these, we have 0<=x<=height-1 and 0<=y<=width-1. Thus, boundary conditions check is not necessary. //In languages other than C/C++ or ratio>=1, take care. if (x0 == m_iWidth-1) x0--; if (y0 == m_iHeight-1) y0--; x = x - x0; y = y - y0; fx0 = m_Data[y0][x0] + x*(m_Data[y0][x0+1]-m_Data[y0][x0]); fx1 = m_Data[y0+1][x0] + x*(m_Data[y0+1][x0+1]-m_Data[y0+1][x0]); result.m_Data[i][j] = fx0 + y*(fx1-fx0); } }
void ReadOneTrainingSample(ifstream& is,IntImage& image) { int i,j; char buf[256]; ASSERT(sx<=256 && sy<=256); is>>image.label; is.ignore(256,'\n'); ASSERT( (image.label == 0) || (image.label == 1) ); is>>image.height>>image.width; is.ignore(256,'\n'); ASSERT(image.height==sx); ASSERT(image.width==sy); image.SetSize(CSize(image.height+1,image.width+1)); for(i=0;i<image.height;i++) image.data[i][0] = 0; for(i=0;i<image.width;i++) image.data[0][i] = 0; for(i=1;i<image.height;i++) { is.read(buf,image.width-1); for(j=1;j<image.width;j++) { image.data[i][j] = REAL(int(unsigned char(buf[j-1]))); ASSERT(image.data[i][j]>=0 && image.data[i][j] <= 255); } } is.ignore(256,'\n'); }
void IntImage::CalcSquareAndIntegral(IntImage& square, IntImage& image) const { REAL partialsum,partialsum2; square.SetSize(CSize(m_iHeight+1,m_iWidth+1)); image.SetSize(CSize(m_iHeight+1,m_iWidth+1)); for(int i=0;i<=m_iWidth+1;i++) square.m_Buf[i]=image.m_Buf[i]=0; for(int i=1;i<=m_iHeight;i++) { partialsum = partialsum2 = 0; square.m_Data[i][0] = 0; image.m_Data[i][0] = 0; for(int j=1;j<=m_iWidth;j++) { partialsum += (m_Data[i-1][j-1]*m_Data[i-1][j-1]); partialsum2 += m_Data[i-1][j-1]; square.m_Data[i][j] = square.m_Data[i-1][j] + partialsum; image.m_Data[i][j] = image.m_Data[i-1][j] + partialsum2; } } }
void IntImage::CalcSquareAndIntegral(IntImage& square, IntImage& image) const { REAL partialsum,partialsum2; square.SetSize(MSize(height+1,width+1)); image.SetSize(MSize(height+1,width+1)); for(int i=0; i<=width+1; i++) square.buf[i]=image.buf[i]=0; for(int i=1; i<=height; i++) { partialsum = partialsum2 = 0; square.data[i][0] = 0; image.data[i][0] = 0; for(int j=1; j<=width; j++) { partialsum += (data[i-1][j-1]*data[i-1][j-1]); partialsum2 += data[i-1][j-1]; square.data[i][j] = square.data[i-1][j] + partialsum; image.data[i][j] = image.data[i-1][j] + partialsum2; } } }
void IntImage<T>::Resize(IntImage<T>& result,const int height,const int width) const { assert(height>0 && width>0); result.SetSize(height,width); REAL ixratio = nrow*1.0/height, iyratio = ncol*1.0/width; REAL* p_y = new REAL[result.ncol]; assert(p_y!=NULL); int* p_y0 = new int[result.ncol]; assert(p_y0!=NULL); for(int i=0; i<width; i++) { p_y[i] = i*iyratio; p_y0[i] = (int)p_y[i]; if(p_y0[i]==ncol-1) p_y0[i]--; p_y[i] -= p_y0[i]; } for(int i=0; i<height; i++) { int x0; REAL x; x = i*ixratio; x0 = (int)x; if(x0==nrow-1) x0--; x -= x0; T* rp = result.p[i]; const T* px0 = p[x0]; const T* px1 = p[x0+1]; for(int j=0; j<width; j++) { int y0=p_y0[j]; REAL y=p_y[j],fx0,fx1; fx0 = REAL(px0[y0] + y*(px0[y0+1]-px0[y0])); fx1 = REAL(px1[y0] + y*(px1[y0+1]-px1[y0])); rp[j] = T(fx0 + x*(fx1-fx0)); } } delete[] p_y; p_y=NULL; delete[] p_y0; p_y0=NULL; }
const bool BoostingInputFiles(const bool discard) { int i,pointer,index; IntImage im; ofstream of; im.SetSize(CSize(gSx+1,gSy+1)); gCascade->LoadDefaultCascade(); pointer=gFaceCount; for(i=gFaceCount;i<gTotalCount;i++) { if(discard) break; if(gCascade->ApplyImagePatch(gTrainSet[i])!=0) { if(pointer!=i) SwapIntImage(gTrainSet[i],gTrainSet[pointer]); pointer++; if(pointer==gTotalCount) break; } } if(pointer==gTotalCount) return true; index = 0; while(pointer<gTotalCount) { if(index==gBootstrapSize) { if(bootstrap_level==max_bootstrap_level-1) return false; else { bootstrap_level++; for(i=0;i<gMaxNumFiles;i++) gFileUsed[i] = 0; index=0; pointer=gFaceCount; } } if(gFileUsed[index]==1) { index++; continue; } gCascade->ApplyOriginalSizeForInputBoosting(gBootstrap_Filenames[index],pointer); gFileUsed[index]=1; index++; } for(i=0;i<gTotalCount;i++) { int k,t; memcpy(im.m_Buf,gTrainSet[i].m_Buf,(gSx+1)*(gSy+1)*sizeof(im.m_Buf[0])); for(k=0;k<=gSy;k++) gTrainSet[i].m_Data[0][k] = 0; for(k=0;k<=gSx;k++) gTrainSet[i].m_Data[k][0] = 0; for(k=1;k<=gSx;k++) for(t=1;t<=gSy;t++) gTrainSet[i].m_Data[k][t] = im.m_Data[k][t]-im.m_Data[k-1][t]-im.m_Data[k][t-1]+im.m_Data[k-1][t-1]; } of.open(gTrainset_Filename,ios_base::out | ios_base::binary); of<<gTotalCount<<endl; unsigned char* writebuf; writebuf = new unsigned char[gSx*gSy]; ASSERT(writebuf!=NULL); for(i=0;i<gTotalCount;i++) { of<<gTrainSet[i].m_iLabel<<endl; of<<gSx<<" "<<gSy<<endl; for(int k=0;k<gSx;k++) for(int t=0;t<gSy;t++) writebuf[k*gSy+t] = (unsigned char)((int)gTrainSet[i].m_Data[k+1][t+1]); of.write((char*)writebuf,gSx*gSy); of<<endl; } delete[] writebuf; writebuf=NULL; of.close(); for(i=0;i<gTotalCount;i++) gTrainSet[i].CalculateVarianceAndIntegralImageInPlace(); for(i=gFaceCount;i<gTotalCount;i++) { if(gCascade->ApplyImagePatch(gTrainSet[i])==0) ; //AfxMessageBox("Something is wrong?"); } return true; }