Ошибка в функции OpenCV2.3 cv :: split (). Одинаковые значения во всех 3 каналах - PullRequest
3 голосов
/ 11 сентября 2011

Потратив пару дней, пытаясь выяснить, почему 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 () или я сделал что-то не так?

1 Ответ

8 голосов
/ 12 сентября 2011

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

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

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

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

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

std::vector<cv::Mat> rgbChannels(3);
cv::split(inputImage, rgbChannels);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...