【问题标题】:Overlap test for two digital shapes两个数字形状的重叠测试
【发布时间】:2015-08-31 18:57:35
【问题描述】:

我有两个用二进制图像表示的形状,我需要检查它们是否重叠。其中之一以已知量旋转和平移。它们可以是凹形的。

可以容忍一些不准确(大约一个像素错误)并且速度是有利的;我期望位图的宽度/高度具有线性时间复杂度。典型尺寸可扩展到 512 x 512。

允许对形状进行预处理,但只能在之前应用旋转。

我想到的一个可能的解决方案是将旋转的形状变成多边形,使用扫描填充算法并检查水平扫描线中的重叠段(预先计算的固定形状的扫描线表示)。

这将满足复杂性要求。

您是否看到更好/更简单/更有效的方法?


更新:

没有旋转,有一个基于形状运行长度编码的简单解决方案,运行时间与运行次数成线性关系。我怀疑可以做得更好。

【问题讨论】:

    标签: algorithm computational-geometry


    【解决方案1】:

    问题中提到的直接解决方案可能可以扩展到旋转/平移形状的情况:对于每个像素,必须检查 transformed 像素是否与其他形状。

    假设图像以某种形式的二维数组给出,并且像素可以通过p = image0[x,y] 访问(在恒定时间内)。图像 1 使用 3x3 矩阵 M 进行转换(其中包含旋转和平移部分)。那么重叠测试的伪代码可以是

    for (each pixel coordinate (x,y) of image1)
    {
        // Compute the transformed position of a pixel of image 1
        (x',y') = M*(x,y) 
    
        // Check whether the transformed coordinate is in the bounds of image 0
        if (image0 contains (x',y'))
        {
            p0 = image0[x',y']
            p1 = image1[x ,y ]
            if (p0 is opaque and p1 is opaqe)
            {
                return true;
            }
        }
    }
    

    昂贵的部分将是像素坐标的转换,(x',y') = M*(x,y)。可以根据目标语言和数据结构对其进行重构,以首先检查源像素是否不透明,并在许多情况下跳过此计算,如

    for (each coordinate (x,y) of OPAQUE pixels in image 1)
    {
        ...
    }
    

    但不管怎样,运行时间将线性在一张图像的像素数上(最好是较小的那个)。

    (如果这听起来是一种可行的方法,我可以在今天晚些时候尝试添加一个小示例实现(Java,C-ish 风格))

    【讨论】:

    • 我同意“on-the-fly-transformation”原则,但这种解决方案效率不高,因为它在像素数上是线性的(如 O(N²))。与运行次数呈线性关系的解决方案要快得多 (O(N))。无论如何,谢谢你的提议。
    • “运行次数”到底是什么意思? (即在这种情况下,什么是“运行”?)
    • 一次运行是一系列水平连续的像素。对于凸形,每行恰好有一次运行;对于非病理性凹形,通常每行 1-3 个。
    • 好吧,在某种程度上我不同意您提到的“复杂性”,但不管怎样:有关应用程序模式的更多信息可能会有所帮助。您是否考虑过其他数据结构,例如定向边界框的层次结构、空间散列或类似的...?
    • 这正是我的问题的目标:寻找替代品。这些形状是手绘的,具有相对平滑和简单的轮廓。给出的示例是典型的,尽管它们可能更大。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    • 2013-01-01
    • 2012-07-06
    • 2012-03-08
    相关资源
    最近更新 更多