4

目前我正在使用相机来检测标记。我使用 opencv 和 Aruco 库。

只有我现在遇到了一个问题。我需要检测 2 个标记之间的距离是否小于特定值。我有一个计算距离的功能,我可以比较一切。但我正在寻找最有效的方法来跟踪所有标记(大约 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 包含 a ,Point2f所以我可以很容易地比较它们。

4

3 回答 3

8

提高性能的一种方法是保持所有距离的平方并避免使用平方根函数。如果您将要检查的特定值平方,那么这应该可以正常工作。

于 2014-06-03T17:55:23.600 回答
5

真的没有太多值得推荐的。如果我理解了这个问题并且我正确地计算了对,那么当你有 5 个点时,你需要计算 10 个距离,当你有 6 个点时,你需要计算 15 个距离。如果您需要确定所有距离,那么您别无选择,只能计算所有距离。我看不出有什么办法。我能给出的唯一建议是确保你只计算每对之间的距离一次(例如,一旦你知道点 A 和 B 之间的距离,你就不需要计算 B 和 A 之间的距离)。

有可能以可以使循环短路的方式对向量进行排序。例如,如果您正确排序并且点 A 和点 B 之间的距离大于您的阈值,那么 A 和 C 以及 A 和 D 之间的距离也将大于阈值。但请记住,排序不是免费的,而且对于少量的点,只计算所有距离可能会更快( “当n小时,花式算法很慢,而n通常很小。花式算法有很大常数。除非你知道n经常会很大,否则不要幻想。...例如,对于日常问题,二叉树总是比张开树快。”)。

较新版本的 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;
        }
        ...
    }
}
于 2014-06-03T18:08:53.777 回答
4

如果您要处理向量中的大量数据,您可能需要考虑使用future.

Vector <Marker>可以分块成X块,这些块被异步计算在一起并存储在里面std::future<>,使用@Sesame 的建议也会提高你的速度。

于 2014-06-03T17:59:18.157 回答