Ask Your Question

Converting RGB into LMS model using C++ and OpenCV

asked 2018-01-27 08:18:27 -0500

raisa_ gravatar image

I'm trying to convert image with RGB colorspace into LMS model. The transformation matrix value I got from this paper. I read this Question : RGB to LMS color space conversion with OpenCV, we referred to the same paper and I already followed all the instructions in the answer.

To make sure my codes do well, I convert the original RGB into LMS, then convert the LMS back into RGB using inverse matrix of the first matrix, and see if the output matches the original image.

image description

But the output doesn't match the original image source. Here's my code :

void test(const Mat &original, Mat &pic, int rows, int cols)
    for (int i = 0; i < original.rows; i++) {
        for (int j = 0; j < original.cols; j++) {
        //RGB into LMS
  <Vec3b>(i, j)[0] =<Vec3b>(i, j)[0] * 1.4671 + 
                              <Vec3b>(i, j)[1] * 0.1843 + 
                              <Vec3b>(i, j)[2] * 0.003;   //B-->S
  <Vec3b>(i, j)[1] =<Vec3b>(i, j)[0] * 3.8671 + 
                              <Vec3b>(i, j)[1] * 27.1554 + 
                              <Vec3b>(i, j)[2] * 3.4557;   //G-->M
  <Vec3b>(i, j)[2] =<Vec3b>(i, j)[0] * 4.1194 + 
                              <Vec3b>(i, j)[1] * 43.5161 + 
                              <Vec3b>(i, j)[2] * 17.8824;  //R-->L

            //LMS back into RGB
  <Vec3b>(i, j)[0] =<Vec3b>(i, j)[0] * 0.6935 + 
                              <Vec3b>(i, j)[1] * -0.0041 + 
                              <Vec3b>(i, j)[2] * -0.0004;   //S-->B
 <Vec3b>(i, j)[1] =<Vec3b>(i, j)[0] * -0.1136 + 
                              <Vec3b>(i, j)[1] * 0.0540 + 
                              <Vec3b>(i, j)[2] * -0.0102;   //M-->G
 <Vec3b>(i, j)[2] =<Vec3b>(i, j)[0] * 0.1167 + 
                              <Vec3b>(i, j)[1] * -0.1305 + 
                              <Vec3b>(i, j)[2] * 0.0809;   //L-->R



int main(int argv, char** argc){
Mat original= imread("original.png", CV_LOAD_IMAGE_COLOR);
int rows = original.rows;
int cols = original.cols;

Mat pic(rows, cols, CV_8UC3);

test(original, pic, rows, cols);
imwrite("pic.png", pic);

Any suggestion ? Any help will be appreciated.

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted

answered 2018-01-29 03:02:22 -0500

updated 2018-01-29 03:10:03 -0500

Hi Please note that conversion from one color space to another color space is not always reversible. i.e You cannot expect to get back the original image after conversion.

Here is a Sample code for Transforming an Image using 3x3 Color Transformation Matrix. You have to find correct transformation matrix for your color Space.

Note: Please refrain from using loops in your code and try to use existing OpenCV functions as much as possible.

void imshow_RGB(string WindowName,Mat mSrc)
    Mat mSrc_BGR;
    cvtColor(mSrc, mSrc_BGR, CV_RGB2BGR);
    imshow(WindowName, mSrc_BGR);

int main(int argc, const char** argv)
    cv::Mat mSrc = cv::imread("C:\\Users\\Public\\Pictures\\Sample Pictures\\Koala.jpg", 1);
    cv::Mat mDst;
    if (mSrc.empty())
        cout << "Invalid input image";
        return 0;

    cvtColor(mSrc, mSrc, CV_BGR2RGB);
    imshow_RGB("Source Image", mSrc);

    Mat mRGB2LMS_Matrix= Mat::eye(3,3,CV_32FC1);
    Mat mLMS2RGB_Matrix = Mat::eye(3, 3, CV_32FC1);

    //Fill your 3x3 Transformation Matrix here!!
    /*mRGB2LMS_Matrix = (Mat_<float>(3, 3) << 17.8824, 43.5161, 4.1194,
                                        3.4557, 27.1554, 3.8671,
                                        0.0300, 0.1843, 1.4671);

mLMS2RGB_Matrix = (Mat_<float>(3, 3) << 0.0809, -0.1305, 0.1167,
                                        -0.0102, 0.0540, -0.1136,
                                        -0.0004, -0.0041, 0.6935);*/

    //Forward Transformation from RGB -> Destination Color Space
    transform(mSrc, mDst, mRGB2LMS_Matrix);
    imshow_RGB("Forward Transformation", mDst);

    //Inverse Transformation from Destination Color Space -> RGB Color Space 
    transform(mDst, mSrc, mLMS2RGB_Matrix);
    imshow_RGB("Inverse Transformation Image", mSrc);

    return 0;
edit flag offensive delete link more


Hi, thanks for the explanation and sample code ! Very helpful. Also about the reversible, I follow these steps according to this paper I mentioned before. In case it's not reversible, how would we know if the transformation is correct ? If you wouldn't mind.. any reference for that will be a huge help for me.

raisa_ gravatar imageraisa_ ( 2018-01-30 10:43:17 -0500 )edit

As I've mentioned before you cannot expect to get back the original image when you reduce the number of colors in it! So there is no way to verify it with only one image. Common practice is to use a color chart which has all the possible(as much as) colors and compare it with the Target Color Model. You can refer this answer if you want to know How to compare two colors.

Balaji R gravatar imageBalaji R ( 2018-01-30 22:42:44 -0500 )edit
Login/Signup to Answer

Question Tools

1 follower


Asked: 2018-01-27 08:18:27 -0500

Seen: 201 times

Last updated: Jan 29 '18