我有一个使用RGB-D相机和文本文件获取的数据集,其中对于数据集的每个图像,存储时间戳和文件名。我所做的是解析这个文件并填充两个std :: map,一个用于rgb图像,另一个用于深度图像。现在,由于时间戳不相交,我必须编写一个例程,根据时间戳找到匹配的图像。这是我到目前为止写的:
typedef map<double,string> StampImageMap;
...
vector<string> &vstrImageFilenamesRGB;
vector<string> &vstrImageFilenamesD;
vector<double> &vTimestampsRGB;
vector<double> &vTimestampsDPT;
double tolerance = 0.02;
for(StampImageMap::iterator it=rgb_images.begin(); it != rgb_images.end(); it++) {
bool found = false;
StampImageMap::iterator jt=depth_images.begin();
while(found == false && jt!=depth_images.end()) {
if(fabs(it->first - jt->first) < tolerance) {
found = true;
vstrImageFilenamesRGB.push_back(it->second);
vstrImageFilenamesD.push_back(jt->second);
vTimestampsRGB.push_back(it->first);
vTimestampsDPT.push_back(jt->first);
}
jt++;
}
}
我想知道是否有更有效的方法来执行此任务!
答案 0 :(得分:2)
现在编写代码时,复杂度为Θ(n m),其中 n , m 是序列的大小。至少有两种方法可以改善这种情况(第二种方法更有效,但编码更难)。
在外环的主体中,不要通过while(found == false && jt!=depth_images.end())
遍历第二个地图中的所有元素。相反,请使用std::map::lower_bound
和std::map::upper_bound
分别搜索it->first - tolerance
和it->first + tolerance
。仅在这两个调用的结果之间循环。
所以,代码就像这样:
for(StampImageMap::iterator it=rgb_images.begin(); it != rgb_images.end(); it++) {
StampImageMap::const_iterator lower = depth_images.lower_bound(it->first - tolerance);
StampImageMap::const_iterator upper = depth_images.lower_bound(it->first + tolerance);
// Now just search between lower and upper.
}
这会将每次迭代减少到Θ(log(m))+ p ,其中 p 是此范围的大小。
由于地图的键已排序,您可以修改standard technique of finding the intersection of two sorted arrays到这种情况。这会将运行时间缩短到Θ(m + n)。请注意,修改有点棘手,因为您不是要找到精确元素的交集,而是“足够接近”元素的交集。
这种情况下的伪代码:
it = rgb_image.begin();
jt = depth_image.begin();
while(it != rgb_image.end() && jt != depth_image.end()) {
if(fabs(it->first - jt->first) < tolerance) {
// Match found!
++it;
++jt;
continue;
}
if(it.first > jt.first + tolerance) {
++jt;
continue;
}
++it;
}