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