【发布时间】:2019-04-18 05:46:24
【问题描述】:
TLDR:如何找到水平排列的框
鉴于我有来自这样的图像的数据:
我们可以直观地看到我们有两行:
Tare: 11700 kg 10:40:58 am 16-MayGross: 21300 kg 12:49:34 pm 9-Aug
图片中显示的每个蓝色框的数据是:
TopLeftWidthHeight- 方框每个角的坐标(
X、Y)
我的主要想法是从我的“网格”顶部开始循环遍历 y 的每个值,然后将它们共享最多匹配“y”值的框分组,但对于看起来简单的东西。
不确定从这里去哪里
我能够使用这段代码(在 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]
我可能会为此提出一个新问题,但对此的部分答案是找出一条线的实际曲线,而不仅仅是假设所有线的中角是线的实际“曲线” ,所以如果我从最左边的框开始,然后进入第二个框,现在我有两条不同的线,我想找到平滑曲线,然后我将用它来找到下一个框,因为我找到每个框我想调整这条曲线以找到完整的线,我会进一步调查这个,如果有人有任何提示,请提及。
【问题讨论】:
-
也许看看每个
Top到Top + Height的区间,通过计算重叠和相应的分组来与之前的区间进行比较? -
框可以重叠吗?线条总是水平的还是可以倾斜的?
-
线条可以稍微倾斜,我有重叠的可能,但几乎不会发生,我收到的数据通常和例子一样。 @TrebuchetMS 我曾使用第一个框的中间找到该行的“中线”,然后将其他框与之进行比较,但我觉得我错过了一些案例。
-
另一种方法可以做到这一点...从一个矩阵开始,通过查看最小的
Left来填写第一列(票价、总金额等)。通过查看间隔将每个框分组到 列。然后将这些列添加到您的矩阵中。 (这在逻辑上比解析单个行更好。由于角度是“轻微的”,因此水平变化不应该像垂直变化一样多。但同样,这可能不适用于角度 >30º。)听起来像你正在从事的很酷的 ML 项目。 :-) -
绝对是一个很酷的项目。上面发布的图像是可以收集的信息的一些通用示例,我添加了更多显示更多数据的图像,表明按列组织可能会有点困难。
标签: math language-agnostic geometry