2

I am trying to look for an equivalent OpenCV function for interp2 and I refer to this poster to use remap function in OpenCV.

cv::remap (in opencv) and interp2 (matlab)

However, I realized that there is a significant difference of the output between these two functions. Here is my Matlab Code

U = [0.1 0.1 0.1; 0.2 0.2 0.2; 0.3 0.3 0.3];
X = [0 0 0; 0.5 0.5 0.5; 1 1 1];
Y = [0 0.5 1;0 0.5 1;0 0.5 1];
V = interp2(U,X,Y,'linear',NaN)

I get the output V matrix as

   NaN       NaN       NaN
   NaN       NaN       NaN
   NaN       NaN    0.1000

This is my OpenCV code

#include "highgui.h"
#include "cv.h"
using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
    //generate flowmap model
    CvFileStorage* fx = cvOpenFileStorage("result.txt", 0, CV_STORAGE_WRITE);//ask storage for save file
    Mat xmesh = cvCreateMat(3, 3, 5);
    Mat ymesh = cvCreateMat(3, 3, 5);

    for (int i = 0; i < xmesh.rows; i++)
        for (int j = 0; j < xmesh.cols; j++)
        {
            xmesh.at<float>(i, j) = i*0.5;
            ymesh.at<float>(i, j) = j*0.5;
        }

    //generate optical flow folder
    Mat u = cvCreateMat(3, 3, 5);

    for (int i = 0; i <u.rows; i++)
        for (int j = 0; j < u.cols; j++)
        {
            u.at<float>(i, j) = (i + 1)*0.1;
        }
    Mat v = Mat::zeros(u.size(), u.type());

    remap(u, v, xmesh, ymesh, INTER_LINEAR, 0, cvScalarAll(0));

    //convert mat to Iplimage
    IplImage* xmesh_a = cvCloneImage(&(IplImage)xmesh);
    IplImage* ymesh_a = cvCloneImage(&(IplImage)ymesh);
    IplImage* u_a = cvCloneImage(&(IplImage)u);
    IplImage* v_a = cvCloneImage(&(IplImage)v);

    //save end to txt
    cvWrite(fx, "xmesh", xmesh_a, cvAttrList());
    cvWrite(fx, "ymesh", ymesh_a, cvAttrList());
    cvWrite(fx, "u", u_a, cvAttrList());
    cvWrite(fx, "v", v_a, cvAttrList());
    cvReleaseFileStorage(&fx);

    waitKey();

}

The output V matrix I get is

1.00000001e-001, 1.50000006e-001, 2.00000003e-001,
1.00000001e-001, 1.50000006e-001, 2.00000003e-001,
1.00000001e-001, 1.50000006e-001, 2.00000003e-001

Any help will be appreciated. Thanks!

rahnema1
  • 15,264
  • 3
  • 15
  • 27
SimaGuanxing
  • 673
  • 2
  • 10
  • 29
  • In the case that `U` holds your data, isn't the function call like this: `interp2(X,Y,U,...)`? – Irreducible Oct 12 '17 at 05:19
  • @Irreducible Thanks for the reply but I think it makes no difference for grid interpolation. Read this poster https://stackoverflow.com/questions/32235379/how-to-do-grid-interpolation-interp2-in-opencv – SimaGuanxing Oct 12 '17 at 14:18

1 Answers1

2

The difference in the results is related to difference in indexing between c++ and MATLAB that is 0-based and 1-based respectively.

interp2(U,X,Y,'linear',NaN) is the same as interp2(1:3,1:3,U,X,Y,'linear',NaN) changing it to interp2(0:2,0:2,U,X,Y,'linear',NaN) you will get the same result as OpenCV.

If you want result of remap to be the same as that of interp2 you can shift the xmesh and ymesh one step back and search for negative locations to produce nan values.

#include <cmath>
//...
//...
for (int i = 0; i < xmesh.rows; i++)
    for (int j = 0; j < xmesh.cols; j++)
    {
        xmesh.at<float>(i, j) = i*0.5-1;
        ymesh.at<float>(i, j) = j*0.5-1;
    }
//...
//...
remap(u, v, xmesh, ymesh, INTER_LINEAR, 0, cvScalarAll(NAN));

Result:

nan nan nan 
nan nan nan
nan nan 0.1
rahnema1
  • 15,264
  • 3
  • 15
  • 27
  • Thanks! @rahnema1 Can you show me how to modify OpenCV code to realize the same result compared with Matlab function? Thanks! – SimaGuanxing Oct 16 '17 at 16:13
  • I mean, if I want to change OpenCV code to realize what the orignial interp2 function does in Matlab, I need to use grid value which is outside of my current grid, right? Do I need to paddle my xmesh and ymesh using NaN at this point? I am trying to paddle NaA but don't know how to assign a NaN value in OpenCV. – SimaGuanxing Oct 16 '17 at 17:32
  • You need to shift the grid one step back. I mean `for (int i = -1; i < xmesh.rows-1; i++) for (int j = -1; j < xmesh.cols-1; j++)` and include `` and set the last parameter of the `remap` function to `NAN`. – rahnema1 Oct 16 '17 at 18:39
  • I changed my OpenCV code but still didn't get the same results. It would be great if you can post the modified OpenCV code so that I can test it. I appreciate your help and will accept answer once I get the identical results. – SimaGuanxing Oct 16 '17 at 20:19