1

I want to remove some indexes from a vector inside a loop.
I currently have the following code:

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;
  }
}

and I want to delete those faces that have ratio < 0.5. How is it possible to remove items from the vector<Rect> faces?

Baldrickk
  • 4,291
  • 1
  • 15
  • 27
Jose Ramon
  • 5,572
  • 25
  • 76
  • 152
  • 2
    possible duplicate of [Erasing elements from a vector](http://stackoverflow.com/questions/347441/erasing-elements-from-a-vector) – Cory Kramer Oct 21 '14 at 14:58
  • what does this have to do with opencv? – Adam Oct 21 '14 at 15:00
  • +1 adam. Simple solution, loop over the vector backward and remove element with my_vector.erase(my_vector.begin()+i). – biquette Oct 21 '14 at 15:12
  • 4
    You're passing `faces` by value, meaning that any changes you make to it within the function are done on a temporary vector. If you expected the `faces` vector that you're passing in to be changed on return, it won't be changed. Pass the vector by reference, not by value if the desired behavior is to have `faces` changed. – PaulMcKenzie Oct 21 '14 at 15:23
  • 2
    To follow up from what PaulMcKenzie wrote, you should avoid ever passing std:: containers by value, since that's **extremely** expensive. Pass by reference, and if you don't want the container changed, pass by `const` reference. – dgnuff Oct 21 '14 at 16:15

3 Answers3

5

The correct method is to do:

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());
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
2

You could do something like this :

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;
}
hao
  • 228
  • 2
  • 9
-1

should be:

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

    //[...]

    if(ratio<0.5)
       faces.erase(faces.begin()+i);

    //[...]
}