# remap of remap is not equal to remap

I have two successive remap calls and I'm trying to merge them:

for (int j = 0; j < h; j++)
for (int i = 0; i < w; i++) {
float x, y;
x = mapx2.at<float>(j, i);
y = mapy2.at<float>(j, i);
x = RANGE(x, 0, w - 1);
y = RANGE(y, 0, h - 1);
mapx1_2.at<float>(j, i) = mapx1.at<float>(y, x);
mapy1_2.at<float>(j, i) = mapy1.at<float>(y, x);
}


The overall result looks the same but details are different. Here is an example. The first extract with the two successive remaps shows a smooth line. The second extract with the single merged remap is not smooth.

I tried to cast x and y to int but with the same result.

I understand that "interpolation of interpolation" is not the same as a single merged interpolation. How could I fix the problem?

PS: I asked the question on Stackoverflow but here should be a better place to get an answer I think.

edit retag close merge delete

Sort by » oldest newest most voted

Short answer: You're missing the interpolation. Your floats are getting down-converted to int when you access the pixel of the second map and you're losing the interpolation between them.

I honestly don't know if there's a good way to solve this. If one of the remaps is a simple transform, you can simply apply it yourself to make it work, but if they're both arbitrary...

more

I'm still confused. The extract looks GOOD when the two successive remaps occur. It's NOT, when I have the single merged remap. From your explanation, I would have thought the opposite.

( 2016-08-20 02:20:04 -0500 )edit

In my case, map[xy]2 is completely arbitrary but map[xy]1 corresponds to a 45-degree 3D rotation around the Y axis. I used this link to convert the transformation into a remap. I calculated the transformation with this link. In my code above, x and y are float. So even if I manage to replace mapx1 and mapy1 by sin/cos formula, how is it going to change and fix my problem?

( 2016-08-20 02:26:12 -0500 )edit
1

So, let's pretend that you're only shifting 0.25 pixels in the x direction, in both maps. You look up pixel (0,0) and see that the x is 0.25. Great. You check the range, and it's within the range, so that's good. Now you look up the second map. Here you can't look up what is in pixel 0.25, since there's no such thing. So it rounds to 0 and looks up what is in pixel 0, which is 0.25 again. Now your final shift is 0.25, when it should be 0.5.

All along, the first map is being rounded to the nearest int, which leads to the jaggies. If you know the math (which you say you do), you can do the floating point math on the values directly and not lose any precision.

( 2016-08-20 13:36:29 -0500 )edit

Very clear explanation. I got it now. The int-casting is done by "map[xy]1.at". Thanks.

( 2016-08-20 14:07:54 -0500 )edit

The overall result looks the same but details are different. Here is an example. The first extract with the two successive remaps shows a smooth line. The second extract with the single merged remap is not smooth.

more

Official site

GitHub

Wiki

Documentation