C ++ - 比较向量的有效方法

时间:2014-06-03 17:50:08

标签: c++ opencv vector performance aruco

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

现在只有我遇到了问题。我需要检测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; 
}

Marker包含Point2f,因此我可以轻松比较它们。

3 个答案:

答案 0 :(得分:8)

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

答案 1 :(得分:5)

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

可以对矢量进行排序,使您可以使循环短路。例如,如果您正确排序并且A点和B点之间的距离大于您的阈值,则A和C之间的距离以及A和D之间的距离也将大于阈值。但请记住,排序不是免费的,而且对于小的点集,可能会更快地计算所有距离("Fancy algorithms are slow when n is small, and n is usually small. Fancy algorithms have big constants. Until you know that n is frequently going to be big, don't get fancy. ... For example, binary trees are always faster than splay trees for workaday problems.")。

较新版本的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;
        }
        ...
    }
}

答案 2 :(得分:4)

如果您正在处理向量中的大量数据,则可能需要考虑使用future进行多线程处理。

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