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