Image Component Library (ICL)
|
00001 /******************************************************************** 00002 ** Image Component Library (ICL) ** 00003 ** ** 00004 ** Copyright (C) 2006-2013 CITEC, University of Bielefeld ** 00005 ** Neuroinformatics Group ** 00006 ** Website: www.iclcv.org and ** 00007 ** http://opensource.cit-ec.de/projects/icl ** 00008 ** ** 00009 ** File : ICLCV/src/ICLCV/OpenSurfLib.h ** 00010 ** Module : ICLCV ** 00011 ** Authors: Christof Elbrechter (+see below) ** 00012 ** ** 00013 ** ** 00014 ** GNU LESSER GENERAL PUBLIC LICENSE ** 00015 ** This file may be used under the terms of the GNU Lesser General ** 00016 ** Public License version 3.0 as published by the ** 00017 ** ** 00018 ** Free Software Foundation and appearing in the file LICENSE.LGPL ** 00019 ** included in the packaging of this file. Please review the ** 00020 ** following information to ensure the license requirements will ** 00021 ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt ** 00022 ** ** 00023 ** The development of this software was supported by the ** 00024 ** Excellence Cluster EXC 277 Cognitive Interaction Technology. ** 00025 ** The Excellence Cluster EXC 277 is a grant of the Deutsche ** 00026 ** Forschungsgemeinschaft (DFG) in the context of the German ** 00027 ** Excellence Initiative. ** 00028 ** ** 00029 ********************************************************************/ 00030 00031 /*********************************************************** 00032 * Please note that this file contains the whole OpenSURF * 00033 * library. We decided to include the library by-source * 00034 * in order to be able to ship its functionality easier * 00035 * * 00036 * --- OpenSURF --- * 00037 * This library is distributed under the GNU GPL. Please * 00038 * use the contact form at http://www.chrisevansdev.com * 00039 * for more information. * 00040 * * 00041 * C. Evans, Research Into Robust Visual Features, * 00042 * MSc University of Bristol, 2008. * 00043 * * 00044 ************************************************************/ 00045 00046 #pragma once 00047 00048 #include <vector> 00049 #include <opencv/cv.h> 00050 00051 #include <ICLCV/SurfFeature.h> 00052 00053 namespace icl{ 00054 00055 namespace cv{ 00056 00057 namespace opensurf{ 00058 00059 typedef SurfFeature Ipoint; 00060 typedef std::vector<SurfFeature> IpVec; 00061 typedef std::vector<SurfMatch> IpPairVec; 00062 00064 class ResponseLayer; 00065 class FastHessian; 00069 ICLCV_API void getMatches(IpVec &ipts1, IpVec &ipts2, IpPairVec &matches); 00070 00071 ICLCV_API int translateCorners(IpPairVec &matches, const CvPoint src_corners[4], CvPoint dst_corners[4]); 00072 00074 00075 ICLCV_API IplImage *Integral(IplImage *img); 00076 00077 00079 00080 ICLCV_API float BoxIntegral(IplImage *img, int row, int col, int rows, int cols); 00081 00082 00083 00084 00086 00091 class ICLCV_API Kmeans { 00092 public: 00093 00095 ~Kmeans() {}; 00096 00098 Kmeans() {}; 00099 00101 void Run(IpVec *ipts, int clusters, bool init = false); 00102 00104 void SetIpoints(IpVec *ipts); 00105 00107 void InitRandomClusters(int n); 00108 00110 bool AssignToClusters(); 00111 00113 void RepositionClusters(); 00114 00116 float Distance(Ipoint &ip1, Ipoint &ip2); 00117 00119 IpVec *ipts; 00120 00122 IpVec clusters; 00123 00124 }; 00125 00127 class ICLCV_API ResponseLayer{ 00128 public: 00129 00130 int width, height, step, filter; 00131 float *responses; 00132 unsigned char *laplacian; 00133 00134 inline ResponseLayer(int width, int height, int step, int filter){ 00135 assert(width > 0 && height > 0); 00136 00137 this->width = width; 00138 this->height = height; 00139 this->step = step; 00140 this->filter = filter; 00141 00142 responses = new float[width*height]; 00143 laplacian = new unsigned char[width*height]; 00144 00145 memset(responses,0,sizeof(float)*width*height); 00146 memset(laplacian,0,sizeof(unsigned char)*width*height); 00147 } 00148 00149 inline ~ResponseLayer(){ 00150 if (responses) delete [] responses; 00151 if (laplacian) delete [] laplacian; 00152 } 00153 00154 inline unsigned char getLaplacian(unsigned int row, unsigned int column) 00155 { 00156 return laplacian[row * width + column]; 00157 } 00158 00159 inline unsigned char getLaplacian(unsigned int row, unsigned int column, ResponseLayer *src) 00160 { 00161 int scale = this->width / src->width; 00162 00163 #ifdef RL_DEBUG 00164 assert(src->getCoords(row, column) == this->getCoords(scale * row, scale * column)); 00165 #endif 00166 00167 return laplacian[(scale * row) * width + (scale * column)]; 00168 } 00169 00170 inline float getResponse(unsigned int row, unsigned int column) 00171 { 00172 return responses[row * width + column]; 00173 } 00174 00175 inline float getResponse(unsigned int row, unsigned int column, ResponseLayer *src) 00176 { 00177 int scale = this->width / src->width; 00178 00179 #ifdef RL_DEBUG 00180 assert(src->getCoords(row, column) == this->getCoords(scale * row, scale * column)); 00181 #endif 00182 00183 return responses[(scale * row) * width + (scale * column)]; 00184 } 00185 00186 #ifdef RL_DEBUG 00187 std::vector<std::pair<int, int>> coords; 00188 00189 inline std::pair<int,int> getCoords(unsigned int row, unsigned int column) 00190 { 00191 return coords[row * width + column]; 00192 } 00193 00194 inline std::pair<int,int> getCoords(unsigned int row, unsigned int column, ResponseLayer *src) 00195 { 00196 int scale = this->width / src->width; 00197 return coords[(scale * row) * width + (scale * column)]; 00198 } 00199 #endif 00200 }; 00201 00203 class ICLCV_API Surf { 00204 00205 public: 00206 00208 Surf(IplImage *img, std::vector<Ipoint> &ipts); 00209 00211 void getDescriptors(bool bUpright = false); 00212 00213 private: 00214 00216 void getOrientation(); 00217 00219 void getDescriptor(bool bUpright = false); 00220 00222 inline float gaussian(int x, int y, float sig); 00223 inline float gaussian(float x, float y, float sig); 00224 00226 inline float haarX(int row, int column, int size); 00227 inline float haarY(int row, int column, int size); 00228 00230 float getAngle(float X, float Y); 00231 00232 00234 IplImage *img; 00235 00237 IpVec &ipts; 00238 00240 int index; 00241 }; 00242 00243 static const int OCTAVES = 5; 00244 static const int INTERVALS = 4; 00245 static const float THRES = 0.0004f; 00246 static const int INIT_SAMPLE = 2; 00247 00249 ICLCV_API void surfDetDes(IplImage *img, /* image to find Ipoints in */ 00250 std::vector<Ipoint> &ipts, /* reference to vector of Ipoints */ 00251 bool upright = false, /* run in rotation invariant mode? */ 00252 int octaves = OCTAVES, /* number of octaves to calculate */ 00253 int intervals = INTERVALS, /* number of intervals per octave */ 00254 int init_sample = INIT_SAMPLE, /* initial sampling step */ 00255 float thres = THRES /* blob response threshold */); 00256 00258 ICLCV_API void surfDet(IplImage *img, /* image to find Ipoints in */ 00259 std::vector<Ipoint> &ipts, /* reference to vector of Ipoints */ 00260 int octaves = OCTAVES, /* number of octaves to calculate */ 00261 int intervals = INTERVALS, /* number of intervals per octave */ 00262 int init_sample = INIT_SAMPLE, /* initial sampling step */ 00263 float thres = THRES /* blob response threshold */); 00264 00266 ICLCV_API void surfDes(IplImage *img, /* image to find Ipoints in */ 00267 std::vector<Ipoint> &ipts, /* reference to vector of Ipoints */ 00268 bool upright = false); /* run in rotation invariant mode? */ 00269 00270 00272 ICLCV_API void error(const char *msg); 00273 00275 ICLCV_API void showImage(const IplImage *img); 00276 00278 ICLCV_API void showImage(char *title, const IplImage *img); 00279 00280 // Convert image to single channel 32F 00281 ICLCV_API IplImage* getGray(const IplImage *img); 00282 00284 ICLCV_API void drawIpoint(IplImage *img, Ipoint &ipt, int tailSize = 0); 00285 00287 ICLCV_API void drawIpoints(IplImage *img, std::vector<Ipoint> &ipts, int tailSize = 0); 00288 00290 ICLCV_API void drawWindows(IplImage *img, std::vector<Ipoint> &ipts); 00291 00292 // Draw the FPS figure on the image (requires at least 2 calls) 00293 ICLCV_API void drawFPS(IplImage *img); 00294 00296 ICLCV_API void drawPoint(IplImage *img, Ipoint &ipt); 00297 00299 ICLCV_API void drawPoints(IplImage *img, std::vector<Ipoint> &ipts); 00300 00302 ICLCV_API void saveSurf(char *filename, std::vector<Ipoint> &ipts); 00303 00305 ICLCV_API void loadSurf(char *filename, std::vector<Ipoint> &ipts); 00306 00308 inline int fRound(float flt) { return (int) floor(flt+0.5f); } 00309 00310 } // end of namespace opensurf 00311 00312 } // end of namespace cv 00313 00314 } // end of namespace icl