有毛病吗退出循环时,while语句中填充良好的vector <mat>会意外更改其内容

时间:2019-05-12 01:10:26

标签: c++ opencv vector

问题如下:

一方面,我用视频的所有帧填充向量。我检查帧是否实际上包含视频的帧,并且顺序正确:是。

另一方面,当我退出while语句并使用for循环读取其内容时,它的行为就好像每一帧都等于视频的最后一帧(重复图像的矢量)。

我解决了这个问题,发现了以下事实:

  • 正确读取每个图像并将其存储在frame_temp中(从视频的开头到结尾检索每个帧)。
  • imshow(frames [i])在while循环内显示正确的图像。
  • imshow(frames [i])仅显示视频在for循环内的最后一帧,无论“ i”的值是什么。

我尝试用vector.push_back来做,但是结果是一样的。

void GetFramesFromVideo(String filepath, vector<Mat>& frames)
{
    Mat frame_temp;
    VideoCapture cap = VideoCapture(filepath);
    int videosize = cap.get(7);
    frames = vector<Mat>(videosize);
    bool success = cap.read(frame_temp);
    frames[0]=frame_temp;
    namedWindow("he");
    int i = 1;
    while (success)
    {
        success = cap.read(frame_temp);
        if (success)
        {
            frames[i] = frame_temp;
            i++;
        }
        imshow("he", frames[i-1]);
        waitKey(10);
        cout << "Read a new frame: " << success;
    }
    for (int i = 0; i < frames.size(); i++)
    {
        imshow("he", frames[i]);
        waitKey(10);
    }
}
  • while循环中的imshow(“ he”)会复制视频-每个帧[i]是视频的实际帧。
  • for循环中的imshow(“ he”)一次又一次重复视频的最后一帧。帧向量似乎填充了最后一个“ push_backed”帧的重复项。

1 个答案:

答案 0 :(得分:1)

cv::Mat是一种具有引用语义而非值语义的类型。换句话说,您可以将其视为指向矩阵的智能指针。

operator=(const Mat&)的{​​{3}}说:

  

矩阵分配是O(1)运算。这意味着没有数据被复制,但是数据被共享,并且引用计数器(如果有)增加。

因此,问题很简单:您始终在写frame_temp(这是您仅有的实际数据),然后将对这些数据的引用重复存储在vector<Mat>中。您每次都需要创建一个新的Mat