【问题标题】:Java 2D weighted data interpolationJava 2D 加权数据插值
【发布时间】:2013-02-06 23:26:01
【问题描述】:

我正在尝试查找一些 Java 库、代码示例(或起点)来帮助我弄清楚如何插入具有权重的 2d 点列表以生成插值水平曲线。

谷歌搜索我发现有several algorithms available 可以做到这一点,我发现一些explanations 有有趣的内容。我想尝试的第一个算法是反距离加权插值。

但是有了所有这些信息,我有一些基本的疑问:

  • 要生成如下图所示的一张图片,我必须做一个像素矩阵(带权重),插入数据,将像素组合在一起(按颜色范围),然后加入点绘制曲线并放置像this这样的参考文本值?

  • 如果我需要做这个像素矩阵,对于一个巨大的插值来说会非常昂贵,所以我可以做更少的点并使用样条连接然后创建颜色级别吗?

示例数据:

+-------------------+
|  X  |  Y  | WEIGHT|
+-------------------+
|  2  |  5  |   30  |
|  7  |  3  |   25  |
|  1  |  1  |   10  |
|  5  |  6  |   45  |
|  7  |  9  |   15  |
+-------------------+

示例规则:

  • 00-10 之间的值:蓝色
  • 10-20 之间的值:绿色
  • 20-30 之间的值:黄色
  • 30-40 之间的值:红色

示例结果:

示例数据、规则和结果不兼容,只是随机示例来解释我的问题。


这是我最后的测试课:http://pastebin.com/nD6MT8eS

【问题讨论】:

  • 你考虑过linear regression吗?它还使您能够通过将问题的维度增加到(x,y,xy,x^2,y^2,...,x^(k-1)y,y^(k-1)x,x^k,y^k) 来获得度数为k 的多项式。 Weka 获得了 LinearRegression 功能。你会觉得它有用吗?或者您正在严格寻找反距离加权? (注意:线性回归试图最小化从预测到给定数据的平方误差
  • @amit,我需要使用 inverse distance weightedKriging 来做,因为这两种方法是业界最常用的,最终会用到软件。因此,起始点将是加权的反距离
  • 您可以使用 JHeatChart 进行绘图。您可能需要获取源代码,以便尝试不同的插值。 javaheatmap.com
  • JHeatChart 不进行散点插值,它适用于输入数据的二维网格。
  • 下面我的回答有什么遗漏吗?它告诉你如何计算上面的图像。如果这不是你想要的,你能把问题说得更清楚吗?如果您想要一张与您发布的图像类似的图像,则无法避免在某些时候创建像素数组。如果您将颜色分割成条带,它将隐含轮廓。如果你想获得代表等高线的函数,那是另一个问题。此外,你暗示你想要一个算法。如果您希望有一个图书馆为您做这件事,您应该明确说明

标签: java algorithm interpolation


【解决方案1】:

假设您有一个可以使用的 Point 类(例如 java.awt.Point),您可以将权重放入 Map:

Map<Point,Double> points = new HashMap<Point,Double>();
points.put( new Point(2,5), 30 )
...

然后,您制作一个图像,并为每个 x,y 坐标找到最佳分数。我假设分数是反距离乘以表中点的权重。如果是这样,它是这样的:

image = createBitmap( width, height )
for( int x = 0; x < width; x++ )
    for( int y = 0; y < height; y++ )
    {
         double maxScore = -Double.MAX_VALUE
         for( Point p : points.keySet() ) 
         {
             double score = points.get(p)/p.distance( x, y ) //Inverse distance times point weight
             minDist = Math.max( maxScore, score )
         }
         image.setPixelColour( x, y, getColorForDistance( 1/minDist * points.get(p) )
    }

getColourForDistance( double dist ) 应该很明显,尽管您必须正确设置级别。我假设 createBitmap(width, height) 是创建一个图像。您制作的图像类型取决于您的应用程序,它是否具有 setPixelColour 方法或类似方法也是如此。分数等级的选择也取决于您的应用程序。

这不是优化的 - 它至少是 O(x*y*p) 其中 p 是点数。如果 p 变大,您可能需要查看更合理的数据结构来存储点。

【讨论】:

  • 你对我应该如何优化这段代码有什么建议吗?我正在使用它,但使用 3000 像素 x 3000 像素的图像 + 5 点速度很慢,我的最终目标是生成一张 1000 点的图像。谢谢。
  • 什么是花时间?你能介绍一下吗?慢是什么意思(即需要多长时间?)。它必须经过 900 万像素,这通常需要一些时间。您可能最好将此优化作为一个单独的问题发布。如果点的数量很大,您可以尝试空间索引,或者通过从每个点开始并向外工作来创建最小距离图,然后将其反转。但实际上,您需要进行分析以查看花费时间的原因。
【解决方案2】:

为了补充 @mo-seph 和 @Xipan-Xiao 的答案,您可以查看 jFreeChart 项目中的 NonGridContourDataset 类,该类实现了反向距离功率算法。

【讨论】:

    【解决方案3】:

    不知道如何添加 cmets,所以我在这个答案区域添加我的想法。

    至少您不需要“将像素组合在一起(按颜色范围),然后加入点并绘制曲线”。要生成您需要的图片,只需执行以下操作:

    picture = createBitmap( width, height );
    for( int x = 0; x < width; ++ x ){
        for( int y = 0;y < height; ++ y ){
            double value = interpolate( x, y, inputs );
            Color color = colorRangeOf( value );
            picture.setPixel( x, y, color );
        }
    }
    

    因此,无需创建像素矩阵、对颜色进行分组即可创建图片。指定图片的每个像素值后,边界“曲线”会自动出现。

    【讨论】:

    • @JesseJ - 只有 1 个声望点,您不能评论其他人的帖子。为此,您至少需要 50 个。
    • @xipan-xiao,我生成位图没有问题,我需要弄清楚如何生成带有文本标记和曲线的插值数据。
    • Tiago,使用 @mo-seph 发布的逆 d(可能是平方)公式,它会自动生成这些曲线。这有点类似于物理学中的引力和电场强度问题。您只需使用“力”作为该区域的权重。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-09
    • 2011-07-05
    • 1970-01-01
    • 2020-09-04
    • 1970-01-01
    • 1970-01-01
    • 2013-12-27
    相关资源
    最近更新 更多