作者:July、二零一一年三月十二日
出处:
http://blog.csdn.net/v_JULY_v。
参考:Rob Hess维护的sift 库
环境:windows xp+vc6.0
条件:c语言实现。
说明:本BLOG内会陆续一一实现所有经典算法。
------------------------
本文接上,教你一步一步用c语言实现sift算法、上,而来:
函数编写
ok,接上文,咱们一个一个的来编写main函数中所涉及到所有函数,这也是本文的关键部分:
-
- CvMat * halfSizeImage(CvMat * im)
- {
- unsigned int i,j;
- int w = im->cols/2;
- int h = im->rows/2;
- CvMat *imnew = cvCreateMat(h, w, CV_32FC1);
-
- #define Im(ROW,COL) ((float *)(im->data.fl + im->step/sizeof(float) *(ROW)))[(COL)]
- #define Imnew(ROW,COL) ((float *)(imnew->data.fl + imnew->step/sizeof(float) *(ROW)))[(COL)]
- for ( j = 0; j < h; j++)
- for ( i = 0; i < w; i++)
- Imnew(j,i)=Im(j*2, i*2);
- return imnew;
- }
-
-
- CvMat * doubleSizeImage(CvMat * im)
- {
- unsigned int i,j;
- int w = im->cols*2;
- int h = im->rows*2;
- CvMat *imnew = cvCreateMat(h, w, CV_32FC1);
-
- #define Im(ROW,COL) ((float *)(im->data.fl + im->step/sizeof(float) *(ROW)))[(COL)]
- #define Imnew(ROW,COL) ((float *)(imnew->data.fl + imnew->step/sizeof(float) *(ROW)))[(COL)]
-
- for ( j = 0; j < h; j++)
- for ( i = 0; i < w; i++)
- Imnew(j,i)=Im(j/2, i/2);
-
- return imnew;
- }
-
-
- CvMat * doubleSizeImage2(CvMat * im)
- {
- unsigned int i,j;
- int w = im->cols*2;
- int h = im->rows*2;
- CvMat *imnew = cvCreateMat(h, w, CV_32FC1);
-
- #define Im(ROW,COL) ((float *)(im->data.fl + im->step/sizeof(float) *(ROW)))[(COL)]
- #define Imnew(ROW,COL) ((float *)(imnew->data.fl + imnew->step/sizeof(float) *(ROW)))[(COL)]
-
-
- for ( j = 0; j < h; j++)
- {
- for ( i = 0; i < w; i++)
- {
- Imnew(j,i)=Im(j/2, i/2);
- }
- }
-
-
-
-
-
-
-
-
- for ( j = 0; j < h; j += 2)
- for ( i = 1; i < w - 1; i += 2)
- Imnew(j,i)=0.5*(Im(j/2, i/2)+Im(j/2, i/2+1));
-
- for ( j = 1; j < h - 1; j += 2)
- for ( i = 0; i < w; i += 2)
- Imnew(j,i)=0.5*(Im(j/2, i/2)+Im(j/2+1, i/2));
-
- for ( j = 1; j < h - 1; j += 2)
- for ( i = 1; i < w - 1; i += 2)
- Imnew(j,i)=0.25*(Im(j/2, i/2)+Im(j/2+1, i/2)+Im(j/2, i/2+1)+Im(j/2+1, i/2+1));
- return imnew;
- }
-
-
- float getPixelBI(CvMat * im, float col, float row)
- {
- int irow, icol;
- float rfrac, cfrac;
- float row1 = 0, row2 = 0;
- int width=im->cols;
- int height=im->rows;
- #define ImMat(ROW,COL) ((float *)(im->data.fl + im->step/sizeof(float) *(ROW)))[(COL)]
-
- irow = (int) row;
- icol = (int) col;
-
- if (irow < 0 || irow >= height
- || icol < 0 || icol >= width)
- return 0;
- if (row > height - 1)
- row = height - 1;
- if (col > width - 1)
- col = width - 1;
- rfrac = 1.0 - (row - (float) irow);
- cfrac = 1.0 - (col - (float) icol);
- if (cfrac < 1)
- {
- row1 = cfrac * ImMat(irow,icol) + (1.0 - cfrac) * ImMat(irow,icol+1);
- }
- else
- {
- row1 = ImMat(irow,icol);
- }
- if (rfrac < 1)
- {
- if (cfrac < 1)
- {
- row2 = cfrac * ImMat(irow+1,icol) + (1.0 - cfrac) * ImMat(irow+1,icol+1);
- } else
- {
- row2 = ImMat(irow+1,icol);
- }
- }
- return rfrac * row1 + (1.0 - rfrac) * row2;
- }
-
-
- void normalizeMat(CvMat* mat)
- {
- #define Mat(ROW,COL) ((float *)(mat->data.fl + mat->step/sizeof(float) *(ROW)))[(COL)]
- float sum = 0;
-
- for (unsigned int j = 0; j < mat->rows; j++)
- for (unsigned int i = 0; i < mat->cols; i++)
- sum += Mat(j,i);
- for ( j = 0; j < mat->rows; j++)
- for (unsigned int i = 0; i < mat->rows; i++)
- Mat(j,i) /= sum;
- }
-
-
- void normalizeVec(float* vec, int dim)
- {
- unsigned int i;
- float sum = 0;
- for ( i = 0; i < dim; i++)
- sum += vec[i];
- for ( i = 0; i < dim; i++)
- vec[i] /= sum;
- }
-
-
- float GetVecNorm( float* vec, int dim )
- {
- float sum=0.0;
- for (unsigned int i=0;i<dim;i++)
- sum+=vec[i]*vec[i];
- return sqrt(sum);
- }
-
-
- float* GaussianKernel1D(float sigma, int dim)
- {
-
- unsigned int i;
-
-
- float *kern=(float*)malloc( dim*sizeof(float) );
- float s2 = sigma * sigma;
- int c = dim / 2;
- float m= 1.0/(sqrt(2.0 * CV_PI) * sigma);
- double v;
- for ( i = 0; i < (dim + 1) / 2; i++)
- {
- v = m * exp(-(1.0*i*i)/(2.0 * s2)) ;
- kern[c+i] = v;
- kern[c-i] = v;
- }
-
-
-
-
- return kern;
- }
-
-
- CvMat* GaussianKernel2D(float sigma)
- {
-
- int dim = (int) max(3.0f, 2.0 * GAUSSKERN *sigma + 1.0f);
-
- if (dim % 2 == 0)
- dim++;
-
- CvMat* mat=cvCreateMat(dim, dim, CV_32FC1);
- #define Mat(ROW,COL) ((float *)(mat->data.fl + mat->step/sizeof(float) *(ROW)))[(COL)]
- float s2 = sigma * sigma;
- int c = dim / 2;
-
- float m= 1.0/(sqrt(2.0 * CV_PI) * sigma);
- for (int i = 0; i < (dim + 1) / 2; i++)
- {
- for (int j = 0; j < (dim + 1) / 2; j++)
- {
-
- float v = m * exp(-(1.0*i*i + 1.0*j*j) / (2.0 * s2));
- Mat(c+i,c+j) =v;
- Mat(c-i,c+j) =v;
- Mat(c+i,c-j) =v;
- Mat(c-i,c-j) =v;
- }
- }
-
- return mat;
- }
-
-
- float ConvolveLocWidth(float* kernel, int dim, CvMat * src, int x, int y)
- {
- #define Src(ROW,COL) ((float *)(src->data.fl + src->step/sizeof(float) *(ROW)))[(COL)]
- unsigned int i;
- float pixel = 0;
- int col;
- int cen = dim / 2;
-
- for ( i = 0; i < dim; i++)
- {
- col = x + (i - cen);
- if (col < 0)
- col = 0;
- if (col >= src->cols)
- col = src->cols - 1;
- pixel += kernel[i] * Src(y,col);
- }
- if (pixel > 1)
- pixel = 1;
- return pixel;
- }
-
-
- void Convolve1DWidth(float* kern, int dim, CvMat * src, CvMat * dst)
- {
- #define DST(ROW,COL) ((float *)(dst->data.fl + dst->step/sizeof(float) *(ROW)))[(COL)]
- unsigned int i,j;
-
- for ( j = 0; j < src->rows; j++)
- {
- for ( i = 0; i < src->cols; i++)
- {
-
- DST(j,i) = ConvolveLocWidth(kern, dim, src, i, j);
- }
- }
- }
-
-
- float ConvolveLocHeight(float* kernel, int dim, CvMat * src, int x, int y)
- {
- #define Src(ROW,COL) ((float *)(src->data.fl + src->step/sizeof(float) *(ROW)))[(COL)]
- unsigned int j;
- float pixel = 0;
- int cen = dim / 2;
-
- for ( j = 0; j < dim; j++)
- {
- int row = y + (j - cen);
- if (row < 0)
- row = 0;
- if (row >= src->rows)
- row = src->rows - 1;
- pixel += kernel[j] * Src(row,x);
- }
- if (pixel > 1)
- pixel = 1;
- return pixel;
- }
-
-
- void Convolve1DHeight(float* kern, int dim, CvMat * src, CvMat * dst)
- {
- #define Dst(ROW,COL) ((float *)(dst->data.fl + dst->step/sizeof(float) *(ROW)))[(COL)]
- unsigned int i,j;
- for ( j = 0; j < src->rows; j++)
- {
- for ( i = 0; i < src->cols; i++)
- {
-
- Dst(j,i) = ConvolveLocHeight(kern, dim, src, i, j);
- }
- }
- }
-
-
- int BlurImage(CvMat * src, CvMat * dst, float sigma)
- {
- float* convkernel;
- int dim = (int) max(3.0f, 2.0 * GAUSSKERN * sigma + 1.0f);
- CvMat *tempMat;
-
- if (dim % 2 == 0)
- dim++;
- tempMat = cvCreateMat(src->rows, src->cols, CV_32FC1);
- convkernel = GaussianKernel1D(sigma, dim);
-
- Convolve1DWidth(convkernel, dim, src, tempMat);
- Convolve1DHeight(convkernel, dim, tempMat, dst);
- cvReleaseMat(&tempMat);
- return dim;
- }
五个步骤
ok,接下来,进入重点部分,咱们依据上文介绍的sift算法的几个步骤,来一一实现这些函数。
为了版述清晰,再贴一下,主函数,顺便再加强下对sift 算法的五个步骤的认识:
1、SIFT算法第一步:图像预处理
CvMat *ScaleInitImage(CvMat * im) ; //金字塔初始化
2、SIFT算法第二步:建立高斯金字塔函数
ImageOctaves* BuildGaussianOctaves(CvMat * image) ; //建立高斯金字塔
3、SIFT算法第三步:特征点位置检测,最后确定特征点的位置
int DetectKeypoint(int numoctaves, ImageOctaves *GaussianPyr);
4、SIFT算法第四步:计算高斯图像的梯度方向和幅值,计算各个特征点的主方向
void ComputeGrad_DirecandMag(int numoctaves, ImageOctaves *GaussianPyr);
5、SIFT算法第五步:抽取各个特征点处的特征描述字
void ExtractFeatureDescriptors(int numoctaves, ImageOctaves *GaussianPyr);
ok,接下来一一具体实现这几个函数:
SIFT算法第一步
SIFT算法第一步:扩大图像,预滤波剔除噪声,得到金字塔的最底层-第一阶的第一层:
- CvMat *ScaleInitImage(CvMat * im)
- {
- double sigma,preblur_sigma;
- CvMat *imMat;
- CvMat * dst;
- CvMat *tempMat;
-
- imMat = cvCreateMat(im->rows, im->cols, CV_32FC1);
- BlurImage(im, imMat, INITSIGMA);
-
-
- if (DOUBLE_BASE_IMAGE_SIZE)
- {
- tempMat = doubleSizeImage2(imMat);
- #define TEMPMAT(ROW,COL) ((float *)(tempMat->data.fl + tempMat->step/sizeof(float) * (ROW)))[(COL)]
-
- dst = cvCreateMat(tempMat->rows, tempMat->cols, CV_32FC1);
- preblur_sigma = 1.0;
- BlurImage(tempMat, dst, preblur_sigma);
-
-
- sigma = sqrt( (4*INITSIGMA*INITSIGMA) + preblur_sigma * preblur_sigma );
-
-
- BlurImage(dst, tempMat, sigma);
- cvReleaseMat( &dst );
- return tempMat;
- }
- else
- {
- dst = cvCreateMat(im->rows, im->cols, CV_32FC1);
-
- preblur_sigma = 1.0;
- sigma = sqrt( (4*INITSIGMA*INITSIGMA) + preblur_sigma * preblur_sigma );
-
- BlurImage(imMat, dst, sigma);
- return dst;
- }
- }
SIFT算法第二步
SIFT第二步,建立Gaussian金字塔,给定金字塔第一阶第一层图像后,计算高斯金字塔其他尺度图像,
每一阶的数目由变量SCALESPEROCTAVE决定,给定一个基本图像,计算它的高斯金字塔图像,返回外部向量是阶梯指针,内部向量是每一个阶梯内部的不同尺度图像。
-
- ImageOctaves* BuildGaussianOctaves(CvMat * image)
- {
- ImageOctaves *octaves;
- CvMat *tempMat;
- CvMat *dst;
- CvMat *temp;
-
- int i,j;
- double k = pow(2, 1.0/((float)SCALESPEROCTAVE));
- float preblur_sigma, initial_sigma , sigma1,sigma2,sigma,absolute_sigma,sigma_f;
-
- int dim = min(image->rows, image->cols);
- int numoctaves = (int) (log((double) dim) / log(2.0)) - 2;
-
- numoctaves = min(numoctaves, MAXOCTAVES);
-
- octaves=(ImageOctaves*) malloc( numoctaves * sizeof(ImageOctaves) );
- DOGoctaves=(ImageOctaves*) malloc( numoctaves * sizeof(ImageOctaves) );
-
- printf("BuildGaussianOctaves(): Base image dimension is %dx%d/n", (int)(0.5*(image->cols)), (int)(0.5*(image->rows)) );
- printf("BuildGaussianOctaves(): Building %d octaves/n", numoctaves);
-
-
- tempMat=cvCloneMat( image );
-
- initial_sigma = sqrt(2);
-
-
-
- for ( i = 0; i < numoctaves; i++)
- {
-
- printf("Building octave %d of dimesion (%d, %d)/n", i, tempMat->cols,tempMat->rows);
-
- octaves[i].Octave= (ImageLevels*) malloc( (SCALESPEROCTAVE + 3) * sizeof(ImageLevels) );
- DOGoctaves[i].Octave= (ImageLevels*) malloc( (SCALESPEROCTAVE + 2) * sizeof(ImageLevels) );
-
- (octaves[i].Octave)[0].Level=tempMat;
-
- octaves[i].col=tempMat->cols;
- octaves[i].row=tempMat->rows;
- DOGoctaves[i].col=tempMat->cols;
- DOGoctaves[i].row=tempMat->rows;
- if (DOUBLE_BASE_IMAGE_SIZE)
- octaves[i].subsample=pow(2,i)*0.5;
- else
- octaves[i].subsample=pow(2,i);
-
- if(i==0)
- {
- (octaves[0].Octave)[0].levelsigma = initial_sigma;
- (octaves[0].Octave)[0].absolute_sigma = initial_sigma;
- printf("0 scale and blur sigma : %f /n", (octaves[0].subsample) * ((octaves[0].Octave)[0].absolute_sigma));
- }
- else
- {
- (octaves[i].Octave)[0].levelsigma = (octaves[i-1].Octave)[SCALESPEROCTAVE].levelsigma;
- (octaves[i].Octave)[0].absolute_sigma = (octaves[i-1].Octave)[SCALESPEROCTAVE].absolute_sigma;
- printf( "0 scale and blur sigma : %f /n", ((octaves[i].Octave)[0].absolute_sigma) );
- }
- sigma = initial_sigma;
-
- for ( j = 1; j < SCALESPEROCTAVE + 3; j++)
- {
- dst = cvCreateMat(tempMat->rows, tempMat->cols, CV_32FC1);
- temp = cvCreateMat(tempMat->rows, tempMat->cols, CV_32FC1);
-
-
-
-
-
-
- sigma_f= sqrt(k*k-1)*sigma;
-
-
-
-
-
- sigma = k*sigma;
- absolute_sigma = sigma * (octaves[i].subsample);
- printf("%d scale and Blur sigma: %f /n", j, absolute_sigma);
-
- (octaves[i].Octave)[j].levelsigma = sigma;
- (octaves[i].Octave)[j].absolute_sigma = absolute_sigma;
-
- int length=BlurImage((octaves[i].Octave)[j-1].Level, dst, sigma_f);
- (octaves[i].Octave)[j].levelsigmalength = length;
- (octaves[i].Octave)[j].Level=dst;
-
- cvSub( ((octaves[i].Octave)[j]).Level, ((octaves[i].Octave)[j-1]).Level, temp, 0 );
-
- ((DOGoctaves[i].Octave)[j-1]).Level=temp;
- }
-
- tempMat = halfSizeImage( ( (octaves[i].Octave)[SCALESPEROCTAVE].Level ) );
- }
- return octaves;
- }
SIFT算法第三步
SIFT算法第三步,特征点位置检测,最后确定特征点的位置检测DOG金字塔中的局部最大值,找到之后,还要经过两个检验才能确认为特征点:一是它必须有明显的差异,二是他不应该是边缘点,(也就是说,在极值点处的主曲率比应该小于某一个阈值)。
-
- int DetectKeypoint(int numoctaves, ImageOctaves *GaussianPyr)
- {
-
- double curvature_threshold;
- curvature_threshold= ((CURVATURE_THRESHOLD + 1)*(CURVATURE_THRESHOLD + 1))/CURVATURE_THRESHOLD;
- #define ImLevels(OCTAVE,LEVEL,ROW,COL) ((float *)(DOGoctaves[(OCTAVE)].Octave[(LEVEL)].Level->data.fl + DOGoctaves[(OCTAVE)].Octave[(LEVEL)].Level->step/sizeof(float) *(ROW)))[(COL)]
-
- int keypoint_count = 0;
- for (int i=0; i<numoctaves; i++)
- {
- for(int j=1;j<SCALESPEROCTAVE+1;j++)
- {
-
-
-
- int dim = (int)(0.5*((GaussianPyr[i].Octave)[j].levelsigmalength)+0.5);
- for (int m=dim;m<((DOGoctaves[i].row)-dim);m++)
- for(int n=dim;n<((DOGoctaves[i].col)-dim);n++)
- {
- if ( fabs(ImLevels(i,j,m,n))>= CONTRAST_THRESHOLD )
- {
-
- if ( ImLevels(i,j,m,n)!=0.0 )
- {
- float inf_val=ImLevels(i,j,m,n);
- if(( (inf_val <= ImLevels(i,j-1,m-1,n-1))&&
- (inf_val <= ImLevels(i,j-1,m ,n-1))&&
- (inf_val <= ImLevels(i,j-1,m+1,n-1))&&
- (inf_val <= ImLevels(i,j-1,m-1,n ))&&
- (inf_val <= ImLevels(i,j-1,m ,n ))&&
- (inf_val <= ImLevels(i,j-1,m+1,n ))&&
- (inf_val <= ImLevels(i,j-1,m-1,n+1))&&
- (inf_val <= ImLevels(i,j-1,m ,n+1))&&
- (inf_val <= ImLevels(i,j-1,m+1,n+1))&&
-
- (inf_val <= ImLevels(i,j,m-1,n-1))&&
- (inf_val <= ImLevels(i,j,m ,n-1))&&
- (inf_val <= ImLevels(i,j,m+1,n-1))&&
- (inf_val <= ImLevels(i,j,m-1,n ))&&
- (inf_val <= ImLevels(i,j,m+1,n ))&&
- (inf_val <= ImLevels(i,j,m-1,n+1))&&
- (inf_val <= ImLevels(i,j,m ,n+1))&&
- (inf_val <= ImLevels(i,j,m+1,n+1))&&
-
- (inf_val <= ImLevels(i,j+1,m-1,n-1))&&
- (inf_val <= ImLevels(i,j+1,m ,n-1))&&
- (inf_val <= ImLevels(i,j+1,m+1,n-1))&&
- (inf_val <= ImLevels(i,j+1,m-1,n ))&&
- (inf_val <= ImLevels(i,j+1,m ,n ))&&
- (inf_val <= ImLevels(i,j+1,m+1,n ))&&
- (inf_val <= ImLevels(i,j+1,m-1,n+1))&&
- (inf_val <= ImLevels(i,j+1,m ,n+1))&&
- (inf_val <= ImLevels(i,j+1,m+1,n+1))
- ) ||
- ( (inf_val >= ImLevels(i,j-1,m-1,n-1))&&
- (inf_val >= ImLevels(i,j-1,m ,n-1))&&
- (inf_val >= ImLevels(i,j-1,m+1,n-1))&&
- (inf_val >= ImLevels(i,j-1,m-1,n ))&&
- (inf_val >= ImLevels(i,j-1,m ,n ))&&
- (inf_val >= ImLevels(i,j-1,m+1,n ))&&
- (inf_val >= ImLevels(i,j-1,m-1,n+1))&&
- (inf_val >= ImLevels(i,j-1,m ,n+1))&&
- (inf_val >= ImLevels(i,j-1,m+1,n+1))&&
-
- (inf_val >= ImLevels(i,j,m-1,n-1))&&
- (inf_val >= ImLevels(i,j,m ,n-1))&&
- (inf_val >= ImLevels(i,j,m+1,n-1))&&
- (inf_val >= ImLevels(i,j,m-1,n ))&&
- (inf_val >= ImLevels(i,j,m+1,n ))&&
- (inf_val >= ImLevels(i,j,m-1,n+1))&&
- (inf_val >= ImLevels(i,j,m ,n+1))&&
- (inf_val >= ImLevels(i,j,m+1,n+1))&&
-
- (inf_val >= ImLevels(i,j+1,m-1,n-1))&&
- (inf_val >= ImLevels(i,j+1,m ,n-1))&&
- (inf_val >= ImLevels(i,j+1,m+1,n-1))&&
- (inf_val >= ImLevels(i,j+1,m-1,n ))&&
- (inf_val >= ImLevels(i,j+1,m ,n ))&&
- (inf_val >= ImLevels(i,j+1,m+1,n ))&&
- (inf_val >= ImLevels(i,j+1,m-1,n+1))&&
- (inf_val >= ImLevels(i,j+1,m ,n+1))&&
- (inf_val >= ImLevels(i,j+1,m+1,n+1))
- ) )
- {
-
-
- if ( fabs(ImLevels(i,j,m,n))>= CONTRAST_THRESHOLD )
- {
-
-
-
-
-
-
-
-
-
-
- float Dxx,Dyy,Dxy,Tr_H,Det_H,curvature_ratio;
- Dxx = ImLevels(i,j,m,n-1) + ImLevels(i,j,m,n+1)-2.0*ImLevels(i,j,m,n);
- Dyy = ImLevels(i,j,m-1,n) + ImLevels(i,j,m+1,n)-2.0*ImLevels(i,j,m,n);
- Dxy = ImLevels(i,j,m-1,n-1) + ImLevels(i,j,m+1,n+1) - ImLevels(i,j,m+1,n-1) - ImLevels(i,j,m-1,n+1);
- Tr_H = Dxx + Dyy;
- Det_H = Dxx*Dyy - Dxy*Dxy;
-
- curvature_ratio = (1.0*Tr_H*Tr_H)/Det_H;
- if ( (Det_H>=0.0) && (curvature_ratio <= curvature_threshold) )
- {
-
- keypoint_count++;
- Keypoint k;
-
- k = (Keypoint) malloc(sizeof(struct KeypointSt));
- k->next = keypoints;
- keypoints = k;
- k->row = m*(GaussianPyr[i].subsample);
- k->col =n*(GaussianPyr[i].subsample);
- k->sy = m;
- k->sx = n;
- k->octave=i;
- k->level=j;
- k->scale = (GaussianPyr[i].Octave)[j].absolute_sigma;
- }
- }
- }
- }
- }
- }
- }
- }
- return keypoint_count;
- }
-
-
- void DisplayKeypointLocation(IplImage* image, ImageOctaves *GaussianPyr)
- {
-
- Keypoint p = keypoints;
- while(p)
- {
- cvLine( image, cvPoint((int)((p->col)-3),(int)(p->row)),
- cvPoint((int)((p->col)+3),(int)(p->row)), CV_RGB(255,255,0),
- 1, 8, 0 );
- cvLine( image, cvPoint((int)(p->col),(int)((p->row)-3)),
- cvPoint((int)(p->col),(int)((p->row)+3)), CV_RGB(255,255,0),
- 1, 8, 0 );
-
-
-
- p=p->next;
- }
- }
-
-
- void ComputeGrad_DirecandMag(int numoctaves, ImageOctaves *GaussianPyr)
- {
-
- mag_pyr=(ImageOctaves*) malloc( numoctaves * sizeof(ImageOctaves) );
- grad_pyr=(ImageOctaves*) malloc( numoctaves * sizeof(ImageOctaves) );
-
-
- #define ImLevels(OCTAVE,LEVEL,ROW,COL) ((float *)(GaussianPyr[(OCTAVE)].Octave[(LEVEL)].Level->data.fl + GaussianPyr[(OCTAVE)].Octave[(LEVEL)].Level->step/sizeof(float) *(ROW)))[(COL)]
- for (int i=0; i<numoctaves; i++)
- {
- mag_pyr[i].Octave= (ImageLevels*) malloc( (SCALESPEROCTAVE) * sizeof(ImageLevels) );
- grad_pyr[i].Octave= (ImageLevels*) malloc( (SCALESPEROCTAVE) * sizeof(ImageLevels) );
- for(int j=1;j<SCALESPEROCTAVE+1;j++)
- {
- CvMat *Mag = cvCreateMat(GaussianPyr[i].row, GaussianPyr[i].col, CV_32FC1);
- CvMat *Ori = cvCreateMat(GaussianPyr[i].row, GaussianPyr[i].col, CV_32FC1);
- CvMat *tempMat1 = cvCreateMat(GaussianPyr[i].row, GaussianPyr[i].col, CV_32FC1);
- CvMat *tempMat2 = cvCreateMat(GaussianPyr[i].row, GaussianPyr[i].col, CV_32FC1);
- cvZero(Mag);
- cvZero(Ori);
- cvZero(tempMat1);
- cvZero(tempMat2);
- #define MAG(ROW,COL) ((float *)(Mag->data.fl + Mag->step/sizeof(float) *(ROW)))[(COL)]
- #define ORI(ROW,COL) ((float *)(Ori->data.fl + Ori->step/sizeof(float) *(ROW)))[(COL)]
- #define TEMPMAT1(ROW,COL) ((float *)(tempMat1->data.fl + tempMat1->step/sizeof(float) *(ROW)))[(COL)]
- #define TEMPMAT2(ROW,COL) ((float *)(tempMat2->data.fl + tempMat2->step/sizeof(float) *(ROW)))[(COL)]
- for (int m=1;m<(GaussianPyr[i].row-1);m++)
- for(int n=1;n<(GaussianPyr[i].col-1);n++)
- {
-
- TEMPMAT1(m,n) = 0.5*( ImLevels(i,j,m,n+1)-ImLevels(i,j,m,n-1) );
- TEMPMAT2(m,n) = 0.5*( ImLevels(i,j,m+1,n)-ImLevels(i,j,m-1,n) );
- MAG(m,n) = sqrt(TEMPMAT1(m,n)*TEMPMAT1(m,n)+TEMPMAT2(m,n)*TEMPMAT2(m,n));
-
- ORI(m,n) =atan( TEMPMAT2(m,n)/TEMPMAT1(m,n) );
- if (ORI(m,n)==CV_PI)
- ORI(m,n)=-CV_PI;
- }
- ((mag_pyr[i].Octave)[j-1]).Level=Mag;
- ((grad_pyr[i].Octave)[j-1]).Level=Ori;
- cvReleaseMat(&tempMat1);
- cvReleaseMat(&tempMat2);
- }
- }
- }
SIFT算法第四步
-
- void AssignTheMainOrientation(int numoctaves, ImageOctaves *GaussianPyr,ImageOctaves *mag_pyr,ImageOctaves *grad_pyr)
- {
-
- int num_bins = 36;
- float hist_step = 2.0*PI/num_bins;
- float hist_orient[36];
- for (int i=0;i<36;i++)
- hist_orient[i]=-PI+i*hist_step;
- float sigma1=( ((GaussianPyr[0].Octave)[SCALESPEROCTAVE].absolute_sigma) ) / (GaussianPyr[0].subsample);
- int zero_pad = (int) (max(3.0f, 2 * GAUSSKERN *sigma1 + 1.0f)*0.5+0.5);
-
- #define ImLevels(OCTAVES,LEVELS,ROW,COL) ((float *)((GaussianPyr[(OCTAVES)].Octave[(LEVELS)].Level)->data.fl + (GaussianPyr[(OCTAVES)].Octave[(LEVELS)].Level)->step/sizeof(float) *(ROW)))[(COL)]
-
- int keypoint_count = 0;
- Keypoint p = keypoints;
-
- while(p)
- {
- int i=p->octave;
- int j=p->level;
- int m=p->sy;
- int n=p->sx;
- if ((m>=zero_pad)&&(m<GaussianPyr[i].row-zero_pad)&&
- (n>=zero_pad)&&(n<GaussianPyr[i].col-zero_pad) )
- {
- float sigma=( ((GaussianPyr[i].Octave)[j].absolute_sigma) ) / (GaussianPyr[i].subsample);
-
- CvMat* mat = GaussianKernel2D( sigma );
- int dim=(int)(0.5 * (mat->rows));
-
- #define MAT(ROW,COL) ((float *)(mat->data.fl + mat->step/sizeof(float) *(ROW)))[(COL)]
-
-
- double* orienthist = (double *) malloc(36 * sizeof(double));
- for ( int sw = 0 ; sw < 36 ; ++sw)
- {
- orienthist[sw]=0.0;
- }
-
- for (int x=m-dim,mm=0;x<=(m+dim);x++,mm++)
- for(int y=n-dim,nn=0;y<=(n+dim);y++,nn++)
- {
-
- double dx = 0.5*(ImLevels(i,j,x,y+1)-ImLevels(i,j,x,y-1));
- double dy = 0.5*(ImLevels(i,j,x+1,y)-ImLevels(i,j,x-1,y));
- double mag = sqrt(dx*dx+dy*dy);
-
- double Ori =atan( 1.0*dy/dx );
- int binIdx = FindClosestRotationBin(36, Ori);
- orienthist[binIdx] = orienthist[binIdx] + 1.0* mag * MAT(mm,nn);
- }
-
- AverageWeakBins (orienthist, 36);
-
- double maxGrad = 0.0;
- int maxBin = 0;
- for (int b = 0 ; b < 36 ; ++b)
- {
- if (orienthist[b] > maxGrad)
- {
- maxGrad = orienthist[b];
- maxBin = b;
- }
- }
-
-
- double maxPeakValue=0.0;
- double maxDegreeCorrection=0.0;
- if ( (InterpolateOrientation ( orienthist[maxBin == 0 ? (36 - 1) : (maxBin - 1)],
- orienthist[maxBin], orienthist[(maxBin + 1) % 36],
- &maxDegreeCorrection, &maxPeakValue)) == false)
- printf("BUG: Parabola fitting broken");
-
-
-
-
-
-
-
-
-
-
-
- bool binIsKeypoint[36];
- for ( b = 0 ; b < 36 ; ++b)
- {
- binIsKeypoint[b] = false;
-
- if (b == maxBin)
- {
- binIsKeypoint[b] = true;
- continue;
- }
-
- if (orienthist[b] < (peakRelThresh * maxPeakValue))
- continue;
- int leftI = (b == 0) ? (36 - 1) : (b - 1);
- int rightI = (b + 1) % 36;
- if (orienthist[b] <= orienthist[leftI] || orienthist[b] <= orienthist[rightI])
- continue;
- binIsKeypoint[b] = true;
- }
-
- double oneBinRad = (2.0 * PI) / 36;
- for ( b = 0 ; b < 36 ; ++b)
- {
- if (binIsKeypoint[b] == false)
- continue;
- int bLeft = (b == 0) ? (36 - 1) : (b - 1);
- int bRight = (b + 1) % 36;
-
- double peakValue;
- double degreeCorrection;
-
- double maxPeakValue, maxDegreeCorrection;
- if (InterpolateOrientation ( orienthist[maxBin == 0 ? (36 - 1) : (maxBin - 1)],
- orienthist[maxBin], orienthist[(maxBin + 1) % 36],
- °reeCorrection, &peakValue) == false)
- {
- printf("BUG: Parabola fitting broken");
- }
-
- double degree = (b + degreeCorrection) * oneBinRad - PI;
- if (degree < -PI)
- degree += 2.0 * PI;
- else if (degree > PI)
- degree -= 2.0 * PI;
-
-
- Keypoint k;
-
- k = (Keypoint) malloc(sizeof(struct KeypointSt));
- k->next = keyDescriptors;
- keyDescriptors = k;
- k->descrip = (float*)malloc(LEN * sizeof(float));
- k->row = p->row;
- k->col = p->col;
- k->sy = p->sy;
- k->sx = p->sx;
- k->octave = p->octave;
- k->level = p->level;
- k->scale = p->scale;
- k->ori = degree;
- k->mag = peakValue;
- }
- free(orienthist);
- }
- p=p->next;
- }
- }
-
-
- int FindClosestRotationBin (int binCount, float angle)
- {
- angle += CV_PI;
- angle /= 2.0 * CV_PI;
-
- angle *= binCount;
- int idx = (int) angle;
- if (idx == binCount)
- idx = 0;
- return (idx);
- }
-
-
- void AverageWeakBins (double* hist, int binCount)
- {
-
-
-
- for (int sn = 0 ; sn < 2 ; ++sn)
- {
- double firstE = hist[0];
- double last = hist[binCount-1];
- for (int sw = 0 ; sw < binCount ; ++sw)
- {
- double cur = hist[sw];
- double next = (sw == (binCount - 1)) ? firstE : hist[(sw + 1) % binCount];
- hist[sw] = (last + cur + next) / 3.0;
- last = cur;
- }
- }
- }
-
-
-
-
-
-
-
-
-
-
-
- bool InterpolateOrientation (double left, double middle,double right, double *degreeCorrection, double *peakValue)
- {
- double a = ((left + right) - 2.0 * middle) / 2.0;
-
-
-
- if (a == 0.0)
- return false;
- double c = (((left - middle) / a) - 1.0) / 2.0;
- double b = middle - c * c * a;
- if (c < -0.5 || c > 0.5)
- return false;
- *degreeCorrection = c;
- *peakValue = b;
- return true;
- }
-
-
- void DisplayOrientation (IplImage* image, ImageOctaves *GaussianPyr)
- {
- Keypoint p = keyDescriptors;
- while(p)
- {
- float scale=(GaussianPyr[p->octave].Octave)[p->level].absolute_sigma;
- float autoscale = 3.0;
- float uu=autoscale*scale*cos(p->ori);
- float vv=autoscale*scale*sin(p->ori);
- float x=(p->col)+uu;
- float y=(p->row)+vv;
- cvLine( image, cvPoint((int)(p->col),(int)(p->row)),
- cvPoint((int)x,(int)y), CV_RGB(255,255,0),
- 1, 8, 0 );
-
- float alpha = 0.33;
- float beta = 0.33;
-
- float xx0= (p->col)+uu-alpha*(uu+beta*vv);
- float yy0= (p->row)+vv-alpha*(vv-beta*uu);
- float xx1= (p->col)+uu-alpha*(uu-beta*vv);
- float yy1= (p->row)+vv-alpha*(vv+beta*uu);
- cvLine( image, cvPoint((int)xx0,(int)yy0),
- cvPoint((int)x,(int)y), CV_RGB(255,255,0),
- 1, 8, 0 );
- cvLine( image, cvPoint((int)xx1,(int)yy1),
- cvPoint((int)x,(int)y), CV_RGB(255,255,0),
- 1, 8, 0 );
- p=p->next;
- }
- }
SIFT算法第五步
SIFT算法第五步:抽取各个特征点处的特征描述字,确定特征点的描述字。描述字是Patch网格内梯度方向的描述,旋转网格到主方向,插值得到网格处梯度值。
一个特征点可以用2*2*8=32维的向量,也可以用4*4*8=128维的向量更精确的进行描述。
- void ExtractFeatureDescriptors(int numoctaves, ImageOctaves *GaussianPyr)
- {
-
- float orient_bin_spacing = PI/4;
- float orient_angles[8]={-PI,-PI+orient_bin_spacing,-PI*0.5, -orient_bin_spacing,
- 0.0, orient_bin_spacing, PI*0.5, PI+orient_bin_spacing};
-
- float *feat_grid=(float *) malloc( 2*16 * sizeof(float));
- for (int i=0;i<GridSpacing;i++)
- {
- for (int j=0;j<2*GridSpacing;++j,++j)
- {
- feat_grid[i*2*GridSpacing+j]=-6.0+i*GridSpacing;
- feat_grid[i*2*GridSpacing+j+1]=-6.0+0.5*j*GridSpacing;
- }
- }
-
- float *feat_samples=(float *) malloc( 2*256 * sizeof(float));
- for ( i=0;i<4*GridSpacing;i++)
- {
- for (int j=0;j<8*GridSpacing;j+=2)
- {
- feat_samples[i*8*GridSpacing+j]=-(2*GridSpacing-0.5)+i;
- feat_samples[i*8*GridSpacing+j+1]=-(2*GridSpacing-0.5)+0.5*j;
- }
- }
- float feat_window = 2*GridSpacing;
- Keypoint p = keyDescriptors;
- while(p)
- {
- float scale=(GaussianPyr[p->octave].Octave)[p->level].absolute_sigma;
-
- float sine = sin(p->ori);
- float cosine = cos(p->ori);
-
- float *featcenter=(float *) malloc( 2*16 * sizeof(float));
- for (int i=0;i<GridSpacing;i++)
- {
- for (int j=0;j<2*GridSpacing;j+=2)
- {
- float x=feat_grid[i*2*GridSpacing+j];
- float y=feat_grid[i*2*GridSpacing+j+1];
- featcenter[i*2*GridSpacing+j]=((cosine * x + sine * y) + p->sx);
- featcenter[i*2*GridSpacing+j+1]=((-sine * x + cosine * y) + p->sy);
- }
- }
-
- float *feat=(float *) malloc( 2*256 * sizeof(float));
- for ( i=0;i<64*GridSpacing;i++,i++)
- {
- float x=feat_samples[i];
- float y=feat_samples[i+1];
- feat[i]=((cosine * x + sine * y) + p->sx);
- feat[i+1]=((-sine * x + cosine * y) + p->sy);
- }
-
- float *feat_desc = (float *) malloc( 128 * sizeof(float));
- for (i=0;i<128;i++)
- {
- feat_desc[i]=0.0;
-
- }
-
- for ( i=0;i<512;++i,++i)
- {
- float x_sample = feat[i];
- float y_sample = feat[i+1];
-
-
-
-
-
-
- float sample12=getPixelBI(((GaussianPyr[p->octave].Octave)[p->level]).Level, x_sample, y_sample-1);
- float sample21=getPixelBI(((GaussianPyr[p->octave].Octave)[p->level]).Level, x_sample-1, y_sample);
- float sample22=getPixelBI(((GaussianPyr[p->octave].Octave)[p->level]).Level, x_sample, y_sample);
- float sample23=getPixelBI(((GaussianPyr[p->octave].Octave)[p->level]).Level, x_sample+1, y_sample);
- float sample32=getPixelBI(((GaussianPyr[p->octave].Octave)[p->level]).Level, x_sample, y_sample+1);
-
-
- float diff_x = sample23 - sample21;
- float diff_y = sample32 - sample12;
- float mag_sample = sqrt( diff_x*diff_x + diff_y*diff_y );
- float grad_sample = atan( diff_y / diff_x );
- if(grad_sample == CV_PI)
- grad_sample = -CV_PI;
-
- float *x_wght=(float *) malloc( GridSpacing * GridSpacing * sizeof(float));
- float *y_wght=(float *) malloc( GridSpacing * GridSpacing * sizeof(float));
- float *pos_wght=(float *) malloc( 8*GridSpacing * GridSpacing * sizeof(float));;
- for (int m=0;m<32;++m,++m)
- {
- float x=featcenter[m];
- float y=featcenter[m+1];
- x_wght[m/2] = max(1 - (fabs(x - x_sample)*1.0/GridSpacing), 0);
- y_wght[m/2] = max(1 - (fabs(y - y_sample)*1.0/GridSpacing), 0);
-
- }
- for ( m=0;m<16;++m)
- for (int n=0;n<8;++n)
- pos_wght[m*8+n]=x_wght[m]*y_wght[m];
- free(x_wght);
- free(y_wght);
-
- float diff[8],orient_wght[128];
- for ( m=0;m<8;++m)
- {
- float angle = grad_sample-(p->ori)-orient_angles[m]+CV_PI;
- float temp = angle / (2.0 * CV_PI);
- angle -= (int)(temp) * (2.0 * CV_PI);
- diff[m]= angle - CV_PI;
- }
-
- float x=p->sx;
- float y=p->sy;
- float g = exp(-((x_sample-x)*(x_sample-x)+(y_sample-y)*(y_sample-y))/(2*feat_window*feat_window))/(2*CV_PI*feat_window*feat_window);
-
- for ( m=0;m<128;++m)
- {
- orient_wght[m] = max((1.0 - 1.0*fabs(diff[m%8])/orient_bin_spacing),0);
- feat_desc[m] = feat_desc[m] + orient_wght[m]*pos_wght[m]*g*mag_sample;
- }
- free(pos_wght);
- }
- free(feat);
- free(featcenter);
- float norm=GetVecNorm( feat_desc, 128);
- for (int m=0;m<128;m++)
- {
- feat_desc[m]/=norm;
- if (feat_desc[m]>0.2)
- feat_desc[m]=0.2;
- }
- norm=GetVecNorm( feat_desc, 128);
- for ( m=0;m<128;m++)
- {
- feat_desc[m]/=norm;
- printf("%f ",feat_desc[m]);
- }
- printf("/n");
- p->descrip = feat_desc;
- p=p->next;
- }
- free(feat_grid);
- free(feat_samples);
- }
-
-
- CvMat* MosaicHorizen( CvMat* im1, CvMat* im2 )
- {
- int row,col;
- CvMat *mosaic = cvCreateMat( max(im1->rows,im2->rows),(im1->cols+im2->cols),CV_32FC1);
- #define Mosaic(ROW,COL) ((float*)(mosaic->data.fl + mosaic->step/sizeof(float)*(ROW)))[(COL)]
- #define Im11Mat(ROW,COL) ((float *)(im1->data.fl + im1->step/sizeof(float) *(ROW)))[(COL)]
- #define Im22Mat(ROW,COL) ((float *)(im2->data.fl + im2->step/sizeof(float) *(ROW)))[(COL)]
- cvZero(mosaic);
-
- for ( row = 0; row < im1->rows; row++)
- for ( col = 0; col < im1->cols; col++)
- Mosaic(row,col)=Im11Mat(row,col) ;
- for ( row = 0; row < im2->rows; row++)
- for ( col = 0; col < im2->cols; col++)
- Mosaic(row, (col+im1->cols) )= Im22Mat(row,col) ;
- return mosaic;
- }
-
-
- CvMat* MosaicVertical( CvMat* im1, CvMat* im2 )
- {
- int row,col;
- CvMat *mosaic = cvCreateMat(im1->rows+im2->rows,max(im1->cols,im2->cols), CV_32FC1);
- #define Mosaic(ROW,COL) ((float*)(mosaic->data.fl + mosaic->step/sizeof(float)*(ROW)))[(COL)]
- #define Im11Mat(ROW,COL) ((float *)(im1->data.fl + im1->step/sizeof(float) *(ROW)))[(COL)]
- #define Im22Mat(ROW,COL) ((float *)(im2->data.fl + im2->step/sizeof(float) *(ROW)))[(COL)]
- cvZero(mosaic);
-
-
- for ( row = 0; row < im1->rows; row++)
- for ( col = 0; col < im1->cols; col++)
- Mosaic(row,col)= Im11Mat(row,col) ;
- for ( row = 0; row < im2->rows; row++)
- for ( col = 0; col < im2->cols; col++)
- Mosaic((row+im1->rows),col)=Im22Mat(row,col) ;
-
- return mosaic;
- }
ok,为了版述清晰,再贴一下上文所述的主函数(注,上文已贴出,此是为了版述清晰,重复造轮):
- int main( void )
- {
-
- IplImage* src = NULL;
- IplImage* image1 = NULL;
- IplImage* grey_im1 = NULL;
- IplImage* DoubleSizeImage = NULL;
-
- IplImage* mosaic1 = NULL;
- IplImage* mosaic2 = NULL;
-
- CvMat* mosaicHorizen1 = NULL;
- CvMat* mosaicHorizen2 = NULL;
- CvMat* mosaicVertical1 = NULL;
-
- CvMat* image1Mat = NULL;
- CvMat* tempMat=NULL;
-
- ImageOctaves *Gaussianpyr;
- int rows,cols;
-
- #define Im1Mat(ROW,COL) ((float *)(image1Mat->data.fl + image1Mat->step/sizeof(float) *(ROW)))[(COL)]
-
-
- #define Im1B(ROW,COL) ((uchar*)(image1->imageData + image1->widthStep*(ROW)))[(COL)*3]
- #define Im1G(ROW,COL) ((uchar*)(image1->imageData + image1->widthStep*(ROW)))[(COL)*3+1]
- #define Im1R(ROW,COL) ((uchar*)(image1->imageData + image1->widthStep*(ROW)))[(COL)*3+2]
-
- storage = cvCreateMemStorage(0);
-
-
- if( (src = cvLoadImage( "street1.jpg", 1)) == 0 )
- return -1;
-
-
- image1 = cvCreateImage(cvSize(src->width, src->height), IPL_DEPTH_8U,3);
- grey_im1 = cvCreateImage(cvSize(src->width, src->height), IPL_DEPTH_8U,1);
- DoubleSizeImage = cvCreateImage(cvSize(2*(src->width), 2*(src->height)), IPL_DEPTH_8U,3);
-
-
- image1Mat = cvCreateMat(src->height, src->width, CV_32FC1);
-
- cvCvtColor(src, grey_im1, CV_BGR2GRAY);
-
- cvConvert(grey_im1, image1Mat);
-
- double t = (double)cvGetTickCount();
-
- cvConvertScale( image1Mat, image1Mat, 1.0/255, 0 );
-
- int dim = min(image1Mat->rows, image1Mat->cols);
- numoctaves = (int) (log((double) dim) / log(2.0)) - 2;
- numoctaves = min(numoctaves, MAXOCTAVES);
-
-
- tempMat = ScaleInitImage(image1Mat) ;
-
- Gaussianpyr = BuildGaussianOctaves(tempMat) ;
-
- t = (double)cvGetTickCount() - t;
- printf( "the time of build Gaussian pyramid and DOG pyramid is %.1f/n", t/(cvGetTickFrequency()*1000.) );
-
- #define ImLevels(OCTAVE,LEVEL,ROW,COL) ((float *)(Gaussianpyr[(OCTAVE)].Octave[(LEVEL)].Level->data.fl + Gaussianpyr[(OCTAVE)].Octave[(LEVEL)].Level->step/sizeof(float) *(ROW)))[(COL)]
-
- for (int i=0; i<numoctaves;i++)
- {
- if (i==0)
- {
- mosaicHorizen1=MosaicHorizen( (Gaussianpyr[0].Octave)[0].Level, (Gaussianpyr[0].Octave)[1].Level );
- for (int j=2;j<SCALESPEROCTAVE+3;j++)
- mosaicHorizen1=MosaicHorizen( mosaicHorizen1, (Gaussianpyr[0].Octave)[j].Level );
- for ( j=0;j<NUMSIZE;j++)
- mosaicHorizen1=halfSizeImage(mosaicHorizen1);
- }
- else if (i==1)
- {
- mosaicHorizen2=MosaicHorizen( (Gaussianpyr[1].Octave)[0].Level, (Gaussianpyr[1].Octave)[1].Level );
- for (int j=2;j<SCALESPEROCTAVE+3;j++)
- mosaicHorizen2=MosaicHorizen( mosaicHorizen2, (Gaussianpyr[1].Octave)[j].Level );
- for ( j=0;j<NUMSIZE;j++)
- mosaicHorizen2=halfSizeImage(mosaicHorizen2);
- mosaicVertical1=MosaicVertical( mosaicHorizen1, mosaicHorizen2 );
- }
- else
- {
- mosaicHorizen1=MosaicHorizen( (Gaussianpyr[i].Octave)[0].Level, (Gaussianpyr[i].Octave)[1].Level );
- for (int j=2;j<SCALESPEROCTAVE+3;j++)
- mosaicHorizen1=MosaicHorizen( mosaicHorizen1, (Gaussianpyr[i].Octave)[j].Level );
- for ( j=0;j<NUMSIZE;j++)
- mosaicHorizen1=halfSizeImage(mosaicHorizen1);
- mosaicVertical1=MosaicVertical( mosaicVertical1, mosaicHorizen1 );
- }
- }
- mosaic1 = cvCreateImage(cvSize(mosaicVertical1->width, mosaicVertical1->height), IPL_DEPTH_8U,1);
- cvConvertScale( mosaicVertical1, mosaicVertical1, 255.0, 0 );
- cvConvertScaleAbs( mosaicVertical1, mosaic1, 1, 0 );
-
-
- cvNamedWindow("mosaic1",1);
- cvShowImage("mosaic1", mosaic1);
- cvWaitKey(0);
- cvDestroyWindow("mosaic1");
-
- for ( i=0; i<numoctaves;i++)
- {
- if (i==0)
- {
- mosaicHorizen1=MosaicHorizen( (DOGoctaves[0].Octave)[0].Level, (DOGoctaves[0].Octave)[1].Level );
- for (int j=2;j<SCALESPEROCTAVE+2;j++)
- mosaicHorizen1=MosaicHorizen( mosaicHorizen1, (DOGoctaves[0].Octave)[j].Level );
- for ( j=0;j<NUMSIZE;j++)
- mosaicHorizen1=halfSizeImage(mosaicHorizen1);
- }
- else if (i==1)
- {
- mosaicHorizen2=MosaicHorizen( (DOGoctaves[1].Octave)[0].Level, (DOGoctaves[1].Octave)[1].Level );
- for (int j=2;j<SCALESPEROCTAVE+2;j++)
- mosaicHorizen2=MosaicHorizen( mosaicHorizen2, (DOGoctaves[1].Octave)[j].Level );
- for ( j=0;j<NUMSIZE;j++)
- mosaicHorizen2=halfSizeImage(mosaicHorizen2);
- mosaicVertical1=MosaicVertical( mosaicHorizen1, mosaicHorizen2 );
- }
- else
- {
- mosaicHorizen1=MosaicHorizen( (DOGoctaves[i].Octave)[0].Level, (DOGoctaves[i].Octave)[1].Level );
- for (int j=2;j<SCALESPEROCTAVE+2;j++)
- mosaicHorizen1=MosaicHorizen( mosaicHorizen1, (DOGoctaves[i].Octave)[j].Level );
- for ( j=0;j<NUMSIZE;j++)
- mosaicHorizen1=halfSizeImage(mosaicHorizen1);
- mosaicVertical1=MosaicVertical( mosaicVertical1, mosaicHorizen1 );
- }
- }
-
- double min_val=0;
- double max_val=0;
- cvMinMaxLoc( mosaicVertical1, &min_val, &max_val,NULL, NULL, NULL );
- if ( min_val<0.0 )
- cvAddS( mosaicVertical1, cvScalarAll( (-1.0)*min_val ), mosaicVertical1, NULL );
- mosaic2 = cvCreateImage(cvSize(mosaicVertical1->width, mosaicVertical1->height), IPL_DEPTH_8U,1);
- cvConvertScale( mosaicVertical1, mosaicVertical1, 255.0/(max_val-min_val), 0 );
- cvConvertScaleAbs( mosaicVertical1, mosaic2, 1, 0 );
-
-
- cvNamedWindow("mosaic1",1);
- cvShowImage("mosaic1", mosaic2);
- cvWaitKey(0);
-
-
- int keycount=DetectKeypoint(numoctaves, Gaussianpyr);
- printf("the keypoints number are %d ;/n", keycount);
- cvCopy(src,image1,NULL);
- DisplayKeypointLocation( image1 ,Gaussianpyr);
-
- cvPyrUp( image1, DoubleSizeImage, CV_GAUSSIAN_5x5 );
- cvNamedWindow("image1",1);
- cvShowImage("image1", DoubleSizeImage);
- cvWaitKey(0);
- cvDestroyWindow("image1");
-
-
- ComputeGrad_DirecandMag(numoctaves, Gaussianpyr);
- AssignTheMainOrientation( numoctaves, Gaussianpyr,mag_pyr,grad_pyr);
- cvCopy(src,image1,NULL);
- DisplayOrientation ( image1, Gaussianpyr);
-
-
- cvNamedWindow("image1",1);
-
- cvShowImage("image1", image1);
- cvWaitKey(0);
-
-
- ExtractFeatureDescriptors( numoctaves, Gaussianpyr);
- cvWaitKey(0);
-
-
- cvDestroyWindow("image1");
- cvDestroyWindow("mosaic1");
-
- cvReleaseImage(&image1);
- cvReleaseImage(&grey_im1);
- cvReleaseImage(&mosaic1);
- cvReleaseImage(&mosaic2);
- return 0;
- }
最后,再看一下,运行效果(图中美女为老乡+朋友,何姐08年照):
完。
版权声明:
1、本文版权归本人和CSDN共同拥有。转载,请注明出处及作者本人。
2、版权侵犯者,无论任何人,任何网站,1、永久追踪,2、永久谴责,3、永久追究法律责任的权利。
July、二零一一年三月十二日声明。
本文转载自:http://blog.csdn.net/v_JULY_v/article/details/6246213,如有转载请注明原出处。谢谢