如何构建具有连续值之间最大平均距离的阈值图?

Posted

技术标签:

【中文标题】如何构建具有连续值之间最大平均距离的阈值图?【英文标题】:How to construct a threshold map with maximum average distance between consecutive values? 【发布时间】:2019-10-02 09:59:27 【问题描述】:

我有一个预先生成的 2D 点云,例如:

假设网格包含 64 个点。 对于每一点,我想在 [0,63] 范围内分配一个值,这样:

没有已分配值的点(简单) 对于具有给定值的给定点,连续数字之间的平均距离尽可能大,并确保表格在边缘“环绕”

基本上它与应用于Bayer Matrix 的算法相同,只是我的点不在轴对齐网格中。

可以用一个简单的规则设计任意大小的阈值图:首先用连续的整数填充每个槽。然后对它们重新排序,使地图中两个连续数字之间的平均距离尽可能大,确保表格在边缘“环绕”。

我试图搜索算法来生成两个矩阵的非幂,但我没有找到任何相关的算法。

如何才能满足第二个条件?

编辑 1:

云中的点数不是 2 的幂!

编辑 2:

这是结果,您可以看到某些范围似乎是轴对齐分布的,如果我只想使用某些范围,这对我来说实际上并不有效。

我会尝试找到一种方法来添加一些抖动。 您有什么技巧可以实现这一目标吗?

范围 [0,0.1] []3

范围 [0.1,0.2] []4

范围 [0.8, 0.9] []5

范围 [0, 1] []6

【问题讨论】:

也许你想用谷歌搜索“蓝噪声掩码” 【参考方案1】:

给定 4^k 点不在网格中,您可以将它们分配给 2^k x 2^k 网格中的点,然后通过拜耳矩阵中的关联值标记每个点。分配过程类似于k-d tree 的构造。您将一组点划分为大小相等的子集,其中一个子集完全位于另一个子集的左侧。左子集中点的 x 坐标以二进制形式从 0 开始;右子集中点的 x 坐标从 1 开始。然后,您通过 y 坐标递归地细分每个子集,确定网格中 y 坐标的第一位。然后对子子集进行递归调用以查找其余位。

Python 代码:

import operator


def threshold_map_recursive(points, base, increment, result):
    if len(points) == 0:
        return
    if len(points) == 1:
        result[points[0]] = base
        return
    n3, r = divmod(len(points), 4)
    n0 = n3 + (r > 0)
    n2 = n3 + (r > 2)
    points.sort(key=operator.itemgetter(0))
    left = points[: n0 + n3]
    left.sort(key=operator.itemgetter(1))
    threshold_map_recursive(left[:n0], base, 4 * increment, result)
    threshold_map_recursive(left[n0:], base + 3 * increment, 4 * increment, result)
    right = points[n0 + n3 :]
    right.sort(key=operator.itemgetter(1))
    threshold_map_recursive(right[:n2], base + 2 * increment, 4 * increment, result)
    threshold_map_recursive(right[n2:], base + increment, 4 * increment, result)


def threshold_map(points):
    result = 
    threshold_map_recursive(list(points), 0, 1, result)
    return result


def test(n, m):
    tm = threshold_map((x, y) for x in range(n) for y in range(m))
    for k in range(1, n * m):
        for y in range(m):
            print("".join("@" if tm[x, y] < k else "." for x in range(n)))
        print()


test(5, 5)

【讨论】:

感谢您的回答。目前我不能保证我的点云包含两个点的幂,所以将值映射到两个网格的幂然后将其映射到拜耳矩阵我猜是不准确的。没有别的办法吗? 只要密度均匀,就可以进行调整。我会尝试在第二天左右发布代码。 @Qzaac 添加了一些 Python。结果并不完美,但相当不错。 @DavidEistenstat 很抱歉回复晚了,非常感谢代码!!!我已经尝试过你的算法,它似乎运作良好。经过一些经验,它似乎正确地重新创建了两个点云的轴对齐幂的拜耳矩阵,但不适用于非 2 的幂(我仔细地用 c++ 翻译了你的代码,所以它似乎来自算法)。此外,似乎某些值范围似乎是轴对齐的,我必须修复它。我将编辑我的帖子以向您展示结果

以上是关于如何构建具有连续值之间最大平均距离的阈值图?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Gnuplot 中绘制噪声值的平均值

具有最小值/最大值的平均值和阴影的线图

R - 对连续变量标题进行分组,将分类变量因子作为行并聚合为最小值、最大值、平均值

如何计算行之间的动态平均值?

如何用C++或C编写求MAX,MIN,平均值,均方差

如何找到向量的统计信息?最大值/最小值、众数、中值、平均值