OpenCV2.3 cv :: split()函数中的错误。所有3个通道中的值相同

时间:2011-09-11 19:56:33

标签: opencv split

在花了几天时间试图弄明白为什么opencv DFT会为所有三个频道提供100%相似的结果后我发现OpenCV可能存在分裂输入图像的split()函数中的错误到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 个答案:

答案 0 :(得分:8)

这不是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);