Учитывая много прямоугольников, что является лучшим подходом для группировки по строке - PullRequest
0 голосов
/ 15 ноября 2018

TLDR: как найти прямоугольники, выстроенные в горизонтальное положение


Учитывая, что у меня есть данные из изображения, подобного этому:

Example image, boxes straight

Мы можем визуально увидеть, что у нас есть две строки:

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

Данные, которые у меня есть для каждой синей рамки, показанной на рисунке:

  • Top
  • Left
  • Width
  • Height
  • Координаты для каждого угла поля (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;
}

Приведенный выше код с указанным выше набором данных дает нам этот результат

Однако это не учитывает небольшие углы на коробках, например, это изображение:

Boxes on an agle


Еще один пример различных ящиков с удаленной конфиденциальной информацией:

Example of boxes

Из вышесказанного видно, что значения, указанные ниже, должны рассматриваться в одной строке:

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

Я могу задать для этого новый вопрос, но часть ответа на него состоит в том, чтобы выяснить фактическую кривую линии, а не просто предположить, что средний угол всех линий является действительной «кривой» линии , поэтому, если бы я должен был начать с самого левого блока, затем перейти ко второму блоку, теперь у меня есть две отдельные линии, для которых я хотел бы найти сглаженную кривую, которую я затем использовал бы, чтобы найти следующий блок, так как я найти каждую клетку. Я бы хотел настроить эту кривую, чтобы найти полную линию, я буду исследовать эту дополнительно, если у кого-нибудь есть какие-либо подсказки, пожалуйста, укажите ее.

1 Ответ

0 голосов
/ 16 ноября 2018

Мне удалось решить эту проблему с помощью варианта кода, размещенного в вопросе.

Вот кодовая песочница решения, я сделаю полное описание этого, но сейчас это так: https://codesandbox.io/s/102xnl7on3

Вот пример сгруппированногобоксы, основанные на угловых линиях, рассчитанных по углу всех горизонтальных линий, если все прямоугольники должны быть прямыми, то результатом будут также прямые линии, поэтому это должно работать во всех сценариях.

enter image description here

Вот также пример, где линии прямые:

enter image description here

Вы можете видеть линии из коробки перед пересечением со следующей коробкой, она делает это каждый раз, пока не может найти полную линию коробок (до тех пор, пока не будет больше выстраиваться в линию), это работает лучше, чем использование среднего угла извесь набор данных.

Я хотел бы иметь возможность сгенерировать математическую кривую для уже найденных блоков и применить ее для поиска следующего блока, но пока, используя предыдущий блок в качестве привязки, работает довольно хорошо.

...