2

I have a two-dimensional matrix whose elements represent data that can be colormapped and represented as an image. I want to interpolate them, but I get strange behavior at some of the boundaries that I can't explain.

Here is the original image, the image after 3 iterations of the interpolation routine, and the image after 10 interpolation iterations. Original data Data after 3 interpolation iterations Data after 10 interpolation iterations

Here's my code:

close all

ifactor = 0.9;  % Interpolation factor

% Cut out the meaningless stuff at the edges
bshift_i = bshift(1:16, 1:50);

[m, n] = size(bshift_i);

% Plot the initial data using colormapping
figure()
imagesc(bshift_i, [7.5 10.5])
colorbar()

% Main processing loop
for ii = 1:10
    % Every iteration, we generate a grid that has the same size as the
    % existing data, and another one that whose axis step sizes are
    % (ifactor) times smaller than the existing axes.
    [b_x, b_y] = meshgrid(1:ifactor^(ii - 1):n, 1:ifactor^(ii - 1):m);
    [b_xi, b_yi] = meshgrid(1:ifactor^ii:n, 1:ifactor^ii:m);

    % Interpolate our data and reassign to bshift_i so that we can use it
    % in the next iteration
    bshift_i = interp2(b_x, b_y, bshift_i, b_xi, b_yi);
end

% Plot the interpolated image
figure()
imagesc(bshift_i, [7.5 10.5])
colorbar()

I'm mainly wondering why the blue artifacts at the bottom and right edges occur, and if so, how I can work around/avoid them.

Scott
  • 319
  • 4
  • 13

1 Answers1

1

The problem is how you define the x and y ranges for the interpolation.
Let's take a look at 1:ifactor^(ii - 1):m:

  • For the first iteration, you get 16 values, from 1 to 16.
  • For the second iteration, you get 17 values, from 1 to 15.4
  • For the third iteration, you get 19 values, from 1 to 15.58

An this is enough to illustrate the problem. With the second iteration, everything is fine, because your upper interpolation bound is inside the value range. However, for the third iteration, your upper bound is now outside the value range (15.58 > 15.4).
interp2 does not extrapolate, it returns a NaN (after the 3rd iteration, bshift_i(end,end) is NaN). These NaNs get plotted as 0, hence blue.

To fix this, you have to ensure that your x and y range always include the last value. One way to do this could be:

[b_x, b_y] = meshgrid(linspace(1,n,n./(ifactor^(ii - 1))), ...
                      linspace(1,m,m./(ifactor^(ii - 1))));
[b_xi, b_yi] = meshgrid(linspace(1,n,n./(ifactor^(ii))), ...
                        linspace(1,m,m./(ifactor^(ii))));

linspace always includes the first and the last element. However, the third input is not the increment, but the number of elements. That's why you'd have to adapt that condition to resemble your approach.

Schorsch
  • 7,761
  • 6
  • 39
  • 65