1 //////////////////////////////////////////////////////////////////////////// 2 // File: SiftGPU.h 3 // Author: Changchang Wu 4 // Description : interface for the SIFTGPU class. 5 // SiftGPU: The SiftGPU Tool. 6 // SiftGPUEX: SiftGPU + viewer 7 // SiftParam: Sift Parameters 8 // SiftMatchGPU: GPU SIFT Matcher; 9 // 10 // 11 // Copyright (c) 2007 University of North Carolina at Chapel Hill 12 // All Rights Reserved 13 // 14 // Permission to use, copy, modify and distribute this software and its 15 // documentation for educational, research and non-profit purposes, without 16 // fee, and without a written agreement is hereby granted, provided that the 17 // above copyright notice and the following paragraph appear in all copies. 18 // 19 // The University of North Carolina at Chapel Hill make no representations 20 // about the suitability of this software for any purpose. It is provided 21 // 'as is' without express or implied warranty. 22 // 23 // Please send BUG REPORTS to ccwu@cs.unc.edu 24 // 25 //////////////////////////////////////////////////////////////////////////// 26 27 28 #ifndef GPU_SIFT_H 29 #define GPU_SIFT_H 30 31 #if defined(_WIN32) 32 #ifdef SIFTGPU_DLL 33 #ifdef DLL_EXPORT 34 #define SIFTGPU_EXPORT __declspec(dllexport) 35 #else 36 #define SIFTGPU_EXPORT __declspec(dllimport) 37 #endif 38 #else 39 #define SIFTGPU_EXPORT 40 #endif 41 #define SIFTGPU_EXPORT_EXTERN SIFTGPU_EXPORT 42 #if _MSC_VER > 1000 43 #pragma once 44 #endif 45 #else 46 #define SIFTGPU_EXPORT 47 #define SIFTGPU_EXPORT_EXTERN extern "C" 48 #endif 49 50 #ifdef _MSC_VER 51 #if _MSC_VER >= 1600 52 #include <stdint.h> 53 #else 54 typedef __int8 int8_t; 55 typedef __int16 int16_t; 56 typedef __int32 int32_t; 57 typedef __int64 int64_t; 58 typedef unsigned __int8 uint8_t; 59 typedef unsigned __int16 uint16_t; 60 typedef unsigned __int32 uint32_t; 61 typedef unsigned __int64 uint64_t; 62 #endif 63 #elif __GNUC__ >= 3 64 #include <stdint.h> 65 #endif 66 67 /////////////////////////////////////////////////////////////////// 68 //clss SiftParam 69 //description: SIFT parameters 70 //////////////////////////////////////////////////////////////////// 71 class GlobalUtil; 72 class SiftParam 73 { 74 public: 75 float* _sigma; 76 float _sigma_skip0; // 77 float _sigma_skip1; // 78 79 //sigma of the first level 80 float _sigma0; 81 float _sigman; 82 int _sigma_num; 83 84 //how many dog_level in an octave 85 int _dog_level_num; 86 int _level_num; 87 88 //starting level in an octave 89 int _level_min; 90 int _level_max; 91 int _level_ds; 92 //dog threshold 93 float _dog_threshold; 94 //edge elimination 95 float _edge_threshold; 96 void ParseSiftParam(); 97 public: 98 float GetLevelSigma(int lev); 99 float GetInitialSmoothSigma(int octave_min); 100 SIFTGPU_EXPORT SiftParam(); 101 }; 102 103 class LiteWindow; 104 class GLTexInput; 105 class ShaderMan; 106 class SiftPyramid; 107 class ImageList; 108 //////////////////////////////////////////////////////////////// 109 //class SIftGPU 110 //description: Interface of SiftGPU lib 111 //////////////////////////////////////////////////////////////// 112 class SiftGPU:public SiftParam 113 { 114 public: 115 enum 116 { 117 SIFTGPU_NOT_SUPPORTED = 0, 118 SIFTGPU_PARTIAL_SUPPORTED = 1, // detction works, but not orientation/descriptor 119 SIFTGPU_FULL_SUPPORTED = 2 120 }; 121 122 int gpu_index = 0; 123 124 typedef struct SiftKeypoint 125 { 126 float x, y, s, o; //x, y, scale, orientation. 127 }SiftKeypoint; 128 protected: 129 //when more than one images are specified 130 //_current indicates the active one 131 int _current; 132 //_initialized indicates if the shaders and OpenGL/SIFT parameters are initialized 133 //they are initialized only once for one SiftGPU inistance 134 //that is, SIFT parameters will not be changed 135 int _initialized; 136 //_image_loaded indicates if the current images are loaded 137 int _image_loaded; 138 //the name of current input image 139 char* _imgpath; 140 //_outpath containes the name of the output file 141 char* _outpath; 142 //the list of image filenames 143 ImageList * _list; 144 //the texture that holds loaded input image 145 GLTexInput * _texImage; 146 //the SiftPyramid 147 SiftPyramid * _pyramid; 148 //print out the command line options 149 static void PrintUsage(); 150 //Initialize OpenGL and SIFT paremeters, and create the shaders accordingly 151 void InitSiftGPU(); 152 //load the image list from a file 153 void LoadImageList(const char *imlist); 154 public: 155 //timing results for 10 steps 156 float _timing[10]; GetCurrentImagePath()157 inline const char* GetCurrentImagePath() {return _imgpath; } 158 public: 159 //set the image list for processing 160 SIFTGPU_EXPORT virtual void SetImageList(int nimage, const char** filelist); 161 //get the number of SIFT features in current image 162 SIFTGPU_EXPORT virtual int GetFeatureNum(); 163 //save the SIFT result as a ANSCII/BINARY file 164 SIFTGPU_EXPORT virtual void SaveSIFT(const char * szFileName); 165 //Copy the SIFT result to two vectors 166 SIFTGPU_EXPORT virtual void GetFeatureVector(SiftKeypoint * keys, float * descriptors); 167 //Set keypoint list before running sift to get descriptors 168 SIFTGPU_EXPORT virtual void SetKeypointList(int num, const SiftKeypoint * keys, int keys_have_orientation = 1); 169 //Enable downloading results to CPU. 170 //create a new OpenGL context for processing 171 //call VerifyContextGL instead if you want to crate openGL context yourself, or your are 172 //mixing mixing siftgpu with other openGL code 173 SIFTGPU_EXPORT virtual int CreateContextGL(); 174 //verify the current opengl context.. 175 //(for example, you call wglmakecurrent yourself and verify the current context) 176 SIFTGPU_EXPORT virtual int VerifyContextGL(); 177 //check if all siftgpu functions are supported 178 SIFTGPU_EXPORT virtual int IsFullSupported(); 179 //set verbose mode 180 SIFTGPU_EXPORT virtual void SetVerbose(int verbose = 4); 181 //set SiftGPU to brief display mode, which is faster SetVerboseBrief()182 inline void SetVerboseBrief(){SetVerbose(2);}; 183 //parse SiftGPU parameters 184 SIFTGPU_EXPORT virtual void ParseParam(const int argc, const char **argv); 185 //run SIFT on a new image given filename 186 SIFTGPU_EXPORT virtual int RunSIFT(const char * imgpath); 187 //run SIFT on an image in the image list given the file index 188 SIFTGPU_EXPORT virtual int RunSIFT(int index); 189 //run SIFT on a new image given the pixel data and format/type; 190 //gl_format (e.g. GL_LUMINANCE, GL_RGB) is the format of the pixel data 191 //gl_type (e.g. GL_UNSIGNED_BYTE, GL_FLOAT) is the data type of the pixel data; 192 //Check glTexImage2D(...format, type,...) for the accepted values 193 //Using image data of GL_LUMINANCE + GL_UNSIGNED_BYTE can minimize transfer time 194 SIFTGPU_EXPORT virtual int RunSIFT(int width, int height, const void * data, 195 unsigned int gl_format, unsigned int gl_type); 196 //run SIFT on current image (specified by arguments), or processing the current image again 197 SIFTGPU_EXPORT virtual int RunSIFT(); 198 //run SIFT with keypoints on current image again. 199 SIFTGPU_EXPORT virtual int RunSIFT(int num, const SiftKeypoint * keys, int keys_have_orientation = 1); 200 //constructor, the parameter np is ignored.. 201 SIFTGPU_EXPORT SiftGPU(int np = 1); 202 //destructor 203 SIFTGPU_EXPORT virtual ~SiftGPU(); 204 //set the active pyramid...dropped function SetActivePyramid(int)205 SIFTGPU_EXPORT virtual void SetActivePyramid(int) {}; 206 //retrieve the number of images in the image list 207 SIFTGPU_EXPORT virtual int GetImageCount(); 208 //set parameter GlobalUtil::_ForceTightPyramid 209 SIFTGPU_EXPORT virtual void SetTightPyramid(int tight = 1); 210 //allocate pyramid for a given size of image 211 SIFTGPU_EXPORT virtual int AllocatePyramid(int width, int height); 212 //none of the texture in processing can be larger 213 //automatic down-sample is used if necessary. 214 SIFTGPU_EXPORT virtual void SetMaxDimension(int sz); 215 SIFTGPU_EXPORT int GetFeatureCountThreshold(); 216 SIFTGPU_EXPORT int GetMaxOrientation(); 217 SIFTGPU_EXPORT int GetMaxDimension(); 218 /// 219 public: 220 //overload the new operator because delete operator is virtual 221 //and it is operating on the heap inside the dll (due to the 222 //compiler setting of /MT and /MTd). Without the overloaded operator 223 //deleting a SiftGPU object will cause a heap corruption in the 224 //static link case (but not for the runtime dll loading). 225 SIFTGPU_EXPORT void* operator new (size_t size); 226 }; 227 228 229 230 //////////////////////////////////////////////////////////////// 231 //class SIftGPUEX 232 //description: adds some visualization functions to the interface of SiftGPU 233 //////////////////////////////////////////////////////////////// 234 235 class SiftGPUEX:public SiftGPU 236 { 237 //view mode 238 int _view; 239 //sub view mode 240 int _sub_view; 241 //whether display a debug view 242 int _view_debug; 243 //colors for SIFT feature display 244 enum{COLOR_NUM = 36}; 245 float _colors[COLOR_NUM*3]; 246 //display functions 247 void DisplayInput(); //display gray level image of input image 248 void DisplayDebug(); //display debug view 249 void DisplayFeatureBox(int i); //display SIFT features 250 void DisplayLevel(void (*UseDisplayShader)(), int i); //display one level image 251 void DisplayOctave(void (*UseDisplayShader)(), int i); //display all images in one octave 252 //display different content of Pyramid by specifying different data and display shader 253 //the first nskip1 levels and the last nskip2 levels are skiped in display 254 void DisplayPyramid( void (*UseDisplayShader)(), int dataName, int nskip1 = 0, int nskip2 = 0); 255 //use HSVtoRGB to generate random colors 256 static void HSVtoRGB(float hsv[3],float rgb[3]); 257 258 public: 259 SIFTGPU_EXPORT SiftGPUEX(); 260 //change view mode 261 SIFTGPU_EXPORT void SetView(int view, int sub_view, char * title); 262 //display current view 263 SIFTGPU_EXPORT void DisplaySIFT(); 264 //toggle debug mode on/off 265 SIFTGPU_EXPORT void ToggleDisplayDebug(); 266 //randomize the display colors 267 SIFTGPU_EXPORT void RandomizeColor(); 268 //retrieve the size of current input image 269 SIFTGPU_EXPORT void GetImageDimension(int &w, int&h); 270 //get the location of the window specified by user 271 SIFTGPU_EXPORT void GetInitWindowPotition(int& x, int& y); 272 }; 273 274 ///matcher export 275 //This is a gpu-based sift match implementation. 276 class SiftMatchGPU 277 { 278 public: 279 enum SIFTMATCH_LANGUAGE { 280 SIFTMATCH_SAME_AS_SIFTGPU = 0, //when siftgpu already initialized. 281 SIFTMATCH_GLSL = 2, 282 SIFTMATCH_CUDA = 3, 283 SIFTMATCH_CUDA_DEVICE0 = 3 //to use device i, use SIFTMATCH_CUDA_DEVICE0 + i 284 }; 285 286 int gpu_index = 0; 287 288 private: 289 int __language; 290 SiftMatchGPU * __matcher; InitSiftMatch()291 virtual void InitSiftMatch(){} 292 protected: 293 int __max_sift; 294 //move the two functions here for derived class 295 SIFTGPU_EXPORT virtual int _CreateContextGL(); 296 SIFTGPU_EXPORT virtual int _VerifyContextGL(); 297 public: 298 //OpenGL Context creation/verification, initialization is done automatically inside CreateContextGL()299 inline int CreateContextGL() {return _CreateContextGL();} VerifyContextGL()300 inline int VerifyContextGL() {return _VerifyContextGL();} 301 302 //Consructor, the argument specifies the maximum number of features to match 303 SIFTGPU_EXPORT SiftMatchGPU(int max_sift = 4096); 304 305 //change gpu_language, check the enumerants in SIFTMATCH_LANGUAGE. 306 SIFTGPU_EXPORT virtual void SetLanguage(int gpu_language); 307 308 //after calling SetLanguage, you can call SetDeviceParam to select GPU 309 //-winpos, -display, -cuda [device_id] 310 //This is only used when you call CreateContextGL.. 311 //This function doesn't change the language. 312 SIFTGPU_EXPORT virtual void SetDeviceParam(int argc, char**argv); 313 314 // Allocate all matrices the matrices and return true if successful. 315 virtual bool Allocate(int max_sift, int mbm); 316 317 //change the maximum of features to match whenever you want 318 SIFTGPU_EXPORT virtual void SetMaxSift(int max_sift); GetMaxSift()319 SIFTGPU_EXPORT virtual int GetMaxSift() const { return __max_sift; }; 320 //desctructor 321 SIFTGPU_EXPORT virtual ~SiftMatchGPU(); 322 323 //Specifiy descriptors to match, index = [0/1] for two features sets respectively 324 //Option1, use float descriptors, and they be already normalized to 1.0 325 SIFTGPU_EXPORT virtual void SetDescriptors(int index, int num, const float* descriptors, int id = -1); 326 //Option 2 unsigned char descriptors. They must be already normalized to 512 327 SIFTGPU_EXPORT virtual void SetDescriptors(int index, int num, const unsigned char * descriptors, int id = -1); 328 329 //match two sets of features, the function RETURNS the number of matches. 330 //Given two normalized descriptor d1,d2, the distance here is acos(d1 *d2); 331 SIFTGPU_EXPORT virtual int GetSiftMatch( 332 int max_match, // the length of the match_buffer. 333 uint32_t match_buffer[][2], //buffer to receive the matched feature indices 334 float distmax = 0.7, //maximum distance of sift descriptor 335 float ratiomax = 0.8, //maximum distance ratio 336 int mutual_best_match = 1); //mutual best match or one way 337 338 //two functions for guded matching, two constraints can be used 339 //one homography and one fundamental matrix, the use is as follows 340 //1. for each image, first call SetDescriptor then call SetFeatureLocation 341 //2. Call GetGuidedSiftMatch 342 //input feature location is a vector of [float x, float y, float skip[gap]] 343 SIFTGPU_EXPORT virtual void SetFeautreLocation(int index, const float* locations, int gap = 0); SetFeatureLocation(int index,const SiftGPU::SiftKeypoint * keys)344 inline void SetFeatureLocation(int index, const SiftGPU::SiftKeypoint * keys) 345 { 346 SetFeautreLocation(index, (const float*) keys, 2); 347 } 348 349 //use a guiding Homography H and a guiding Fundamental Matrix F to compute feature matches 350 //the function returns the number of matches. 351 SIFTGPU_EXPORT virtual int GetGuidedSiftMatch( 352 int max_match, uint32_t match_buffer[][2], //buffer to recieve 353 float* H, //homography matrix, (Set NULL to skip) 354 float* F, //fundamental matrix, (Set NULL to skip) 355 float distmax = 0.7, //maximum distance of sift descriptor 356 float ratiomax = 0.8, //maximum distance ratio 357 float hdistmax = 32, //threshold for |H * x1 - x2|_2 358 float fdistmax = 16, //threshold for sampson error of x2'FX1 359 int mutual_best_match = 1); //mutual best or one way 360 361 public: 362 //overload the new operator, the same reason as SiftGPU above 363 SIFTGPU_EXPORT void* operator new (size_t size); 364 }; 365 366 typedef SiftGPU::SiftKeypoint SiftKeypoint; 367 368 //Two exported global functions used to create SiftGPU and SiftMatchGPU 369 SIFTGPU_EXPORT_EXTERN SiftGPU * CreateNewSiftGPU(int np =1); 370 SIFTGPU_EXPORT_EXTERN SiftMatchGPU* CreateNewSiftMatchGPU(int max_sift = 4096); 371 372 373 //////////////////////////////////////////////////////////////////////////// 374 class ComboSiftGPU: public SiftGPU, public SiftMatchGPU 375 { 376 public: 377 /////////////////////////////////////////////// 378 SIFTGPU_EXPORT void* operator new (size_t size); 379 }; 380 SIFTGPU_EXPORT_EXTERN ComboSiftGPU* CreateComboSiftGPU(); 381 382 ///////////////////////////////////////////////////////////////////////////////////////////// 383 //Multi-process mode and remote mode 384 SIFTGPU_EXPORT_EXTERN ComboSiftGPU* CreateRemoteSiftGPU(int port = 7777, char* remote_server = NULL); 385 //Run SiftGPU computation on a remote computer/process/thread 386 //if( remote_server == NULL) 387 // a local server is created in a different process and connected 388 // multiple-GPU can be used by creating multiple instances 389 // GPU selection done through SiftGPU::ParseParam function 390 //otherwise, 391 // Assumes the existenc of a remote server and connects to it 392 // GPU selection skipped if already done on the server-end 393 // RUN server: server_siftgpu -server port [siftgpu_param] 394 //example: 395 // ComboSiftGPU * combo = CreateRemoteSiftGPU(7777, "my.gpuserver.com"); 396 // SiftGPU* siftgpu = combo, SiftMatchGPU * matcher = combo; 397 // siftgpu->ParseParam... siftgpu->CreateContextGL.. 398 // matcher->SetLanguage...matcher->VerifyContextGL... 399 // // GPU-selection is done throught siftgpu->ParseParam, 400 // // it doesn't really initialize SiftGPU untill you call CreateContextGL/VerifyContextGL 401 // delete combo; 402 403 //////////////////////////////////////////////////////////////////////// 404 //two internally used function. 405 SIFTGPU_EXPORT int CreateLiteWindow(LiteWindow* window); 406 SIFTGPU_EXPORT void RunServerLoop(int port, int argc, char** argv); 407 #endif 408