opencv — эффективный способ сравнения векторов

В данный момент я работаю с камерой, чтобы обнаружить маркер. Я использую opencv и Aruco Libary.

Только я застрял с проблемой прямо сейчас. Мне нужно определить, меньше ли расстояние между двумя маркерами, чем определенное значение. У меня есть функция для расчета расстояния, я могу сравнить все. Но я ищу наиболее эффективный способ отслеживать все маркеры (около 5/6) и насколько близко они находятся вместе.

Есть список с маркерами, но я не могу найти эффективный способ сравнить их все.

у меня есть

Vector <Marker>

У меня также есть функция под названием getDistance,

double getDistance(cv::Point2f punt1, cv::Point2f punt2)
{
float xd = punt2.x-punt1.x;
float yd = punt2.y-punt1.y;
double Distance = sqrtf(xd*xd + yd*yd);
return Distance;
}

Markers содержат Point2fтак что я могу сравнить их легко.

4

Решение

Там не так много, чтобы рекомендовать. Если я понимаю вопрос и правильно рассчитываю пары, вам нужно рассчитать 10 расстояний, когда у вас есть 5 баллов, и 15 расстояний, когда у вас есть 6 баллов. Если вам нужно определить все расстояния, то у вас нет другого выбора, кроме как рассчитать все расстояния. Я не вижу никакого способа обойти это. Единственный совет, который я могу дать, это убедиться, что вы рассчитываете расстояние между каждой парой только один раз (например, когда вы знаете расстояние между точками A и B, вам не нужно вычислять расстояние между B и A).

Может быть возможно отсортировать вектор таким образом, чтобы вы могли замкнуть контур. Например, если вы правильно сортируете и расстояние между точкой A и точкой B больше вашего порога, тогда расстояния между A и C и A и D также будут больше, чем пороговое значение. Но имейте в виду, что сортировка не является бесплатной, и, скорее всего, для небольших наборов точек будет проще просто рассчитать все расстояния («Необычные алгоритмы работают медленно, когда N маленький, и N обычно маленький. У причудливых алгоритмов большие константы. Пока вы не знаете, что N часто собирается быть большим, не увлекайтесь … Например, двоичные деревья всегда быстрее, чем splay-деревья для рабочих задач «.).

Более новые версии стандартной библиотеки C и C ++ имеют hypot функция для расчета расстояния между точками:

#include <cmath>

double getDistance(cv::Point2f punt1, cv::Point2f punt2)
{
return std::hypot(punt2.x - punt1.x, punt2.y - punt1.y);
}

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


Одна небольшая оптимизация — просто проверить, превышает ли изменение X или Y пороговое значение. Если это так, вы можете игнорировать расстояние между этими двумя точками, потому что общее расстояние также будет превышать порог:

const double threshold = ...;
std::vector<cv::Point2f> points;
// populate points
...
for (auto i = points.begin(); i != points.end(); ++i) {
for (auto j = i + 1; j != points.end(); ++j) {
double dx = std::abs(i->x - j->x), dy = std::abs(i->y - j->y);
if (dx > threshold || dy > threshold) {
continue;
}
double distance = std::hypot(dx, dy);
if (distance > threshold) {
continue;
}
...
}
}
5

Другие решения

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

8

Если вы имеете дело с большими объемами данных внутри вашего вектора, вы можете рассмотреть возможность использования многопоточности, используя future,

Vector <Marker> может быть разбит на кусочки X куски, которые асинхронно вычисляются вместе и хранятся внутри std::future<>использование предложения @ Sesame также увеличит вашу скорость.

4
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector