I have several pictures of plants (tif files). Each picture contains a set of Munsell color chips. The "true" RGB values of the Munsell color chips are known. My goal is to correct the colors of the pictures, by comparing the "observed" and the "true" colors of the Munsell color chips. I tried to use a simple linear regression for each channel. Here is an example for the Red channel: (EDITED:)

x1 = mean_value_of_red_channel_of_observed_color_chip_1
x2 = mean_value_of_red_channel_of_observed_color_chip_2
y1 = red_value_of_true_color_chip_1
y2 = red_value_of_true_color_chip_2
x_mean = (x1+x2)/2
y_mean = (y1+y2)/2
slope = ((x1-x_mean)*(y1-y_mean)+(x2-x_mean)*(y2-y_mean))/((y1-y_mean)^2+(y2-y_mean)^2)
y_intercept = y_mean-(slope*x_mean)
corrected_red_channel_of_image = (slope*red_channel_of_image)+y_intercept

The result does not look right:

Original Image Original Image Corrected Image Corrected Image

For the conversion I used Python 3.6 with Open CV.
Any ideas what I did wrong?

  • 1
    What you did wrong starts with the assumption that color correction is linear, but may include other issues as well... – twalberg Mar 6 at 16:33
  • @twalberg the sensor is linear in the way it captures light, so it's a reasonable assumption. Problem is that a curve is applied in the raw conversion for gamma and other adjustments. – Mark Ransom Mar 6 at 16:38
  • 1
    Real world objects do not have "true" RGB values (even with scare quotes). It's probably better to use a word like "target" or "expected". – mattdm Mar 6 at 18:19
  • 1
    I just realized that maybe you're assuming the image is in RGB order when it's actually BGR. I don't know that for a fact but it would explain your result, it's worth checking. – Mark Ransom Mar 6 at 21:01
  • 1
    no but you can do it with dcraw. – ths Mar 7 at 13:24

With your formula, black (0,0,0) becomes a visible color (y_intercept_R,y_intercept_G,y_intercept_B). Your math are based on wrong assumptions. If the picture is correctly exposed, you have the constraint that 0. gives 0. and 1. (or 100% or 255) gives 1. (or 100% or 255). So your adjustment cannot be linear, it is more like a gamma correction on each channel.

  • I'm not sure you need to keep the constraint that 1.=1., but 0=0 is probably a must. – Mark Ransom Mar 7 at 4:29
  • In my script I added a correction, that sets all negative values to zero and all values higher than 255 to 255. This should not cause the color shifting.. – Hans Müller Mar 7 at 13:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.