Как проверить, образуют ли четыре точки прямоугольник

Я работаю над приложением для распознавания фигуры. В этот момент набор точек (x, y) определяется угловым детектором (красные точки, img. 2.). Четыре из этих точек (в красных кадрах, img. 2.) - это вершины прямоугольника (иногда немного деформированного прямоугольника). Каким будет лучший способ найти их среди других?

Вот пример входного изображения: Input image

И это выглядит после обнаружения угла:

Image with detected corners

Ответ 1

Это не ответ на ваш вопрос - это просто предложение.

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

  • Эта марка является фиолетовым цветом, поэтому первое, что вам нужно сделать, это сегментация цвета.
  • После того, как вы выполнили шаг 1, вы можете использовать преобразование Houhg для обнаружения строк на двоичном изображении. Или найдите все контуры в изображении.
  • И последний шаг - обнаружить прямоугольник.

Update:

Здесь другое решение, которое также должно работать в серых изображениях.

  • Сделайте порог для преобразования изображения в 1 бит (я использовал 200 от 255 в качестве порога).
  • Найти все контуры в новом изображении, которые имеют площадь больше некоторой константы (я взял 1000).
  • Найдите ограничивающий прямоугольник для каждого контура и выполните проверку:

ContourArea/BoundingReactangleArea > константа

Я принимаю этот constant как 0.9.

И этот алгоритм дал мне следующий результат: enter image description here

Здесь код OpenCV:

Mat src = imread("input.jpg"), gray, result;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;

result = Mat(src.size(), CV_8UC1);

cvtColor(src, src, CV_BGR2GRAY);
threshold(src, gray, 200, 255, THRESH_BINARY_INV);
findContours(gray, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

result = Scalar::all(0);
for (size_t i=0; i<contours.size(); i++)
{
    Rect rect = boundingRect(contours[i]);
    if (rect.area() > 1000)
    {
        double area = contourArea(contours[i]);
        if (area/rect.area() > 0.9)
        {
            drawContours(result, contours, i, Scalar(255), -1);
        }
    }
}

Ответ 2

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

Ответ 3

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

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

Позвоните по методу @mathematician1975 method 1 и выполните параллельную проверку method 2. Тогда:

%# method 1: 
n1 = |u1-u2|    %#  3 sub., 3 mult, 2 add. per distance
n2 = |u3-u2|    %#  total of 6 distances to compute.
n3 = |u4-u3|    %#  then max 5+4+3+2+1 = 15 comp. to find unique distances
n4 = |u1-u4|    
n5 = |u4-u2|    %#  Total:
n6 = |u3-u1|    %#  12 sub., 18 mult., 12 add, 15 comp



%# method 2:
w1 = u1-u2       %#  3 subtractions per vector
w2 = u3-u2       %#  total of 4 vectors to compute 
w3 = u3-u2
w4 = u1-u4                
                        %#  12 sub.
abs(w1-w3) == [0 0 0]   %#  3 sub., 3 comp., 1 sign.
abs(w2-w4) == [0 0 0]   %#  3 sub., 3 comp., 1 sign.

                        %# Total: 18 sub., 6 comp. 2 sign.

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

Обратите внимание также, что method 2 должно знать заранее, что вершины уже находятся в правильном порядке. Если это не так, это увеличит стоимость в 4 раза, что больше, чем method 1..

Могу ли я спросить, как вы вычисляете расстояния?

Ответ 4

Учтите, что у вас должен быть номер 8, но вы получили номер 7, тогда вы собираетесь добавить номер 1 (называемый дельта или исправление ошибок), чтобы исправить его.

Аналогичным образом имеют прямоугольник прямоугольника треугольника для коррекции прямоугольника. Убедитесь, что точка (координата) попадает внутрь треугольника треугольника.

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

x+delta,y+delta
x-delta,y+delta
x+delta,y-delta
x-delta,y-delta

Сообщите мне, если это будет хорошо для вас или если вы найдете лучшее решение