#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 Возможно, добавьте несколько примеров координат до и после сортировки, чтобы уточнить, как вы хотите отсортировать точки.