在花了几天时间试图弄明白为什么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()函数或者我做错了什么?
答案 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);