1

I'm trying to implement color conversion from RGB-LMS and LMS-RGB back and using reshape for multiplication matrix, following answer from this question : Fastest way to apply color matrix to RGB image using OpenCV 3.0?

My ori Mat object is from an image with 3 channel (RGB), and I need to multiply them with matrix of 1 channel (lms), it seems like I have an issue with the matrix type. I've read reshape docs and questions related to this issue, like Issues multiplying Mat matrices, and I believe I have followed the instructions.

Here's my code : [UPDATED : Convert into flat image]

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);
}

I define my Mat object, and I have converted it into float using convertTo

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);

Error is :

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

so it's the type issue.

I tried to change all type into either 32FC3 of 32FC1, but doesn't seem to work. Any suggestion ?

raisa_
  • 594
  • 2
  • 10
  • 28

1 Answers1

1

I believe what you need is to convert your input to a flat image and than multiply them

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); 

I might have messed up with lms matrix there, but I guess you will catch up from here.

Also see 3D matrix multiplication in opencv for RGB color mixing

EDIT: Problem with distortion is that you got overflow after float to 8U conversion. This would do the trick:

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

Output: enter image description here;

Also I'm not sure but quick google search gives me different matrix for LMS see here. Also note that opencv stores colors in B-G-R format instead of RGB so change your mix mtraixes recordingly.

Dmitrii Z.
  • 2,287
  • 3
  • 19
  • 29
  • Hi, thanks ! I've updated my code and seen your recommended question. I think now I'm facing the same issue as him (image distortion), here's [my result](https://i.imgur.com/kF9GYvL.jpg) So I need to multiply my source image with the matrix lms (conversion RGB-LMS), then the result will be multiplied with transpose matrix of lms to get the original RGB back (LMS-RGB). Thst's why I need to use transpose. Any idea why the distortion ? – raisa_ Jan 31 '18 at 04:26
  • Hi, thanks ! Yes.. actually there are several different conversion matrices from RGB to LMS, according to which reference we choose. In my case, I'm referring to [this paper](https://arxiv.org/pdf/1711.10662.pdf). Sure, I'm aware of the BGR order, that's why I switched the matrix rows. I can either convert my image into RGB and directly use the matrix or switch the matrix to match BGR order. And something must be really wrong with my code.. I can't get the image that I want, still try to figure out. But I know your answer is the best approach to this. Thanks a lot !! – raisa_ Feb 05 '18 at 06:26