2013-01-14 74 views
0

我想用C編寫程序以確定兩張圖像之間的平移所拍攝的兩張圖像中相同元素之間的距離(通過立體圖測量距離) 。如何計算2張圖像中相同元素之間的像素距離

我正在用逐像素計算的兩幅圖像之間的估計「距離」計算該距離。但是,這真的很慢。

我聽說過使用稱爲交叉相關和FFT的方法能更快地完成它的方法。但我無法在網上找到任何代碼或信息。

你有一些信息嗎?

謝謝!

P.S. :我使用OpenCV加載和處理圖像。

+0

這裏是[模板匹配(HTTP: //docs.opencv.org/doc/tutorials/imgproc/histograms/template_matching/template_matching.html)來自OpenCV文檔的教程。 – flowfree

回答

0

感謝您的回答,我設法編寫了一個幾乎可以工作的代碼。

struct Peak Find_FFT(IplImage* src, IplImage* tpl, int hamming) 
{ 
    int i, j, k; 
    double tmp; //To store the modulus temporarily 

    //src and tpl must be the same size 
    assert(src->width == tpl->width); 
    assert(src->height == tpl->height); 

    // Get image properties 
    int width = src->width; 
    int height = src->height; 
    int step  = src->widthStep; 
    int fft_size = width * height; 

    //fftw_init_threads(); //Initialize FFTW for multithreading with a max number of 4 threads 
    //fftw_plan_with_nthreads(4); 

    //Allocate arrays for FFT of src and tpl 
    fftw_complex *src_spatial = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * width * height); 
    fftw_complex *src_freq = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * width * height); 
    fftw_complex *tpl_spatial = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * width * height); 
    fftw_complex *tpl_freq = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * width * height); 

    fftw_complex *res_spatial = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * width * height); //Result = Cross correlation 
    fftw_complex *res_freq = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * width * height); 

    // Setup pointers to images 
    uchar *src_data = (uchar*) src->imageData; 
    uchar *tpl_data = (uchar*) tpl->imageData; 

    // Fill the structure that will be used by fftw 
    for(i = 0; i < height; i++) 
    { 
     for(j = 0 ; j < width ; j++, k++) 
     { 
      src_spatial[k][0] = (double) src_data[i * step + j]; 
      src_spatial[k][1] = 0.0; 

      tpl_spatial[k][0] = (double) tpl_data[i * step + j]; 
      tpl_spatial[k][1] = 0.0; 
     } 
    } 

    // Hamming window to improve FFT (but slightly slower to compute) 
    if(hamming == 1) 
    { 
     double omega = 2.0*M_PI/(fft_size-1); 
     double A= 0.54; 
     double B= 0.46; 
     for(i=0,k=0;i<height;i++) 
     { 
      for(j=0;j<width;j++,k++) 
      { 
       src_spatial[k][0]= (src_spatial[k][0])*(A-B*cos(omega*k)); 
       tpl_spatial[k][0]= (tpl_spatial[k][0])*(A-B*cos(omega*k)); 
      } 
     } 
    } 

    // Setup FFTW plans 
    fftw_plan plan_src = fftw_plan_dft_2d(height, width, src_spatial, src_freq, FFTW_FORWARD, FFTW_ESTIMATE); 
    fftw_plan plan_tpl = fftw_plan_dft_2d(height, width, tpl_spatial, tpl_freq, FFTW_FORWARD, FFTW_ESTIMATE); 
    fftw_plan plan_res = fftw_plan_dft_2d(height, width, res_freq, res_spatial, FFTW_BACKWARD, FFTW_ESTIMATE); 

    // Execute the FFT of the images 
    fftw_execute(plan_src); 
    fftw_execute(plan_tpl); 

    // Compute the cross-correlation 
    for(i = 0; i < fft_size ; i++) 
    { 
     res_freq[i][0] = tpl_freq[i][0] * src_freq[i][0] + tpl_freq[i][1] * src_freq[i][1]; 
     res_freq[i][1] = tpl_freq[i][0] * src_freq[i][1] - tpl_freq[i][1] * src_freq[i][0]; 

     tmp = sqrt(pow(res_freq[i][0], 2.0) + pow(res_freq[i][1], 2.0)); 

     res_freq[i][0] /= tmp; 
     res_freq[i][1] /= tmp; 
    } 

    // Get the phase correlation array = compute inverse fft 
    fftw_execute(plan_res); 

    // Find the peak 
    struct Peak pk; 
    IplImage* peak_find = cvCreateImage(cvSize(tpl->width,tpl->height), IPL_DEPTH_64F, 1); 
    double *peak_find_data = (double*) peak_find->imageData; 

    for(i = 0 ; i < fft_size ; i++) 
    { 
     peak_find_data[i] = res_spatial[i][0]/(double) fft_size; 
    } 

    CvPoint minloc, maxloc; 
    double minval, maxval; 

    cvMinMaxLoc(peak_find, &minval, &maxval, &minloc, &maxloc, 0); 

    pk.pt = maxloc; 
    pk.maxval = maxval; 

    // Clear memory 
    fftw_destroy_plan(plan_src); 
    fftw_destroy_plan(plan_tpl); 
    fftw_destroy_plan(plan_res); 
    fftw_free(src_spatial); 
    fftw_free(tpl_spatial); 
    fftw_free(src_freq); 
    fftw_free(tpl_freq); 
    fftw_free(res_spatial); 
    fftw_free(res_freq); 
    cvReleaseImage(&peak_find); 

    //fftw_cleanup_threads(); //Cleanup everything else related to FFTW 

    return pk; 
} 

問題是與fftw_free(src_freq);返回我一個錯誤(無效的指針),我只是找不到爲什麼...

感謝

+0

我解決了它,這是一個愚蠢的錯誤... 我只是忘了初始化k ... – user1977881