0

両方のショット間の平行移動で撮影された2つの画像の同じ要素間の距離を決定するプログラムをCで作成したいと思います(立体視で距離を測定するため)。

この距離は、ピクセルごとに計算された2つの画像間の推定「距離」で計算しています。しかし、これは本当に遅いです。

相互相関とFFTと呼ばれる方法でそれをより速くする方法について聞いた。しかし、Web上でコードやその情報を見つけることができません。

情報はありますか?

ありがとう !

PS:私はOpenCVを使用して画像を読み込んで作業しています。

4

2 に答える 2

0

あなたは本質的にimage registrationについて話している。これには多くのアルゴリズムがありますが、あなたがほのめかしているのはおそらく位相相関です。

于 2013-01-14T16:53:34.363 に答える
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);、エラー (無効なポインター) が返されることであり、その理由がわかりません...

ありがとう

于 2013-01-15T17:12:07.127 に答える