【问题标题】:find largest rectangle not (necessary) aligned with image boundary in binary matrix在二进制矩阵中找到不(必要)与图像边界对齐的最大矩形
【发布时间】:2014-05-01 11:50:27
【问题描述】:

我正在使用this solution 在二进制矩阵中查找与图像边框对齐的矩形。假设现在我想找到一个与图像边框不对齐的矩形,而且我不知道它的方向;找到它的最快方法是什么?

为了这个例子,让我们寻找一个只包含 1 的矩形。例如:

1 1 1 1 0 0 0 0 0 1 0 0 1 1 1
0 1 1 1 1 1 0 0 0 1 0 0 1 1 0
0 0 0 1 1 1 1 1 0 1 0 0 1 0 0
0 0 0 0 0 1 1 1 1 1 0 0 0 0 0
0 0 0 0 0 0 0 1 1 1 1 1 0 0 0
0 0 0 0 0 0 0 0 0 1 1 1 1 1 0

那么我在above 描述的解决方案中描述的算法只会找到一个大小为 6 (3x2) 的矩形。我想找一个更大的倾斜的矩形;我们可以清楚地看到至少大小为 10 或更大的矩形...

我正在使用 C/C++,但任何语言或伪代码的算法描述都会对我有很大帮助。

更多细节:

  • 图像中可以有多个矩形:我只需要最大的一个
  • 图像中的矩形不是漂亮的矩形(我稍微调整了上面的示例)
  • 我处理大图像 (1280x1024),因此我正在寻找最快的解决方案(蛮力 O(n³) 算法会非常慢)
  • (可选)如果解决方案可以并行化,那是一个加分项(然后我可以使用 GPU、SIMD 等进一步提升它)

【问题讨论】:

  • 我想知道是否知道包含所有 1 的最小边界框的方向是否可以提供关于仅包含 1 的最大矩形方向的任何指示。一般情况下它可能不起作用,但它可能是一个开始。例如,凸形可能就是这种情况......
  • 如果你想“去做” - 你可以申请O(n^3)搜索矩形算法。 IE。 - 开始检查每个1 点中的矩形,构建所有可能的矩形。然后找到面积最大的矩形(可能不止一个)
  • @AlmaDo 我对方向一无所知;所以我不能选择所有可能的方向:每 10 度?每5度? ...但是我同意这将是一个可能的解决方案,但非常次优。 (我使用 1280x1024 图像)
  • 视情况而定。您需要决定什么应该被视为矩形(这里我们谈到了在离散空间上绘制线图。这可以通过Bresenham algorithm 来完成)。所以:你需要确定给定的点是否代表矩形的边界。要做到这一点,你需要知道什么是边界——什么是正确的离散表示(因为我们不在连续平面上,我们在一些离散空间上)
  • 嗯,我想澄清一下so I prefer an optimal solution (which I'll be able to boost myself later using GPU, SIMD or others ...),因为高度并行的算法并不总是(甚至)接近最优算法。您是在寻找高度并行的算法还是最优的算法?我也想了解有关您的问题的离散性的更多信息。你认为细胞是二维坐标还是它们真的是正方形,因为穿过它们的线被认为是穿过整个细胞?

标签: arrays algorithm


【解决方案1】:

我对这个问题只有部分答案,对于我提出的建议的复杂性或速度只有一些想法。

蛮力

我看到的第一个想法是利用您的问题是离散的这一事实来实现围绕图像中心的旋转重复您已经使用的算法以找到轴对齐的解决方案

这有检查大量候选轮换的缺点。但是,此检查可以并行进行,因为它们彼此独立。这可能仍然很慢,尽管实现它(不应该太难)并且一旦并行化就会为问题速度提供更明确的答案。

请注意,您的工作空间是一个离散矩阵,只有有限个旋转次数浏览。

其他方法

我看到的第二种解决方案是:

  1. 削减您的基础矩阵,以便分离连接的组件[1](对应于您感兴趣的值集)。
  2. 对于每个较小的矩阵 -- 请注意,它们可能会根据分布重叠 -- 找到最小定向边界框 对于您感兴趣的值集。
  3. 仍然对于其中的每一个,旋转您的矩阵,使最小定向边界框现在与轴对齐
  4. 启动您已经必须找到最大轴对齐矩形的算法,该矩形仅包含值集中的值。
  5. 此算法找到的解决方案将是从所有连通分量中获得的最大矩形

第二个解决方案可能会为您提供解决方案的近似值,但我相信它可能值得一试。

供参考

我为最大/最大空矩形问题找到的唯一解决方案是轴对齐。我在 2D 连续空间上看到了许多与此问题的定向版本相对应的未回答问题。

编辑:

[1]由于我们想要的是分离连通分量,如果有一定程度的重叠,你应该像下面的例子那样做:

0 1 0 0
0 1 0 1
0 0 0 1

应分为:

0 0 0 0
0 0 0 1
0 0 0 1

0 1 0 0
0 1 0 0
0 0 0 0

请注意,我保留了矩阵的原始尺寸。我这样做是因为我从您的帖子中猜测它具有一定的重要性,并且无法找到一个远离边界扩展的矩形作为解决方案(即我们不能仅仅假设边界之外的值为零)。

编辑 #2:

是否保留矩阵维度的选择是有争议的,因为它不会直接影响算法。

然而,值得注意的是,如果与连通分量对应的矩阵在非零值上不重叠,您可以选择“就地”存储这些矩阵。

您还需要考虑这样一个事实:如果您希望将矩形的坐标作为输出返回,为每个连接的组件创建一个具有不同维度的矩阵,这将迫使您将新创建的矩阵的坐标存储在原来的一个(其实一点,比如左上角,就足够了)。

【讨论】:

  • 好的,那么是否保留矩阵维度的选择是有争议的,因为它不会直接影响算法。但是,值得注意的是,如果与连通分量对应的矩阵在非零值上不重叠,您可以选择“就地”存储这些矩阵并跨线程共享。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-03
相关资源
最近更新 更多