Search code examples
c++opencvmatlogarithmcolor-space

OpenCV - How to project RGB image to log (R/G) ~ log (B/G) space?


I am trying to project an RGB image to log (R/G) ~ log (B/G) coordinate system.

According to the definition here and here the log (R/G) ~ log (B/G) space is calculated like this:

enter image description here

Basically, I want two arrays X and Y (I use Mat as an array) where:

enter image description here

enter image description here

This is what I have tried:

calculating X* and Y*:

    Mat input = imread("an RGB image");
    Mat X, Y, B, G, R, input_f;
    input.convertTo(input_f, CV_32FC3);
    vector<Mat> channels(3);
    split(input_f, channels);
    B = channels[0];
    G = channels[1];
    R = channels[2];

    //-- calculate X , Y vectors
    Mat div_x, div_y;
    divide(R, G, div_x);
    divide(B, G, div_y);
    log(div_x, X);
    log(div_y, Y);
    X.setTo(0, Mat(X < 0));
    Y.setTo(0, Mat(Y < 0));

    //-- calculate X* , Y* vectors
    Mat X_star, Y_star;
    Scalar x_bar = mean(X);
    Scalar y_bar = mean(Y); 

    subtract(X, Scalar(x_bar), X_star);
    subtract(Y, Scalar(y_bar), Y_star);

But when I try the rest of the instructions to obtain the result, my result does not look like theirs at all.

enter image description here

calculating the intrinsic image:

    Mat intrinsic;
    intrinsic = X * cos(alpha) + Y * sin(alpha);
    imshow("intrinsic", intrinsic);

I think I am doing something wrong in calculating the X* and Y* matrices. Because when I try this with any value of alpha the result dows not become right:

This is the image:

enter image description here

This is the expected result:

enter image description here

This is what I am getting:

enter image description here

Here is a screenshot of the first paper: enter image description here


Solution

  • One small question (sorry, I can't comment yet):

    Shouldn't the X

    intrinsic = X * cos(alpha) + Y * sin(alpha);
    

    be X_star instead?

    intrinsic = X_star * cos(alpha) + Y_star * sin(alpha);
    

    Otherwise you could write subtract(X, Scalar(x_bar), X);

    And how to you compute α?

    Edit enter image description here

    This is a screenshot from your 2nd posted source.

    As you can see, the gray-scale image G inv is computed by means of your X_star: intrinsic = X_star * cos(alpha) + Y_star * sin(alpha);. This also the case for the first equation you posted.

    I can not access the first link you posted, it is not free.