Ошибка в функции OpenCV2.3 cv :: split (). Идентичные значения во всех 3 каналах

Потратив пару дней на попытки выяснить, почему opencv DFT дает 100% одинаковые результаты для всех трех каналов, я в итоге обнаружил, что может быть ошибка в функции split (), которую OpenCV предоставляет для разделения входного изображения на 3 отдельных изображения каналов.

std::vector<cv::Mat> rgbChannels(3,cv::Mat(inputImage.size(),CV_64FC1));
cv::split(inputImage, rgbChannels);

После сохранения значений изображения на диск и использования инструмента сравнения файлов я обнаружил, что все значения в разделенных каналах идентичны.

Я сделал что-то не так?

Моя работа была следующей функцией. Но это также дало мне точные идентичные значения, давая мне подсказку, что каким-то образом векторы не обрабатывались правильно OpenCV.

SplitImage(cv::Mat inputImage)
{
    //copy original in BGR order
    std::vector<cv::Mat> splittedImage(3,cv::Mat(inputImage.size(),CV_64FC1));

        cv::Mat tempImage(inputImage.size(),CV_64FC1);
        for (int row = 0; row < inputImage.size().height; row++)
        {
            for (int col = 0; col < inputImage.size().width; col++)
            {               
splittedImage[0].at<double>(row, col) = inputImage.at<cv::Vec3d>(row, col)[0];
splittedImage[1].at<double>(row, col) = inputImage.at<cv::Vec3d>(row, col)[1];
splittedImage[2].at<double>(row, col) = inputImage.at<cv::Vec3d>(row, col)[2];
            }
        }
    return splittedImage;
}

И, наконец, написал следующее, чтобы решить проблему

SplitImage(cv::Mat inputImage)
{
    //copy original in BGR order
    std::vector<cv::Mat> splittedImage(3,cv::Mat(inputImage.size(),CV_64FC1));
    std::vector<cv::Mat>::iterator it;
    it = splittedImage.begin();

    for(int channelNo = 0; channelNo < inputImage.channels(); channelNo++)
    {
        cv::Mat tempImage(inputImage.size(),CV_64FC1);
        for (int row = 0; row < inputImage.size().height; row++)
        {
            for (int col = 0; col < inputImage.size().width; col++)
            {
    tempImage.at<double>(row, col) = inputImage.at<cv::Vec3d>(row, col)[channelNo];
            }
        }

  it = splittedImage.insert ( it , tempImage );     
  it++;
    }
    return splittedImage;
}

У кого-нибудь была проблема с функцией split () или я что-то сделал не так?


person Community    schedule 11.09.2011    source источник


Ответы (1)


Это не ошибка в OpenCV, но есть проблема с вашим кодом.

Следующая строка не создает вектор из 3 разных матов:

std::vector<cv::Mat> rgbChannels(3,cv::Mat(inputImage.size(),CV_64FC1));

Вместо этого эта строка создает вектор из 3 заголовков Mat, использующих одну и ту же память. Это работает так, потому что конструктор копирования Mat не делает глубокую копию - он просто увеличивает внутренний счетчик ссылок.

Просто измените свой код на следующий, чтобы решить вашу проблему:

std::vector<cv::Mat> rgbChannels(3);
cv::split(inputImage, rgbChannels);
person Andrey Kamaev    schedule 11.09.2011
comment
Разве способ, которым я создал векторы, не предполагает создание матов одинаковых размеров? т.е. каналы и ширина по высоте? - person ; 12.09.2011
comment
Андрей: cv::split работает ли с многомерными массивами с несколькими каналами одновременно? т.е. может ли он разбить что-то вроде int dims[] = {5,4,3}; Mat(3, dims, CV_8UC2);? - person Amro; 22.06.2015