您的位置:首页 > 运维架构

SIFT:第一步使用OpenCV构建DOG金字塔

2015-03-16 21:31 501 查看
main函数

#include<opencv2/opencv.hpp>

#include"PC_SIFT.h"

using namespace std;
using namespace cv;

int main(int argc,char*argv[])
{
struct feature *feat;
int n;
Mat img1=cv::imread("E://corner.jpg",-1);
if(!img1.data)
{cout<<"Error!No such file!"<<endl;
return -1;
}

cv::namedWindow("test1",CV_WINDOW_AUTOSIZE);
imshow("test1",img1);

n=pc_sift_features(img1, &feat);

cv::waitKey(0);

return 0;

}


CPP文件

#include<opencv2/opencv.hpp>
#include<math.h>

#include "PC_SIFT.h"

using namespace std;
using namespace cv;

Size Wsize(5,5); // the size of gaussain smooth kernel

/*************************Static Function Feclaration**************************/
static int _sift_features( Mat, struct feature**, int ,double , double , int ,int , int );
static Mat create_init_img( Mat, double );
static void build_gauss_pyr( Mat,vector<Mat>&, int,int, double );
static Mat downsample( Mat);
static void build_dog_pyr(vector<Mat>&dog_pyr,vector<Mat>&gauss_pyr, int octvs, int intvls );

/************************Main function pc_sift_features************************/
/*we skipped the first ocatve */
int pc_sift_features(Mat img,struct feature ** feat)
{
return _sift_features( img, feat, SIFT_INTVLS, SIFT_SIGMA, SIFT_CONTR_THR,
SIFT_CURV_THR, SIFT_DESCR_WIDTH,
SIFT_DESCR_HIST_BINS );
}

int _sift_features( Mat img, struct feature** feat, int intvls,
double sigma, double contr_thr, int curv_thr,
int descr_width, int descr_hist_bins )
{
Mat init_img;
vector<Mat> gauss_pyr,dog_pyr;

int n=0;
int octvs;
/*create the init img via original gaussian smooth and converting to type 32 float*/
init_img=create_init_img( img, sigma );

/* build scale space pyramid; */
octvs=(int)log( static_cast<double>MIN( init_img.rows, init_img.cols ) ) / log(2.0) - 2;
build_gauss_pyr( init_img,gauss_pyr, octvs, intvls, sigma );
build_dog_pyr(dog_pyr,gauss_pyr,octvs,intvls);

/*find scale extrama candidate keypoints and discard the bad points */

/*display*/
Mat display;
string winName="1";
char cnt='1';
for(int i=0;i<=12;i++)
{
winName+=cnt;
dog_pyr[i].convertTo(display,CV_8UC1);
imshow(winName,display);
}

/*release the img and pyramid*/
return n;
}

static Mat create_init_img( Mat img, double sigma )
{
Mat gray;
double sig_diff;

img.convertTo(gray,CV_32FC1);

sig_diff = sqrt( sigma * sigma - SIFT_INIT_SIGMA * SIFT_INIT_SIGMA );

cv::GaussianBlur(gray,gray,Wsize,sig_diff);

return gray;
}

static void build_gauss_pyr( Mat base, vector<Mat> &gauss_pyr,int octvs,
int intvls, double sigma )
{

double* sig = (double*)calloc( intvls + 3, sizeof(double));
gauss_pyr.resize(octvs*(intvls+3));

double sig_total, sig_prev, k;
int i, o;

/*
precompute Gaussian sigmas using the following formula:

\sigma_{total}^2 = \sigma_{i}^2 + \sigma_{i-1}^2
*/
sig[0] = sigma;
k = pow( 2.0, 1.0 / intvls );
for( i = 1; i < intvls + 3; i++ )
{
sig_prev = pow( k, i - 1 ) * sigma;
sig_total = sig_prev * k;
sig[i] = sqrt( sig_total * sig_total - sig_prev * sig_prev );
}

/*****build gauss pyramid *************/

for( o = 0; o < octvs; o++ )
for( i = 0; i < intvls + 3; i++ )
{

if( o == 0 && i == 0 )
gauss_pyr[o*(intvls+3)+i]=base.clone();
/* base of new octvave is halved image from end of previous octave */
else if( i == 0 )
gauss_pyr[o*(intvls+3)+i]=downsample(gauss_pyr[(o-1)*(intvls+3)+intvls]);
/* blur the current octave's last image to create the next one */
else
cv::GaussianBlur(gauss_pyr[o*(intvls+3)+i-1],gauss_pyr[o*(intvls+3)+i],Wsize,sig[i]);

}

free( sig );
}

static Mat downsample( Mat img )
{
Mat smaller;
smaller.create(img.rows/2,img.cols/2,CV_32FC1);
cv::resize(img,smaller,cv::Size(img.rows/2,img.cols/2));
return smaller;
}

static void build_dog_pyr(vector<Mat>&dog_pyr,vector<Mat>&gauss_pyr, int octvs, int intvls )
{
dog_pyr.resize(octvs*(intvls+2));
for(int o=0;o<octvs;o++)
for(int i=0;i<intvls+2;i++)
{
Mat& src1=gauss_pyr[o*(intvls+3)+i+1];
Mat& src2=gauss_pyr[o*(intvls+3)+i];
Mat& dst=dog_pyr[o*(intvls+2)+i];
cv::subtract(src1,src2,dst);
}
}

h文件
//#ifndef PC_SIFT_H
//#define PC_SIFT_H

#include<opencv2\opencv.hpp>

/** max feature descriptor length */
#define FEATURE_MAX_D 128

/**
Structure to represent an affine invariant image feature.
*/
struct feature
{
double x; /**< x coord */
double y; /**< y coord */
/*********/
int octv; // Octave
int intvl; // inteval
/*********/
double scl; /**< scale of a Lowe-style feature */
double ori; /**< orientation of a Lowe-style feature */
int d; /**< descriptor length */
double descr[FEATURE_MAX_D]; /**< descriptor */
int category; /**< all-purpose feature category */
struct feature* fwd_match; /**< matching feature from forward image */

CvPoint2D64f img_pt; /**< location in image */
CvPoint2D64f mdl_pt; /**< location in model */
void* feature_data; /**< user-definable data */

};

/******************************* Defs and macros *****************************/

/** default number of sampled intervals per octave */
#define SIFT_INTVLS 3

/** default sigma for initial gaussian smoothing */
#define SIFT_SIGMA 1.6
/** default threshold on keypoint contrast |D(x)| */
#define SIFT_CONTR_THR 0.04

/** default threshold on keypoint ratio of principle curvatures */
#define SIFT_CURV_THR 10

/** double image size before pyramid construction? */
#define SIFT_IMG_DBL 0 //no, for sar img ,we abandon the first ovtave

/** default width of descriptor histogram array */
#define SIFT_DESCR_WIDTH 4

/** default number of bins per histogram in descriptor array */
#define SIFT_DESCR_HIST_BINS 8

/* assumed gaussian blur for input image */
#define SIFT_INIT_SIGMA 0.5

/* width of border in which to ignore keypoints */
#define SIFT_IMG_BORDER 5

/*********** Function Proto types ********/

//int pc_sift_features(Mat img,struct feature ** feat);
extern "C" {
extern int pc_sift_features(cv::Mat img,struct feature ** feat);
}

//#endif

gaussian pyramid

DOG Pyramid
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  图像处理 sift