数组插值

在我开始之前,请接受我的道歉,我不是一名数学家,并且我真的不知道我正在尝试做什么的正确名称…;)指向可能有帮助的任何简单英语解释赞赏(因为我现在基于我认为解决方案可能是纯粹的谷歌搜索)。

如果有一个多维的源值数组并希望将该数组放大n倍,我认为我需要使用的是双立方插值当然,该页面右上方的图像代表了我的意思旨在 – 根据周围邻居的价值在基础源数据点之间创建渐进的价值流。 我完全接受通过不增加数据量而不是增加数据的分辨率; 只是模糊边缘。

类似于此事的东西;

源网格

对此(及以后);

目标网格

在维基百科文章中的链接之后给了我一个(假设的)我正在努力的实例 ,但是如果确实如此,我担心我现在错过了让自己在那里的逻辑飞跃。 当我在BicubicInterpolator上调用getValue(source,0.5,0.5)时,我又回来了什么? 我如果我给出(0.0,0.0)的x / y,我会回到网格的左下角值,如果我看(1,1),我会得到右上角,并且之间的任何值都会给我在插值网格内的指定位置。

double[][] source = new double[][] {{1, 1, 1, 2}, {1, 2, 2, 3}, {1, 2, 2, 3}, {1, 1, 3, 3}}; BicubicInterpolator bi = new BicubicInterpolator(); for (double idx = 0; idx <= 1; idx += 0.1) { LOG.info("Result (" + String.format("%3.1f", idx) + ", " + String.format("%3.1f", idx) + ") : " + bi.getValue(source, idx, idx)); } 

但是,源网格中对角线的输出是;

 Result (0.0, 0.0) : 2.0 Result (0.1, 0.1) : 2.08222625 Result (0.2, 0.2) : 2.128 Result (0.3, 0.3) : 2.13747125 Result (0.4, 0.4) : 2.11424 Result (0.5, 0.5) : 2.06640625 Result (0.6, 0.6) : 2.00672 Result (0.7, 0.7) : 1.9518312500000001 Result (0.8, 0.8) : 1.92064 Result (0.9, 0.9) : 1.93174625 Result (1.0, 1.0) : 2.0 

我很困惑,因为对角线从1到3和1到2; 从2到2没有任何变化,只有很少的(整体)变化。 我完全误解了事情吗?


编辑:按照彼得的建议扩大分析边界,现在可以将网格生成为30×30矩阵的快速高档;

彼得的回答是网格

现在正在发生的事情更有意义,我可以看到我需要考虑一些额外的事情;

  • 控制过冲(在网格中间看到,源有四个单元格的块,值为2,但内插值在2.2处达到峰值)
  • 满足源网格中的空白值,并将它们视为空白而不是零,这样它们就不会使计算偏差
  • 准备被告知我是在傻瓜的差事,需要一个不同的解决方案
  • 看看这是否是客户认为他们真正想要的东西,当他们说“ 减少块状 ”时

如果您假设“外部”温度与最外面的数值环相同,并且您想要移动正在考虑的网格的哪个端口…

 public static void main(String... args) { double[][] source = new double[][]{{1, 1, 1, 2}, {1, 2, 2, 3}, {1, 2, 2, 3}, {1, 1, 3, 3}}; BicubicInterpolator bi = new BicubicInterpolator(); for (int i = 0; i <= 30; i++) { double idx = i / 10.0; System.out.printf("Result (%3.1f, %3.1f) : %3.1f%n", idx, idx, bi.getValue(source, idx, idx)); } } public static class CubicInterpolator { public static double getValue(double[] p, double x) { int xi = (int) x; x -= xi; double p0 = p[Math.max(0, xi - 1)]; double p1 = p[xi]; double p2 = p[Math.min(p.length - 1,xi + 1)]; double p3 = p[Math.min(p.length - 1, xi + 2)]; return p1 + 0.5 * x * (p2 - p0 + x * (2.0 * p0 - 5.0 * p1 + 4.0 * p2 - p3 + x * (3.0 * (p1 - p2) + p3 - p0))); } } public static class BicubicInterpolator extends CubicInterpolator { private double[] arr = new double[4]; public double getValue(double[][] p, double x, double y) { int xi = (int) x; x -= xi; arr[0] = getValue(p[Math.max(0, xi - 1)], y); arr[1] = getValue(p[xi], y); arr[2] = getValue(p[Math.min(p.length - 1,xi + 1)], y); arr[3] = getValue(p[Math.min(p.length - 1, xi + 2)], y); return getValue(arr, x+ 1); } } 

版画

 Result (0.0, 0.0) : 1.0 Result (0.1, 0.1) : 1.0 Result (0.2, 0.2) : 1.0 Result (0.3, 0.3) : 1.1 Result (0.4, 0.4) : 1.1 Result (0.5, 0.5) : 1.3 Result (0.6, 0.6) : 1.4 Result (0.7, 0.7) : 1.6 Result (0.8, 0.8) : 1.7 Result (0.9, 0.9) : 1.9 Result (1.0, 1.0) : 2.0 Result (1.1, 1.1) : 2.1 Result (1.2, 1.2) : 2.1 Result (1.3, 1.3) : 2.1 Result (1.4, 1.4) : 2.1 Result (1.5, 1.5) : 2.1 Result (1.6, 1.6) : 2.0 Result (1.7, 1.7) : 2.0 Result (1.8, 1.8) : 1.9 Result (1.9, 1.9) : 1.9 Result (2.0, 2.0) : 2.0 Result (2.1, 2.1) : 2.1 Result (2.2, 2.2) : 2.3 Result (2.3, 2.3) : 2.5 Result (2.4, 2.4) : 2.7 Result (2.5, 2.5) : 2.8 Result (2.6, 2.6) : 2.9 Result (2.7, 2.7) : 3.0 Result (2.8, 2.8) : 3.0 Result (2.9, 2.9) : 3.0 Result (3.0, 3.0) : 3.0 

看看它是如何工作的,你有一个2x2的内部值网格和一个4x4的外部值用于外部值。 (0.0,0.0)到(1.0,1.0)值使用外部值映射2(在单元格2,2)和2(单元格3,3)之间的对角线,以帮助插值。

 double[][] source = new double[][]{{1, 1, 1, 2}, {1, 2, 2, 3}, {1, 2, 2, 3}, {1, 1, 3, 3}}; BicubicInterpolator bi = new BicubicInterpolator(); for (int i = -10; i <= 20; i++) { double idx = i / 10.0; System.out.printf("Result (%3.1f, %3.1f) : %3.1f%n", idx, idx, bi.getValue(source, idx, idx)); } 

版画

 Result (-1.0, -1.0) : -5.0 Result (-0.9, -0.9) : -2.8 Result (-0.8, -0.8) : -1.2 Result (-0.7, -0.7) : -0.2 Result (-0.6, -0.6) : 0.5 Result (-0.5, -0.5) : 1.0 Result (-0.4, -0.4) : 1.3 Result (-0.3, -0.3) : 1.5 Result (-0.2, -0.2) : 1.7 Result (-0.1, -0.1) : 1.9 Result (0.0, 0.0) : 2.0 Result (0.1, 0.1) : 2.1 Result (0.2, 0.2) : 2.1 Result (0.3, 0.3) : 2.1 Result (0.4, 0.4) : 2.1 Result (0.5, 0.5) : 2.1 Result (0.6, 0.6) : 2.0 Result (0.7, 0.7) : 2.0 Result (0.8, 0.8) : 1.9 Result (0.9, 0.9) : 1.9 Result (1.0, 1.0) : 2.0 Result (1.1, 1.1) : 2.1 Result (1.2, 1.2) : 2.3 Result (1.3, 1.3) : 2.5 Result (1.4, 1.4) : 2.7 Result (1.5, 1.5) : 2.8 Result (1.6, 1.6) : 2.7 Result (1.7, 1.7) : 2.1 Result (1.8, 1.8) : 0.9 Result (1.9, 1.9) : -1.4 Result (2.0, 2.0) : -5.0