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