Search code examples
c++opencvvectorpointpush-back

Push_back is replacing current point instead of adding a new one to the vector


I am having trouble appending new points onto the end of my current Vector of points. What it is currently doing is overwriting the existing vector with the new point I am trying to add, leaving the vector with only 1 element.

This is the class definition (.h file):

class person
{
public:
    person();
    ~person();

    int ID;
    std::vector<cv::Point> history;

    void addposition(cv::Point);
    void person::drawhistory(cv::Mat*,std::vector<cv::Point>);
};

And this is how the function declarations that appear in the .cpp file of the class:

person::person()
{
}

person::~person()
{
}

void person::addposition(cv::Point inpt) {
    std::cout << "Adding a position ----" << std::endl;
    std::cout << "Pushing inpt.x: " << inpt.x << std::endl;
    std::cout << "Pushing inpt.y: " << inpt.y << std::endl;
    history.push_back(inpt);
    std::cout << "Current Size: " << history.size() << std::endl;
    if (history.size()>15)
    {
        history.erase(history.begin());
    }
}

void person::drawhistory( cv::Mat* image, std::vector<cv::Point> hist) {
    cv::Point pt;
    for (cv::Point const& pt : hist)
    {
        std::cout << "Printing the History" << std::endl;
        std::cout << "Current Pt.x: " << pt.x << std::endl;
        std::cout << "Current Pt.y: " << pt.y << std::endl;
        cv::circle(*image, pt, 5, cv::Scalar(0, 0, 0), -1);
    }
}

And this is how these two functions are being called in the main function. Note that detectBox is declared as such:

vector<RECT> detectBox

and it is correctly storing the necessary points in the frame, so im pretty sure that it is not the cause of the issue:

for (RECT const& rect : *detectBox)
{
        std::cout << "Inside the LOOOOOP" << std::endl;
        //This is simply finding the middle point of the rectangle currently stored in detectBox        
        pt.y = (rect.bottom + rect.top) / 2; 
        pt.x = (rect.left + rect.right) / 2;

    person personn;
    personn.addposition(pt);
    personn.drawhistory(&img_8bit, personn.history);

    cv::circle(img_8bit, pt, 3, cv::Scalar(255, 255, 0), -1);
}
cv::imshow("8Bit", img_8bit);

I would think that it would be straightforward to push points into the vector but somehow its not adding new ones onto the bottom of the vector. Also note that I have added an erase step that keeps the number of points stored to 15.

Is the problem with the functions in my class definition (I am new to classes), or is it an issue with how I am calling the functions from the main loop?


Solution

  • This is most likely not what you want to do:

    person personn;
    personn.addposition(pt);
    personn.drawhistory(&img_8bit, personn.history);
    

    Your presonn is local to the body of the loop, thus on each iteration you create a new person, add a single position and print that. Just declare personn outside of the loop.

    PS: A mcve of the issue could look like this:

    #include <vector>
    #include <iostream>
    int main() {
        for (int i=0; i<5; i++) {
            std::vector<int> vect;
            vect.push_back(i);
            std::cout << vect.size() << std::endl;
        }
    }
    

    It reproduces the issue you are having, it compiles and it has only the minimal code necessary to do so. If you created that yourself you probably had found the mistake yourself. Of course it is not always so easy to get to the source of the error. A debugger might help to find the spot where it goes wrong.