九之再续 教你一步一步用c语言实现sift算法 下

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.youkuaiyun.com/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

                      教你一步一步用c语言实现sift算法、下


作者:July、二零一一年三月十二日
出处:http://blog.youkuaiyun.com/v_JULY_v
参考:Rob Hess维护的sift 库
环境:windows xp+vc6.0
条件:c语言实现。
说明:本BLOG内会陆续一一实现所有经典算法。
------------------------


本文接上,教你一步一步用c语言实现sift算法、上,而来:
函数编写
    ok,接上文,咱们一个一个的来编写main函数中所涉及到所有函数,这也是本文的关键部分:

  1. //下采样原来的图像,返回缩小2倍尺寸的图像  
  2. CvMat * halfSizeImage(CvMat * im)   
  3. {  
  4.  unsigned int i,j;  
  5.  int w = im->cols/2;  
  6.  int h = im->rows/2;   
  7.  CvMat *imnew = cvCreateMat(h, w, CV_32FC1);  
  8.    
  9. #define Im(ROW,COL) ((float *)(im->data.fl + im->step/sizeof(float) *(ROW)))[(COL)]  
  10. #define Imnew(ROW,COL) ((float *)(imnew->data.fl + imnew->step/sizeof(float) *(ROW)))[(COL)]  
  11.  for ( j = 0; j < h; j++)   
  12.   for ( i = 0; i < w; i++)   
  13.    Imnew(j,i)=Im(j*2, i*2);  
  14.   return imnew;  
  15. }  
  16.   
  17. //上采样原来的图像,返回放大2倍尺寸的图像  
  18. CvMat * doubleSizeImage(CvMat * im)   
  19. {  
  20.  unsigned int i,j;  
  21.  int w = im->cols*2;  
  22.  int h = im->rows*2;   
  23.  CvMat *imnew = cvCreateMat(h, w, CV_32FC1);  
  24.    
  25. #define Im(ROW,COL) ((float *)(im->data.fl + im->step/sizeof(float) *(ROW)))[(COL)]  
  26. #define Imnew(ROW,COL) ((float *)(imnew->data.fl + imnew->step/sizeof(float) *(ROW)))[(COL)]  
  27.    
  28.  for ( j = 0; j < h; j++)   
  29.   for ( i = 0; i < w; i++)   
  30.    Imnew(j,i)=Im(j/2, i/2);  
  31.     
  32.   return imnew;  
  33. }  
  34.   
  35. //上采样原来的图像,返回放大2倍尺寸的线性插值图像  
  36. CvMat * doubleSizeImage2(CvMat * im)   
  37. {  
  38.  unsigned int i,j;  
  39.  int w = im->cols*2;  
  40.  int h = im->rows*2;   
  41.  CvMat *imnew = cvCreateMat(h, w, CV_32FC1);  
  42.    
  43. #define Im(ROW,COL) ((float *)(im->data.fl + im->step/sizeof(float) *(ROW)))[(COL)]  
  44. #define Imnew(ROW,COL) ((float *)(imnew->data.fl + imnew->step/sizeof(float) *(ROW)))[(COL)]  
  45.    
  46.  // fill every pixel so we don't have to worry about skipping pixels later  
  47.  for ( j = 0; j < h; j++)   
  48.  {  
  49.   for ( i = 0; i < w; i++)   
  50.   {  
  51.    Imnew(j,i)=Im(j/2, i/2);  
  52.   }  
  53.  }  
  54.  /* 
  55.  A B C 
  56.  E F G 
  57.  H I J 
  58.  pixels A C H J are pixels from original image 
  59.  pixels B E G I F are interpolated pixels 
  60.  */  
  61.  // interpolate pixels B and I  
  62.  for ( j = 0; j < h; j += 2)  
  63.   for ( i = 1; i < w - 1; i += 2)  
  64.    Imnew(j,i)=0.5*(Im(j/2, i/2)+Im(j/2, i/2+1));  
  65.   // interpolate pixels E and G  
  66.   for ( j = 1; j < h - 1; j += 2)  
  67.    for ( i = 0; i < w; i += 2)  
  68.     Imnew(j,i)=0.5*(Im(j/2, i/2)+Im(j/2+1, i/2));  
  69.    // interpolate pixel F  
  70.    for ( j = 1; j < h - 1; j += 2)  
  71.     for ( i = 1; i < w - 1; i += 2)  
  72.      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));  
  73.     return imnew;  
  74. }  
  75.   
  76. //双线性插值,返回像素间的灰度值  
  77. float getPixelBI(CvMat * im, float col, float row)   
  78. {  
  79.  int irow, icol;  
  80.  float rfrac, cfrac;  
  81.  float row1 = 0, row2 = 0;  
  82.  int width=im->cols;  
  83.  int height=im->rows;  
  84. #define ImMat(ROW,COL) ((float *)(im->data.fl + im->step/sizeof(float) *(ROW)))[(COL)]  
  85.    
  86.  irow = (int) row;  
  87.  icol = (int) col;  
  88.    
  89.  if (irow < 0 || irow >= height  
  90.   || icol < 0 || icol >= width)  
  91.   return 0;  
  92.  if (row > height - 1)  
  93.   row = height - 1;  
  94.  if (col > width - 1)  
  95.   col = width - 1;  
  96.  rfrac = 1.0 - (row - (float) irow);  
  97.  cfrac = 1.0 - (col - (float) icol);  
  98.  if (cfrac < 1)   
  99.  {  
  100.   row1 = cfrac * ImMat(irow,icol) + (1.0 - cfrac) * ImMat(irow,icol+1);  
  101.  }   
  102.  else   
  103.  {  
  104.   row1 = ImMat(irow,icol);  
  105.  }  
  106.  if (rfrac < 1)   
  107.  {  
  108.   if (cfrac < 1)   
  109.   {  
  110.    row2 = cfrac * ImMat(irow+1,icol) + (1.0 - cfrac) * ImMat(irow+1,icol+1);  
  111.   } else   
  112.   {  
  113.    row2 = ImMat(irow+1,icol);  
  114.   }  
  115.  }  
  116.  return rfrac * row1 + (1.0 - rfrac) * row2;  
  117. }  
  118.   
  119. //矩阵归一化  
  120. void normalizeMat(CvMat* mat)   
  121. {  
  122. #define Mat(ROW,COL) ((float *)(mat->data.fl + mat->step/sizeof(float) *(ROW)))[(COL)]  
  123.  float sum = 0;  
  124.    
  125.  for (unsigned int j = 0; j < mat->rows; j++)   
  126.   for (unsigned int i = 0; i < mat->cols; i++)   
  127.    sum += Mat(j,i);  
  128.   for ( j = 0; j < mat->rows; j++)   
  129.    for (unsigned int i = 0; i < mat->rows; i++)   
  130.     Mat(j,i) /= sum;  
  131. }  
  132.   
  133. //向量归一化  
  134. void normalizeVec(float* vec, int dim)   
  135. {  
  136.     unsigned int i;  
  137.  float sum = 0;  
  138.  for ( i = 0; i < dim; i++)  
  139.   sum += vec[i];  
  140.  for ( i = 0; i < dim; i++)  
  141.   vec[i] /= sum;  
  142. }  
  143.   
  144. //得到向量的欧式长度,2-范数  
  145. float GetVecNorm( float* vec, int dim )  
  146. {  
  147.  float sum=0.0;  
  148.  for (unsigned int i=0;i<dim;i++)  
  149.   sum+=vec[i]*vec[i];  
  150.     return sqrt(sum);  
  151. }  
  152.   
  153. //产生1D高斯核  
  154. float* GaussianKernel1D(float sigma, int dim)   
  155. {  
  156.    
  157.  unsigned int i;  
  158.  //printf("GaussianKernel1D(): Creating 1x%d vector for sigma=%.3f gaussian kernel/n", dim, sigma);  
  159.    
  160.  float *kern=(float*)malloc( dim*sizeof(float) );  
  161.  float s2 = sigma * sigma;  
  162.  int c = dim / 2;  
  163.  float m= 1.0/(sqrt(2.0 * CV_PI) * sigma);  
  164.     double v;   
  165.  for ( i = 0; i < (dim + 1) / 2; i++)   
  166.  {  
  167.   v = m * exp(-(1.0*i*i)/(2.0 * s2)) ;  
  168.   kern[c+i] = v;  
  169.   kern[c-i] = v;  
  170.  }  
  171.  //   normalizeVec(kern, dim);  
  172.  // for ( i = 0; i < dim; i++)  
  173.  //  printf("%f  ", kern[i]);  
  174.  //  printf("/n");  
  175.  return kern;  
  176. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值