Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;-比较向量的有效方法_C++_Opencv_Vector_Performance_Aruco - Fatal编程技术网

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

C++ C++;-比较向量的有效方法,c++,opencv,vector,performance,aruco,C++,Opencv,Vector,Performance,Aruco,目前我正在用摄像机检测一个标记。我使用opencv和阿鲁科图书馆 只是我现在有个问题。我需要检测两个标记之间的距离是否小于特定值。我有一个计算距离的函数,我可以比较一切。但我正在寻找最有效的方法来跟踪所有标记(大约5/6)以及它们之间的距离 有一个带有标记的列表,但我找不到一个有效的方法来比较所有的标记 我有一个 Vector <Marker> 标记s包含一个点2f,因此我可以轻松比较它们。提高性能的一种方法是保持所有距离的平方,并避免使用平方根函数。如果你对你所检查的特定值进行

目前我正在用摄像机检测一个标记。我使用opencv和阿鲁科图书馆

只是我现在有个问题。我需要检测两个标记之间的距离是否小于特定值。我有一个计算距离的函数,我可以比较一切。但我正在寻找最有效的方法来跟踪所有标记(大约5/6)以及它们之间的距离

有一个带有标记的列表,但我找不到一个有效的方法来比较所有的标记

我有一个

Vector <Marker> 

标记
s包含一个
点2f
,因此我可以轻松比较它们。

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

如果你处理向量中的大量数据,你可能想考虑使用多线程,使用<代码>未来< /代码>。
Vector
可以分为
X
块,这些块异步计算在一起并存储在
std::future
中,使用@Sesame的建议也会提高您的速度。

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

可以对向量进行排序,这样可以使循环短路。例如,如果正确排序,且点A和点B之间的距离大于阈值,则A和C以及A和D之间的距离也将大于阈值。但请记住,排序并不是免费的,对于小的点集,只计算所有距离可能会更快()

<>新版本的C和C++标准库具有计算点间距离的功能:

#include <cmath>

double getDistance(cv::Point2f punt1, cv::Point2f punt2)
{
    return std::hypot(punt2.x - punt1.x, punt2.y - punt1.y);
}
#包括
双getDistance(cv::Point2f punt1,cv::Point2f punt2)
{
返回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;
        }
        ...
    }
}
常量双阈值=。。。; std::向量点; //填充点 ... 对于(自动i=点。开始();i!=点。结束();++i){ 对于(自动j=i+1;j!=points.end();+j){ 双dx=std::abs(i->x-j->x),dy=std::abs(i->y-j->y); 如果(dx>阈值| | dy>阈值){ 继续; } 双距离=标准::低电压(dx,dy); 如果(距离>阈值){ 继续; } ... } }
您目前是否受到vectors性能的严重影响?或者您只是希望得到一个稍微快一点的解决方案?如果您返回一个
double
,请使用该类型进行中间计算。你想要什么样的比较?不管怎样,如果你知道有一个常数/小范围的元素,一个向量可能是多余的,考虑<代码> STD::数组< /代码>。你可以只考虑距离^ 2,并且省略SqRTF一个操作,如果你只需要一个比较的度量,记住,如果你只跟踪6个标记,然后,您只需使用15个比较,就可以将它们相互比较。最有效的算法和最简单的算法之间可能不会有太大区别。但是如果你只处理6个元素,我真的认为做一个简单的蛮力比较不会是瓶颈。扫描图像搜索标记要昂贵得多。感谢所有快速而好的答案!我会尝试一些事情,并会选择一个好的答案!感谢您在这个答案中所做的所有工作,我尝试了这个和其他一些性能提示。我进行了一些非常大的性能升级,我对结果非常满意。
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;
        }
        ...
    }
}