48 #if defined(SIFTGPU_CUDA_ENABLED)
52 #if defined(CL_SIFTGPU_ENABLED)
60 #pragma warning (disable : 4786)
61 #pragma warning (disable : 4996)
64 #define _stricmp strcasecmp
70 #if !defined(_MAX_PATH)
71 #if defined (PATH_MAX)
72 #define _MAX_PATH PATH_MAX
89 _imgpath[0] = _outpath[0] = 0;
101 _view = _sub_view = 0;
104 srand((
unsigned int)time(
NULL));
111 float hsv[3] = {0, 0.8f, 1.0f};
112 for(
int i = 0; i < COLOR_NUM*3; i+=3)
114 hsv[0] = (rand()%100)*0.01f;
115 HSVtoRGB(hsv, _colors+i);
121 if(_pyramid)
delete _pyramid;
136 #if !defined(SIFTGPU_CUDA_ENABLED)
140 std::cerr <<
"---------------------------------------------------------------------------\n"
141 <<
"CUDA not supported in this binary! To enable it, please use SiftGPU_CUDA_Enable\n"
142 <<
"solution for VS2005+ or set siftgpu_enable_cuda to 1 in makefile\n"
143 <<
"----------------------------------------------------------------------------\n";
153 std::cerr <<
"Switch from OpenGL to CUDA\n";
158 std::cerr <<
"Switch from CUDA to OpenGL\n";
167 #if defined(SIFTGPU_CUDA_ENABLED)
169 _pyramid =
new PyramidCU(*
this);
172 #if defined(CL_SIFTGPU_ENABLED)
174 _pyramid =
new PyramidCL(*
this);
198 index = index % _list->size();
199 if(strcmp(_imgpath, _list->at(index).data()))
201 strcpy(_imgpath, _list->at(index).data());
217 if(!_initialized) InitSiftGPU();
226 if(_texImage->SetImageData(
width,
height, data, gl_format, gl_type))
234 _pyramid->InitPyramid(
width,
height, _texImage->_down_sampled);
252 if(imgpath && imgpath[0])
255 strcpy(_imgpath, imgpath);
268 if(num <=0)
return 0;
269 _pyramid->SetKeypointList(num, (
const float*) keys, 1, keys_have_orientation);
276 if(_imgpath[0]==0 && _image_loaded == 0)
return 0;
294 timer.StartTimer(
"RUN SIFT");
296 if( _image_loaded ==0)
301 if(!_texImage->LoadImageFile(_imgpath,
width,
height))
return 0;
308 _pyramid->InitPyramid(
width,
height, _texImage->_down_sampled);
318 _texImage->FitTexViewPort();
320 if(_image_loaded == 1)
322 _timing[0] = _timing[1] = 0;
329 if(_pyramid->_allocated ==0 )
return 0;
333 _pyramid->BeginDEBUG(_imgpath);
337 _pyramid->RunSIFT(_texImage);
340 _pyramid->GetPyramidTiming(_timing + 2);
343 if(_outpath[0] ){ SaveSIFT(_outpath); _outpath[0] = 0;}
351 return _pyramid->GetSucessStatus();
357 _pyramid->SetKeypointList(num, (
const float*)keys, 0, keys_have_orientation);
360 void SiftGPUEX::DisplayInput()
362 if(_texImage==
NULL)
return;
363 _texImage->VerifyTexture();
364 _texImage->BindTex();
365 _texImage->DrawImage();
366 _texImage->UnbindTex();
382 std::cout <<
"Console output disabled, press Q/V to enable\n\n";
388 }
else if(verbose == -2)
417 float sa = _sigma0 * powf(2.0f,
float(_level_min)/
float(_dog_level_num)) ;
418 float sb = _sigman / powf(2.0f,
float(octave_min)) ;
419 float sigma_skip0 = sa > sb + 0.001?sqrt(sa*sa - sb*sb): 0.0f;
426 if(_dog_level_num ==0) _dog_level_num = 3;
427 if(_level_max ==0) _level_max = _dog_level_num + 1;
428 if(_sigma0 ==0.0f) _sigma0 = 1.6f * powf(2.0f, 1.0f / _dog_level_num) ;
429 if(_sigman == 0.0f) _sigman = 0.5f;
432 _level_num = _level_max -_level_min + 1;
434 _level_ds = _level_min + _dog_level_num;
435 if(_level_ds > _level_max ) _level_ds = _level_max ;
438 float _sigmak = powf(2.0f, 1.0f / _dog_level_num) ;
439 float dsigma0 = _sigma0 * sqrt (1.0f - 1.0f / (_sigmak*_sigmak) ) ;
443 sa = _sigma0 * powf(_sigmak, (
float)_level_min) ;
446 _sigma_skip0 = sa>sb+ 0.001?sqrt(sa*sa - sb*sb): 0.0f;
448 sa = _sigma0 * powf(_sigmak,
float(_level_min )) ;
449 sb = _sigma0 * powf(_sigmak,
float(_level_ds - _dog_level_num)) ;
451 _sigma_skip1 = sa>sb + 0.001? sqrt(sa*sa - sb*sb): 0.0f;
453 _sigma_num = _level_max - _level_min;
454 _sigma =
new float[_sigma_num];
456 for(
int i = _level_min + 1; i <= _level_max; i++)
458 _sigma[i-_level_min -1] = dsigma0 * powf(_sigmak,
float(i)) ;
461 if(_dog_threshold ==0) _dog_threshold = 0.02f / _dog_level_num ;
462 if(_edge_threshold==0) _edge_threshold = 10.0f;
466 void SiftGPUEX::DisplayOctave(
void (*UseDisplayShader)(),
int i)
468 if(_pyramid ==
NULL)
return;
469 const int grid_sz = (int)
ceil(_level_num/2.0);
470 double scale = 1.0/grid_sz ;
471 int gx=0, gy=0, dx, dy;
473 if(_pyramid->_octave_min >0) scale *= (1<<_pyramid->_octave_min);
474 else if(_pyramid->_octave_min < 0) scale /= (1<<(-_pyramid->_octave_min));
477 i = i% _pyramid->_octave_num;
478 if(i<0 ) i+= _pyramid->_octave_num;
488 glScaled(scale, scale, scale);
489 for(
int level = _level_min; level<= _level_max; level++)
491 GLTexImage * tex = _pyramid->GetLevelTexture(i+_pyramid->_octave_min, level);
498 glTranslated(dx*gx, dy*gy, 0);
520 void SiftGPUEX::DisplayPyramid(
void (*UseDisplayShader)(),
int dataName,
int nskip1,
int nskip2)
523 if(_pyramid ==
NULL)
return;
524 int grid_sz = (_level_num -nskip1 - nskip2);
525 if(grid_sz > 4) grid_sz = (int)
ceil(grid_sz*0.5);
526 double scale = 1.0/grid_sz;
527 int stepx = 0, stepy = 0, dx, dy=0, nstep;
529 if(_pyramid->_octave_min >0) scale *= (1<<_pyramid->_octave_min);
530 else if(_pyramid->_octave_min < 0) scale /= (1<<(-_pyramid->_octave_min));
534 glScaled(scale, scale, scale);
536 for(
int i = _pyramid->_octave_min; i < _pyramid->_octave_min+_pyramid->_octave_num; i++)
539 nstep = i==_pyramid->_octave_min? grid_sz: _level_num;
542 for(
int j = _level_min + nskip1; j <= _level_max-nskip2; j++)
544 GLTexImage * tex = _pyramid->GetLevelTexture(i, j, dataName);
549 if(j == _level_min + nskip1 + nstep)
556 glTranslated(dx, dy, 0);
575 void SiftGPUEX::DisplayLevel(
void (*UseDisplayShader)(),
int i)
577 if(_pyramid ==
NULL)
return;
579 i = i%(_level_num * _pyramid->_octave_num);
580 if (i<0 ) i+= (_level_num * _pyramid->_octave_num);
581 int octave = _pyramid->_octave_min + i/_level_num;
582 int level = _level_min + i%_level_num;
585 if(octave >0) scale *= (1<<octave);
586 else if(octave < 0) scale /= (1<<(-octave));
588 GLTexImage * tex = _pyramid->GetLevelTexture(octave, level);
593 glScaled(scale, scale, scale);
603 if(_pyramid ==
NULL)
return;
609 DisplayFeatureBox(_sub_view);
635 const char* view_titles[] =
641 "Difference of Gaussian",
645 const int view_num = 7;
646 _view = view % view_num;
647 if(_view <0) _view +=view_num;
648 _sub_view = sub_view;
651 strcpy(title,
"Debug...");
653 strcpy(title, view_titles[_view]);
662 <<
"-h -help : Parameter information\n"
663 <<
"-i <strings> : Filename(s) of the input image(s)\n"
664 <<
"-il <string> : Filename of an image list file\n"
665 <<
"-o <string> : Where to save SIFT features\n"
666 <<
"-f <float> : Filter width factor; Width will be 2*factor+1 (default : 4.0)\n"
667 <<
"-w <float> : Orientation sample window factor (default: 2.0)\n"
668 <<
"-dw <float> * : Descriptor grid size factor (default : 3.0)\n"
669 <<
"-fo <int> * : First octave to detect DOG keypoints(default : 0)\n"
670 <<
"-no <int> : Maximum number of Octaves (default : no limit)\n"
671 <<
"-d <int> : Number of DOG levels in an octave (default : 3)\n"
672 <<
"-t <float> : DOG threshold (default : 0.02/3)\n"
673 <<
"-e <float> : Edge Threshold (default : 10.0)\n"
674 <<
"-m <int=2> : Multi Feature Orientations (default : 1)\n"
675 <<
"-m2p : 2 Orientations packed as one float\n"
676 <<
"-s <int=1> : Sub-Pixel, Sub-Scale Localization, Multi-Refinement(num)\n"
677 <<
"-lcpu -lc <int> : CPU/GPU mixed Feature List Generation (default: 6)\n"
678 <<
" Use GPU first, and use CPU when reduction size <= pow(2,num)\n"
679 <<
" When <num> is missing or equals -1, no GPU will be used\n"
680 <<
"-noprep : Upload raw data to GPU (default: RGB->LUM and down-sample on CPU)\n"
681 <<
"-sd : Skip descriptor computation if specified\n"
682 <<
"-unn * : Write unnormalized descriptor if specified\n"
683 <<
"-b * : Write binary sift file if specified\n"
684 <<
"-fs <int> : Block Size for freature storage <default : 4>\n"
685 <<
"-cuda <int=0> : Use CUDA SiftGPU, and specify the device index\n"
686 <<
"-tight : Automatically resize pyramid to fit new images tightly\n"
687 <<
"-p <W>x<H> : Inititialize the pyramids to contain image of WxH (eg -p 1024x768)\n"
688 <<
"-tc[1|2|3] <int> *: Threshold for limiting the overall number of features (3 methods)\n"
689 <<
"-v <int> : Level of timing details. Same as calling Setverbose() function\n"
690 <<
"-loweo : (0, 0) at center of top-left pixel (default: corner)\n"
691 <<
"-maxd <int> * : Max working dimension (default : 2560 (unpacked) / 3200 (packed))\n"
692 <<
"-nomc : Disabling auto-downsamping that try to fit GPU memory cap\n"
693 <<
"-exit : Exit program after processing the input image\n"
694 <<
"-unpack : Use the old unpacked implementation\n"
695 <<
"-di : Use dynamic array indexing if available (default : no)\n"
696 <<
" It could make computation faster on cards like GTX 280\n"
697 <<
"-ofix * : use 0 as feature orientations.\n"
698 <<
"-ofix-not * : disable -ofix.\n"
699 <<
"-winpos <X>x<Y> * : Screen coordinate used in Win32 to select monitor/GPU.\n"
700 <<
"-display <string>*: Display name used in Linux/Mac to select monitor/GPU.\n"
702 <<
"NOTE: parameters marked with * can be changed after initialization\n"
708 #define CHAR1_TO_INT(x) ((x >= 'A' && x <= 'Z') ? x + 32 : x)
709 #define CHAR2_TO_INT(str, i) (str[i] ? CHAR1_TO_INT(str[i]) + (CHAR1_TO_INT(str[i+1]) << 8) : 0)
710 #define CHAR3_TO_INT(str, i) (str[i] ? CHAR1_TO_INT(str[i]) + (CHAR2_TO_INT(str, i + 1) << 8) : 0)
711 #define STRING_TO_INT(str) (CHAR1_TO_INT(str[0]) + (CHAR3_TO_INT(str, 1) << 8))
715 #define MAKEINT1(a) (#@a )
747 #define MAKEINT1(a) (mychar##a )
749 #define MAKEINT2(a, b) (MAKEINT1(a) + (MAKEINT1(b) << 8))
750 #define MAKEINT3(a, b, c) (MAKEINT1(a) + (MAKEINT2(b, c) << 8))
751 #define MAKEINT4(a, b, c, d) (MAKEINT1(a) + (MAKEINT3(b, c, d) << 8))
754 const char* arg, *param, * opt;
755 int setMaxD = 0, opti;
756 for(
int i = 0; i< argc; i++)
759 if(arg ==
NULL || arg[0] !=
'-' || !arg[1])
continue;
772 #if defined(SIFTGPU_CUDA_ENABLED)
778 if(i+1 <argc && sscanf(param,
"%d", &device) && device >=0)
785 std::cerr <<
"---------------------------------------------------------------------------\n"
786 <<
"CUDA not supported in this binary! To enable it, please use SiftGPU_CUDA_Enable\n"
787 <<
"solution for VS2005+ or set siftgpu_enable_cuda to 1 in makefile\n"
788 <<
"----------------------------------------------------------------------------\n";
792 #if defined(CL_SIFTGPU_ENABLED)
795 std::cerr <<
"---------------------------------------------------------------------------\n"
796 <<
"OpenCL not supported in this binary! Define CL_SIFTGPU_CUDA_ENABLED to..\n"
797 <<
"----------------------------------------------------------------------------\n";
816 if(i+1 <argc) sscanf(param,
"%d", &gskip);
867 if(i+1 <argc) sscanf(param,
"%d", &mo);
883 if(i+1 <argc) sscanf(param,
"%d", &sp);
916 if(i + 1 >= argc)
break;
920 strcpy(_imgpath, param);
923 _list->push_back(param);
924 while( i+1 < argc && argv[i+1][0] !=
'-')
926 _list->push_back(argv[++i]);
930 LoadImageList(param);
934 strcpy(_outpath, param);
940 if(sscanf(param,
"%f", &factor) && factor > 0 )
950 if(sscanf(param,
"%f", &factor) && factor>0 )
960 if(sscanf(param,
"%f", &factor) && factor>0 )
970 if(sscanf(param,
"%f", &factor) && factor > 0 )
979 int first_octave = -3;
980 if(sscanf(param,
"%d", &first_octave) && first_octave >=-2 )
991 if(sscanf(param,
"%d", &octave_num))
993 octave_num =
max(-1, octave_num);
994 if(octave_num ==-1 || octave_num >=1)
1004 float threshold = 0.0f;
1005 if(sscanf(param,
"%f", &threshold) && threshold >0 && threshold < 0.5f)
1014 float threshold = 0.0f;
1015 if(sscanf(param,
"%f", &threshold) && threshold >0 )
1025 if(sscanf(param,
"%d", &num) && num >=1 && num <=10)
1035 if(sscanf(param,
"%d", &num) && num >=1)
1045 if(sscanf(param,
"%dx%d", &w, &h) == 2 && w >0 && h>0)
1056 if(sscanf(param,
"%dx%d", &x, &y) == 2)
1073 if(sscanf(param,
"%d", &num) && num >=1000)
1083 if(sscanf(param,
"%f", &num) && num >=0.001)
1102 if(sscanf(param,
"%d", &num) && num > 0)
1112 if(sscanf(param,
"%d", &num) && num >=0 && num <= 4)
1121 if(sscanf(param,
"%d", &num) && num > 0)
1131 if(sscanf(param,
"%d", &num) && num >= 8)
1149 if(_outpath[0] && _list->size()>1) _outpath[0] = 0;
1156 for(
int i = 0; i < nimage; i++)
1158 _list->push_back(filelist[i]);
1166 ifstream in(imlist);
1176 strcpy(_imgpath, _list->at(0).data());
1178 char * slash = strrchr(
filename,
'\\');
1179 if(slash == 0) slash = strrchr(
filename,
'/');
1192 return _sigma0 * powf( 2.0f,
float(lev) /
float(_dog_level_num ));
1197 void SiftGPUEX::DisplayFeatureBox(
int view )
1201 if(view ==2)
return;
1203 const int *fnum = _pyramid->GetLevelFeatureNum();
1204 const GLuint *vbo = _pyramid->GetFeatureDipslayVBO();
1205 const GLuint *vbop = _pyramid->GetPointDisplayVBO();
1206 if(vbo ==
NULL || vbop ==
NULL)
return;
1208 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1209 glEnableClientState(GL_VERTEX_ARRAY);
1215 if(_pyramid->_octave_min >0) scale *= (1<<_pyramid->_octave_min);
1216 else if(_pyramid->_octave_min < 0) scale /= (1<<(-_pyramid->_octave_min));
1217 glScalef(scale, scale, 1.0f);
1220 for(
int i = 0; i < _pyramid->_octave_num; i++)
1223 for(
int j = 0; j < _dog_level_num; j++, idx++)
1229 glColor3f(0.2f, 1.0f, 0.2f);
1230 glBindBuffer(GL_ARRAY_BUFFER_ARB, vbop[idx]);
1231 glVertexPointer( 4, GL_FLOAT,4*
sizeof(
float), (
char *) 0);
1232 glDrawArrays( GL_POINTS, 0, fnum[idx]);
1238 glColor3fv(_colors+ (idx%COLOR_NUM)*3);
1239 glBindBuffer(GL_ARRAY_BUFFER_ARB, vbo[idx]);
1240 glVertexPointer( 4, GL_FLOAT,4*
sizeof(
float), (
char *) 0);
1241 glDrawArrays( GL_LINES, 0, fnum[idx]*10 );
1248 glTranslatef(-.5f, -.5f, 0.0f);
1249 glScalef(2.0f, 2.0f, 1.0f);
1253 glDisableClientState(GL_VERTEX_ARRAY);
1254 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1261 _view_debug = !_view_debug;
1264 void SiftGPUEX::DisplayDebug()
1267 glColor3f(1.0f, 0.0f, 0.0f);
1270 for(
int i = 0; i < 100; i++)
1272 glVertex2f(i*4.0f+0.5f, i*4.0f+0.5f);
1286 #if SIFTGPU_CUDA_ENABLED
1293 return VerifyContextGL();
1309 _pyramid->SaveSIFT(szFileName);
1314 return _pyramid->GetFeatureNum();
1323 _pyramid->CopyFeatureVector((
float*) (&keys[0]), &
descriptors[0]);
1327 _pyramid->CopyFeatureVector((
float*) (&keys[0]),
NULL);
1338 _pyramid->_down_sample_factor = 0;
1350 return _pyramid->_pyramid_height ==
height &&
width == _pyramid->_pyramid_width ;
1378 return _list->size();
1381 void SiftGPUEX::HSVtoRGB(
float hsv[3],
float rgb[3] )
1386 float hh,f, v = hsv[2];
1389 rgb[0]=rgb[1]=rgb[2]=v;
1398 p= v * ( 1 - hsv[1] );
1399 q = v * ( 1 - hsv[1] * f );
1400 t = v * ( 1 - hsv[1] * ( 1 - f ) );
1402 case 0:rgb[0] = v;rgb[1] = t;rgb[2] = p;
break;
1403 case 1:rgb[0] = q;rgb[1] = v;rgb[2] = p;
break;
1404 case 2:rgb[0] = p;rgb[1] = v;rgb[2] = t;
break;
1405 case 3:rgb[0] = p;rgb[1] = q;rgb[2] = v;
break;
1406 case 4:rgb[0] = t;rgb[1] = p;rgb[2] = v;
break;
1407 case 5:rgb[0] = v;rgb[1] = p;rgb[2] = q;
break;
1408 default:rgb[0]= 0;rgb[1] = 0;rgb[2] = 0;
1415 w = _texImage->GetImgWidth();
1416 h = _texImage->GetImgHeight();
#define MAKEINT4(a, b, c, d)
SiftGPU * CreateNewSiftGPU(int np)
#define STRING_TO_INT(str)
#define MAKEINT3(a, b, c)
ComboSiftGPU * CreateComboSiftGPU()
static void InitHighResolution()
static float _FilterWidthFactor
static int _TruncateMethod
static int _octave_num_default
static int _SubpixelLocalization
static int _octave_min_default
static float _DescriptorWindowFactor
static int _OrientationPack2
static int _InitPyramidHeight
static int _FixedOrientation
static float _MulitiOrientationThreshold
static float _OrientationWindowFactor
static int _FeatureCountThreshold
static int _NarrowFeatureTex
static int _ForceTightPyramid
static int _UseDynamicIndexing
static int _KeepExtremumSign
static int _ExitAfterSIFT
static float _MaxFeaturePercent
static int _DarknessAdaption
static int _MaxLevelFeatureNum
static int _NormalizedSIFT
static int _FeatureTexBlock
static int _DescriptorPPT
static int _KeyPointListForceLevel0
static int _InitPyramidWidth
static int _ListGenSkipGPU
static int _MaxOrientation
static int _FullSupported
static int _PreProcessOnCPU
static const char * _WindowDisplay
static void SelectDisplay()
static void FitViewPort(int width, int height)
static float GetElapsedTime()
static void StartTimer(const char *event)
static int CreateWindowEZ()
static void UseShaderDisplayGrad()
static void UseShaderDisplayDOG()
static void UseShaderDisplayGaussian()
static void UnloadProgram()
static void UseShaderDisplayKeypoints()
static void UseShaderDebug()
void GetInitWindowPotition(int &x, int &y)
void SetView(int view, int sub_view, char *title)
void ToggleDisplayDebug()
void GetImageDimension(int &w, int &h)
virtual void ParseParam(int argc, const char **argv)
virtual void GetFeatureVector(SiftKeypoint *keys, float *descriptors)
virtual void SetKeypointList(int num, const SiftKeypoint *keys, int keys_have_orientation=1)
virtual int VerifyContextGL()
virtual void SaveSIFT(const char *szFileName)
virtual void SetTightPyramid(int tight=1)
virtual int AllocatePyramid(int width, int height)
virtual void SetImageList(int nimage, const char **filelist)
virtual void SetVerbose(int verbose=4)
virtual void SetMaxDimension(int sz)
virtual int IsFullSupported()
virtual int GetImageCount()
virtual int CreateContextGL()
void LoadImageList(const char *imlist)
int GetFeatureCountThreshold()
virtual int GetFeatureNum()
float GetInitialSmoothSigma(int octave_min)
float GetLevelSigma(int lev)
QTextStream & endl(QTextStream &stream)
MiniVec< float, N > ceil(const MiniVec< float, N > &a)