00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
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
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;
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
00140 void SiftGPU::InitSiftGPU()
00141 {
00142 if(_initialized || GlobalUtil::_GoodOpenGL ==0) return;
00143
00144
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
00236 GlobalUtil::StartTimer("Upload Image data");
00237 if(_texImage->SetImageData(width, height, data, gl_format, gl_type))
00238 {
00239 _image_loaded = 2;
00240 GlobalUtil::StopTimer();
00241 _timing[0] = GlobalUtil::GetElapsedTime();
00242
00243
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
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
00287 if(_imgpath[0]==0 && _image_loaded == 0) return 0;
00288
00289
00290 if(GlobalUtil::_GoodOpenGL ==0 ) return 0;
00291
00292 ClockTimer timer;
00293
00294 if(!_initialized)
00295 {
00296
00297 InitSiftGPU();
00298 if(GlobalUtil::_GoodOpenGL ==0 ) return 0;
00299 }else
00300 {
00301
00302 GlobalUtil::SetGLParam();
00303 }
00304
00305 timer.StartTimer("RUN SIFT");
00306
00307 if( _image_loaded ==0)
00308 {
00309 int width, height;
00310
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
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
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 {
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
00348 _pyramid->RunSIFT(_texImage);
00349
00350
00351 _pyramid->GetPyramidTiming(_timing + 2);
00352
00353
00354 if(_outpath[0] ){ SaveSIFT(_outpath); _outpath[0] = 0;}
00355
00356
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
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
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
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):
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):
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):
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;
00882 if(i+1 <argc) sscanf(param, "%d", &mo);
00883
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;
00898 if(i+1 <argc) sscanf(param, "%d", &sp);
00899
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):
00907 GlobalUtil::_LoweOrigin = 1;
00908 break;
00909 case MAKEINT4(n, a, r, r):
00910 GlobalUtil::_NarrowFeatureTex = 1;
00911 break;
00912 case MAKEINT4(d, e, b, u):
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
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):
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):
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):
01106 case MAKEINT3(t, c, 3):
01107 case MAKEINT2(t, c):
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
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 ));
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
01223 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
01224 glEnableClientState(GL_VERTEX_ARRAY);
01225 glPushMatrix();
01226
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
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
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
01335 if(GlobalUtil::_DescriptorPPT)
01336 {
01337
01338 _pyramid->CopyFeatureVector((float*) (&keys[0]), &descriptors[0]);
01339 }else
01340 {
01341
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 ;
01394 i =(int)hh ;
01395 f = hh- i;
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