【问题标题】:Remove items from vector inside a loop从循环内的向量中删除项目
【发布时间】:2014-10-21 14:57:19
【问题描述】:

我想从循环内的向量中删除一些索引。
我目前有以下代码:

static void store_faces(Mat image, vector<Rect> faces,  string path, string fileName){

 SkinDetector mySkinDetector;
 int counter = 0;
 for(int i = 0; i < faces.size(); i++){
    Mat temp = image(faces.at(i));

    double ratio= mySkinDetector.getSkin(temp);
    cout << "found face skin ratio.. " << ratio << endl;

    string file_name = path+ fileName + "_"+ NumberToString(counter)+".jpg";
    imwrite(file_name, temp);
    counter+=1;
  }
}

我想删除那些有ratio &lt; 0.5 的面孔。如何从vector&lt;Rect&gt; faces 中删除项目?

【问题讨论】:

  • 这和opencv有什么关系?
  • +1 亚当。简单的解决方案,向后循环向量并使用 my_vector.erase(my_vector.begin()+i) 删除元素。
  • 您通过值传递faces,这意味着您在函数中对其所做的任何更改都是在临时向量上完成的。如果您希望传入的 faces 向量在返回时发生更改,则不会更改。如果期望的行为是改变faces,则通过引用而不是值传递向量。
  • 为了跟进 PaulMcKenzie 所写的内容,您应该避免按值传递 std:: 容器,因为这非常昂贵。通过引用传递,如果您不想更改容器,请通过 const 引用传递。

标签: c++ opencv vector


【解决方案1】:

正确的方法是:

std::vector<Rect> vec = ...;
auto tail = std::remove_if(vec.begin(), vec.end(), [&](Rect const & rect) -> bool {
    return mySkinDetector.getSkin(image(rect)) < 0.5;
});

vec.erase(tail, vec.end());

【讨论】:

    【解决方案2】:

    你可以这样做:

    void fct(vector<Rect> faces)
    {
        for(vector<Rect>::iterator it=faces.begin(); it!=faces.end(); /*nothing here*/)
        {
            if( condition )
                it = faces.erase(it)
            else
                ++it;
    }
    

    【讨论】:

      【解决方案3】:

      应该是:

      for(int i = 0; i < faces.size(); i++){
          Mat temp = image(faces.at(i));
      
          //[...]
      
          if(ratio<0.5)
             faces.erase(faces.begin()+i);
      
          //[...]
      }
      

      【讨论】:

      • 除非您仅有条件地递增 i,否则您将跳过元素。
      猜你喜欢
      • 2016-08-14
      • 2020-06-24
      • 2013-04-22
      • 2012-01-27
      • 1970-01-01
      • 2012-05-08
      • 1970-01-01
      相关资源
      最近更新 更多