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


siftgpu
Author(s): Changchang Wu (library), Bence Magyar (ROS wrapper)
autogenerated on Thu Jan 2 2014 11:38:01