【问题标题】:how to elminate the "doubled" elements of a vector in c++如何在 C++ 中消除向量的“双”元素
【发布时间】:2026-01-25 12:20:04
【问题描述】:

我正在使用HoughLines检测帧中的线条,线条信息保存在cv::vector<cv::Vec2f>中,我将其作为二维数组处理,我对第二个感兴趣,它的角度线,我只想保留角度差大于1.5 rad 的线,因为我在这里做了什么:

.............................
cv::vector<cv::Vec2f> lineQ;
..............................

  // ordring the vector based on the angle value in rad 
for ( int i = 0 ; i< lineQ.size()-1; i++){
                for(int j= i+1;j<lineQ.size();j++){
                        if(lineQ[i][1] > lineQ[j][1]){
                            tmp = lineQ[i];
                            lineQ[i] = lineQ[j];
                            lineQ[j] = tmp;
                        }           
                }
            }

现在我想根据角度比较向量元素之间的关系

cv::vector<cv::Vec2f> line;
for ( int i = 0 ; i< lineQ.size()-1; i++){
                for ( int j= i+1; j<lineQ.size(); j++){
            if(fabs(lineQ[i][1] - lineQ[j][1])>1.5){
                        line.push_back(lineQ[i]);

                        }
                }
            }

这适用于 2 条线,但是当我得到 3 条时,假设 1.3rad 作为 line 大小的角度 大于 2。我虽然使用 erase 但这改变了我的向量的大小!

【问题讨论】:

标签: c++ arrays algorithm vector


【解决方案1】:

一种选择是为std::unique_copy 提供一个软“等于”:

std::unique_copy(lineQ.begin(), lineQ.end(), std::back_inserter(line),
                 [](const cv::Vec2f & a, const cv::Vec2f & b) {
                     return b[1] - a[1] <= 1.5;
                 });

旁注:您还可以避免编写自己的排序(冒泡排序几乎是最糟糕的选择。)并使用标准库。像这样的东西应该可以工作:

std::sort(lineQ.begin(), lineQ.end(),
          [](const cv::Vec2f & a, const cv::Vec2f & b) {
              return a[1] < b[1];
          })).

(上面的代码假设 C++11,我们大多数人现在都有。如果你卡在早期版本,你可以写几个仿函数类。)

【讨论】:

  • 返回 b[1] - a[1] 是什么意思? 1 是什么意思?
  • @Engine: ab 对应于 lineQ[i]lineQ[j](有点)。既然你写了lineQ[i][1],我假设每个向量的第一个元素包含排序/匹配键。
  • 非常感谢您的帮助!只是为了理解函数( const ...)之前的 [] 是什么意思?
  • @Engine:这是 C++11 lambda(又名匿名函数)的语法。这有点像在文件范围内声明一个函数bool Vec2f_approx_eq(const cv::Vec2f &amp; a, const cv::Vec2f &amp; b) { return …; },然后将其作为谓词传入:std::unique_copy(…, Vec2f_approx_eq);。显然,lambda 更简洁,因为它可以让您将所有内容保存在一个地方。
  • @Engine:很高兴,但请注意,cmets 是用于评论问题或答案,而不是用于联系人。