图像匹配—NCC算法,即归一化互相关匹配

来源:互联网 发布:p2p网络借贷公司注册 编辑:程序博客网 时间:2024/05/17 09:06

一、NCC的基础概念

  NCCnormalized cross correlation)算法,归一化互相关匹配法,是基于图像灰度信息的匹配方法。

二、NCC算法定义为:


三、代码(利用NCC的密集匹配)

  1. <pre name="code" class="cpp">/***********************************************  
  2.  * 
  3.  *   left_sq存放了左图窗口内像素与均值差值的平方 
  4.  *   right_sq存放了右图窗口内像素与均值差值的平方 
  5.  *   left_avg存放了左图窗口内像素的均值 
  6.  *   right_avg存放了右图窗口内像素的均值 
  7.  * 
  8.  **************************************************/  
  9. void compute_sq(IplImage* left_img, IplImage* right_img, float *left_sq, float *right_sq, float *left_avg, float *right_avg)  
  10. {  
  11.     //图像的高度和宽度  
  12.     int height = left_img->height;  
  13.     int width = left_img->width;  
  14.     //窗口半径,为奇数  
  15.     int N = 5;  
  16.     //图像匹配的起始行和终止行  
  17.     int line_start = N;  
  18.     int line_end = height-N;  
  19.     //图像需要视差搜索的起始列和终止列  
  20.     int row_start = N;  
  21.     int row_end = width-N;  
  22.     int addr = 0;  
  23.     float temp_l = 0, temp_r = 0, suml = 0, sumr = 0;  
  24.   
  25.   
  26.     for (int j = line_start; j < line_end; j++)  
  27.     {  
  28.         for (int i = row_start; i < row_end; i++)  
  29.         {  
  30.             suml = 0.0, sumr = 0.0;  
  31.             temp_l = 0.0; temp_r = 0.0;  
  32.             for (int m = j - N; m <= j + N; m++)  
  33.             {  
  34.                 for (int n = i - N; n <= i + N; n++)  
  35.                 {  
  36.                     suml += ((uchar*)(left_img->imageData + m*left_img->widthStep))[n];  
  37.                     //cout << "l_px:" << (int)((uchar*)(left_img->imageData + m*left_img->widthStep))[n] << endl;  
  38.                     sumr += ((uchar*)(right_img->imageData + m*right_img->widthStep))[n];  
  39.                     //cout << "r_px:" << (int)((uchar*)(right_img->imageData + m*right_img->widthStep))[n]<<endl;  
  40.                 }  
  41.             }  
  42.             addr = j*width + i;  
  43.             left_avg[addr] = suml / pow((2 * N + 1), 2);  
  44.             right_avg[addr] = sumr / pow((2 * N + 1), 2);  
  45.             //cout << "l_avg:" << (float)left_avg[addr]<<endl;  
  46.             //cout << "r_avg:" << (float)right_avg[addr]<<endl;  
  47.             for (int m = j - N; m <= j + N; m++)  
  48.             {  
  49.                 for (int n = i - N; n <= i + N; n++)  
  50.                 {  
  51.                     temp_l += pow((((uchar*)(left_img->imageData + m*left_img->widthStep))[n] - left_avg[addr]), 2);  
  52.                     temp_r += pow((((uchar*)(right_img->imageData + m*right_img->widthStep))[n] - right_avg[addr]), 2);  
  53.                 }  
  54.   
  55.                   
  56.             }  
  57.             left_sq[addr] = temp_l;  
  58.             right_sq[addr] = temp_r;  
  59.             //cout << "l_sq:" << (float)left_sq[addr] << endl;  
  60.             //cout << "r_sq:" << (float)right_sq[addr] << endl;  
  61.         }  
  62.           
  63.   
  64.     }  
  65.   
  66. }  
  67. void compute_DP(IplImage* left_img, IplImage* right_img, IplImage* depth_img, float *left_sq, float *right_sq, float *left_avg, float *right_avg)  
  68.     {  
  69.         //图像的高度和宽度  
  70.         int height = left_img->height;  
  71.         int width = left_img->width;  
  72.         //窗口半径,为奇数  
  73.         int N = 5;   
  74.         //搜索的视差值范围  
  75.         int maxD = 10;  
  76.         int minD = 1;  
  77.         //图像匹配的起始行和终止行  
  78.         int line_start = N;  
  79.         int line_end = height-N;  
  80.         //图像需要视差搜索的起始列和终止列  
  81.         int row_start = N;  
  82.         int row_end = width-N-maxD;  
  83.   
  84.         int addr;  
  85.         float max_tmp, cov_tmp;  
  86.         //视差  
  87.         int vd = 0;  
  88.   
  89.         for (int j = line_start; j < line_end; j++)  
  90.         {  
  91.             for (int i = row_start; i < row_end; i++)  
  92.             {  
  93.                 for (int d = minD; d <= maxD; d++)  
  94.                 {  
  95.                     cov_tmp = 0.0;  
  96.                     addr = j*width + i;  
  97.                     for (int m = j - N; m <= j + N; m++)  
  98.                     {  
  99.                         for (int n = i - N; n <= i + N; n++)  
  100.                         {  
  101.                             //cout << "l_px:" << (int)((uchar*)(left_img->imageData + m*left_img->widthStep))[n] << endl;  
  102.                             //cout << "l-avg:" << (float)(((uchar*)(left_img->imageData + m*left_img->widthStep))[n] - left_avg[addr]) << endl;  
  103.                             //cout << "r_px:" << (int)((uchar*)(right_img->imageData + m*right_img->widthStep))[n + d] << endl;  
  104.                             //cout << "r-avg:" << (float)(((uchar*)(right_img->imageData + m*right_img->widthStep))[n + d] - right_avg[addr+d])<<endl;  
  105.                             cov_tmp += (((uchar*)(left_img->imageData + m*left_img->widthStep))[n]-left_avg[addr])*(((uchar*)(right_img->imageData + m*right_img->widthStep))[n + d]-right_avg[addr+d]);  
  106.                         }  
  107.                     }  
  108.                     //cout << "a:" << cov_tmp << endl;          
  109.                     cov_tmp = (float)(cov_tmp / sqrt(left_sq[addr] * right_sq[addr+d]));  
  110.                     //cout << "cov_tmp:" << cov_tmp << endl;  
  111.                     if (d == minD)  
  112.                     {  
  113.                         max_tmp = cov_tmp;  
  114.                         vd = d;  
  115.                     }  
  116.                     else  
  117.                     {  
  118.                         if (cov_tmp > max_tmp)  
  119.                         {  
  120.                             max_tmp = cov_tmp;  
  121.                             vd = d;  
  122.                         }  
  123.                     }  
  124.                 }  
  125.                 vd = vd * 20;  
  126.                 if (vd > 255)  
  127.                 {  
  128.                     vd = 255;  
  129.                 }  
  130.                 else if (vd < 0)  
  131.                 {  
  132.                     vd = 0;  
  133.                 }  
  134.                 //cout << "d:" << vd << endl;  
  135.                 ((uchar*)(depth_img->imageData + j*depth_img->widthStep))[i] = vd;  
  136.             }  
  137.         }     
  138. }  
  139. void NCC_Match(IplImage* left_img, IplImage* right_img, IplImage* depth_img)  
  140. {  
  141.     float *left_sq, *right_sq, *left_avg, *right_avg;  
  142.     int img_size = left_img->height*left_img->width;  
  143.   
  144.     left_sq = (float *)malloc(img_size * sizeof(float));  
  145.     right_sq = (float *)malloc(img_size * sizeof(float));  
  146.     left_avg = (float *)malloc(img_size * sizeof(float));  
  147.     right_avg = (float *)malloc(img_size * sizeof(float));  
  148.   
  149.     memset(left_sq, 0, img_size);  
  150.     memset(right_sq, 0, img_size);  
  151.   
  152.     compute_sq(left_img, right_img, left_sq, right_sq,left_avg,right_avg);  
  153.     compute_DP(left_img, right_img, depth_img, left_sq, right_sq,left_avg,right_avg);  
  154.   
  155.     free(left_sq);  
  156.     free(right_sq);  
  157.   
  158.     return;  
  159. }  

原创粉丝点击