访问指针向量的元素

时间:2013-11-29 17:04:47

标签: c++ pointers opencv vector

我有一个复杂的问题。我试着解释一下我做了什么。 我有一个大班,有班级成员

Mat vidImg
vector<Mat*> *VideoBuffer;
unsigned int currentVideoFrame;

我也有一个班级方法

void loadVideoInBuffer(int num)
{
    VideoBuffer.clear();
    currentVideoFrame = 0;
    vidDev.open(ListVideos.at(num).absoluteFilePath().toStdString()); // open videofile

    while(true)
    {
        if(vidDev.read(vidImg) == false) // read from file int vidImg object
            break;
        VideoBuffer.push_back(new Mat(vidImg)); // pushback into vector
    }
    ui->tbVideo->setEnabled(true);
} 

在此我将从另一个文件加载的一些对象加载到Videobuffer向量中。 如果我尝试再次从这个向量中加载它在另一个我在这里分配的类成员:

void grabAndProcessFrameVideo() // reload and show loaded inage
{
    if(vidFlag == true)
    {   
        vidImg = Mat(*(VideoBuffer[currentVideoFrame]));  // load from vector
        currentVideoFrame++; // inc index for vector
        imshow("img",vidImg); // show reloaded object in another window
    }
}

Mat对象和imshow函数来自opencv lib,但我认为这并不重要。我的问题是,它只显示最后一张图片。如果我尝试以这种方式直接在加载函数中访问缓冲区向量

void EAMViewer::loadVideoInBuffer(int num)
{
    ui->tbVideo->setDisabled(true);
    VideoBuffer.clear();
    currentVideoFrame = 0;
    if(vidDev.open(ListVideos.at(num).absoluteFilePath().toStdString()) == false)
    {
        newLineInText(tr("no Device found"));
        return;
    }
    while(true)
    {
        if(vidDev.read(vidImg) == false)
            break;
        VideoBuffer.push_back(new Mat(vidImg));
        imshow("img",Mat(*(VideoBuffer)[currentVideoFrame]));
        waitKey(30);
        currentVideoFrame++;
    }
    currentVideoFrame = 0;
    ui->tbVideo->setEnabled(true);
}

然后它显示我想要的。所以我认为如果我留在范围内,向量指针星座是有问题的。

我现在的问题是:  1.为什么程序在抓取和处理时不会崩溃?  2.我该怎么办,它可以防止删除?

提前致谢,

英格

3 个答案:

答案 0 :(得分:2)

仅显示最后一帧的原因是Mat是引用计数类。所以当你做类似的事情时

Mat vidImg;
vidDev.read(vidImg);

Mat* a =  new Mat(vidImg);

a和vidImg指向同一图像。因此,向量中的所有元素都指向相同(最后加载)的图像。你想要做的是:

Mat a = vidImg.clone(); 

或在您的情况下(删除指针,因为它们不应该在那里:))

vector<Mat> VideoBuffer;
VideoBuffer.push_back(vidImg.clone());

所以:

  1. 删除所有指针(不应该让它们原始),因为Mat已经是“句柄”类型
  2. 使用clone()方法复制图像数据。

答案 1 :(得分:1)

我相信这可能是因为你正在取消引用向量,因为你拥有它是一个指向向量而不是向量的指针,而不是它实际包含的元素。

也许尝试更改

vector<Mat*> *VideoBuffer;

vector<Mat*> VideoBuffer;

我还建议使用智能指针向量而不是原始指针,因为目前你的代码正在整个地方泄漏内存。如果您坚持使用原始指针,则应在删除之前删除缓冲区向量的每个元素,因为单独清除不会释放内存

您还需要更改

imshow("img",Mat(*(VideoBuffer)[currentVideoFrame]));

imshow("img",Mat(*VideoBuffer[currentVideoFrame]));

在较低的while循环中

答案 2 :(得分:0)

你有没有调用grabAndProcessFrameVideo()的循环所以它会显示所有图像?

是不是它显示了你的所有图像但速度非常快,所以你只能看到最后一张?如果是这样,请在loadVideoInBuffer()(waitKey(30);)中添加一个暂停,您应该看到所有图像。