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 "CUDA/CudaHmax.H"
00039
00040 #include "CUDA/CudaFilterOps.H"
00041 #include "CUDA/CudaImage.H"
00042
00043 #include "Image/Image.H"
00044 #include "Image/Kernels.H"
00045 #include "CUDA/CudaMathOps.H"
00046 #include "CUDA/CudaConvolutions.H"
00047 #include "Image/MathOps.H"
00048
00049 #include "Util/MathFunctions.H"
00050 #include "Util/Types.H"
00051 #include "Util/log.H"
00052 #include "Util/safecopy.H"
00053
00054 #include <cmath>
00055 #include <fstream>
00056 #include <iostream>
00057 #include <iomanip>
00058 #include <cstdio>
00059 #include <cstdlib>
00060 #include <limits>
00061
00062
00063 CudaHmax::CudaHmax()
00064 { initialized = false; }
00065
00066
00067 CudaHmax::CudaHmax(MemoryPolicy mp, int dev, const int nori, const std::vector<int>& spacess,
00068 const std::vector<int>& scaless, const int c1spaceol,
00069 const bool angleflag, const float s2t, const float s2s,
00070 const float stdmin, const float stdstep,
00071 const int fsmin, const int fsstep)
00072 {
00073 initialized = false;
00074 init(mp,dev,nori, spacess, scaless, c1spaceol, angleflag, s2t, s2s);
00075 initFilters(stdmin,stdstep,fsmin,fsstep);
00076 }
00077
00078
00079 void CudaHmax::init(MemoryPolicy mp, int dev, const int nori, const std::vector<int>& spacess,
00080 const std::vector<int>& scaless, const int c1spaceol,
00081 const bool angleflag, const float s2t, const float s2s)
00082 {
00083 itsMp = mp;
00084 itsDev = dev;
00085 freeMem(); initialized = true; ns = scaless[scaless.size() - 1]; no = nori;
00086 c1SpaceOL = c1spaceol; angleFlag = angleflag; s2Target = s2t; s2Sigma = s2s;
00087 spaceSS.resize(spacess.size()); scaleSS.resize(scaless.size());
00088
00089
00090 nsb = scaleSS.size() - 1;
00091
00092 for (unsigned int i = 0; i < spacess.size(); i ++) spaceSS[i] = spacess[i];
00093 for (unsigned int i = 0; i < scaless.size(); i ++) scaleSS[i] = scaless[i];
00094
00095 }
00096
00097 void CudaHmax::initFilters(const float stdmin, const float stdstep, const int fsmin, const int fsstep)
00098 {
00099
00100 typedef CudaImage<float>* FloatImagePtr;
00101 filter = new FloatImagePtr[ns];
00102 for(int s = 0; s < ns; s++)
00103 {
00104 filter[s] = new CudaImage<float>[no];
00105 for(int o = 0; o < no; o ++)
00106 {
00107
00108 Image<float> tmp = dogFilter<float>(stdmin + stdstep * s,
00109 (float)o * 180.0F / (float)no,
00110 fsmin + fsstep * s);
00111 filter[s][o] = CudaImage<float>(tmp,itsMp,itsDev);
00112
00113
00114
00115
00116 filter[s][o] -= cudaGetAvg(filter[s][o]);
00117
00118
00119 filter[s][o] /= cudaGetSum(cudaSquared(filter[s][o]));
00120 }
00121 }
00122 }
00123
00124
00125 void CudaHmax::freeMem()
00126 {
00127 if (initialized)
00128 {
00129 for(int s = 0; s < ns; s++) delete [] filter[s];
00130 delete [] filter;
00131 initialized = false;
00132 }
00133 }
00134
00135
00136 CudaHmax::~CudaHmax()
00137 { freeMem(); }
00138
00139
00140 std::vector<std::string> CudaHmax::readDir(std::string inName)
00141 {
00142 DIR *dp = opendir(inName.c_str());
00143 if(dp == NULL)
00144 {
00145 LFATAL("Directory does not exist %s",inName.c_str());
00146 }
00147 dirent *dirp;
00148 std::vector<std::string> fList;
00149 while ((dirp = readdir(dp)) != NULL ) {
00150 if (dirp->d_name[0] != '.')
00151 fList.push_back(inName + '/' + std::string(dirp->d_name));
00152 }
00153 LINFO("%"ZU" files in the directory\n", fList.size());
00154 LINFO("file list : \n");
00155 for (unsigned int i=0; i<fList.size(); i++)
00156 LINFO("\t%s", fList[i].c_str());
00157 std::sort(fList.begin(),fList.end());
00158 return fList;
00159 }
00160
00161
00162 std::vector<std::string> CudaHmax::readList(std::string inName)
00163 {
00164 std::ifstream inFile;
00165 inFile.open(inName.c_str(),std::ios::in);
00166 if(!inFile){
00167 LFATAL("Unable to open image path list file: %s",inName.c_str());
00168 }
00169 std::string sLine;
00170 std::vector<std::string> fList;
00171 while (std::getline(inFile, sLine)) {
00172 std::cout << sLine << std::endl;
00173 fList.push_back(sLine);
00174 }
00175 LINFO("%"ZU" paths in the file\n", fList.size());
00176 LINFO("file list : \n");
00177 for (unsigned int i=0; i<fList.size(); i++)
00178 LINFO("\t%s", fList[i].c_str());
00179 inFile.close();
00180 return fList;
00181 }
00182
00183
00184
00185
00186
00187 void CudaHmax::getC1(const CudaImage<float>& input, CudaImage<float>** &c1Res)
00188 {
00189 CudaImage<float> *c1Buff = new CudaImage<float>[no];
00190 CudaImage<float> s1Res;
00191
00192
00193
00194 for(int sb = 0; sb < nsb; sb ++) {
00195
00196
00197 for(int i = 0; i < no; i ++)
00198 c1Buff[i] = CudaImage<float>(input.getWidth(), input.getHeight(), ZEROS, itsMp, itsDev);;
00199
00200
00201 for(int s = scaleSS[sb]; s < scaleSS[sb + 1]; s++) {
00202
00203 for(int o = 0; o < no; o ++) {
00204
00205 if (angleFlag) {
00206 s1Res = cudaConvolveHmax(input, filter[s][o]);
00207
00208 }
00209 else {
00210 s1Res = cudaConvolve(input, filter[s][o], CONV_BOUNDARY_CLEAN);
00211
00212 cudaAbs(s1Res);
00213 }
00214
00215
00216
00217 c1Buff[o] = cudaTakeMax(c1Buff[o], s1Res);
00218 }
00219 }
00220
00221
00222 int c1R = (int)ceil((float)spaceSS[sb] / (float)c1SpaceOL);
00223 int c1PR = spaceSS[sb];
00224
00225
00226 for(int o = 0; o < no; o ++){
00227 c1Res[sb][o] = cudaSpatialPoolMax(c1Buff[o], c1R, c1R, c1PR, c1PR);
00228
00229 }
00230
00231 }
00232
00233 delete [] c1Buff;
00234 }
00235
00236 void CudaHmax::initC1(CudaImage<float> **&c1Res)
00237 {
00238 c1Res = new CudaImage<float>*[nsb];
00239 for (int sb = 0; sb < nsb; sb ++) c1Res[sb] = new CudaImage<float>[no];
00240 }
00241
00242 void CudaHmax::clearC1(CudaImage<float> **&c1Res)
00243 {
00244 for (int sb = 0; sb < nsb; sb ++) delete [] c1Res[sb];
00245 delete [] c1Res;
00246 }
00247
00248 void CudaHmax::printCorners(const char name[], const CudaImage<float>& cim, bool cond)
00249 {
00250 Image<float> im = cim.exportToImage();
00251 if(cond) {
00252 printf("%s\n",name);
00253 int w = im.getWidth();
00254 int h = im.getHeight();
00255 std::string s;
00256 if(w>2 && h>2) {
00257 printf("%f\t%f\t%f\t%f\t%f\n",im.getVal(0,0),im.getVal(1,0),im.getVal(2,0),im.getVal(w-2,0),im.getVal(w-1,0));
00258 printf("%f\t%f\t\t\t%f\t%f\n\n", im.getVal(0,1),im.getVal(1,1),im.getVal(w-2,1),im.getVal(w-1,1));
00259 printf("%f\t%f\t\t\t%f\t%f\n", im.getVal(0,h-2),im.getVal(1,h-2),im.getVal(w-2,h-2),im.getVal(w-1,h-2));
00260 printf("%f\t%f\t%f\t%f\t%f\n",im.getVal(0,h-1),im.getVal(1,h-1),im.getVal(2,h-1),im.getVal(w-2,h-1),im.getVal(w-1,h-1));
00261 }
00262 else if(w>1 && h>1) {
00263 printf("%f\t%f\n",im.getVal(0,0),im.getVal(1,0));
00264 printf("%f\t%f\n", im.getVal(0,1),im.getVal(1,1));
00265 }
00266 else if(w>0 && h>0){
00267 printf("%f\n",im.getVal(0,0));
00268 }
00269 std::cout << "Mean of " << name << " " << mean(im) << std::endl;
00270 std::cout << "Var of " << name << " " << (stdev(im)*stdev(im)) << std::endl;
00271 std::cout << "Width of " << w << " and height of " << h << std::endl;
00272
00273
00274
00275 }
00276 }
00277
00278 void CudaHmax::writeOutImage(const CudaImage<float>& cim,std::string & fName)
00279 {
00280 std::ofstream oFile;
00281 Image<float> d;
00282 oFile.open(fName.c_str(),std::ios::out);
00283 d = cim.exportToImage();
00284 int w,h;
00285 w = d.getWidth();
00286 h = d.getHeight();
00287 for(int i=0;i<w;i++){
00288 for(int j=0;j<h;j++){
00289 oFile << d.getVal(i,j) <<" ";
00290 }
00291 if(i!=w-1)
00292 oFile << std::endl;
00293 }
00294 oFile.close();
00295
00296 }
00297
00298
00299
00300 CudaImage<float> CudaHmax::getC2(const CudaImage<float>& input)
00301 {
00302
00303
00304 CudaImage<float> **c1Res;
00305 initC1(c1Res);
00306
00307
00308
00309
00310 getC1(input, c1Res);
00311
00312
00313
00314
00315 CudaImage<float> c2Res(no * no, no * no, NO_INIT,itsMp,itsDev);
00316 cudaClear(c2Res,-1.0E10F);
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 LFATAL("Generic HMAX C2 Calculation not supported");
00345 return c2Res;
00346 }
00347
00348 void CudaHmax::sumFilter(const CudaImage<float>& image, const float radius, CudaImage<float>& newImage)
00349 {
00350 Rectangle sumSupport = Rectangle::tlbrI(0,0,int(radius*2.0F),int(radius*2.0F));
00351 sumFilter(image,sumSupport,newImage);
00352 }
00353
00354 void CudaHmax::sumFilter(const CudaImage<float>& image, const Rectangle& support, CudaImage<float>& newImage)
00355 {
00356
00357 Dims d(support.top()+support.bottomI()+1,support.left()+support.rightI()+1);
00358
00359 CudaImage<float> a(d,NO_INIT,itsMp,itsDev);
00360 cudaClear(a,1.0F);
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 newImage = cudaConvolve(image,a,CONV_BOUNDARY_ZERO);
00372 }
00373
00374
00375
00376
00377
00378
00379