Почему печать пиксельных значений изображений из вектора возвращает чепуху? - PullRequest
0 голосов
/ 18 мая 2019

У меня есть некоторый код, который просматривает каталог белых и черных изображений, читает его, изменяет его размер и затем помещает в вектор изображений.Однако, когда я вызываю изображения из вектора, это не работает.Он печатается так, как если бы оба изображения были белыми.Что я здесь не так делаю?Это связано с вектором?

vector<cv::Mat> images;
vector<cv::String> imageNames;

void prepareData(cv::String &directory)
{
    cv::glob(directory, imageNames, false);
    cv::Mat colorful, grey, out;
    number = imageNames.size();

    cout << "Number of images to train on " << number << endl;

    for(size_t i = 0; i < number; i++)
    {
        colorful = cv::imread(imageNames[i]);
        cv::resize(colorful, out, cv::Size(5, 5));
        cv::cvtColor(out, grey, cv::COLOR_BGR2GRAY);
        images.push_back(grey);
        cout << grey << endl;
    }

    for (int i = 0; i < number; ++i)
    {
        cout << "IMAGE " << i << " " << images[i] << endl;
    }

Вот вывод, который я получаю.2 изображения вначале показывают правильные значения пикселей изображения (23 -> черный, 255 -> белый), но во-вторых, когда я вспоминаю это из вектора, я получаю, что оба моих изображения белые.Что я делаю не так?

Number of images to train on 2

[23, 23, 23, 23, 23;
  23, 23, 23, 23, 23;
  23, 23, 23, 23, 23;
  23, 23, 23, 23, 23;
  23, 23, 23, 23, 23]
[255, 255, 255, 255, 255;
  255, 255, 255, 255, 255;
  254, 254, 255, 255, 255;
  254, 255, 255, 255, 254;
  255, 255, 255, 255, 255]


IMAGE 0 [255, 255, 255, 255, 255;
  255, 255, 255, 255, 255;
  254, 254, 255, 255, 255;
  254, 255, 255, 255, 254;
  255, 255, 255, 255, 255]
IMAGE 1 [255, 255, 255, 255, 255;
  255, 255, 255, 255, 255;
  254, 254, 255, 255, 255;
  254, 255, 255, 255, 254;
  255, 255, 255, 255, 255]

1 Ответ

2 голосов
/ 18 мая 2019

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

Рассмотрим код ниже:

vector<cv::Mat> vec;
cv::Mat m1;
vec.push_back(m1); // vec[0] refers to m1
some operations on m1

теперь печатное содержимое vec[0] и m1 будет одинаковым.

В для цикла вы выдвигаете два новых экземпляра cv::Mat, но они ссылаются на данные grey. Поэтому, когда вы печатаете содержимое вектора, вы видите последнее изменение на матрице grey.

Создать out и grey как локальные внутри для loop:

    colorful = cv::imread(imageNames[i]);
    cv::Mat out, grey; // <----- added
    cv::resize(colorful, out, cv::Size(5, 5));
    cv::cvtColor(out, grey, cv::COLOR_BGR2GRAY);
    images.push_back(grey);
    cout << grey << endl;

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

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