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

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

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

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

Image with detected corners

4 ответов


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

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

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

обновление:

вот еще одно решение, которое также должно работать в серых изображений.

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

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

Я беру это constant as 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);
        }
    }
}

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


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

в любом случае, помимо метода, уже данного @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..

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


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

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

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

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

позвольте мне знать, если это работает для вас или если вы найдете лучше решение