【问题标题】:Given many rectangles, whats the best approach to group by line给定许多矩形,按行分组的最佳方法是什么
【发布时间】:2019-04-18 05:46:24
【问题描述】:

TLDR:如何找到水平排列的框


鉴于我有来自这样的图像的数据:

我们可以直观地看到我们有两行:

  • Tare: 11700 kg 10:40:58 am 16-May
  • Gross: 21300 kg 12:49:34 pm 9-Aug

图片中显示的每个蓝色框的数据是:

  • Top
  • Left
  • Width
  • Height
  • 方框每个角的坐标(XY

我的主要想法是从我的“网格”顶部开始循环遍历 y 的每个值,然后将它们共享最多匹配“y”值的框分组,但对于看起来简单的东西。

不确定从这里去哪里

Example data set


我能够使用这段代码(在 JavaScript 中)将框排成一行,它基本上找到第一个“最左上角”的框,然后找到任何与从中间开始的线“相交”的框第一个盒子

我们不在乎按什么顺序放入盒子,所以只要我们从任何一条线上最左边的开始,我们就是黄金。

function getMostTopLeftBox(boxes) {
  const sorted = boxes.slice()
    .sort(
      (a, b) => {
        if (a.Left === b.Left) {
          return a.Top < b.Top ? -1 : 1;
        }
        return a.Left < b.Left ? -1 : 1;
      }
    );
  return sorted[0];
}

function getAlignedBoxesFromSet(boxes) {
  const mostTopLeftBox = getMostTopLeftBox(boxes);
  const line = mostTopLeftBox.Top + (mostTopLeftBox.Height / 2);
  return boxes
    .filter(({ Top, Height }) => Top < line && (Top + Height) > line)
    .sort(({ Left: a }, { Left: b }) => a < b ? -1 : 1)
}

function getAlignedBoxes(boxes) {
  let remaining = boxes;

  const lines = [];

  const next = () => {
    const line = getAlignedBoxesFromSet(remaining);
    lines.push(line);

    remaining = remaining.filter(box => line.indexOf(box) === -1);

    if (!remaining.length) {
      return;
    }

    return next();
  };

  next();

  return lines;
}

上面的代码加上上面提供的数据集给了我们this result

但是,它没有考虑盒子上的微小角度,例如这张图片:


另一个不同框的示例,已删除敏感信息:

从上面可以看出,下面的值应该被认为在同一行:

  • Product: [type]
  • Num Of [type]: 0
  • [value]: [value]

我可能会为此提出一个新问题,但对此的部分答案是找出一条线的实际曲线,而不仅仅是假设所有线的中角是线的实际“曲线” ,所以如果我从最左边的框开始,然后进入第二个框,现在我有两条不同的线,我想找到平滑曲线,然后我将用它来找到下一个框,因为我找到每个框我想调整这条曲线以找到完整的线,我会进一步调查这个,如果有人有任何提示,请提及。

【问题讨论】:

  • 也许看看每个TopTop + Height的区间,通过计算重叠和相应的分组来与之前的区间进行比较?
  • 框可以重叠吗?线条总是水平的还是可以倾斜的?
  • 线条可以稍微倾斜,我有重叠的可能,但几乎不会发生,我收到的数据通常和例子一样。 @TrebuchetMS 我曾使用第一个框的中间找到该行的“中线”,然后将其他框与之进行比较,但我觉得我错过了一些案例。
  • 另一种方法可以做到这一点...从一个矩阵开始,通过查看最小的Left 来填写第一列(票价、总金额等)。通过查看间隔将每个框分组到 。然后将这些列添加到您的矩阵中。 (这在逻辑上比解析单个行更好。由于角度是“轻微的”,因此水平变化不应该像垂直变化一样多。但同样,这可能不适用于角度 >30º。)听起来像你正在从事的很酷的 ML 项目。 :-)
  • 绝对是一个很酷的项目。上面发布的图像是可以收集的信息的一些通用示例,我添加了更多显示更多数据的图像,表明按列组织可能会有点困难。

标签: math language-agnostic geometry


【解决方案1】:

我已经设法通过问题中发布的代码变体解决了这个问题。

这是解决方案的代码沙箱,我将对此进行完整的记录,但现在就在这里:https://codesandbox.io/s/102xnl7on3

这是一个基于从所有水平线的角度计算的角度线的分组框的示例,如果所有框都是直的,那么结果也将是直线,所以它应该适用于所有情景。

这里还有一个直线的例子:

您可以在与下一个框相交之前看到框的线条,它每次都会这样做,直到找到完整的框线(直到没有更多的线条),这比使用平均角度更好整个数据集。

我希望能够为已找到的框生成数学曲线并将其应用于查找下一个框,但目前,使用前一个框作为锚点效果很好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多