Жук? хорошо заполненный вектор <Mat>внутри оператора while неожиданно меняет свое содержимое при выходе из цикла - PullRequest
0 голосов
/ 12 мая 2019

Проблема в следующем:

С одной стороны, я заполняю вектор всеми кадрами видео.Я проверяю, действительно ли кадры содержат кадры видео, в правильном порядке: ДА.

С другой стороны, когда я выхожу из оператора 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);
    }
}
  • imshow («он») внутри цикла while воспроизводит видео - каждый кадр [i] является фактическим кадром видео.
  • Imshow («он») внутри цикла for повторяет последний кадрвидео снова и снова.Кажется, что вектор кадров заполнен дубликатами последнего кадра "push_backed".

1 Ответ

1 голос
/ 12 мая 2019

cv::Mat - это тип, который имеет ссылочную семантику, а не семантику значения.Другими словами, вы можете думать об этом как об умном указателе на матрицу.

Документация для operator=(const Mat&) гласит:

Назначение матрицы - этоO (1) операция.Это означает, что данные не копируются, но данные используются совместно, и счетчик ссылок, если таковые имеются, увеличивается.

Итак, ваша проблема проста: вы всегда пишете в frame_temp, который являетсятолько фактические данные, которые у вас есть, и затем вы постоянно сохраняете ссылки на эти данные в вашем vector<Mat>.Вам нужно каждый раз создавать новый Mat.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...