简体   繁体   中英

Accessing Pointers in a Vector C++

i am refering to this question . Because i can't answering there i ask the question new with a better singling out of the problem i had.

For this i have coded a compilable file.

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

class VecOfPointers
{
public:
    explicit VecOfPointers()
    {
        if(!vidDev.open(str))
        {
            cout << "no file found" << endl;
            return;
        }
        namedWindow("test load");
        loadVideoInBuffer();
        cout << "file loaded" << endl;
        namedWindow("test show");
        playVideoInBuffer();
    }

    ~VecOfPointers()
    {
        for(unsigned int h = 0; h < VideoBuffer.size(); h++)
        {
            Mat* img = VideoBuffer[h];
            delete img;
        }
        VideoBuffer.clear();
        destroyAllWindows();
    }

    unsigned int currentVideoFrame = 0;
    Mat vidImg;
    VideoCapture vidDev;
    const string str = "/home/Inge/DA/videos/testVideo.avi";
    vector<Mat*> VideoBuffer;

    void loadVideoInBuffer()
    {
        for(unsigned int h = 0; h < VideoBuffer.size(); h++)
        {
            Mat* img = VideoBuffer[h];
            delete img;
        }
        currentVideoFrame = 0;
        while(true)
        {
            if(vidDev.read(vidImg) == false)
                break;
            VideoBuffer.push_back(new Mat(vidImg));
            vidImg = *(VideoBuffer[currentVideoFrame]);
            waitKey(50);
            imshow("test load",vidImg);
            currentVideoFrame++;
            cout << currentVideoFrame << endl;
        }
    }

    void playVideoInBuffer()
    {
        currentVideoFrame = 0;
        while(currentVideoFrame != VideoBuffer.size())
        {
            vidImg = *(VideoBuffer[currentVideoFrame]);
            imshow("test show", vidImg);
            waitKey(50);
            cout << currentVideoFrame << endl;
            currentVideoFrame++;
        }
    }
};

int main()
{
    VecOfPointers testClass;
}

The testvideo for that you can download here .

I hope this figures better out my problem. I will summarize it as follows:

  • i have coded a class which shall open a videofile (opencv-lib) and play it back
  • the videoframes are stored in the heap and the according pointers are saved in a vector of pointers, to every frame
  • the saving is done in the loadVideoInBuffer() method
  • the playback is done in the playVideoInBuffer() method

In my mind that shouldn't do any problems but the show method does only show one frame and this is the last one. The confusing thing for me is now, that i have used exactly the same code in both functions (loading and showing) to play the VideoBuffer-content back. In the loading function it runs as wanted.

If i change the loading function in this way

void loadVideoInBuffer()
{
    for(unsigned int h = 0; h < VideoBuffer.size(); h++)
    {
        Mat* img = VideoBuffer[h];
        delete img;
    }
    while(true)
    {
        if(vidDev.read(vidImg) == false)
            break;
        VideoBuffer.push_back(new Mat(vidImg));
    }
    currentVideoFrame = 0;
    while(currentVideoFrame != VideoBuffer.size())
    {
        vidImg = *(VideoBuffer[currentVideoFrame]);
        waitKey(50);
        imshow("test load",vidImg);
        currentVideoFrame++;
        cout << currentVideoFrame << endl;
    }
} 

it will show only the last frame too and i don't know why.

I hope i have figured out now the problem which i also have had in the last question i have linked at the top of this post.

I see that there is a problem and where the problem is but do not know the reason. It seems, that it writes all over the other pointers. What is happen to the pointers in the vector and why does all of them point to the content of the last one, although i have allocated new space?

Thanks in advance! Inge

To the system: OpenSuse 13.1 IdeQt5.0 with gcc 4.8.1 OpenCV-2.4.7

According project file

HEADERS +=

SOURCES += \
    main.cpp
QMAKE_CXXFLAGS += -std=c++11
LIBS += `pkg-config opencv --cflags --libs`

Opencv avoids copies. This:

            VideoBuffer.push_back(new Mat(vidImg));

does not copy the data in vidImg , it merely creates a new header, so later changes to the data in vidImg change all the elements of VideoBuffer . Use the clone method to copy the data.

apart from what @etarion said, make your life easy, and discard all those pointers , you don't need them at all.

class VecOfMats
{
public:
    explicit VecOfMats()
    {
        if(!vidDev.open(str))
        {
            cout << "no file found" << endl;
            return;
        }
        namedWindow("test load");
        loadVideoInBuffer();
        cout << "file loaded" << endl;
        namedWindow("test show");
        playVideoInBuffer();
    }

    ~VecOfMats()
    {
        VideoBuffer.clear();
        destroyAllWindows();
    }

    unsigned int currentVideoFrame = 0;
    Mat vidImg;
    VideoCapture vidDev;
    const string str = "/home/Inge/DA/videos/testVideo.avi";
    vector<Mat> VideoBuffer;

    void loadVideoInBuffer()
    {
        VideoBuffer.clear();
        currentVideoFrame = 0;
        while(true)
        {
            if(vidDev.read(vidImg) == false)
                break;
            VideoBuffer.push_back(vidImg.clone());  // <-- here goes the clone() !
            waitKey(50);
            imshow("test load",vidImg);
            currentVideoFrame++;
            cout << currentVideoFrame << endl;
        }
    }

    void playVideoInBuffer()
    {
        currentVideoFrame = 0;
        while(currentVideoFrame != VideoBuffer.size())
        {
            vidImg = VideoBuffer[currentVideoFrame];
            imshow("test show", vidImg);
            waitKey(50);
            cout << currentVideoFrame << endl;
            currentVideoFrame++;
        }
    }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM