C#2D阵列插值
我需要用c#插值整个二维数组 我设法写了一个插值类。它应该作为matlab的intpl2函数工作 切片:是要插值的二维数组 xaxis:插值x轴 yaxis:插值y轴 它映射为 v0 v1 | v3 v2 编辑:解决问题,但我愿意接受更优雅的解决方案:)C#2D阵列插值,c#,multidimensional-array,linear-interpolation,C#,Multidimensional Array,Linear Interpolation,我需要用c#插值整个二维数组 我设法写了一个插值类。它应该作为matlab的intpl2函数工作 切片:是要插值的二维数组 xaxis:插值x轴 yaxis:插值y轴 它映射为 v0 v1 | v3 v2 编辑:解决问题,但我愿意接受更优雅的解决方案:) 插值结果错误(与matlab中的interp2不同),我找不到原因 似乎您交换了v1和v3。顺便说一句,我觉得这个代码结构很奇怪。为什么ArrayBinlinear设置类成员而不是将它们作为参数传递?这将使你陷入严重的麻烦,只要你想多线程。让所
插值结果错误(与matlab中的interp2不同),我找不到原因 似乎您交换了
v1
和v3
。顺便说一句,我觉得这个代码结构很奇怪。为什么ArrayBinlinear
设置类成员而不是将它们作为参数传递?这将使你陷入严重的麻烦,只要你想多线程。让所有方法都是静态的听起来更合理。还有,你为什么要缩放坐标?是的,我看到了v1和v3谢谢。代码只是为了测试,我将把它转换成静态类。但这并不能解决我的问题。那你有什么问题?(20,20)和(77,77)是从哪里来的?结果是不对的,我相信我最初和最初的计算中有些地方是错误的。(20,20和(77,77)这只是一个例子。我试图将matlab interp2函数转换为c#。我将其转换为一个静态函数。能否请您发布一篇文章,其中包含一些显示问题的数据?告诉我们您得到了什么以及您期望得到什么。似乎您交换了v1
和v3
。顺便说一句,我发现这个代码结构非常奇怪。为什么ArrayBilinear
>设置类成员而不是将其作为参数传递?这会在您想要多线程时给您带来严重的麻烦。使所有方法都是静态的听起来更合理。还有,为什么要缩放坐标?是的,我看到了v1,v3谢谢。代码只是为了测试,我会将其转换为静态类。但是(20,20)和(77,77)是从哪里来的?结果是不对的,我相信我的原始和原始计算中有一些错误。(20,20和(77,77)这只是一个例子。我正在尝试将matlab interp2函数转换为c#。我将其转换为一个静态函数。能否请您发布一篇文章,其中包含一些显示问题的数据?告诉我们您得到了什么以及您的期望。
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 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]
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);
}