Surf算法学习心得(二)——源码简析

说明:作为初学者,我对于源代码也只是简单的分析,开始和(一)中一样都叫做源码分析,后来感觉自己分析的质量不太好,还是都改为源码简析吧,结合起(一)及后面的心得来看估计效果会好点,呵呵。只是希望对于即将要学习Surf算法的人有一定的帮助就行!对于一些介绍得不对的地方,也希望各位大虾能过指出,相互交流,共同进步!

Surf算法源代码分析

surf算法源代码分为两种文件,学过C/C++的都知道,在此不多说。头文件主要包括:imload.h、ipoint.h、image.h、fasthessian.h、surf.h、surflib.h,其中每个文件用于声明一个特定的相应类,下面大体进行简单介绍。
ImLoad.h——声明类ImLoad,主要封装了对图像的读取和保存函数。
Image *readImage(const char *filename);                             //从图像文件中读取图像
void saveImage(const char *filename, Image* im);           //将图像保存到文件中
ipoint.h——声明类Ipoint,主要定义关键点的相应属性。
Ipoint(){                                                                                                //构造函数
ivec = NULL;
ori = 0.0;
};
~Ipoint(){                                                                                             //析构函数
if (ivec)
delete [] ivec;
};
void allocIvec(const int si){                                                         //内存空间分配
ivec = new double[si];
};
double x, y;                                                                                          //特征点在图像中的坐标
double scale;                                                                                       // 检测范围
double strength;                                                                                //特征点的强度
double ori;                                                                                           //特征点主方向
int laplace;                                                                                           //Laplacian相关的值
double *ivec;                                                                                      //特征点描述器( 局部特征)
image.h——声明类Image,主要定义图像的相关属性。
Image(const int w, const int h);                                                 //带参数的构造函数
~Image();                                                                                            //析构函数
Image(double **pixels, int w, int h);                                      //根据已存在的像素数组构造图像
Image(Image *im, bool doubleImSize=false);                   //构造积分图像
void setFrame(unsigned char *im);                                       //通过单一的帧到(预初始化)结构
void setFrame(Image *im);
Image *HalfImage();                                                                    //将图片长宽个变为原来的1/2
double getHessian(int *x);                                                        //获得特定点的Hessian检测值
int getTrace(int *x);                                                                    //获得Hessian矩阵的迹(线性代数中学过迹)
double **getPixels() const;                                                      //获得指向图像像素的指针
double getPix(const int x, const int y) const {                 //获得某一指定位置的像素值
return _pixels[y][x];
}
double &getPix(const int x, const int y) {                          //重载getPix并返回引用
return _pixels[y][x];
}
void setPix(const int x, const int y, const double val) {  //设置指定位置的像素值
_pixels[y][x] = val;
}
int getWidth();
int getHeight();
void setWidth(int wi);
void setHeight(int hi);
void allocPixels(int w, int h);                                                  //为图像像素分配二维内存空间
double *_buf;                                                                                //指向图像实际缓冲区的指针
double **_pixels;                                                                         //指向图像像素二维数组的指针
int _height, _width;
int _orihi;                                                                                        //原始图像高度
bool _ref;                                                                                         //对图像是否为引用的一种标志
fasthessian.h——声明类FastHessian,主要定义算法中的快速Hessian检测子方法
~FastHessian();
//带参数的构造方法
FastHessian(Image *im, std::vector< Ipoint >& ip, double thres = 0.2, bool doub = false,
short int initMasksize = 9, short int samplingStep = 2,
short int octaves = 4);
void setIimage( Image *iim );                                                  //传入积分图像
void getInterestPoints();                                                           //检测图像的所有特征点
//在特定位置创建新的点,并在一定范围内
void makeIpoint(double x, double y, double scale, double strength=0);
void allocateOctave();                                                                //为Octave分配内存空间
//Fast non-maximum-suppression
void findMaximum(int *borders, int o, int octave);
void interpFeature(int s, int row, int col, Image *map,
int o, int octave, int movesRemain,
int *borders);
int fitQuadrat(int s, int r, int c, double &res);
Image *_Iimage;
Image **_scaleLevel;                                                               //Octaves
int _vas[9];                                                                                    //向量变量
double _threshold;                                                                    //检测特征点时的阈值
bool _doubled;                                                                            //图像是否放大
std::vector< Ipoint >& _ipts;                                               //从外部传进来的指向特征点向量的引用
short int _initLobe;                                               //在某一方向第二次求导时的初始lobe值,默认为3
short int _maxScales;                                                              //Number scales
short int _maxOctaves;                                                          //Number octaves
short int _sampling;                                                                 //The sampling step
int _width;                                                                                   //积分图像的宽
int _height;
double _offset[3];                                                                      //二次拟合的结果
surf.h——声明surf,主要用于定义Surf中关键点相应的描述器
Surf();
Surf(Image *im, bool dbl=false, bool usurf=false,
bool ext=false, int insi=4);
~Surf();
int getVectLength();                                                              //获得特征描述器向量的长度
void setIpoint(Ipoint *ipt);                                               //为一个需要计算的描述器设置相应点
void assignOrientation();                                                   // 定向分配重现
void makeDescriptor();                                                      //计算不变图像特征
void createVector(double scale,                                    //创建向量
double row, double col);
void createUprightVector(double scale,
double row, double col);
void AddSample(int r, int c, double rpos,                   //向向量添加样本
double cpos, double rx, double cx, int step);
void AddUprightSample(int r, int c, double rpos,
double cpos, double rx, double cx, int step);
void PlaceInIndex(double mag1, int ori1,                  //为向量中样本设置索引值
double mag2, int ori2, double rx, double cx);
//! Normalise descriptor vector for illumination invariance for Lambertian surfaces
void normalise();
void createLookups();                                                       //创建查找表
surflib.h——声明surf算法要用到的库函数。
//针对整个图像定义关键点及其相应描述器(关键点附加的详细信息(局部特征))
//其中关键点信息保存在向量ipts当中
inline void surfDetDes(Image *im, std::vector< Ipoint >& ipts,
double thres = 4.0, bool doubleImageSize = false,
int initLobe = 3, int samplingStep = 2, int octaves = 4,
bool upright = false, bool extended = false, int indexSize = 4)
//针对一个给定的特征点,计算相应的描述器(局部特征)
inline void surfDes(Image *im, std::vector< Ipoint >& ipts,
 bool doubleImageSize = false,
 bool upright = false, bool extended = false, int indexSize = 4)

编译运行

cmd下进入可执行文件目录,输入可执行文件名,得到如下提示:
可以在相应的提示下进行运行,如:
注意:输入文件 -i 参数后面的文件必须是PGM格式的图像文件,可以自行网上下载,有个“人脸pgm图片库”可以拿来使用,输出不限,如本程序中是output.txt
运行完成后,打开文件output.txt可以看到文件中的如下数据:
这只是一个简单的示例,直接运行可执行文件名出现的帮助里面还有很多选项,别的选项也就是与Surf算法源代码中的那些参数对应的,大家应该都懂的,要学习的可以试一下,这样就能更深入的了解Surf算法。另外源文件中有文件README的说明 ,里面有关于数据格式以及数据输入输出格式的说明,有兴趣的朋友可以自行研究下。

本文链接:http://www.yongblog.com/archives/152.html 转载请注明出处。

你可能感兴趣的:(算法,image,vector,IM,Descriptor,代码分析)