在Vector C ++中访问指针

时间:2013-12-03 12:34:24

标签: c++ pointers opencv vector

我正在引用这个question。因为我无法在那里回答,所以我可以通过更好地解决我遇到的问题来提出问题。

为此,我编写了一个可编辑的文件。

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

您可以下载here的测试视频。

我希望这能更好地解决我的问题。我将总结如下:

  • 我编写了一个类,它将打开一个视频文件(opencv-lib)并播放它
  • 视频帧存储在堆中,并且相应的指针保存在指针向量中,每帧都存在
  • 保存在loadVideoInBuffer()方法
  • 中完成
  • 播放在playVideoInBuffer()方法
  • 中完成

在我看来,不应该做任何问题,但show方法只显示一帧,这是最后一帧。对我来说,令人困惑的是,我在两个函数(加载和显示)中使用了完全相同的代码来播放VideoBuffer内容。在加载功能中,它按需运行。

如果我以这种方式更改加载功能

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

它也只显示最后一帧,我不知道为什么。

我希望我现在已经弄清楚我在本帖子顶部链接的最后一个问题中也遇到了这个问题。

我发现存在问题,问题出在哪里,但不知道原因。看起来,它写的所有其他指针。向量中的指针会发生什么,为什么所有指针都指向最后一个的内容,尽管我已经分配了新的空间?

提前致谢! 英格

到系统: OpenSuse 13.1 IdeQt5.0与gcc 4.8.1 的OpenCV-2.4.7

根据项目文件

HEADERS +=

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

2 个答案:

答案 0 :(得分:3)

Opencv避免了副本。 这个:

            VideoBuffer.push_back(new Mat(vidImg));

不会复制vidImg中的数据,它只会创建一个新标头,因此稍后更改vidImg中的数据会更改VideoBuffer的所有元素。使用clone方法复制数据。

答案 1 :(得分:0)

除了@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++;
        }
    }
};