在OpenCV中使用重塑,Mat类型问题乘以Mat矩阵

时间:2018-01-30 19:36:44

标签: c++ opencv image-processing matrix reshape

我尝试从RGB-LMS和LMS-RGB实现颜色转换,并使用重塑用于乘法矩阵,然后回答这个问题:Fastest way to apply color matrix to RGB image using OpenCV 3.0?

我的ori Mat对象是来自3通道(RGB)的图像,我需要将它们与1通道(lms)的矩阵相乘,看起来我的矩阵类型有问题。我已阅读reshape docs以及与此问题相关的问题,例如Issues multiplying Mat matrices,我相信我已按照说明操作。

这是我的代码:[更新:转换为平面图片]

void test(const Mat &forreshape, Mat &output, Mat &pic, int rows, int cols)
{
    Mat lms(3, 3, CV_32FC3);
    Mat rgb(3, 3, CV_32FC3);
    Mat intolms(rows, cols, CV_32F);

    lms = (Mat_<float>(3, 3) << 1.4671, 0.1843, 0.0030,
                                3.8671, 27.1554, 3.4557,
                                4.1194, 45.5161 , 17.884 );
    /* switch the order of the matrix according to the BGR order of color on OpenCV */


    Mat transpose = (3, 3, CV_32F, lms).t();  // this will do transpose from matrix lms

    pic     = forreshape.reshape(1, rows*cols);
    Mat flatFloatImage;
    pic.convertTo(flatFloatImage, CV_32F);

    rgb         = flatFloatImag*transpose;
    output      = rgb.reshape(3, cols);
}

我定义了Mat对象,并使用convertTo

将其转换为float
Mat ori = imread("ori.png", CV_LOAD_IMAGE_COLOR);
int rows = ori.rows;
int cols = ori.cols;

Mat forreshape;
ori.convertTo(forreshape, CV_32F);

Mat pic(rows, cols, CV_32FC3);
Mat output(rows, cols, CV_32FC3);

错误是:

OpenCV Error: Assertion failed (type == B.type() && (type == CV_32FC1 || type == CV_64FC1 || type == CV_32FC2 || type == CV_64FC2)) , 

所以这是类型问题。

我尝试将所有类型更改为32FC1的32FC3,但似乎无法正常工作。有什么建议吗?

1 个答案:

答案 0 :(得分:1)

我相信您需要的是将输入转换为平面图像而不是将它们相乘

float lms [] = {1.4671, 0.1843, 0.0030,
                            3.8671, 27.1554, 3.4557,
                            4.1194, 45.5161 , 17.884};
Mat lmsMat(3, 3, CV_32F, lms );

Mat flatImage = ori.reshape(1, ori.rows * ori.cols);
Mat flatFloatImage;
flatImage.convertTo(flatFloatImage, CV_32F);
Mat mixedImage = flatFloatImage * lmsMat;
Mat output = mixedImage.reshape(3, imData.rows); 

我可能在那里弄​​乱了lms矩阵,但我想你会从这里赶上来。

另见3D matrix multiplication in opencv for RGB color mixing

编辑: 失真问题是浮动到8U转换后溢出。这样就可以了:

rgb         = flatFloatImage*transpose;
rgb.convertTo(pic, CV_32S);
output      = pic.reshape(3, rows)

输出: enter image description here;

另外我不确定但快速谷歌搜索为LMS see here提供了不同的矩阵。另请注意,opencv以B-G-R格式存储颜色而不是RGB,因此可以录制更改混合mtraix。