I need to interpolate whole 2d array in with c#.
I managed to write an interpolation class. It should work as intpl2 function of matlab.
slice: is the 2d array that going to be interpolated xaxis: interpolated x axis yaxis: interpolated y axis
It maps as v0 v1 | v3 v2
EDIT: Solve the issue, but I am open to more elegant solution :)
public static float[,] ArrayBilinear(float[,] slice, float[] xaxis, float[] yaxis)
{
float[,] scaledSlice = new float[xaxis.Length, yaxis.Length];
double xscale = ((xaxis.Length - 1) / (slice.GetLength(0) - 1));
double yscale = ((yaxis.Length - 1) / (slice.GetLength(1) - 1));
for (int x = 0; x < scaledSlice.GetLength(0) ; x++)
{
for (int y = 0; y < scaledSlice.GetLength(1) ; y++)
{
float gx = ((float)x) / xaxis.Length * (slice.GetLength(0) - 1);
float gy = ((float)y) / yaxis.Length * (slice.GetLength(1) - 1);
int xInOriginal = (int)gx;
int yInOriginal = (int)gy;
double v0 = slice[xInOriginal, yInOriginal];
double v1 = slice[xInOriginal + 1, yInOriginal];
double v2 = slice[xInOriginal + 1, yInOriginal + 1];
double v3 = slice[xInOriginal, yInOriginal + 1];
double newValue = (1 - GetScale(xscale, x)) * (1 - GetScale(yscale, y)) * v0 + GetScale(xscale, x) * (1 - GetScale(yscale, y)) * v1 + GetScale(xscale, x) * GetScale(yscale, y) * v2 + (1 - GetScale(xscale, x)) * GetScale(yscale, y) * v3;
scaledSlice[x, y] = (float)newValue;
}
}
return scaledSlice;
}
private static double GetScale(double scale, int i)
{
if (i == 0)
return 0;
if (i % scale > 0)
return (i % scale) / scale;
return 1.0;
}
public static float[] LinSpace(float start, float stop, int length)
{
if (length < 0)
{
throw new ArgumentOutOfRangeException(nameof(length));
}
if (length == 0) return new float[0];
if (length == 1) return new[] { stop };
float step = (stop - start) / (length - 1);
var data = new float[length];
for (int i = 0; i < data.Length; i++)
{
data[i] = start + i * step;
}
data[data.Length - 1] = stop;
return data;
}
Test with random 2d array
[Test]
public void testBilinearInterpolation()
{
float[,] array2D = new float[4, 4] { { 0, 0, 0, 5 }, { 1, 1, 4, 0 }, { 0, 1, 3, 1 }, { 0, 4, 0, 1 } };
var xaxes = LinSpace(0, 3, 10);
var yaxes = LinSpace(0, 3, 10);
var intepolatedarr = ArrayBilinear(array2D, xaxes , yaxes);
}
The interpolation result is wrong (Different from interp2 from matlab) I couldn't found why.