Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6872453
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T03:55:47+00:00 2026-05-27T03:55:47+00:00

I want to calculate phase correlation of function in OpenCV. I’ve found http://nashruddin.com/phase-correlation-function-in-opencv.html but

  • 0

I want to calculate phase correlation of function in OpenCV. I’ve found http://nashruddin.com/phase-correlation-function-in-opencv.html but there is used some other library and I want to do it with OpenCV.

My problem is differen cause I want to calculate phase correlation of two arrays, both 360 elements.
I tried to evaluate from documentation how to do it, but I don’t know if my method is good.
My R matrix isn’t normalized, how to normalize it and is it necessary?
If you give me some examples I would be grateful.
My function to do this task:

void calcPhaseCorrelation(int* x1, int* x2){
    Mat array1 = Mat(1,360,DataType<float>::type); 
    Mat array2 = Mat(1,360,DataType<float>::type);

    uchar* begin = array1.data;
    uchar* end = begin + (array1.step.p[0]/ sizeof(float)) * array1.size().height;
    uchar *ptr = begin;

    int ctr1 = 0, ctr2 = 0; //control in loops
    while(ptr<end)
    {
       *ptr = (float)x1[ctr1];
       ctr1++;
       ptr++;
    }

    begin = array2.data;
    end = begin + (array2.step.p[0]/ sizeof(float)) * array2.size().height;
    ptr = begin;
    while(ptr<end)
    {
        *ptr = x2[ctr2];
        ctr2++;
        ptr++;
    }

    Mat outputArray;
    outputArray.create(abs(array1.rows - array2.rows)+1, 
        abs(array1.cols - array2.cols)+1, array1.type());
    Size dftSize;
    dftSize.width = getOptimalDFTSize(array1.cols + array2.cols - 1);
    dftSize.height = getOptimalDFTSize(array1.rows + array2.rows - 1);

    Mat resultA(dftSize, array1.type(), Scalar::all(0));
    Mat resultB(dftSize, array2.type(), Scalar::all(0));
    dft(array1,resultA);
    dft(array2,resultB);

    Mat R;
    mulSpectrums(resultA,resultB,R,DFT_ROWS,true);
    Mat NormR;
normalize(R,NormR);
    idft(NormR,outputArray);
    double minVal, maxVal;
    Point minLoc, maxLoc;
    minMaxLoc(outputArray,&minVal,&maxVal,&minLoc,&maxLoc);

    std::cout<<"Min value: "<<minVal<<", max value: "<<maxVal<<std::endl;
    std::cout<<"Min loc x: "<<minLoc.x<<", min loc y: "<<minLoc.y<<std::endl;
    std::cout<<"Max loc x: "<<maxLoc.x<<", max loc y: "<<maxLoc.y<<std::endl;
}

I know that code is not clear etc., but it’s only fast test. I want to know if method is correct. But also there every advice is appreciated.

//Edit:
I used mevatron code and get #QNAN also while debugging seen that in function that it does not find a peak, value is (-1,-1).
Function I’m using with new OpenCV correlation function:

void phaseCorrelationOpenCvTrunk(int* array1, int* array2)
{
    Mat hann;

    vector<double> arr1, arr2;

    for(int i = 0; i < 360; i++)
    {
        arr1.push_back((double)array1[i]);
        arr2.push_back((double)array2[i]);
    }


    Mat firstArray = Mat(arr1);
    Mat secondArray = Mat(arr2);

    std::cout<<"Type control: "<<firstArray.type()<<std::endl;

    createHanningWindow(hann, firstArray.size(), CV_64F);

    Point2d shift = phaseCorrelate(firstArray, secondArray,hann);

    std::cout<<"shift: "<<shift.x<<";"<<shift.y<<std::endl;
}

What am I doing wrong?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T03:55:47+00:00Added an answer on May 27, 2026 at 3:55 am

    I have actually implemented this method for OpenCV, but unfortunately it is only in the SVN trunk at this stage.

    Here is a sample using the new method.

    If you would like to reference my implementation of it, you can find that here.

    Also, here is the test case for an additional example of using it.

    If you would like to use the trunk you can get a hold of it doing this:

    svn co https://code.ros.org/svn/opencv/trunk/opencv opencv-trunk
    

    Here is the CMake build guide for Linux. Here is the build guide for Windows.

    EDIT :
    Got a patch for you 🙂

    I found a few bugs in my code as well, so they should be corrected now. It also should support 1D phase-correlation now. I also found an issue with the cv::sqrt() function causing some -nan’s to show up even though std::sqrt() did not. I’m guessing it’s either a bug with OpenCV, or just an accuracy issue. Haven’t dug into it enough to find out though.

    Unfortunately, you can’t just use svn update to get my latest changes because I have to wait for the OpenCV developers to apply this patch. So, instead of you having to wait on that here is a patch you can apply to the $(OPENCV_SRC)/modules/imgproc/src/phasecorr.cpp file. Save this file as something like phasecorr.patch, and place it in the root of the OpenCV source directory. Here is a short TortoiseSVN guide for creating/applying patches from/to source trees.

    Index: modules/imgproc/src/phasecorr.cpp
    ===================================================================
    --- modules/imgproc/src/phasecorr.cpp   (revision 6971)
    +++ modules/imgproc/src/phasecorr.cpp   (working copy)
    @@ -83,8 +83,8 @@
    
                     for( j = 1; j <= rows - 2; j += 2 )
                     {
    -                    dataDst[j*stepDst] = (float)((double)dataSrc[j*stepSrc]*dataSrc[j*stepSrc] +
    -                                         (double)dataSrc[(j+1)*stepSrc]*dataSrc[(j+1)*stepSrc]);
    +                    dataDst[j*stepDst] = (float)std::sqrt((double)dataSrc[j*stepSrc]*dataSrc[j*stepSrc] +
    +                                                          (double)dataSrc[(j+1)*stepSrc]*dataSrc[(j+1)*stepSrc]);
                     }
    
                     if( k == 1 )
    @@ -103,7 +103,7 @@
    
                 for( j = j0; j < j1; j += 2 )
                 {
    -                dataDst[j] = (float)((double)dataSrc[j]*dataSrc[j] + (double)dataSrc[j+1]*dataSrc[j+1]);
    +                dataDst[j] = (float)std::sqrt((double)dataSrc[j]*dataSrc[j] + (double)dataSrc[j+1]*dataSrc[j+1]);
                 }
             }
         }
    @@ -127,8 +127,8 @@
    
                     for( j = 1; j <= rows - 2; j += 2 )
                     {
    -                    dataDst[j*stepDst] = dataSrc[j*stepSrc]*dataSrc[j*stepSrc] +
    -                                         dataSrc[(j+1)*stepSrc]*dataSrc[(j+1)*stepSrc];
    +                    dataDst[j*stepDst] = std::sqrt(dataSrc[j*stepSrc]*dataSrc[j*stepSrc] +
    +                                                   dataSrc[(j+1)*stepSrc]*dataSrc[(j+1)*stepSrc]);
                     }
    
                     if( k == 1 )
    @@ -147,13 +147,10 @@
    
                 for( j = j0; j < j1; j += 2 )
                 {
    -                dataDst[j] = dataSrc[j]*dataSrc[j] + dataSrc[j+1]*dataSrc[j+1];
    +                dataDst[j] = std::sqrt(dataSrc[j]*dataSrc[j] + dataSrc[j+1]*dataSrc[j+1]);
                 }
             }
         }
    -
    -    // do batch sqrt to use SSE optimizations...
    -    cv::sqrt(dst, dst);
     }
    
     static void divSpectrums( InputArray _srcA, InputArray _srcB, OutputArray _dst, int flags, bool conjB)
    @@ -196,9 +193,9 @@
                 {
                     if( k == 1 )
                         dataA += cols - 1, dataB += cols - 1, dataC += cols - 1;
    -                dataC[0] = dataA[0] / dataB[0];
    +                dataC[0] = dataA[0] / (dataB[0] + eps);
                     if( rows % 2 == 0 )
    -                    dataC[(rows-1)*stepC] = dataA[(rows-1)*stepA] / dataB[(rows-1)*stepB];
    +                    dataC[(rows-1)*stepC] = dataA[(rows-1)*stepA] / (dataB[(rows-1)*stepB] + eps);
                     if( !conjB )
                         for( j = 1; j <= rows - 2; j += 2 )
                         {
    @@ -239,9 +236,9 @@
             {
                 if( is_1d && cn == 1 )
                 {
    -                dataC[0] = dataA[0] / dataB[0];
    +                dataC[0] = dataA[0] / (dataB[0] + eps);
                     if( cols % 2 == 0 )
    -                    dataC[j1] = dataA[j1] / dataB[j1];
    +                    dataC[j1] = dataA[j1] / (dataB[j1] + eps);
                 }
    
                 if( !conjB )
    @@ -281,9 +278,9 @@
                 {
                     if( k == 1 )
                         dataA += cols - 1, dataB += cols - 1, dataC += cols - 1;
    -                dataC[0] = dataA[0] / dataB[0];
    +                dataC[0] = dataA[0] / (dataB[0] + eps);
                     if( rows % 2 == 0 )
    -                    dataC[(rows-1)*stepC] = dataA[(rows-1)*stepA] / dataB[(rows-1)*stepB];
    +                    dataC[(rows-1)*stepC] = dataA[(rows-1)*stepA] / (dataB[(rows-1)*stepB] + eps);
                     if( !conjB )
                         for( j = 1; j <= rows - 2; j += 2 )
                         {
    @@ -323,9 +320,9 @@
             {
                 if( is_1d && cn == 1 )
                 {
    -                dataC[0] = dataA[0] / dataB[0];
    +                dataC[0] = dataA[0] / (dataB[0] + eps);
                     if( cols % 2 == 0 )
    -                    dataC[j1] = dataA[j1] / dataB[j1];
    +                    dataC[j1] = dataA[j1] / (dataB[j1] + eps);
                 }
    
                 if( !conjB )
    @@ -354,31 +351,57 @@
     static void fftShift(InputOutputArray _out)
     {
         Mat out = _out.getMat();
    -    
    +
    +    if(out.rows == 1 && out.cols == 1)
    +    {
    +        // trivially shifted.
    +        return;
    +    }
    +
         vector<Mat> planes;
         split(out, planes);
    -    
    +
         int xMid = out.cols >> 1;
         int yMid = out.rows >> 1;
    -    
    -    for(size_t i = 0; i < planes.size(); i++)
    +
    +    bool is_1d = xMid == 0 || yMid == 0;
    +
    +    if(is_1d)
         {
    -        // perform quadrant swaps...
    -        Mat tmp;
    -        Mat q0(planes[i], Rect(0,    0,    xMid, yMid));
    -        Mat q1(planes[i], Rect(xMid, 0,    xMid, yMid));
    -        Mat q2(planes[i], Rect(0,    yMid, xMid, yMid));
    -        Mat q3(planes[i], Rect(xMid, yMid, xMid, yMid));
    -        
    -        q0.copyTo(tmp);
    -        q3.copyTo(q0);
    -        tmp.copyTo(q3);
    -        
    -        q1.copyTo(tmp);
    -        q2.copyTo(q1);
    -        tmp.copyTo(q2);
    +        xMid = xMid + yMid;
    +
    +        for(size_t i = 0; i < planes.size(); i++)
    +        {
    +            Mat tmp;
    +            Mat half0(planes[i], Rect(0, 0, xMid, 1));
    +            Mat half1(planes[i], Rect(xMid, 0, xMid, 1));
    +
    +            half0.copyTo(tmp);
    +            half1.copyTo(half0);
    +            tmp.copyTo(half1);
    +        }
         }
    -    
    +    else
    +    {
    +        for(size_t i = 0; i < planes.size(); i++)
    +        {
    +            // perform quadrant swaps...
    +            Mat tmp;
    +            Mat q0(planes[i], Rect(0,    0,    xMid, yMid));
    +            Mat q1(planes[i], Rect(xMid, 0,    xMid, yMid));
    +            Mat q2(planes[i], Rect(0,    yMid, xMid, yMid));
    +            Mat q3(planes[i], Rect(xMid, yMid, xMid, yMid));
    +
    +            q0.copyTo(tmp);
    +            q3.copyTo(q0);
    +            tmp.copyTo(q3);
    +
    +            q1.copyTo(tmp);
    +            q2.copyTo(q1);
    +            tmp.copyTo(q2);
    +        }
    +    }
    +
         merge(planes, out);
     }
    
    @@ -548,38 +571,67 @@
         int rows = dst.rows;
         int cols = dst.cols;
    
    +    bool is_1d = rows == 1 || cols == 1;
    +
    +    if(is_1d)
    +    {
    +        cols = cols + rows - 1;
    +    }
    +
         if(dst.depth() == CV_32F)
         {
             float* dstData = (float*)dst.data;
    
    -        for(int i = 0; i < rows; i++)
    +        if(is_1d)
             {
    -            double wr = 0.5 * (1.0f - cos(2.0f * CV_PI * (double)i / (double)(rows - 1)));
    -            for(int j = 0; j < cols; j++)
    +            for(int i = 0; i < cols; i++)
                 {
    -                double wc = 0.5 * (1.0f - cos(2.0f * CV_PI * (double)j / (double)(cols - 1)));
    -                dstData[i*cols + j] = (float)(wr * wc);
    +                double w = 0.5 * (1.0f - cos(2.0f * CV_PI * (double)i / (double)(cols - 1)));
    +                dstData[i] = (float)w;
                 }
             }
    +        else
    +        {
    +            for(int i = 0; i < rows; i++)
    +            {
    +                double wr = 0.5 * (1.0f - cos(2.0f * CV_PI * (double)i / (double)(rows - 1)));
    +                for(int j = 0; j < cols; j++)
    +                {
    +                    double wc = 0.5 * (1.0f - cos(2.0f * CV_PI * (double)j / (double)(cols - 1)));
    +                    dstData[i*cols + j] = (float)(wr * wc);
    +                }
    +            }
    
    -        // perform batch sqrt for SSE performance gains
    -        cv::sqrt(dst, dst);
    +            // perform batch sqrt for SSE performance gains
    +            cv::sqrt(dst, dst);
    +        }
         }
         else
         {
             double* dstData = (double*)dst.data;
    
    -        for(int i = 0; i < rows; i++)
    +        if(is_1d)
             {
    -            double wr = 0.5 * (1.0 - cos(2.0 * CV_PI * (double)i / (double)(rows - 1)));
    -            for(int j = 0; j < cols; j++)
    +            for(int i = 0; i < cols; i++)
                 {
    -                double wc = 0.5 * (1.0 - cos(2.0 * CV_PI * (double)j / (double)(cols - 1)));
    -                dstData[i*cols + j] = wr * wc;
    +                double w = 0.5 * (1.0f - cos(2.0f * CV_PI * (double)i / (double)(cols - 1)));
    +                dstData[i] = w;
                 }
             }
    +        else
    +        {
    +            for(int i = 0; i < rows; i++)
    +            {
    +                double wr = 0.5 * (1.0 - cos(2.0 * CV_PI * (double)i / (double)(rows - 1)));
    +                for(int j = 0; j < cols; j++)
    +                {
    +                    double wc = 0.5 * (1.0 - cos(2.0 * CV_PI * (double)j / (double)(cols - 1)));
    +                    dstData[i*cols + j] = wr * wc;
    +                }
    +            }
    
    -        // perform batch sqrt for SSE performance gains
    -        cv::sqrt(dst, dst);
    +            // perform batch sqrt for SSE performance gains
    +            cv::sqrt(dst, dst);
    +        }
         }
     }
    

    Finally, here is a code sample of using the 1D phase correlation I was using.

    int main(int argc, char* argv[])
    {
        Mat firstArray = Mat::zeros(Size(360, 1), CV_64F);
        Mat secondArray = Mat::zeros(Size(360, 1), CV_64F);
    
        for(int i = 0; i < firstArray.cols; i++)
        {
            if(i < 8)
            {
                firstArray.at<double>(0, i) = 1;
            }
    
            if(i < 6)
            {
                secondArray.at<double>(0, i) = 1;
            }
        }
    
        Mat hann;
        createHanningWindow(hann, firstArray.size(), CV_64F);
    
        Point2d shift = phaseCorrelate(firstArray, secondArray, hann);
    
        std::cout<< "shift: " << shift.x << ";" << shift.y << std::endl;
        return 0;
    }
    

    You should see an output of (-2, 0.5). The y value will always be 0.5 in the 1D case because that would be midway through the only row.

    Hope that is helpful to you!

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I want to calculate my countrys((new zealand) local date and time in php but
I want to calculate covariance matrix using Java. Is there any free library to
I want to calculate average number of re-opened tickets by project,but I couldn't do
I want to calculate number of used columns for each row in excel 2007
I want to calculate the mean for each Day but for a portion of
I want to calculate the size in bytes of the http response headers and
I want to calculate the time span between 2 times which I saved in
I want to calculate what is $x percentage of a $total. $x could be
I want to calculate the age of a person given the date of birth
I want to calculate the sum of 1/1 + 1/2 + 1/3 + ...

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.