简体   繁体   English

在向量C ++中访问指针

[英]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 我已经编码了一个类,它将打开一个视频文件(opencv-lib)并播放
  • 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 保存是通过loadVideoInBuffer()方法完成的
  • the playback is done in the playVideoInBuffer() method 播放是通过playVideoInBuffer()方法完成的

In my mind that shouldn't do any problems but the show method does only show one frame and this is the last one. 在我看来,应该没有任何问题,但是show方法只显示一帧,这是最后一帧。 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. 现在对我来说令人困惑的是,我在两个函数(加载和显示)中使用了完全相同的代码来播放VideoBuffer-content。 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 到系统:带有gcc 4.8.1 OpenCV-2.4.7的OpenSuse 13.1 IdeQt5.0

According project file 根据项目文件

HEADERS +=

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

Opencv avoids copies. Opencv避免复制。 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 . 不复制数据vidImg ,它只是创建了一个新的报头,所以后来在vidImg更改数据更改的所有元素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. 除了@etarion所说的以外,使您的生活变得轻松,并丢弃所有这些指针 ,您根本不需要它们。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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