00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "HMAX/Hmax.H"
00039
00040 #include "Image/FilterOps.H"
00041 #include "Image/Image.H"
00042 #include "Image/Kernels.H"
00043 #include "Image/MathOps.H"
00044 #include "Util/MathFunctions.H"
00045 #include "Util/Types.H"
00046 #include "Util/log.H"
00047 #include "Util/safecopy.H"
00048
00049 #include <cmath>
00050 #include <fstream>
00051 #include <iostream>
00052 #include <iomanip>
00053 #include <cstdio>
00054 #include <cstdlib>
00055 #include <limits>
00056
00057
00058 Hmax::Hmax()
00059 { initialized = false; }
00060
00061
00062 Hmax::Hmax(const int nori, const std::vector<int>& spacess,
00063 const std::vector<int>& scaless, const int c1spaceol,
00064 const bool angleflag, const float s2t, const float s2s,
00065 const float stdmin, const float stdstep,
00066 const int fsmin, const int fsstep)
00067 {
00068 initialized = false;
00069 init(nori, spacess, scaless, c1spaceol, angleflag, s2t, s2s);
00070 initFilters(stdmin,stdstep,fsmin,fsstep);
00071 initialized = true;
00072 }
00073
00074
00075 void Hmax::init(const int nori, const std::vector<int>& spacess,
00076 const std::vector<int>& scaless, const int c1spaceol,
00077 const bool angleflag, const float s2t, const float s2s)
00078 {
00079 freeMem(); ns = scaless[scaless.size() - 1]; no = nori;
00080 c1SpaceOL = c1spaceol; angleFlag = angleflag; s2Target = s2t; s2Sigma = s2s;
00081 spaceSS.resize(spacess.size()); scaleSS.resize(scaless.size());
00082
00083
00084 nsb = scaleSS.size() - 1;
00085
00086 for (unsigned int i = 0; i < spacess.size(); i ++) spaceSS[i] = spacess[i];
00087 for (unsigned int i = 0; i < scaless.size(); i ++) scaleSS[i] = scaless[i];
00088
00089 }
00090
00091 void Hmax::initFilters(const float stdmin, const float stdstep, const int fsmin, const int fsstep)
00092 {
00093
00094 typedef Image<float>* FloatImagePtr;
00095 filter = new FloatImagePtr[ns];
00096 for(int s = 0; s < ns; s++)
00097 {
00098 filter[s] = new Image<float>[no];
00099 for(int o = 0; o < no; o ++)
00100 {
00101
00102 filter[s][o] = dogFilter<float>(stdmin + stdstep * s,
00103 (float)o * 180.0F / (float)no,
00104 fsmin + fsstep * s);
00105
00106 filter[s][o] -= mean(filter[s][o]);
00107
00108
00109 filter[s][o] /= sum(squared(filter[s][o]));
00110 }
00111 }
00112 }
00113
00114 int Hmax::getNumOrientations()
00115 {
00116 return no;
00117 }
00118
00119
00120 void Hmax::freeMem()
00121 {
00122 if (initialized)
00123 {
00124 initialized = false;
00125 for(int s = 0; s < ns; s++) delete [] filter[s];
00126 delete [] filter;
00127 }
00128 }
00129
00130
00131 Hmax::~Hmax()
00132 { freeMem(); }
00133
00134
00135 std::vector<std::string> Hmax::readDir(std::string inName)
00136 {
00137 DIR *dp = opendir(inName.c_str());
00138 if(dp == NULL)
00139 {
00140 LFATAL("Directory does not exist %s",inName.c_str());
00141 }
00142 dirent *dirp;
00143 std::vector<std::string> fList;
00144 while ((dirp = readdir(dp)) != NULL ) {
00145 if (dirp->d_name[0] != '.')
00146 fList.push_back(inName + '/' + std::string(dirp->d_name));
00147 }
00148 LINFO("%"ZU" files in the directory\n", fList.size());
00149 LINFO("file list : \n");
00150 for (unsigned int i=0; i<fList.size(); i++)
00151 LINFO("\t%s", fList[i].c_str());
00152 std::sort(fList.begin(),fList.end());
00153 return fList;
00154 }
00155
00156
00157 std::vector<std::string> Hmax::readList(std::string inName)
00158 {
00159 std::ifstream inFile;
00160 inFile.open(inName.c_str(),std::ios::in);
00161 if(!inFile){
00162 LFATAL("Unable to open image path list file: %s",inName.c_str());
00163 }
00164 std::string sLine;
00165 std::vector<std::string> fList;
00166 while (std::getline(inFile, sLine)) {
00167 std::cout << sLine << std::endl;
00168 fList.push_back(sLine);
00169 }
00170 LINFO("%"ZU" paths in the file\n", fList.size());
00171 LINFO("file list : \n");
00172 for (unsigned int i=0; i<fList.size(); i++)
00173 LINFO("\t%s", fList[i].c_str());
00174 inFile.close();
00175 return fList;
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 Image<float> Hmax::origGetC2(const Image<float>& input)
00192 {
00193 int offTab[8]={0,0,0,-1,-1,0,-1,-1};
00194 int imgy,imgx;
00195 int i,j,k,x,y,bufX,bufY;
00196 float *buf,*bStart,*currB;
00197 int fx,fy;
00198 float res;
00199 float imgLen;
00200 float *retPtr,*rPtr2;
00201 Image<float> retC2;
00202 float *ret,*c2Ptr;
00203 float *sBuf,*sBufPtr,*sPtr2;
00204 float *c1Act,s2Resp;
00205 int maxFS,sSS,scaleInd,numScaleBands,numSimpleFilters,numPos;
00206 int currScale,yS,xS,sFInd;
00207 int f1,f2,f3,f4,c2Ind,maxXY;
00208 int poolRange;
00209
00210 Image<float>::const_iterator image = input.begin();
00211 imgy = input.getHeight();
00212 imgx = input.getWidth();
00213
00214 maxFS = filter[ns - 1][0].getWidth();
00215
00216
00217
00218
00219
00220
00221 numScaleBands=scaleSS.size()-1;
00222
00223
00224
00225
00226
00227
00228 numSimpleFilters = no;
00229
00230
00231
00232
00233 numPos=(int)(ceil((double)(imgy/spaceSS[0]))*ceil((double)(imgx/spaceSS[0])))*
00234 c1SpaceOL*c1SpaceOL;
00235
00236
00237
00238 retC2.resize(numSimpleFilters*numSimpleFilters,
00239 numSimpleFilters*numSimpleFilters);
00240 c2Ptr=retC2.getArrayPtr();
00241
00242 ret=(float*)malloc(numPos*numScaleBands*numSimpleFilters*sizeof(float));
00243
00244
00245
00246 sBuf=(float*)malloc(numSimpleFilters*imgy*imgx*sizeof(float));
00247
00248
00249 bufX=imgx+maxFS;
00250 bufY=imgy+maxFS;
00251 buf=(float*)malloc(bufX*bufY*sizeof(float));
00252
00253
00254 memset(buf,0,bufX*bufY*sizeof(float));
00255 Image<float>::const_iterator currI = image;
00256 for(currB=buf+(maxFS>>1)*bufX+(maxFS>>1),i=0;i<imgy;i++,
00257 currI+=imgx,currB+=bufX)
00258 safecopy(currB,currI,imgx);
00259
00260 for(scaleInd=0;scaleInd<numScaleBands;scaleInd++){
00261 memset(sBuf,0,numSimpleFilters*imgy*imgx*sizeof(float));
00262 for(currScale=scaleSS[scaleInd];currScale<scaleSS[scaleInd+1];currScale++){
00263 for(sBufPtr=sBuf,sFInd=0;sFInd<numSimpleFilters;sFInd++){
00264 fx = filter[currScale][sFInd].getWidth();
00265 fy = filter[currScale][sFInd].getHeight();
00266 for(y=0,bStart=buf+(maxFS>>1)*bufX+(maxFS>>1);y<imgy;y++,bStart+=
00267 bufX-imgx){
00268 for(x=0;x<imgx;x++,bStart++,sBufPtr++){
00269
00270 Image<float>::const_iterator currF =
00271 filter[currScale][sFInd].begin();
00272 for(res=0,imgLen=0,currB=bStart-fy/2*bufX-fx/2,
00273 j=0;j<fy;j++,currB+=bufX-fx)
00274 for(k=0;k<fx;k++){
00275 imgLen+=*currB**currB;
00276 res += *currB++**currF++;
00277 }
00278 if(angleFlag && (imgLen>0)) res/=sqrt(imgLen);
00279 res=fabs(res);
00280 *sBufPtr = *sBufPtr>res?*sBufPtr:res;
00281 }
00282 }
00283 }
00284 }
00285
00286
00287
00288 for(retPtr=ret+numPos*numSimpleFilters*scaleInd,sSS=(int)
00289 ceil((float)spaceSS[scaleInd]/c1SpaceOL),
00290 poolRange=spaceSS[scaleInd],sFInd=0;sFInd<numSimpleFilters;sFInd++)
00291 for(rPtr2=retPtr+numPos*sFInd,yS=0;yS<imgy;yS+=sSS)
00292 for(xS=0;xS<imgx;xS+=sSS,rPtr2++)
00293
00294
00295 for(*rPtr2=0.0,sBufPtr=sBuf+imgx*(imgy*sFInd+yS)+xS,y=yS;
00296 (y-yS<poolRange)&&(y<imgy);y++)
00297 for(sPtr2=sBufPtr+(y-yS)*imgx,x=xS;(x-xS<poolRange)&&(x<imgx);
00298 x++,sPtr2++)
00299 *rPtr2=*rPtr2>*sPtr2?*rPtr2:*sPtr2;
00300 }
00301
00302
00303
00304
00305
00306
00307 for(c1Act=ret,c2Ind=0,f1=0;f1<numSimpleFilters;f1++)
00308 for(f2=0;f2<numSimpleFilters;f2++)
00309 for(f3=0;f3<numSimpleFilters;f3++)
00310 for(f4=0;f4<numSimpleFilters;f4++,c2Ind++){
00311 for(c2Ptr[c2Ind]=res=-1e10,scaleInd=0;scaleInd<numScaleBands;
00312 scaleInd++){
00313
00314 for(maxXY=(int)ceil(imgy/ceil((float)
00315 spaceSS[scaleInd]/c1SpaceOL)),
00316 y=c1SpaceOL;y<maxXY;y++)
00317 for(x=c1SpaceOL;x<maxXY;x++){
00318
00319
00320 s2Resp=squareOf<float>(c1Act[numPos*(scaleInd*numSimpleFilters+f1)+
00321 y+maxXY*x]-s2Target)+
00322 squareOf<float>(c1Act[numPos*(scaleInd*numSimpleFilters+f2)+y+
00323 c1SpaceOL*offTab[2]+
00324 maxXY*(x+c1SpaceOL*offTab[3])]-s2Target)+
00325 squareOf<float>(c1Act[numPos*(scaleInd*numSimpleFilters+f3)+y+
00326 c1SpaceOL*offTab[4]+
00327 maxXY*(x+c1SpaceOL*offTab[5])]-s2Target)+
00328 squareOf<float>(c1Act[numPos*(scaleInd*numSimpleFilters+f4)+y+
00329 c1SpaceOL*offTab[6]+
00330 maxXY*(x+c1SpaceOL*offTab[7])]-s2Target);
00331 res=s2Resp>res?s2Resp:res;
00332 }
00333 c2Ptr[c2Ind]=c2Ptr[c2Ind]>res?c2Ptr[c2Ind]:res;
00334 }
00335 }
00336 free(sBuf);
00337 free(buf);
00338 free(ret);
00339 return hmaxActivation(retC2, s2Sigma);
00340 }
00341
00342
00343
00344 void Hmax::getC1(const Image<float>& input, Image<float>** &c1Res)
00345 {
00346 Image<float> *c1Buff = new Image<float>[no];
00347 Image<float> s1Res;
00348
00349
00350
00351 for(int sb = 0; sb < nsb; sb ++) {
00352
00353
00354 for(int i = 0; i < no; i ++)
00355 c1Buff[i].resize(input.getWidth(), input.getHeight(), true);;
00356
00357
00358 for(int s = scaleSS[sb]; s < scaleSS[sb + 1]; s++) {
00359
00360 for(int o = 0; o < no; o ++) {
00361
00362 if (angleFlag) {
00363 s1Res = convolveHmax(input, filter[s][o]);
00364
00365 }
00366 else {
00367 s1Res = convolve(input, filter[s][o], CONV_BOUNDARY_CLEAN);
00368
00369 s1Res = abs(s1Res);
00370 }
00371
00372
00373
00374 c1Buff[o] = takeMax<float>(c1Buff[o], s1Res);
00375 }
00376 }
00377
00378
00379 int c1R = (int)ceil((float)spaceSS[sb] / (float)c1SpaceOL);
00380 int c1PR = spaceSS[sb];
00381
00382
00383 for(int o = 0; o < no; o ++){
00384 c1Res[sb][o] = spatialPoolMax(c1Buff[o], c1R, c1R, c1PR, c1PR);
00385
00386 }
00387
00388 }
00389
00390 delete [] c1Buff;
00391 }
00392
00393 void Hmax::initC1(Image<float> **&c1Res)
00394 {
00395 c1Res = new Image<float>*[nsb];
00396 for (int sb = 0; sb < nsb; sb ++) c1Res[sb] = new Image<float>[no];
00397 }
00398
00399 void Hmax::clearC1(Image<float> **&c1Res)
00400 {
00401 for (int sb = 0; sb < nsb; sb ++) delete [] c1Res[sb];
00402 delete [] c1Res;
00403 }
00404
00405 void Hmax::printCorners(const char name[], const Image<float>& im, bool cond)
00406 {
00407 if(cond) {
00408 printf("%s\n",name);
00409 int w = im.getWidth();
00410 int h = im.getHeight();
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427 std::cout << "Mean of " << name << " " << mean(im) << std::endl;
00428 std::cout << "Var of " << name << " " << (stdev(im)*stdev(im)) << std::endl;
00429 std::cout << "Width of " << w << " and height of " << h << std::endl;
00430
00431
00432
00433 }
00434 }
00435
00436 void Hmax::writeOutImage(const Image<float>& im,std::string & fName)
00437 {
00438 std::ofstream oFile;
00439 Image<float> d;
00440 oFile.open(fName.c_str(),std::ios::out);
00441 d = im;
00442 int w,h;
00443 w = d.getWidth();
00444 h = d.getHeight();
00445 for(int i=0;i<w;i++){
00446 for(int j=0;j<h;j++){
00447 oFile << d.getVal(i,j) <<" ";
00448 }
00449 if(i!=w-1)
00450 oFile << std::endl;
00451 }
00452 oFile.close();
00453
00454 }
00455
00456
00457
00458 Image<float> Hmax::getC2(const Image<float>& input)
00459 {
00460
00461 int nsb = scaleSS.size() - 1;
00462
00463
00464 Image<float> **c1Res;
00465 initC1(c1Res);
00466
00467
00468
00469
00470 getC1(input, c1Res);
00471
00472
00473
00474
00475 Image<float> c2Res(no * no, no * no, NO_INIT);
00476 c2Res.clear(-1.0E10F);
00477 int idx = 0;
00478
00479
00480 for (int f1 = 0; f1 < no; f1++)
00481 for (int f2 = 0; f2 < no; f2++)
00482 for (int f3 = 0; f3 < no; f3++)
00483 for (int f4 = 0; f4 < no; f4++) {
00484
00485 float c2r = -1.0E10;
00486
00487 for (int sb = 0; sb < nsb; sb ++) {
00488
00489 float s2r = featurePoolHmax(c1Res[sb][f1], c1Res[sb][f2],
00490 c1Res[sb][f3], c1Res[sb][f4],
00491 c1SpaceOL, c1SpaceOL, s2Target);
00492 if (s2r > c2r) c2r = s2r;
00493 }
00494 c2Res.setVal(idx, c2r); idx ++;
00495 }
00496
00497
00498 clearC1(c1Res);
00499
00500 return hmaxActivation(c2Res, s2Sigma);
00501 }
00502
00503 void Hmax::sumFilter(const Image<float>& image, const float radius, Image<float>& newImage)
00504 {
00505 Rectangle sumSupport = Rectangle::tlbrI(0,0,int(radius*2.0F),int(radius*2.0F));
00506 sumFilter(image,sumSupport,newImage);
00507 }
00508
00509 void Hmax::sumFilter(const Image<float>& image, const Rectangle& support, Image<float>& newImage)
00510 {
00511
00512 Dims d(support.top()+support.bottomI()+1,support.left()+support.rightI()+1);
00513 Image<float> a(d,NO_INIT);
00514 a.clear(1.0F);
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525 newImage = convolve(image,a,CONV_BOUNDARY_ZERO);
00526 }
00527
00528
00529
00530
00531
00532
00533