Сортировать координаты сверху слева направо

#c #sorting #opencv #coordinates #led

#c #сортировка #opencv #координаты #светодиод

Вопрос:

Я извлек 110 координат из контуров массива светодиодов 10×11, используя C и OpenCV, и сохранил их в векторе. Теперь я хочу отсортировать их сверху слева направо, чтобы определить, включен ли индикатор в определенной строке и столбце. Я предварительно отсортировал координаты по y-позиции, чтобы убедиться, что первые 10 координат в векторе представляют первую строку светодиодов на моем изображении.

 vector<Point2f> centers;

bool compareY(Point2f p1, Point2f p2){
if(p1.y < p2.y) return true;
if(p1.y > p2.y) return false;
}

sort(centers.begin(), centers.end(), compareY);
  

Теперь я должен отсортировать их по x-позиции. Проблема в том, что x-позиция от первого светодиода во второй строке или любой другой строке может быть немного меньше, чем у первого светодиода в первой строке. Из-за этого они должны быть отсортированы от центров [0] до центров [9], от центров [10] до центров [20]… строка за строкой. Есть ли у кого-нибудь идея, как это сделать?

Заранее спасибо!

РЕДАКТИРОВАТЬ: Удалось отсортировать точки, но мой алгоритм, основанный на обнаружении контура, недостаточно надежен для обнаружения всех светодиодов. Есть ли у кого-нибудь идея надежного метода их обнаружения?

Комментарии:

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

2. Прежде всего: что возвращает ваша compareY функция в случае p1.y == p2.y ? Вы должны использовать else вместо второго if или лучше просто вернуть логическое значение p1.y < p2.y . Во-вторых, если вы хотите отсортировать вектор от centers[0] до centers[9] , вы просто делаете sort(centers.begin(),centers.begin() 10,compareX) , поскольку вы можете выполнять добавления для vector::iterator.

3. answers.opencv.org/question/31515/…

4. У вас есть UB, если координаты Y совпадают. Просто return p1.y < p2.y; .

5. это из-за эффектов перспективы и того факта, что контуры имеют немного разные координаты центра из-за размывания / расширения.

Ответ №1:

Если вы хотите выполнить лексикографическую сортировку по координате Y, а затем по координате X, вам просто нужно предоставить подходящую функцию сравнения, которая действительно реализует строгий слабый порядок использования. Например

 #include <tuple>

bool compareYX(const Point2famp; p1, const Point2famp; p2)
{
  return std::tie(p1.y, p1.x) < std::tie(p2.y, p2.x);
}
  

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

Комментарии:

1. По какой-то причине #include <tuple> не предоставляет функцию привязки.

2. @user3797009 Странно, так и должно быть. Есть ли у вас полная поддержка C 11? В противном случае, <tr1/tuple> и std::tr1::tie .

3. @user3797009 Если у вас есть полная поддержка C 11, то это должно сработать. Так что вы этого не делаете, или в вашем коде есть другая проблема.

4. Забыл установить -std=c 11 в моем файле .pro. Теперь привязка работает, но сортировка по-прежнему неправильная.

5. @user3797009 Возможно, добавьте несколько примеров координат до и после сортировки, чтобы уточнить, как вы хотите отсортировать точки.