SiftGPU.cpp
Go to the documentation of this file.
00001 
00002 //      File:           SiftGPU.cpp
00003 //      Author:         Changchang Wu
00004 //      Description :   Implementation of the SIFTGPU classes.
00005 //                                      SiftGPU:        The SiftGPU Tool.  
00006 //                                      SiftGPUEX:      SiftGPU + viewer
00007 //                                      SiftParam:      Sift Parameters
00008 //
00009 //      Copyright (c) 2007 University of North Carolina at Chapel Hill
00010 //      All Rights Reserved
00011 //
00012 //      Permission to use, copy, modify and distribute this software and its
00013 //      documentation for educational, research and non-profit purposes, without
00014 //      fee, and without a written agreement is hereby granted, provided that the
00015 //      above copyright notice and the following paragraph appear in all copies.
00016 //      
00017 //      The University of North Carolina at Chapel Hill make no representations
00018 //      about the suitability of this software for any purpose. It is provided
00019 //      'as is' without express or implied warranty. 
00020 //
00021 //      Please send BUG REPORTS to ccwu@cs.unc.edu
00022 //
00024 
00025 #include "GL/glew.h"
00026 #include <iostream>
00027 #include <fstream>
00028 #include <string>
00029 #include <iomanip>
00030 #include <vector>
00031 #include <algorithm>
00032 #include <math.h>
00033 
00034 #include <time.h>
00035 using namespace std;
00036 
00037 
00038 #include "GlobalUtil.h"
00039 #include "SiftGPU.h"
00040 #include "GLTexImage.h"
00041 #include "ShaderMan.h"
00042 #include "FrameBufferObject.h"
00043 #include "SiftPyramid.h"
00044 #include "PyramidGL.h"
00045 
00046 //CUDA works only with vc8 or higher
00047 #if defined(CUDA_SIFTGPU_ENABLED)
00048 #include "PyramidCU.h"
00049 #endif
00050 
00051 #if defined(CL_SIFTGPU_ENABLED)
00052 #include "PyramidCL.h"
00053 #endif
00054 
00055 
00057 #if  defined(_WIN32) 
00058         #include "direct.h"
00059         #pragma warning (disable : 4786) 
00060         #pragma warning (disable : 4996) 
00061 #else
00062         //compatible with linux
00063         #define _stricmp strcasecmp
00064     #include <stdlib.h>
00065     #include <string.h>
00066 #endif
00067 
00068 #if !defined(_MAX_PATH)
00069         #if defined (PATH_MAX)
00070                 #define _MAX_PATH PATH_MAX
00071         #else
00072                 #define _MAX_PATH 512
00073         #endif
00074 #endif
00075 
00078 //
00079 //just want to make this class invisible
00080 class ImageList:public std::vector<std::string> {};
00081 
00082 SiftGPU::SiftGPU(int np)
00083 { 
00084         _texImage = new GLTexInput;
00085         _imgpath =  new char[_MAX_PATH];
00086         _outpath = new char[_MAX_PATH];
00087     _imgpath[0] = _outpath[0] = 0;
00088         _initialized = 0;
00089         _image_loaded = 0;
00090         _current = 0;
00091         _list = new ImageList();
00092         _pyramid = NULL;
00093 }
00094 
00095 
00096 
00097 SiftGPUEX::SiftGPUEX() 
00098 {
00099         _view = _sub_view = 0;
00100         _view_debug = 0;
00101         GlobalUtil::_UseSiftGPUEX = 1;
00102         srand((unsigned int)time(NULL));
00103         RandomizeColor();
00104 }
00105 
00106 void* SiftGPU::operator new (size_t  size){
00107   void * p = malloc(size);
00108   if (p == 0)  
00109   {
00110           const std::bad_alloc ba;
00111           throw ba; 
00112   }
00113   return p; 
00114 }
00115 
00116 
00117 void SiftGPUEX::RandomizeColor()
00118 {
00119         float hsv[3] = {0, 0.8f, 1.0f};
00120         for(int i = 0; i < COLOR_NUM*3; i+=3)
00121         {
00122                 hsv[0] = (rand()%100)*0.01f; //i/float(COLOR_NUM);
00123                 HSVtoRGB(hsv, _colors+i);               
00124         }
00125 }
00126 
00127 SiftGPU::~SiftGPU()
00128 {
00129         if(_pyramid) delete _pyramid; 
00130         delete _texImage;
00131         delete _list;
00132     delete[] _imgpath;
00133     delete[] _outpath;
00134 }
00135 
00136 
00137 inline void SiftGPU::InitSiftGPU()
00138 {
00139         if(_initialized || GlobalUtil::_GoodOpenGL ==0) return;
00140 
00141         //Parse sift parameters
00142         ParseSiftParam();
00143 
00144 #if !defined(CUDA_SIFTGPU_ENABLED)
00145         if(GlobalUtil::_UseCUDA)
00146         {
00147                 GlobalUtil::_UseCUDA = 0;
00148                 std::cerr       << "---------------------------------------------------------------------------\n"
00149                                         << "CUDA not supported in this binary! To enable it, please use SiftGPU_CUDA_Enable\n" 
00150                                         << "solution for VS2005+ or set siftgpu_enable_cuda to 1 in makefile\n"
00151                                         << "----------------------------------------------------------------------------\n";
00152         }
00153 #else
00154         if(GlobalUtil::_UseCUDA == 0  && GlobalUtil::_UseOpenCL == 0) 
00155         {
00156                 GlobalUtil::InitGLParam(0);
00157         }
00158     if(GlobalUtil::_GoodOpenGL == 0)
00159     {
00160         GlobalUtil::_UseCUDA = 1;
00161         std::cerr << "Switch from OpenGL to CUDA\n";
00162     }
00163 
00164     if(GlobalUtil::_UseCUDA && !PyramidCU::CheckCudaDevice(GlobalUtil::_DeviceIndex))
00165     {
00166         std::cerr << "Switch from CUDA to OpenGL\n"; 
00167         GlobalUtil::_UseCUDA = 0;
00168     }
00169 #endif
00170 
00171         if(GlobalUtil::_verbose)        std::cout   <<"\n[SiftGPU Language]:\t" 
00172                                             << (GlobalUtil::_UseCUDA? "CUDA" : 
00173                                             (GlobalUtil::_UseOpenCL? "OpenCL" : "GLSL")) <<"\n";
00174 
00175 #if defined(CUDA_SIFTGPU_ENABLED)
00176         if(GlobalUtil::_UseCUDA)
00177                 _pyramid = new PyramidCU(*this);
00178         else 
00179 #endif
00180 #if defined(CL_SIFTGPU_ENABLED)
00181     if(GlobalUtil::_UseOpenCL)
00182         _pyramid = new PyramidCL(*this);
00183     else 
00184 #endif
00185 
00186     if(GlobalUtil::_usePackedTex) {
00187                 _pyramid = new PyramidPacked(*this);
00188     }
00189         else
00190                 _pyramid = new PyramidNaive(*this);
00191 
00192         if(GlobalUtil::_GoodOpenGL && GlobalUtil::_InitPyramidWidth > 0 && GlobalUtil::_InitPyramidHeight > 0)
00193         {
00194                 GlobalUtil::StartTimer("Initialize Pyramids");
00195                 _pyramid->InitPyramid(GlobalUtil::_InitPyramidWidth, GlobalUtil::_InitPyramidHeight, 0);
00196                 GlobalUtil::StopTimer();
00197         }
00198 
00199         ClockTimer::InitHighResolution();
00200         _initialized = 1;
00201 }
00202 
00203 int      SiftGPU::RunSIFT(int index)
00204 {
00205         if(_list->size()>0 )
00206         {
00207                 index = index % _list->size();
00208                 if(strcmp(_imgpath, _list->at(index).data()))
00209                 {
00210                         strcpy(_imgpath, _list->at(index).data());
00211                         _image_loaded = 0;
00212                         _current = index;
00213                 }
00214                 return RunSIFT();
00215         }else
00216         {
00217                 return 0;
00218         }
00219 
00220 }
00221 
00222 int  SiftGPU::RunSIFT( int width,  int height, const void * data, unsigned int gl_format, unsigned int gl_type)
00223 {
00224         //makes opengl context active
00225         //GlobalUtil::CreateWindowEZ();
00226 
00227         if(GlobalUtil::_GoodOpenGL ==0 ) return 0;
00228         if(!_initialized) {
00229                 InitSiftGPU();
00230         }
00231         else {
00232                 GlobalUtil::SetGLParam();
00233         }
00234         if(GlobalUtil::_GoodOpenGL ==0 ) return 0;
00235         if(width > 0 && height >0 && data != NULL)
00236         {
00237                 _imgpath[0] = 0;
00238                 //try downsample the image on CPU
00239                 GlobalUtil::StartTimer("Upload Image data");
00240                 if(_texImage->SetImageData(width, height, data, gl_format, gl_type))
00241                 {
00242                         _image_loaded = 2; //gldata;
00243                         GlobalUtil::StopTimer();
00244                         _timing[0] = GlobalUtil::GetElapsedTime();
00245                         
00246                         //if the size of image is different, the pyramid need to be reallocated.
00247                         GlobalUtil::StartTimer("Initialize Pyramid");
00248                         _pyramid->InitPyramid(width, height, _texImage->_down_sampled);
00249                         GlobalUtil::StopTimer();
00250                         _timing[1] = GlobalUtil::GetElapsedTime();
00251 
00252                         return RunSIFT();
00253                 }else
00254                 {
00255                         return 0;
00256                 }
00257         }else
00258         {
00259                 return 0;
00260         }
00261 
00262 }
00263 
00264 int  SiftGPU::RunSIFT(const char * imgpath)
00265 {
00266         if(imgpath && imgpath[0])
00267         {
00268                 //set the new image
00269                 strcpy(_imgpath, imgpath);
00270                 _image_loaded = 0;
00271                 return RunSIFT();
00272         }else
00273         {
00274                 return 0;
00275         }
00276 
00277 
00278 }
00279 
00280 int SiftGPU::RunSIFT(int num, const SiftKeypoint * keys, int keys_have_orientation)
00281 {
00282         if(num <=0) return 0;
00283         _pyramid->SetKeypointList(num, (const float*) keys, 1, keys_have_orientation);
00284         return RunSIFT();
00285 }
00286 
00287 int SiftGPU::RunSIFT()
00288 {
00289         //check image data
00290         if(_imgpath[0]==0 && _image_loaded == 0) return 0;
00291 
00292         //check OpenGL support
00293         if(GlobalUtil::_GoodOpenGL ==0 ) return 0;
00294 
00295         ClockTimer timer;
00296 
00297         if(!_initialized)
00298         {
00299             //initialize SIFT GPU for once
00300                 InitSiftGPU();
00301                 if(GlobalUtil::_GoodOpenGL ==0 ) return 0;
00302         }else
00303         {
00304                 //in case some OpenGL parameters are changed by users
00305                 GlobalUtil::SetGLParam();
00306         }
00307 
00308         timer.StartTimer("RUN SIFT");
00309         //process input image file
00310         if( _image_loaded ==0)
00311         {
00312                 int width, height; 
00313                 //load and try down-sample on cpu
00314                 GlobalUtil::StartTimer("Load Input Image");
00315                 if(!_texImage->LoadImageFile(_imgpath, width, height)) return 0;
00316                 _image_loaded = 1;
00317                 GlobalUtil::StopTimer();
00318                 _timing[0] = GlobalUtil::GetElapsedTime();
00319 
00320                 //make sure the pyrmid can hold the new image.
00321                 GlobalUtil::StartTimer("Initialize Pyramid");
00322                 _pyramid->InitPyramid(width, height, _texImage->_down_sampled);
00323                 GlobalUtil::StopTimer();
00324                 _timing[1] = GlobalUtil::GetElapsedTime();
00325 
00326         }else
00327         {
00328                 //change some global states
00329         if(!GlobalUtil::_UseCUDA && !GlobalUtil::_UseOpenCL)
00330                 {
00331                         GlobalUtil::FitViewPort(1,1);
00332                         _texImage->FitTexViewPort();
00333                 }
00334                 if(_image_loaded == 1)
00335                 {
00336                         _timing[0] = _timing[1] = 0;
00337                 }else
00338                 {//2
00339                         _image_loaded = 1; 
00340                 }
00341         }
00342 
00343         if(_pyramid->_allocated ==0 ) return 0;
00344 
00345 
00346 #ifdef DEBUG_SIFTGPU
00347         _pyramid->BeginDEBUG(_imgpath);
00348 #endif
00349 
00350         //process the image
00351         _pyramid->RunSIFT(_texImage);
00352 
00353     //read back the timing
00354         _pyramid->GetPyramidTiming(_timing + 2);
00355 
00356         //write output once if there is only one input
00357         if(_outpath[0] ){   SaveSIFT(_outpath); _outpath[0] = 0;}
00358         
00359         //terminate the process when -exit is provided. 
00360         if(GlobalUtil::_ExitAfterSIFT && GlobalUtil::_UseSiftGPUEX) exit(0); 
00361 
00362         timer.StopTimer();
00363         if(GlobalUtil::_verbose)std::cout<<endl;
00364 
00365     return _pyramid->GetSucessStatus();
00366 }
00367 
00368 
00369 void SiftGPU::SetKeypointList(int num, const SiftKeypoint * keys, int keys_have_orientation)
00370 {
00371         _pyramid->SetKeypointList(num, (const float*)keys, 0, keys_have_orientation);
00372 }
00373 
00374 void SiftGPUEX::DisplayInput() 
00375 {
00376         if(_texImage==NULL) return;
00377     _texImage->VerifyTexture();
00378         _texImage->BindTex();
00379         _texImage->DrawImage();
00380         _texImage->UnbindTex();
00381 
00382 }
00383 
00384 void SiftGPU::SetVerbose(int verbose)
00385 {
00386         GlobalUtil::_timingO = verbose>2;
00387         GlobalUtil::_timingL = verbose>3;
00388         if(verbose == -1)
00389         {
00390                 //Loop between verbose level 0, 1, 2
00391                 if(GlobalUtil::_verbose)
00392                 {
00393                         GlobalUtil::_verbose  = GlobalUtil::_timingS;
00394                         GlobalUtil::_timingS = 0;
00395                         if(GlobalUtil::_verbose ==0 && GlobalUtil::_UseSiftGPUEX)
00396                                 std::cout << "Console ouput disabled, press Q/V to enable\n\n";
00397                 }else
00398                 {
00399                         GlobalUtil::_verbose = 1;
00400                         GlobalUtil::_timingS = 1;
00401                 }
00402         }else if(verbose == -2)
00403         {
00404                 //trick for disabling all output (still keeps the timing level)
00405                 GlobalUtil::_verbose = 0;
00406                 GlobalUtil::_timingS = 1;
00407         }else 
00408         {
00409                 GlobalUtil::_verbose = verbose>0;
00410                 GlobalUtil::_timingS = verbose>1;
00411         }
00412 }
00413 
00414 SiftParam::SiftParam()
00415 {
00416 
00417         _level_min = -1;
00418         _dog_level_num  = 3;
00419         _level_max = 0;
00420         _sigma0 = 0;
00421         _sigman = 0;
00422         _edge_threshold = 0;
00423         _dog_threshold =  0;
00424 
00425 
00426 }
00427 
00428 float SiftParam::GetInitialSmoothSigma(int octave_min)
00429 {
00430         float   sa = _sigma0 * powf(2.0f, float(_level_min)/float(_dog_level_num)) ; 
00431         float   sb = _sigman / powf(2.0f,  float(octave_min)) ;//
00432         float   sigma_skip0 = sa > sb + 0.001?sqrt(sa*sa - sb*sb): 0.0f;
00433         return  sigma_skip0; 
00434 }
00435 
00436 void SiftParam::ParseSiftParam()
00437 { 
00438 
00439         if(_dog_level_num ==0) _dog_level_num = 3;
00440         if(_level_max ==0) _level_max = _dog_level_num + 1;
00441         if(_sigma0 ==0.0f) _sigma0 = 1.6f * powf(2.0f, 1.0f / _dog_level_num) ;
00442         if(_sigman == 0.0f) _sigman = 0.5f;
00443 
00444 
00445         _level_num = _level_max -_level_min + 1;
00446 
00447         _level_ds  = _level_min + _dog_level_num;
00448         if(_level_ds > _level_max ) _level_ds = _level_max ;
00449 
00451         float _sigmak = powf(2.0f, 1.0f / _dog_level_num) ;
00452         float dsigma0 = _sigma0 * sqrt (1.0f - 1.0f / (_sigmak*_sigmak) ) ;
00453         float sa, sb;
00454 
00455  
00456         sa = _sigma0 * powf(_sigmak, (float)_level_min) ; 
00457         sb = _sigman / powf(2.0f,   (float)GlobalUtil::_octave_min_default) ;//
00458 
00459         _sigma_skip0 = sa>sb+ 0.001?sqrt(sa*sa - sb*sb): 0.0f;
00460 
00461     sa = _sigma0 * powf(_sigmak, float(_level_min )) ;
00462     sb = _sigma0 * powf(_sigmak, float(_level_ds - _dog_level_num)) ;
00463 
00464         _sigma_skip1 = sa>sb + 0.001? sqrt(sa*sa - sb*sb): 0.0f;
00465 
00466         _sigma_num = _level_max - _level_min;
00467         _sigma = new float[_sigma_num];
00468 
00469         for(int i = _level_min + 1; i <= _level_max; i++)
00470         {
00471                 _sigma[i-_level_min -1] =  dsigma0 * powf(_sigmak, float(i)) ;
00472         }
00473 
00474         if(_dog_threshold ==0)  _dog_threshold      = 0.02f / _dog_level_num ;
00475         if(_edge_threshold==0) _edge_threshold          = 10.0f;
00476 }
00477 
00478 
00479 void SiftGPUEX::DisplayOctave(void (*UseDisplayShader)(), int i)
00480 {
00481         if(_pyramid == NULL)return;
00482         const int grid_sz = (int)ceil(_level_num/2.0);
00483         double scale = 1.0/grid_sz ;
00484         int gx=0, gy=0, dx, dy;
00485 
00486         if(_pyramid->_octave_min >0) scale *= (1<<_pyramid->_octave_min);
00487         else if(_pyramid->_octave_min < 0) scale /= (1<<(-_pyramid->_octave_min));
00488 
00489 
00490         i = i% _pyramid->_octave_num;  //
00491         if(i<0 ) i+= _pyramid->_octave_num;
00492 
00493         scale *= ( 1<<(i));
00494 
00495 
00496 
00497 
00498         UseDisplayShader();
00499 
00500         glPushMatrix();
00501         glScaled(scale, scale, scale);
00502         for(int level = _level_min; level<= _level_max; level++)
00503         {
00504                 GLTexImage * tex = _pyramid->GetLevelTexture(i+_pyramid->_octave_min, level);
00505                 dx = tex->GetImgWidth();
00506                 dy = tex->GetImgHeight();
00507 
00508                 glPushMatrix();
00509 
00510                 glTranslated(dx*gx, dy*gy, 0);
00511 
00512                 tex->BindTex();
00513 
00514                 tex->DrawImage();
00515                 tex->UnbindTex();
00516 
00517                 glPopMatrix();
00518 
00519                 gx++;
00520                 if(gx>=grid_sz) 
00521                 {
00522                         gx =0;
00523                         gy++;
00524                 }
00525 
00526         }
00527 
00528         glPopMatrix();
00529         ShaderMan::UnloadProgram();
00530 }
00531 
00532 void SiftGPUEX::DisplayPyramid( void (*UseDisplayShader)(), int dataName, int nskip1, int nskip2)
00533 {
00534 
00535         if(_pyramid == NULL)return;
00536         int grid_sz = (_level_num -nskip1 - nskip2);
00537         if(grid_sz > 4) grid_sz = (int)ceil(grid_sz*0.5);
00538         double scale = 1.0/grid_sz;
00539         int stepx = 0, stepy = 0, dx, dy=0, nstep;
00540 
00541         if(_pyramid->_octave_min >0) scale *= (1<<_pyramid->_octave_min);
00542         else if(_pyramid->_octave_min < 0) scale /= (1<<(-_pyramid->_octave_min));
00543 
00544 
00545         glPushMatrix();
00546         glScaled(scale, scale, scale);
00547 
00548         for(int i = _pyramid->_octave_min; i < _pyramid->_octave_min+_pyramid->_octave_num; i++)
00549         {
00550         
00551                 nstep = i==_pyramid->_octave_min? grid_sz: _level_num;
00552                 dx = 0;
00553                 UseDisplayShader();
00554                 for(int j = _level_min + nskip1; j <= _level_max-nskip2; j++)
00555                 {
00556                         GLTexImage * tex = _pyramid->GetLevelTexture(i, j, dataName);
00557                         if(tex->GetImgWidth() == 0 || tex->GetImgHeight() == 0) continue;
00558                         stepx = tex->GetImgWidth();
00559                         stepy = tex->GetImgHeight();    
00561                         if(j == _level_min + nskip1 + nstep)
00562                         {
00563                                 dy += stepy;
00564                                 dx = 0;
00565                         }
00566 
00567                         glPushMatrix();
00568                         glTranslated(dx, dy, 0);
00569                         tex->BindTex();
00570                         tex->DrawImage();
00571                         tex->UnbindTex();
00572                         glPopMatrix();
00573 
00574                         dx += stepx;
00575 
00576                 }
00577 
00578                 ShaderMan::UnloadProgram();
00579 
00580                 dy+= stepy;
00581         }
00582 
00583         glPopMatrix();
00584 }
00585 
00586 
00587 void SiftGPUEX::DisplayLevel(void (*UseDisplayShader)(), int i)
00588 {
00589         if(_pyramid == NULL)return;
00590 
00591         i = i%(_level_num * _pyramid->_octave_num);
00592         if (i<0 ) i+= (_level_num * _pyramid->_octave_num);
00593         int octave = _pyramid->_octave_min + i/_level_num;
00594         int level  = _level_min + i%_level_num;
00595         double scale = 1.0;
00596 
00597         if(octave >0) scale *= (1<<octave);
00598         else if(octave < 0) scale /= (1<<(-octave));
00599 
00600         GLTexImage * tex = _pyramid->GetLevelTexture(octave, level);
00601 
00602         UseDisplayShader();
00603 
00604         glPushMatrix();
00605         glScaled(scale, scale, scale);
00606         tex->BindTex();
00607         tex->DrawImage();
00608         tex->UnbindTex();
00609         glPopMatrix();
00610         ShaderMan::UnloadProgram();
00611 }
00612 
00613 void SiftGPUEX::DisplaySIFT()
00614 {
00615         if(_pyramid == NULL) return;
00616     glEnable(GlobalUtil::_texTarget);
00617         switch(_view)
00618         {
00619         case 0:
00620                 DisplayInput();
00621                 DisplayFeatureBox(_sub_view);
00622                 break;
00623         case 1:
00624                 DisplayPyramid(ShaderMan::UseShaderDisplayGaussian, SiftPyramid::DATA_GAUSSIAN);
00625                 break;
00626         case 2:
00627                 DisplayOctave(ShaderMan::UseShaderDisplayGaussian, _sub_view);  
00628                 break;
00629         case 3:
00630                 DisplayLevel(ShaderMan::UseShaderDisplayGaussian, _sub_view);
00631                 break;
00632         case 4:
00633                 DisplayPyramid(ShaderMan::UseShaderDisplayDOG, SiftPyramid::DATA_DOG, 1);
00634                 break;
00635         case 5:
00636                 DisplayPyramid(ShaderMan::UseShaderDisplayGrad, SiftPyramid::DATA_GRAD, 1);
00637                 break;
00638         case 6:
00639                 DisplayPyramid(ShaderMan::UseShaderDisplayDOG, SiftPyramid::DATA_DOG,2, 1);
00640                 DisplayPyramid(ShaderMan::UseShaderDisplayKeypoints, SiftPyramid::DATA_KEYPOINT, 2,1);
00641         }
00642 }
00643 
00644 
00645 void SiftGPUEX::SetView(int view, int sub_view, char *title)
00646 {
00647         const char* view_titles[] =
00648         {
00649                 "Original Image",
00650                 "Gaussian Pyramid",
00651                 "Octave Images",
00652                 "Level Image",
00653                 "Difference of Gaussian",
00654                 "Gradient",
00655                 "Keypoints"
00656         };
00657         const int view_num = 7;
00658         _view = view % view_num;
00659         if(_view <0) _view +=view_num;
00660         _sub_view = sub_view;
00661 
00662         if(_view_debug)
00663                 strcpy(title, "Debug...");
00664         else
00665                 strcpy(title, view_titles[_view]);
00666 
00667 }
00668 
00669 
00670 void SiftGPU::PrintUsage()
00671 {
00672         std::cout
00673         <<"SiftGPU Usage:\n"
00674         <<"-h -help          : Parameter information\n"
00675         <<"-i <strings>      : Filename(s) of the input image(s)\n"
00676         <<"-il <string>      : Filename of an image list file\n"
00677         <<"-o <string>       : Where to save SIFT features\n"
00678         <<"-f <float>        : Filter width factor; Width will be 2*factor+1 (default : 4.0)\n"
00679         <<"-w  <float>       : Orientation sample window factor (default: 2.0)\n"
00680         <<"-dw <float>  *    : Descriptor grid size factor (default : 3.0)\n"
00681         <<"-fo <int>    *    : First octave to detect DOG keypoints(default : 0)\n"
00682         <<"-no <int>         : Maximum number of Octaves (default : no limit)\n"
00683         <<"-d <int>          : Number of DOG levels in an octave (default : 3)\n"
00684         <<"-t <float>        : DOG threshold (default : 0.02/3)\n"
00685         <<"-e <float>        : Edge Threshold (default : 10.0)\n"
00686         <<"-m  <int=2>       : Multi Feature Orientations (default : 1)\n"
00687         <<"-m2p              : 2 Orientations packed as one float\n"
00688         <<"-s  <int=1>       : Sub-Pixel, Sub-Scale Localization, Multi-Refinement(num)\n"
00689         <<"-lcpu -lc <int>   : CPU/GPU mixed Feature List Generation (defaut : 6)\n"
00690         <<"                    Use GPU first, and use CPU when reduction size <= pow(2,num)\n"
00691         <<"                    When <num> is missing or equals -1, no GPU will be used\n"
00692         <<"-noprep           : Upload raw data to GPU (default: RGB->LUM and down-sample on CPU)\n"
00693         <<"-sd               : Skip descriptor computation if specified\n"
00694         <<"-unn    *         : Write unnormalized descriptor if specified\n"
00695         <<"-b      *         : Write binary sift file if specified\n"
00696         <<"-fs <int>         : Block Size for freature storage <default : 4>\n"
00697     <<"-cuda <int=0>     : Use CUDA SiftGPU, and specifiy the device index\n"
00698         <<"-tight            : Automatically resize pyramid to fit new images tightly\n"
00699         <<"-p  <W>x<H>       : Inititialize the pyramids to contain image of WxH (eg -p 1024x768)\n"
00700         <<"-lm  <int>        : Maximum feature count for a level (for pre-allocation)\n"
00701         <<"-lmp <float>      : Maximum percent of pixels as features (for pre-allocaton)\n"
00702         <<"-tc[1|2|3] <int> *: Threshold for limiting the overall number of features (3 methods)\n"
00703         <<"-v <int>          : Level of timing details. Same as calling Setverbose() function\n"
00704         <<"-loweo            : (0, 0) at center of top-left pixel (defaut: corner)\n"
00705         <<"-maxd <int> *     : Max working dimension (default : 2560 (unpacked) / 3200 (packed))\n"
00706         <<"-exit             : Exit program after processing the input image\n"
00707         <<"-unpack           : Use the old unpacked implementation\n"
00708         <<"-di               : Use dynamic array indexing if available (defualt : no)\n"
00709         <<"                    It could make computation faster on cards like GTX 280\n"
00710         <<"-ofix     *       : use 0 as feature orientations.\n"
00711         <<"-ofix-not *       : disable -ofix.\n"
00712         <<"-winpos <X>x<Y> * : Screen coordinate used in Win32 to select monitor/GPU.\n"
00713     <<"-display <string>*: Display name used in Linux/Mac to select monitor/GPU.\n"
00714     <<"\n"
00715     <<"NOTE: parameters marked with * can be changed after initialization\n"
00716         <<"\n";
00717 }
00718 
00719 void SiftGPU::ParseParam(int argc, char **argv)
00720 {
00721     #define CHAR1_TO_INT(x)         ((x >= 'A' && x <= 'Z') ? x + 32 : x)
00722     #define CHAR2_TO_INT(str, i)    (str[i] ? CHAR1_TO_INT(str[i]) + (CHAR1_TO_INT(str[i+1]) << 8) : 0)  
00723     #define CHAR3_TO_INT(str, i)    (str[i] ? CHAR1_TO_INT(str[i]) + (CHAR2_TO_INT(str, i + 1) << 8) : 0)
00724     #define STRING_TO_INT(str)      (CHAR1_TO_INT(str[0]) +  (CHAR3_TO_INT(str, 1) << 8))
00725 
00726 #ifdef _MSC_VER
00727     //charizing is microsoft only
00728     #define MAKEINT1(a)             (#@a )
00729 #else
00730     #define mychar0    '0'
00731     #define mychar1    '1'
00732     #define mychar2    '2'
00733     #define mychar3    '3'
00734     #define mychara    'a'
00735     #define mycharb    'b'
00736     #define mycharc    'c'
00737     #define mychard    'd'
00738     #define mychare    'e'
00739     #define mycharf    'f'
00740     #define mycharg    'g'
00741     #define mycharh    'h'
00742     #define mychari    'i'
00743     #define mycharj    'j'
00744     #define mychark    'k'
00745     #define mycharl    'l'
00746     #define mycharm    'm'
00747     #define mycharn    'n'
00748     #define mycharo    'o'
00749     #define mycharp    'p'
00750     #define mycharq    'q'
00751     #define mycharr    'r'
00752     #define mychars    's'
00753     #define mychart    't'
00754     #define mycharu    'u'
00755     #define mycharv    'v'
00756     #define mycharw    'w'
00757     #define mycharx    'x'
00758     #define mychary    'y'
00759     #define mycharz    'z'
00760     #define MAKEINT1(a)             (mychar##a )
00761 #endif
00762     #define MAKEINT2(a, b)          (MAKEINT1(a) + (MAKEINT1(b) << 8))
00763     #define MAKEINT3(a, b, c)       (MAKEINT1(a) + (MAKEINT2(b, c) << 8))
00764     #define MAKEINT4(a, b, c, d)    (MAKEINT1(a) + (MAKEINT3(b, c, d) << 8))
00765 
00766 
00767         char* arg, *param, * opt;
00768         int  setMaxD = 0, opti;
00769         for(int i = 0; i< argc; i++)
00770         {
00771                 arg = argv[i];
00772                 if(arg == NULL || arg[0] != '-' || !arg[1])continue;
00773                 opt = arg+1;
00774         opti = STRING_TO_INT(opt);
00775                 param = argv[i+1];
00776  
00778         switch(opti)
00779         {
00780         case MAKEINT1(h):
00781         case MAKEINT4(h, e, l, p):
00782                         PrintUsage();
00783             break;            
00784         case MAKEINT4(c, u, d, a):
00785 #if defined(CUDA_SIFTGPU_ENABLED)
00786 
00787             if(!_initialized) 
00788             {
00789                             GlobalUtil::_UseCUDA = 1;
00790                 int device =  -1; 
00791                             if(i+1 <argc && sscanf(param, "%d", &device) && device >=0)
00792                 {
00793                     GlobalUtil::_DeviceIndex = device; 
00794                     i++;
00795                 }
00796             }
00797 #else
00798                 std::cerr       << "---------------------------------------------------------------------------\n"
00799                                         << "CUDA not supported in this binary! To enable it, please use SiftGPU_CUDA_Enable\n" 
00800                                         << "solution for VS2005+ or set siftgpu_enable_cuda to 1 in makefile\n"
00801                                         << "----------------------------------------------------------------------------\n";
00802 #endif
00803             break;  
00804         case MAKEINT2(c, l):
00805 #if defined(CL_SIFTGPU_ENABLED)
00806             if(!_initialized) GlobalUtil::_UseOpenCL = 1;
00807 #else
00808                     std::cerr   << "---------------------------------------------------------------------------\n"
00809                                             << "OpenCL not supported in this binary! Define CL_CUDA_SIFTGPU_ENABLED to..\n"
00810                                             << "----------------------------------------------------------------------------\n";
00811 #endif
00812             break;
00813 
00814         case MAKEINT4(p, a, c, k):
00815                         if(!_initialized) GlobalUtil::_usePackedTex = 1;
00816             break;            
00817         case MAKEINT4(u, n, p, a): //unpack
00818                         if(!_initialized) 
00819             {
00820                 GlobalUtil::_usePackedTex = 0;
00821                 if(!setMaxD) GlobalUtil::_texMaxDim = 2560;
00822             }
00823             break;            
00824         case MAKEINT4(l, c, p, u):
00825         case MAKEINT2(l, c):
00826             if(!_initialized) 
00827             {
00828                             int gskip = -1;
00829                             if(i+1 <argc)       sscanf(param, "%d", &gskip);
00830                             if(gskip >= 0)
00831                             {
00832                                     GlobalUtil::_ListGenSkipGPU = gskip;
00833                             }else
00834                             {
00835                                     GlobalUtil::_ListGenGPU = 0;
00836                             }
00837             }
00838             break;            
00839         case MAKEINT4(p, r, e, p):
00840                         GlobalUtil::_PreProcessOnCPU = 1;
00841             break;            
00842         case MAKEINT4(n, o, p, r): //noprep
00843                         GlobalUtil::_PreProcessOnCPU = 0;
00844             break;            
00845         case MAKEINT4(f, b, o, 1):
00846                         FrameBufferObject::UseSingleFBO =1;
00847             break;            
00848         case MAKEINT4(f, b, o, s):
00849                         FrameBufferObject::UseSingleFBO = 0;
00850             break;            
00851                 case MAKEINT2(s, d):
00852                         if(!_initialized) GlobalUtil::_DescriptorPPT =0;
00853             break;            
00854         case MAKEINT3(u, n, n):
00855                         GlobalUtil::_NormalizedSIFT =0;
00856             break;    
00857         case MAKEINT4(n, d, e, s):
00858                         GlobalUtil::_NormalizedSIFT =1;
00859             break;  
00860         case MAKEINT1(b):
00861                         GlobalUtil::_BinarySIFT = 1;
00862             break;            
00863         case MAKEINT4(t, i, g, h): //tight
00864                         GlobalUtil::_ForceTightPyramid = 1;
00865             break;            
00866         case MAKEINT4(e, x, i, t):
00867                         GlobalUtil::_ExitAfterSIFT = 1;
00868             break;            
00869         case MAKEINT2(d, i):
00870                         GlobalUtil::_UseDynamicIndexing = 1;
00871             break;            
00872         case MAKEINT4(s, i, g, n):
00873             if(!_initialized || GlobalUtil::_UseCUDA) GlobalUtil::_KeepExtremumSign = 1;
00874             break;    
00875                 case MAKEINT1(m):
00876         case MAKEINT2(m, o):
00877             if(!_initialized) 
00878             {
00879                             int mo = 2; //default multi-orientation
00880                             if(i+1 <argc)       sscanf(param, "%d", &mo);
00881                             //at least two orientation
00882                             GlobalUtil::_MaxOrientation = min(max(1, mo), 4);
00883             }
00884             break;            
00885         case MAKEINT3(m, 2, p):
00886             if(!_initialized) 
00887             {
00888                             GlobalUtil::_MaxOrientation = 2;
00889                             GlobalUtil::_OrientationPack2 = 1;
00890             }
00891             break;            
00892         case MAKEINT1(s):
00893             if(!_initialized) 
00894             {
00895                 int sp = 1; //default refinement
00896                 if(i+1 <argc)   sscanf(param, "%d", &sp);
00897                 //at least two orientation
00898                 GlobalUtil::_SubpixelLocalization = min(max(0, sp),5);
00899             }
00900             break;            
00901         case MAKEINT4(o, f, i, x):
00902                         GlobalUtil::_FixedOrientation = (_stricmp(opt, "ofix")==0);
00903             break;            
00904                 case MAKEINT4(l, o, w, e): // loweo
00905                         GlobalUtil::_LoweOrigin = 1;
00906             break;              
00907         case MAKEINT4(n, a, r, r): // narrow
00908                         GlobalUtil::_NarrowFeatureTex = 1;
00909             break;            
00910         case MAKEINT4(d, e, b, u): // debug
00911                         GlobalUtil::_debug = 1;
00912             break;
00913         case MAKEINT2(k, 0):
00914             GlobalUtil::_KeyPointListForceLevel0 = 1;
00915             break;
00916         case MAKEINT2(k, x):
00917             GlobalUtil::_KeyPointListForceLevel0 = 0;
00918             break;
00919         default:
00920             if(i + 1 >= argc) break;
00921             switch(opti)
00922             {
00923             case MAKEINT1(i):
00924                 strcpy(_imgpath, param);
00925                 i++;
00926                 //get the file list..
00927                 _list->push_back(param);
00928                 while( i+1 < argc && argv[i+1][0] !='-')
00929                 {
00930                     _list->push_back(argv[++i]);
00931                 }
00932                 break;            
00933             case MAKEINT2(i, l):
00934                 LoadImageList(param);
00935                 i++;
00936                 break;            
00937             case MAKEINT1(o):
00938                 strcpy(_outpath, param);
00939                 i++;
00940                 break;
00941             case MAKEINT1(f):
00942                 {
00943                     float factor = 0.0f;
00944                     if(sscanf(param, "%f", &factor) && factor > 0 )
00945                     {
00946                         GlobalUtil::_FilterWidthFactor  = factor;
00947                         i++;
00948                     }
00949                 }
00950                 break;  
00951             case MAKEINT2(o, t): 
00952                 {
00953                     float factor = 0.0f;
00954                     if(sscanf(param, "%f", &factor) && factor>0 )
00955                     {
00956                         GlobalUtil::_MulitiOrientationThreshold  = factor;
00957                         i++;
00958                     }
00959                     break;                
00960                 }
00961             case MAKEINT1(w): 
00962                 {
00963                     float factor = 0.0f;
00964                     if(sscanf(param, "%f", &factor) && factor>0 )
00965                     {
00966                         GlobalUtil::_OrientationWindowFactor  = factor;
00967                         i++;
00968                     }
00969                     break;                
00970                 }
00971             case MAKEINT2(d, w): 
00972                 {
00973                     float factor = 0.0f;
00974                     if(sscanf(param, "%f", &factor) && factor > 0 )
00975                     {
00976                         GlobalUtil::_DescriptorWindowFactor  = factor;
00977                         i++;
00978                     }
00979                     break;                
00980                 }
00981             case MAKEINT2(f, o): 
00982                 {
00983                     int first_octave = -3;
00984                     if(sscanf(param, "%d", &first_octave) && first_octave >=-2 )
00985                     {
00986                         GlobalUtil::_octave_min_default = first_octave;
00987                         i++;
00988                     }
00989                     break;
00990                 }
00991             case MAKEINT2(n, o): 
00992                 if(!_initialized)
00993                 {
00994                     int octave_num=-1;
00995                     if(sscanf(param, "%d", &octave_num))
00996                     {
00997                         octave_num = max(-1, octave_num);
00998                         if(octave_num ==-1 || octave_num >=1)
00999                         {
01000                             GlobalUtil::_octave_num_default = octave_num;
01001                             i++;
01002                         }
01003                     }
01004                 }
01005                 break;
01006             case MAKEINT1(t): 
01007                 {
01008                     float threshold = 0.0f;
01009                     if(sscanf(param, "%f", &threshold) && threshold >0 && threshold < 0.5f)
01010                     {
01011                         SiftParam::_dog_threshold = threshold;
01012                         i++;
01013                     }
01014                     break;                
01015                 }
01016             case MAKEINT1(e):
01017                 {
01018                     float threshold = 0.0f;
01019                     if(sscanf(param, "%f", &threshold) && threshold >0 )
01020                     {
01021                         SiftParam::_edge_threshold = threshold;
01022                         i++;
01023                     }
01024                     break;                
01025                 }
01026             case MAKEINT1(d): 
01027                 {
01028                     int num = 0;
01029                     if(sscanf(param, "%d", &num) && num >=1 && num <=10)
01030                     {
01031                         SiftParam::_dog_level_num = num;
01032                         i++;
01033                     }
01034                     break;
01035                 }
01036             case MAKEINT2(f, s): 
01037                 {
01038                     int num = 0;
01039                     if(sscanf(param, "%d", &num) && num >=1)
01040                     {
01041                         GlobalParam::_FeatureTexBlock = num;
01042                         i++;
01043                     }
01044                     break;
01045                 }
01046             case MAKEINT1(p): 
01047                 {
01048                     int w =0, h=0;
01049                     if(sscanf(param, "%dx%d", &w, &h) == 2 && w >0 &&  h>0)
01050                     {
01051                         GlobalParam::_InitPyramidWidth = w;
01052                         GlobalParam::_InitPyramidHeight = h;
01053                         i++;
01054                     }
01055                     break;                
01056                 }
01057             case MAKEINT4(w, i, n, p): //winpos
01058                 {
01059                     int x =0, y=0;
01060                     if(sscanf(param, "%dx%d", &x, &y) == 2)
01061                     {
01062                         GlobalParam::_WindowInitX = x;
01063                         GlobalParam::_WindowInitY = y;
01064                         i++;
01065                     }
01066                     break;                
01067                 }
01068             case MAKEINT4(d, i, s, p): //display
01069                 {
01070                     GlobalParam::_WindowDisplay = param;
01071                     i++;
01072                     break;                
01073                 }
01074             case MAKEINT2(l, m): 
01075                 {
01076                     int num = 0;
01077                     if(sscanf(param, "%d", &num) && num >=1000)
01078                     {
01079                         GlobalParam::_MaxLevelFeatureNum = num;
01080                         i++;
01081                     }
01082                     break;                
01083                 }
01084             case MAKEINT3(l, m, p): 
01085                 {
01086                     float num = 0.0f;
01087                     if(sscanf(param, "%f", &num) && num >=0.001)
01088                     {
01089                         GlobalParam::_MaxFeaturePercent = num;
01090                         i++;
01091                     }
01092                     break;                
01093                 }
01094             case MAKEINT3(t, c, 2): //downward
01095             case MAKEINT3(t, c, 3):
01096             case MAKEINT2(t, c):  //tc
01097             case MAKEINT3(t, c, 1):  //
01098                 {
01099                     switch (opti)
01100                     {
01101                         case MAKEINT3(t, c, 2): GlobalUtil::_TruncateMethod = 1; break;
01102                         case MAKEINT3(t, c, 3): GlobalUtil::_TruncateMethod = 2; break;
01103                         default:                GlobalUtil::_TruncateMethod = 0; break;
01104                     }
01105                     int num = -1;
01106                     if(sscanf(param, "%d", &num) && num > 0)
01107                     {
01108                         GlobalParam::_FeatureCountThreshold = num;
01109                         i++;
01110                     }
01111                     break;                
01112                 }
01113             case MAKEINT1(v):
01114                 {
01115                     int num = 0;
01116                     if(sscanf(param, "%d", &num) && num >=0 && num <= 4)
01117                     {
01118                         SetVerbose(num);
01119                     }
01120                     break;                
01121                 }
01122             case MAKEINT4(m, a, x, d):   
01123                 {
01124                     int num = 0;
01125                     if(sscanf(param, "%d", &num) && num > 0)
01126                     {
01127                         GlobalUtil::_texMaxDim = num; 
01128                         setMaxD = 1;
01129                     }
01130                     break;
01131                 } 
01132            case MAKEINT4(m, i, n, d):   
01133                 {
01134                     int num = 0;
01135                     if(sscanf(param, "%d", &num) && num >= 8)
01136                     {
01137                         GlobalUtil::_texMinDim = num; 
01138                     }
01139                     break;
01140                 } 
01141             default:
01142                 break;
01143             }           
01144             break;
01145         }
01146         }
01147         //do not write result if there are more than one input images
01148         if(_outpath[0] && _list->size()>1)              _outpath[0] = 0;
01149 } 
01150 
01151 void SiftGPU::SetImageList(int nimage, const char** filelist)
01152 {
01153         _list->resize(0);
01154         for(int i = 0; i < nimage; i++)
01155         {
01156                 _list->push_back(filelist[i]);
01157         }
01158         _current = 0;
01159 
01160 }
01161 void SiftGPU:: LoadImageList(char *imlist)
01162 {
01163         char filename[_MAX_PATH];
01164         ifstream in(imlist);
01165         while(in>>filename)
01166         {
01167                 _list->push_back(filename);
01168         }
01169         in.close();
01170 
01171 
01172         if(_list->size()>0)
01173         {
01174                 strcpy(_imgpath, _list->at(0).data());
01175                 strcpy(filename, imlist);
01176                 char * slash = strrchr(filename, '\\');
01177                 if(slash == 0) slash = strrchr(filename, '/');
01178                 if(slash )
01179                 {
01180                         slash[1] = 0;
01181                         chdir(filename);
01182                 }
01183         }
01184         _image_loaded = 0;
01185 
01186 
01187 }
01188 float SiftParam::GetLevelSigma( int lev)
01189 {
01190         return _sigma0 * powf( 2.0f,  float(lev) / float(_dog_level_num )); //bug fix 9/12/2007
01191 }
01192 
01193 
01194 
01195 void SiftGPUEX::DisplayFeatureBox(int view )
01196 {
01197         view = view%3;
01198         if(view<0)view+=3;
01199         if(view ==2) return;
01200         int idx = 0;
01201         const int *fnum = _pyramid->GetLevelFeatureNum();
01202         const GLuint *vbo = _pyramid->GetFeatureDipslayVBO();
01203         const GLuint *vbop = _pyramid->GetPointDisplayVBO();
01204         if(vbo == NULL || vbop == NULL) return;
01205         //int  nvbo = _dog_level_num * _pyramid->_octave_num;
01206         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
01207         glEnableClientState(GL_VERTEX_ARRAY);
01208         glPushMatrix();
01209 //      glTranslatef(0.0f, 0.0f, -1.0f);
01210         glPointSize(2.0f);
01211 
01212         float scale = 1.0f;
01213         if(_pyramid->_octave_min >0) scale *= (1<<_pyramid->_octave_min);
01214         else if(_pyramid->_octave_min < 0) scale /= (1<<(-_pyramid->_octave_min));
01215         glScalef(scale, scale, 1.0f);
01216 
01217 
01218         for(int i = 0; i < _pyramid->_octave_num; i++)
01219         {
01220 
01221                 for(int j = 0; j < _dog_level_num; j++, idx++)
01222                 {
01223                         if(fnum[idx]>0)
01224                         {
01225                                 if(view ==0)
01226                                 {
01227                                         glColor3f(0.2f, 1.0f, 0.2f);
01228                                         glBindBuffer(GL_ARRAY_BUFFER_ARB, vbop[idx]);
01229                                         glVertexPointer( 4, GL_FLOAT,4*sizeof(float), (char *) 0);
01230                                         glDrawArrays( GL_POINTS, 0, fnum[idx]);
01231                                         glFlush();
01232                                 }else
01233                                 {
01234                                                 
01235                                         //glColor3f(1.0f, 0.0f, 0.0f);
01236                                         glColor3fv(_colors+ (idx%COLOR_NUM)*3);
01237                                         glBindBuffer(GL_ARRAY_BUFFER_ARB, vbo[idx]);
01238                                         glVertexPointer( 4, GL_FLOAT,4*sizeof(float), (char *) 0);
01239                                         glDrawArrays( GL_LINES, 0, fnum[idx]*10 );
01240                                         glFlush();
01241                                 }
01242 
01243                         }
01244                 
01245                 }
01246                 glTranslatef(-.5f, -.5f, 0.0f);
01247                 glScalef(2.0f, 2.0f, 1.0f);
01248 
01249         }
01250         glPopMatrix();
01251         glDisableClientState(GL_VERTEX_ARRAY);
01252         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
01253         glPointSize(1.0f);
01254                                                         
01255 }
01256 
01257 void SiftGPUEX::ToggleDisplayDebug()
01258 {
01259         _view_debug = !_view_debug;
01260 }
01261 
01262 void SiftGPUEX::DisplayDebug()
01263 {
01264         glPointSize(1.0f);
01265         glColor3f(1.0f, 0.0f, 0.0f);
01266         ShaderMan::UseShaderDebug();
01267         glBegin(GL_POINTS);
01268         for(int i = 0; i < 100; i++)
01269         {
01270                 glVertex2f(i*4.0f+0.5f, i*4.0f+0.5f);
01271         }
01272         glEnd();
01273         ShaderMan::UnloadProgram();
01274 }
01275 
01276 int SiftGPU::CreateContextGL()
01277 {
01278     if(GlobalUtil::_UseOpenCL || GlobalUtil::_UseCUDA)
01279     {
01280         //do nothing
01281     }
01282     else if(!GlobalUtil::CreateWindowEZ()) 
01283     {
01284 #if CUDA_SIFTGPU_ENABLED
01285                 GlobalUtil::_UseCUDA = 1;
01286 #else
01287         return 0;
01288 #endif
01289     }
01290 
01291         return VerifyContextGL();
01292 }
01293 
01294 int SiftGPU::VerifyContextGL()
01295 {
01296         InitSiftGPU();
01297         return (GlobalUtil::_GoodOpenGL > 0) + GlobalUtil::_FullSupported;
01298 }
01299 
01300 int SiftGPU::IsFullSupported()
01301 {
01302         return GlobalUtil::_GoodOpenGL > 0 &&  GlobalUtil::_FullSupported;
01303 }
01304 
01305 void SiftGPU::SaveSIFT(const char * szFileName)
01306 {
01307         _pyramid->SaveSIFT(szFileName);
01308 }
01309 
01310 int SiftGPU::GetFeatureNum()
01311 {
01312         return _pyramid->GetFeatureNum();
01313 }
01314 
01315 void SiftGPU::GetFeatureVector(SiftKeypoint * keys, float * descriptors)
01316 {
01317 //      keys.resize(_pyramid->GetFeatureNum());
01318         if(GlobalUtil::_DescriptorPPT)
01319         {
01320         //      descriptors.resize(128*_pyramid->GetFeatureNum());
01321                 _pyramid->CopyFeatureVector((float*) (&keys[0]), &descriptors[0]);
01322         }else
01323         {
01324                 //descriptors.resize(0);
01325                 _pyramid->CopyFeatureVector((float*) (&keys[0]), NULL);
01326         }
01327 }
01328 
01329 void SiftGPU::SetTightPyramid(int tight)
01330 {
01331         GlobalUtil::_ForceTightPyramid = tight;
01332 }
01333 
01334 int SiftGPU::AllocatePyramid(int width, int height)
01335 {
01336         _pyramid->_down_sample_factor = 0;
01337         _pyramid->_octave_min = GlobalUtil::_octave_min_default;
01338         if(GlobalUtil::_octave_min_default>=0)
01339         {
01340                 width >>= GlobalUtil::_octave_min_default;
01341                 height >>= GlobalUtil::_octave_min_default;
01342         }else
01343         {
01344                 width <<= (-GlobalUtil::_octave_min_default);
01345                 height <<= (-GlobalUtil::_octave_min_default);
01346         }
01347         _pyramid->ResizePyramid(width, height);
01348         return _pyramid->_pyramid_height == height && width == _pyramid->_pyramid_width ;
01349 }
01350 
01351 void SiftGPU::SetMaxDimension(int sz)
01352 {
01353         if(sz < GlobalUtil::_texMaxDimGL)
01354         {
01355                 GlobalUtil::_texMaxDim = sz;
01356         }
01357 }
01358 int SiftGPU::GetImageCount()
01359 {
01360         return _list->size();
01361 }
01362 
01363 void SiftGPUEX::HSVtoRGB(float hsv[3],float rgb[3] )
01364 {
01365 
01366         int i;
01367         float q, t, p;
01368         float hh,f, v = hsv[2];
01369         if(hsv[1]==0.0f)
01370         {
01371                 rgb[0]=rgb[1]=rgb[2]=v;
01372         }
01373         else
01374         {
01376                 hh =hsv[0]*6.0f ;   // sector 0 to 5
01377                 i =(int)hh ;
01378                 f = hh- i;   // factorial part of h
01380                 p=  v * ( 1 - hsv[1] );
01381                 q = v * ( 1 - hsv[1] * f );
01382                 t = v * ( 1 - hsv[1] * ( 1 - f ) );
01383                 switch( i ) {
01384                         case 0:rgb[0] = v;rgb[1] = t;rgb[2] = p;break;
01385                         case 1:rgb[0] = q;rgb[1] = v;rgb[2] = p;break;
01386                         case 2:rgb[0] = p;rgb[1] = v;rgb[2] = t;break;
01387                         case 3:rgb[0] = p;rgb[1] = q;rgb[2] = v;break;
01388                         case 4:rgb[0] = t;rgb[1] = p;rgb[2] = v;break;
01389                         case 5:rgb[0] = v;rgb[1] = p;rgb[2] = q;break;
01390                         default:rgb[0]= 0;rgb[1] = 0;rgb[2] = 0;
01391                 }
01392         }
01393 }
01394 
01395 void SiftGPUEX::GetImageDimension( int &w,  int &h)
01396 {
01397         w = _texImage->GetImgWidth();
01398         h = _texImage->GetImgHeight();
01399 
01400 }
01401 
01402 void SiftGPUEX::GetInitWindowPotition(int&x, int&y)
01403 {
01404         x = GlobalUtil::_WindowInitX;
01405         y = GlobalUtil::_WindowInitY;
01406 }
01407 
01408 SiftGPU* CreateNewSiftGPU(int np)
01409 {
01410         return new SiftGPU(np);
01411 }
01412 
01414 void* ComboSiftGPU::operator new (size_t  size){
01415   void * p = malloc(size);
01416   if (p == 0)  
01417   {
01418           const std::bad_alloc ba;
01419           throw ba; 
01420   }
01421   return p; 
01422 }
01423 
01424 ComboSiftGPU* CreateComboSiftGPU()
01425 {
01426         return new ComboSiftGPU();
01427 }
01428 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines


rgbd_registration
Author(s): Ross Kidson
autogenerated on Sun Oct 6 2013 12:00:40