1 ////////////////////////////////////////////////////////////////////////////
2 //	File:		SiftPyramid.h
3 //	Author:		Changchang Wu
4 //	Description : interface for the SiftPyramid class.
5 //		SiftPyramid:			data storage for SIFT
6 //		|---PyramidGL:			OpenGL based implementation
7 //		|   |--PyramidNaive:	Unpacked version
8 //		|   |--PyramidPacked:	packed version
9 //		|--PyramidCU:			CUDA-based implementation
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 
29 #ifndef _SIFT_PYRAMID_H
30 #define _SIFT_PYRAMID_H
31 
32 
33 class GLTexImage;
34 class GLTexInput;
35 class SiftParam;
36 class GlobalUtil;
37 
38 /////////////////////////////////////////////////////////////////////////////
39 //class SiftPyramid
40 //description: virutal class of SIFT data pyramid
41 //			   provides functions for SiftPU to run steps of GPU SIFT
42 //			   class PyramidNaive is the first implementation
43 //			   class PyramidPacked is a better OpenGL implementation
44 //			   class PyramidCU is a CUDA based implementation
45 /////////////////////////////////////////////////////////////////////////////
46 
47 #define NO_DUPLICATE_DOWNLOAD
48 
49 class SiftPyramid : public GlobalUtil
50 {
51 public:
52 	enum{
53 		DATA_GAUSSIAN	= 0,
54 		DATA_DOG		= 1,
55 		DATA_KEYPOINT	= 2,
56 		DATA_GRAD		= 3,
57 		DATA_ROT		= 4,
58 		DATA_NUM		= 5
59 	};
60 	enum{
61 		SIFT_SKIP_FILTERING		= 0x01,
62 		SIFT_SKIP_DETECTION		= 0x02,
63 		SIFT_SKIP_ORIENTATION	= 0x04,
64         SIFT_RECT_DESCRIPTION   = 0x08
65 	};
66 protected:
67 	SiftParam&	param;
68 	int			_hpLevelNum;
69 	int*		_levelFeatureNum;
70 	int			_featureNum;
71 	float*		_histo_buffer;
72     //keypoint list
73 	int			_existing_keypoints;
74 	vector<int>	_keypoint_index;
75 	//display vbo
76 	GLuint*	    _featureDisplayVBO;
77 	GLuint*	 	_featurePointVBO;
78 public:
79 	//
80 	float		_timing[8];
81 	//image size related
82 	//first octave
83 	int			_octave_min;
84 	//how many octaves
85 	int			_octave_num;
86 	//pyramid storage
87 	int			_pyramid_octave_num;
88 	int			_pyramid_octave_first;
89 	int			_pyramid_width;
90 	int			_pyramid_height;
91 	int			_down_sample_factor;
92 	int			_allocated;
93 	int		    _alignment;
94     int         _siftgpu_failed;
95 public:
96 	vector<float>	_keypoint_buffer;
97 	vector<float>	_descriptor_buffer;
98 private:
99 	inline  void PrepareBuffer();
100 	inline  void LimitFeatureCount(int have_keylist = 0);
101 public:
102 	//shared by all implementations
103 	virtual void RunSIFT(GLTexInput*input);
104 	virtual void SaveSIFT(const char * szFileName);
105 	virtual void CopyFeatureVector(float*keys, float *descriptors);
106 	virtual void SetKeypointList(int num, const float * keys, int run_on_current, int skip_orientation);
107 	//implementation-dependent functions
108 	virtual void GetFeatureDescriptors() = 0;
109 	virtual void GenerateFeatureListTex() =0;
110 	virtual void ReshapeFeatureListCPU() =0;
111 	virtual void GenerateFeatureDisplayVBO() =0;
112 	virtual void DownloadKeypoints() = 0;
113 	virtual void GenerateFeatureListCPU()=0;
114 	virtual void GenerateFeatureList()=0;
115 	virtual GLTexImage* GetLevelTexture(int octave, int level)=0;
116 	virtual GLTexImage* GetLevelTexture(int octave, int level, int dataName) = 0;
117 	virtual void BuildPyramid(GLTexInput * input)=0;
118 	virtual void ResizePyramid(int w, int h) = 0;
119 	virtual void InitPyramid(int w, int h, int ds = 0)=0;
120 	virtual void DetectKeypointsEX() = 0;
121 	virtual void ComputeGradient() = 0;
122 	virtual void GetFeatureOrientations() = 0;
123 	virtual void GetSimplifiedOrientation() = 0;
124 
125     ////////////////////////////////
CleanUpAfterSIFT()126     virtual void CleanUpAfterSIFT()  {}
IsUsingRectDescription()127     virtual int  IsUsingRectDescription() {return 0; }
128     static  int  GetRequiredOctaveNum(int inputsz);
129 
130 	///inline functions, shared by all implementations
SetFailStatus()131     inline void SetFailStatus() {_siftgpu_failed = 1; }
GetSucessStatus()132     inline int  GetSucessStatus() {return _siftgpu_failed == 0; }
GetFeatureNum()133 	inline int GetFeatureNum(){return _featureNum;}
GetHistLevelNum()134 	inline int GetHistLevelNum(){return _hpLevelNum;}
GetFeatureDipslayVBO()135 	inline const GLuint * GetFeatureDipslayVBO(){return _featureDisplayVBO;}
GetPointDisplayVBO()136 	inline const GLuint * GetPointDisplayVBO(){return _featurePointVBO;}
GetLevelFeatureNum()137 	inline const int * GetLevelFeatureNum(){return _levelFeatureNum;}
GetPyramidTiming(float * timing)138 	inline void	GetPyramidTiming(float * timing){	for(int i = 0; i < 8; i++) timing[i] = _timing[i];	}
CleanupBeforeSIFT()139     inline void CleanupBeforeSIFT()
140     {
141         _siftgpu_failed = 0;
142         for(int i = 0; i < 8; ++i) _timing[i] = 0;
143     }
SiftPyramid(SiftParam & sp)144 	SiftPyramid(SiftParam&sp):param(sp)
145 	{
146 		_featureNum = 0;
147 		_featureDisplayVBO = 0;
148 		_featurePointVBO = 0;
149 		_levelFeatureNum = NULL;
150 		_histo_buffer = NULL;
151 		_hpLevelNum = 0;
152 
153 		//image size
154 		_octave_num = 0;
155 		_octave_min = 0;
156 		_alignment = 1;
157 		_pyramid_octave_num = _pyramid_octave_first = 0;
158 		_pyramid_width = _pyramid_height = 0;
159 		_allocated = 0;
160 		_down_sample_factor = 0;
161 
162 		/////
163 		_existing_keypoints = 0;
164 	}
~SiftPyramid()165 	virtual ~SiftPyramid() {};
166 
167 #ifdef DEBUG_SIFTGPU
168 private:
169 	void StopDEBUG();
170 	void BeginDEBUG(const char* imagepath);
171 	void WriteTextureForDEBUG(GLTexImage * tex, const char * namet, ...);
172 #endif
173 };
174 
175 #define SIFTGPU_ENABLE_REVERSE_ORDER
176 #ifdef SIFTGPU_ENABLE_REVERSE_ORDER
177 #define FIRST_OCTAVE(R)            (R? _octave_num - 1 : 0)
178 #define NOT_LAST_OCTAVE(i, R)      (R? (i >= 0) : (i < _octave_num))
179 #define GOTO_NEXT_OCTAVE(i, R)     (R? (--i) : (++i))
180 #define FIRST_LEVEL(R)             (R? param._dog_level_num - 1 : 0)
181 #define GOTO_NEXT_LEVEL(j, R)      (R? (--j) : (++j))
182 #define NOT_LAST_LEVEL(j, R)       (R? (j >= 0) : (j < param._dog_level_num))
183 #define FOR_EACH_OCTAVE(i, R)      for(int i = FIRST_OCTAVE(R); NOT_LAST_OCTAVE(i, R); GOTO_NEXT_OCTAVE(i, R))
184 #define FOR_EACH_LEVEL(j, R)       for(int j = FIRST_LEVEL(R);  NOT_LAST_LEVEL(j, R);  GOTO_NEXT_LEVEL(j, R))
185 #else
186 #define FOR_EACH_OCTAVE(i, R) for(int i = 0; i < _octave_num; ++i)
187 #define FOR_EACH_LEVEL(j, R)  for(int j = 0; j < param._dog_level_num; ++j)
188 #endif
189 
190 #endif
191