织梦CMS - 轻松建站从此开始!

罗索

Phase Correlation in OpenCV

落鹤生 发布于 2012-03-14 11:04 点击:次 
Phase Correlation is a method to check the similarity of two images with equal size. It can be used for template matching, object tracking, motion estimation, etc.
TAG:

Phase Correlation is a method to check the similarity of two images with equal size. It can be used for template matching, object tracking, motion estimation, etc. In this article, I will explain the basics and the code to perform Phase Correlation in OpenCV. The source code used in this tutorial is available for you to download. The package contains all necessary files and some installation notes.

Table of Contents:

  1. The Basics
  2. Main Code
  3. Phase Correlation Function
  4. Results
  5. Summary

1. The Basics

To obtain the Phase Correlation of two images, perform these steps:

  1. Load two images, f and g.
  2. Perform FFT on each image, resulting in F and G
  3. Obtain the cross power spectrum using this formula:
    Cross power spectrum formula
    where G bar is the complex conjugate of G.
  4. Obtain the phase correlation by performing IFFT on R

The result is a 2D array with each element has a value between 0 to 1. The location of the highest value corresponds with the object translation movement from image 1 to image 2.

2. Main Code

The main code performs a very simple task. It loads the reference and template images, call phase_correlation() function and display the result.

Note: In the code listings below I removed all error checking lines to make things simple. Remember that you should always have some error checking in your programs.

First, load the template and the reference image. Since Phase Correlation computes 2 equal images, the width and the height of both images need to be checked.

Listing 1: Load reference and template image

  1. /* load reference and template image */
  2. IplImage *ref = cvLoadImage( argv[1], CV_LOAD_IMAGE_GRAYSCALE );
  3. IplImage *tpl = cvLoadImage( argv[2], CV_LOAD_IMAGE_GRAYSCALE );
  4.  
  5. /* both images' size should be equal */
  6. if( ( tpl->width != ref->width ) || ( tpl->height != ref->height ) ) {
  7.     fprintf( stderr, "Both images must have equal width and height!\n" );
  8.     return 1;
  9. }
  10.  

Next create a new image, poc, for the Phase Correlation result. Then call phase_correlation() function with tpl, ref and poc passed as parameters.

Listing 2: Perform Phase Correlation

  1. /* create a new image, to store phase correlation result */
  2. IplImage *poc = cvCreateImage( cvSize( tpl->width, tpl->height ),
  3.                                IPL_DEPTH_64F, 1 );
  4.  
  5. /* get phase correlation of input images */
  6. phase_correlation( ref, tpl, poc );
  7.  

Now that poc contains the result from Phase Correlation, find its maximum value and the location using cvMinMaxLoc. The result then displayed in the command line.

Listing 3: Get maximum value

  1. /* find the maximum value and its location */
  2. CvPoint  minloc, maxloc;
  3. double   minval, maxval;
  4. cvMinMaxLoc( poc, &minval, &maxval, &minloc, &maxloc, 0 );
  5.  
  6. /* print it */
  7. fprintf( stdout,
  8.          "Maxval at (%d, %d) = %2.4f\n", maxloc.x, maxloc.y, maxval );
  9.  

The last step, display the images and free memory.

Listing 4: Display images and free memory

  1. /* display images and free memory */
  2. cvNamedWindow( "tpl", CV_WINDOW_AUTOSIZE );
  3. cvNamedWindow( "ref", CV_WINDOW_AUTOSIZE );    
  4. cvShowImage( "tpl", tpl );
  5. cvShowImage( "ref", ref );
  6.  
  7. cvWaitKey( 0 );
  8.  
  9. cvDestroyWindow( "tpl" );
  10. cvDestroyWindow( "ref" );    
  11. cvReleaseImage( &tpl );
  12. cvReleaseImage( &ref );
  13. cvReleaseImage( &poc );

In the next section I will explain the phase_correlation() function, line by line.

3. Phase Correlation Function

This function performs Phase Correlation operation. It takes 3 parameters:

  1. IplImage *ref: The reference image
  2. IplImage *tpl: The template image
  3. IplImage *poc: Empty image to store the result

To obtain the DFT of the images, I use the FFTW library rather than OpenCV's DFT functions. This will increase the speed since FFTW computes FFT very fast.

First get the width and the height of the image. These properties are needed for the rest of the function. Also setup the pointers to copy the images to FFTW input and vice versa.

Listing 5: Phase Correlation Function

  1. void phase_correlation( IplImage *ref, IplImage *tpl, IplImage *poc )
  2. {
  3.     int     i, j, k;
  4.     double  tmp;
  5.    
  6.     /* get image properties */
  7.     int width    = ref->width;
  8.     int height   = ref->height;
  9.     int step     = ref->widthStep;
  10.     int fft_size = width * height;
  11.  
  12.     /* setup pointers to images */
  13.     uchar   *ref_data = ( uchar* ) ref->imageData;
  14.     uchar   *tpl_data = ( uchar* ) tpl->imageData;
  15.     double  *poc_data = ( double* )poc->imageData;
  16.  

Note that the function above assumes that the three images have equal width and height. Next initialize some FFTW input/output arrays and plans, load the reference image to img1 and the template image to img2.

Listing 6: Initialize FFTW input and output arrays

  1.     /* allocate FFTW input and output arrays */
  2.     fftw_complex *img1 = ( fftw_complex* )fftw_malloc( sizeof( fftw_complex ) * width * height );
  3.     fftw_complex *img2 = ( fftw_complex* )fftw_malloc( sizeof( fftw_complex ) * width * height );
  4.     fftw_complex *res  = ( fftw_complex* )fftw_malloc( sizeof( fftw_complex ) * width * height );    
  5.    
  6.     /* setup FFTW plans */
  7.     fftw_plan fft_img1 = fftw_plan_dft_1d( width * height, img1, img1, FFTW_FORWARD,  FFTW_ESTIMATE );
  8.     fftw_plan fft_img2 = fftw_plan_dft_1d( width * height, img2, img2, FFTW_FORWARD,  FFTW_ESTIMATE );
  9.     fftw_plan ifft_res = fftw_plan_dft_1d( width * height, res,  res,  FFTW_BACKWARD, FFTW_ESTIMATE );
  10.    
  11.     /* load images' data to FFTW input */
  12.     for( i = 0, k = 0 ; i < height ; i++ ) {
  13.         for( j = 0 ; j < width ; j++, k++ ) {
  14.             img1[k][0] = ( double )ref_data[i * step + j];
  15.             img1[k][1] = 0.0;
  16.            
  17.             img2[k][0] = ( double )tpl_data[i * step + j];
  18.             img2[k][1] = 0.0;
  19.         }
  20.     }
  21.  

In the listing above res will hold the end result of the phase correlation operation. Next is the heart of this function. It performs Phase Correlation and store the result to poc.

Listing 7: Compute phase correlation

  1.     /* obtain the FFT of img1 */
  2.     fftw_execute( fft_img1 );
  3.    
  4.     /* obtain the FFT of img2 */
  5.     fftw_execute( fft_img2 );
  6.    
  7.     /* obtain the cross power spectrum */
  8.     for( i = 0; i < fft_size ; i++ ) {
  9.         res[i][0] = ( img2[i][0] * img1[i][0] ) - ( img2[i][1] * ( -img1[i][1] ) );
  10.         res[i][1] = ( img2[i][0] * ( -img1[i][1] ) ) + ( img2[i][1] * img1[i][0] );
  11.  
  12.         tmp = sqrt( pow( res[i][0], 2.0 ) + pow( res[i][1], 2.0 ) );
  13.  
  14.         res[i][0] /= tmp;
  15.         res[i][1] /= tmp;
  16.     }
  17.  
  18.     /* obtain the phase correlation array */
  19.     fftw_execute(ifft_res);
  20.  
  21.     /* normalize and copy to result image */
  22.     for( i = 0 ; i < fft_size ; i++ ) {
  23.         poc_data[i] = res[i][0] / ( double )fft_size;
  24.     }
  25.  

Note that we have to normalize the IFFT result since FFTW computes an unnormalized DFT. Now all we have to do is just free memory and return to main function.

Listing 8: Free Memory

  1.     /* deallocate FFTW arrays and plans */
  2.     fftw_destroy_plan( fft_img1 );
  3.     fftw_destroy_plan( fft_img2 );
  4.     fftw_destroy_plan( ifft_res );
  5.     fftw_free( img1 );
  6.     fftw_free( img2 );
  7.     fftw_free( res );
  8. }

The Phase Correlation result is stored in poc. The main code should find the maximum value and its location from this result.

4. Results

Here are some results I've got when computing phase correlation using this code.

Table 1. Phase Correlation Results

# Image 1 Image 2 Result
1. image 1 image 2
(Image 2 is identical
with image 1)
Max. value = 1.0
in (0,0)
2. image 1 image 2
(image 1 with some noise)
Max. value = 0.2729
in (0,0)
3. image 1 image 2
(object moved 6 pixels to
the right and 15 pixels to
the bottom)
Max. value = 0.6344
in (6,15)

The first result shows the maximum value is 1.0 at (0, 0). This means both images are identical.

The second result shows the maximum value is 0.2729 at (0, 0). This means there is no translation from image 1 to image 2, but image 2 has some noise in it.

The last result shows the maximum value is 0.6344 at (6, 15). This means image 1 has a translative movement 6 pixels to the right and 15 pixels to the bottom.

5. Summary

This article covered Phase Correlation function in OpenCV. The code makes use FFTW library to obtain the DFTs rather than using OpenCV's DFT functions. This will increase the speed since FFTW computes FFT very fast.

The source code in this tutorial is available for you to download. The package contains all necessary files and some installation notes.

Send your comments, questions and bug reports to me [at] nashruddin.com.

(nash ruddin)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201203/15823.html]
本文出处:nashruddin.com 作者:nash ruddin 原文
顶一下
(4)
100%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容