1

I am translating a MATLAB program to Python program. In the MATLAB program I have the following line.

[x,y]=meshgrid(1:width,1:height);
tImg(:,:,1) = interp2(x,y,Img(:,:,1),single(Tx),single(Ty),'cubic');

So I translated it to the following Python code:

tImg[:, :, 0] = cv2.remap(img[:, :, 0], Tx.astype(np.float32), Ty.astype(np.float32), cv2.INTER_CUBIC)

The variable img is a 298 x 142 x 3 matrix. Tx and Ty are both 298 x 142 matrix. I have compared them in MATLAB and in Python and all variables are equal in both places. However, I did not get the same tImg after I execute the line above.

I am wondering if I am doing something wrong here. Thanks for help in advance.

Li Siyao
  • 83
  • 9
  • 3
    I suggest using `scipy.optimize.interp2d`, or even better, `scipy.optimize.griddata`. Those are great for translating from `interp2d`:) And how different are your results? If one implementation works with integers, while the other doubles, you're bound to have differences. And of course there are many ways for interpolation, and all of them can be correct while producing numerically different results. How huge is your difference? – Andras Deak -- Слава Україні Mar 12 '16 at 11:39
  • 1
    MATLAB's `interp2` and `cv2.remap` **are not the same thing**. `interp2` interpolates pixels within a given 2D spatial grid coordinate system. `cv2.remap` defines where pixels need to be shifted into an output image given a new position map. They are in no way going to give you the same output. – rayryeng Mar 12 '16 at 14:50
  • @AndrasDeak Thanks for your inputs. I have problem using interp2d as described [here](http://stackoverflow.com/questions/35871837/scipy-interp2d-memory-error-looking-for-alternative) so I think griddata may be a better alternative. However, when reading the [documentation](http://docs.scipy.org/doc/scipy-0.17.0/reference/generated/scipy.interpolate.griddata.html) I found it requires values to be in ndarray of (n,). I am not sure how this can be applied in my case. Hope you can further help. – Li Siyao Mar 13 '16 at 13:28
  • @LiSiyao that memory error is usually due to improper use of `interp2d`. When you call an interpolating function created with `interp2d`, it doesn't need a *mesh*, but two 1d arrays which *span a mesh*. So if `Tx,Ty=np.meshrid(Tx_vec,Ty_vec)`, then you need to call `interp2(...)(Tx_vec,Ty_vec)`, and the output will be on a mesh! [Here's a recent explanation of mine](http://stackoverflow.com/questions/35955658/unable-to-interprete-matlab-interp2d-in-python-scipy-interp/35959125?noredirect=1#comment59592848_35959125) in a similar context. If you want to use griddata and have problems, just ask. – Andras Deak -- Слава Україні Mar 13 '16 at 13:43
  • @AndrasDeak Yes I believe that is what others have commented under that question as well. Unfortunately I have MemoryError with `scipy.interpolate.interp2d(x, y, img[:, :, 0], kind='cubic')` and therefore it does not even reach the point where I need to use the interpolating function. I think I should try griddata instead, and hope you can guide me on this. – Li Siyao Mar 13 '16 at 13:47
  • I further read the documentation - it seems that if I want to use griddata, I need to make the samping points into a 2-D ndarray and values into a 1-D ndarray...am I right on it? – Li Siyao Mar 13 '16 at 13:54
  • @LiSiyao yes, sampling points have to be a 2d array of shape `[N,2]` if I'm not mistaken, and values 1d. For the interpolating points, you can either use a 2d array, or a tuple of arrays. So for the interpolating points, using `(Tx,Ty)` should work. [Here are some examples of mine](http://stackoverflow.com/questions/34643642/scipy-interp2d-bisplrep-unexpected-output-when-given-1d-input/34656728#34656728) involving griddata, but there I used a 2d array for interpolating points as well. – Andras Deak -- Слава Україні Mar 13 '16 at 14:18
  • @AndrasDeak Thanks. I tried following it and now I have the following: `tImg[:, :, 0] = scipy.interpolate.griddata(np.array([x.ravel(), y.ravel()]).T, img[:, :, 0].ravel(), np.array([Tx.ravel(), Ty.ravel()]).T, method='cubic').reshape(298, 142)`. It did give me result, but it is different from the one I obtained from MATLAB. I understand that the result may not be exactly the same, but what I would like to confirm is my translated code does basically the same thing as the MATLAB code I pasted above. I have compared x, y, Tx, and Ty are exactly the same. – Li Siyao Mar 13 '16 at 14:37
  • I am concerned about this because I have personally experience some differences in how numpy and MATLAB represent matrices differently. For example, the reshape in MATLAB and numpy takes different dafault axis (although I don't think this is a problem here). – Li Siyao Mar 13 '16 at 14:46
  • @LiSiyao [see my first comment](http://stackoverflow.com/questions/35957087/matlab-inter2p-and-opencv-remap-gives-different-result#comment59569688_35957087): "*And of course there are many ways for interpolation, and all of them can be correct while producing numerically different results. How huge is your difference?*". Check the relative error of the two outputs. Plot them: do they look the same? You need to quantify *how much* different they are. – Andras Deak -- Слава Україні Mar 13 '16 at 14:46
  • 1
    @AndrasDeak Yes now after I plot them and see the result I found the different is not huge - and basically I get a similar shape. So I do think at this stage it is already good enough for me. Thank you very much! – Li Siyao Mar 13 '16 at 14:53
  • @LiSiyao no problem. Please consider deleting your question, as in its current form it's unlikely to help future readers. If you disagree, please consider adding an answer of your own. – Andras Deak -- Слава Україні Mar 13 '16 at 14:56

0 Answers0