В данный момент я работаю с камерой, чтобы обнаружить маркер. Я использую 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;
}
Marker
s содержат Point2f
так что я могу сравнить их легко.
Там не так много, чтобы рекомендовать. Если я понимаю вопрос и правильно рассчитываю пары, вам нужно рассчитать 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;
}
...
}
}
Один из способов повысить производительность — сохранить все расстояния в квадрате и избегать использования функции квадратного корня. Если вы возводите в квадрат конкретное значение, по которому вы проверяете, это должно работать нормально.
Если вы имеете дело с большими объемами данных внутри вашего вектора, вы можете рассмотреть возможность использования многопоточности, используя future
,
Vector <Marker>
может быть разбит на кусочки X
куски, которые асинхронно вычисляются вместе и хранятся внутри std::future<>
использование предложения @ Sesame также увеличит вашу скорость.