【问题标题】:How to find the pixel that is farthest from another in the same pixel group如何在同一像素组中找到距离另一个像素最远的像素
【发布时间】:2012-11-08 03:07:07
【问题描述】:

“组”是指一组像素,使得每个像素在同一组中至少有一个相邻像素,图中显示了组的示例。

我想找到与指定像素(例如,绿色像素)的直线距离最大的像素。并且连接两个像素的直线(红线)不能离开组。

我的解决方案是循环遍历度数并模拟从带有度数的绿色像素开始的线条的进度,并查看哪条线行进的距离最远。

longestDist = 0
bestDegree = -1
farthestX = -1
farthestY = -1
FOR EACH degree from 0 to 360
    dx=longestDist * cos(degree);
    dy=longestDist * sin(degree);
    IF Point(x+dx , y+dy) does not belong to the group
        Continue with next degree
        //Because it must not be the longest line, so skip it
    END IF
    (farthestX , farthestY) = simulate(x,y,degree)
    d = findDistance(x , y , farthestX , farthestY)
    IF d > longestDist
        longestDist = d
        bestDegree = degree
    END IF
END FOR

这显然不是最好的算法。因此,我在这里寻求帮助。

谢谢你,对不起我的英语不好。

【问题讨论】:

  • 请注意,您可以丢弃所有内部像素的计算。
  • 而且你不需要使用角度。你只需要使用勾股定理;)
  • @dfens: "内部像素" - 为什么?其中之一可能是解决方案。
  • @Karoly Horvath:我明白我们正在寻找两个最远的像素的问题?所以内部像素不是解决方案?

标签: algorithm pixel distance point


【解决方案1】:

我不会使用角度。但我很确定最大的距离总是在集合边缘的两个像素之间,因此我会追踪轮廓:从集合中的任何像素到任何方向,直到到达集合的边缘。然后沿边缘顺时针移动(向外)。以任何像素为起点执行此操作,您将能够找到最大距离。它仍然很贪婪,但我认为它可能会为您提供一个改进的替代起点。

编辑:我刚想到什么:当你有一个起始像素s 和结束像素e。在使用s 的第一次迭代中,对应的e 将是相邻的(下一个沿顺时针方向沿边缘)。当您沿着边缘迭代时,可能会发生这种情况,即se 之间的集合没有直线。在这种情况下,这条线会碰到设置边缘的另一部分(像素p)。您可以在该像素处继续迭代边缘 (e = p)

Edit2:如果您点击p,您将知道se 之间不再有距离,因此在s 的下一次迭代中,您可以跳过边缘的整个部分(在sp 之间)并再次从p 开始。

Edit3:用上面的方法找到第一个p。将p 作为下一个s 并继续。重复直到您再次到达您的第一个p。最大距离将在其中两个p 之间,除非集合的边缘是凸的,在这种情况下您将找不到p

免责声明:这是未经测试的,只是我头脑中的想法,没有绘制任何图纸来证实我的主张,并且一切都可能是错误的(即在实施之前自己考虑一下;D)

【讨论】:

    【解决方案2】:

    首先,请注意算法中的角度离散化可能取决于网格的大小。如果步长太大,你可能会错过某些单元格,如果太小,你最终会一次又一次地访问同一个单元格。

    我建议您枚举该区域中的单元格并单独测试每个单元格的条件。枚举可以使用广度优先或深度优先搜索来完成(我认为后者会更好,因为它可以让人们快速建立下限并进行一些修剪)。

    可以保持到目前为止找到的最远点 X,并且对于该区域中的每个新点,检查 (a) 该点是否比目前找到的点更远,以及 (b) 它是否通过直线连接到原点线仅通过该区域的单元格。如果两个条件都满足,则更新 X,否则继续搜索。如果条件(a)不满足,则条件(b)不必检查。

    此解决方案的复杂度为O(N*M),其中N 是区域中的单元数,M 是区域的较大维度 (max(width,height))。如果性能至关重要,则可以应用更复杂的启发式方法,但对于合理大小的网格,这应该可以正常工作。

    【讨论】:

      【解决方案3】:

      搜索像素,而不是坡度。伪代码。

      bestLength = 0
      for each pixel in pixels
        currentLength = findDistance(x, y, pixel.x, pixel.y)
        if currentLength > bestLength
          if goodLine(x, y, pixel.x, pixel.y)
            bestLength = currentLength
            bestX = pixel.x
            bestY = pixel.y
          end
        end
      end
      

      您可能希望按 |dx| 降序排列像素+ |dy|在此之前。

      【讨论】:

      • 这里不处理连接线在区域内的要求。
      【解决方案4】:

      使用双重数据结构:

      • 包含按角度排序的像素。
      • 第二个按距离排序(为了快速访问,它还应该包含第一个数据结构的“指针”)。

      遍历排序为 1 的角度,并检查线在该区域内的每个像素。一些像素将具有相同的角度,因此您可以从原点沿线走,直到您离开该区域。您可以消除所有超出该点的像素。此外,如果最大距离增加,则删除所有距离较短的像素。

      【讨论】:

        【解决方案5】:

        将您的区域视为多边形而不是像素集合。从中您可以获得线段列表(多边形的边缘)。

        从起始像素到要检查的每个像素画一条线。不与多边形的任何线段相交的最长线表示最远的像素,该像素可通过像素的直线到达。

        您可以对此进行各种优化,并检查一些边缘情况,但请在我发布这些内容之前告诉我您是否理解这个想法......特别是,您是否理解我将其视为多边形的意思而不是像素集合?

        此外,这种方法将比任何基于角度的方法或需要“行走”除最小像素集合之外的所有像素的方法快得多。您可以进一步优化,因为您的问题相当于从起点通过不相交的直线找到多边形边缘的最远端点。这可以在 O(N^2) 中完成,其中 N 是边数。请注意,N 将远小于像素数,并且许多建议使用角度和/或像素迭代的算法将改为依赖于像素数。

        【讨论】:

          猜你喜欢
          • 2011-07-23
          • 1970-01-01
          • 2013-02-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-10-19
          • 2014-01-04
          相关资源
          最近更新 更多