Color normalization algorithm under various lighting conditions

I am trying to take pictures using cellphones under various lighting conditions which would cause color distortions. Hence some kind of white balance algorithm is needed to correct the lighting of those photos so we get the standardized color. This can be commonly done if you have a "gray card" which many photographers use to tell their cameras what is the true white color under any light. With the "gray card", a person can take a picture with a standard color item by the side. With the item's color as a reference, we hope we can standardize the picture's color. We are doing this for an excellent color normalization.
Does anybody know any readily available algorithms (or something we can modify) for the above purpose? I really appreciate it if you can offer any suggestions.

4 件のコメント

darova
darova 2020 年 4 月 24 日
Can you take a picture with some identificator? Maybe slice of white paper?
LANG Wu
LANG Wu 2020 年 4 月 24 日
Yes, we can. After we take the picture with identificator, what algorithms can I use to normalize the color?
darova
darova 2020 年 4 月 24 日
Is it possible to make that identificator to be in the same place?
LANG Wu
LANG Wu 2020 年 4 月 24 日
That's hard to say. But maybe we can make it in the top right or left. Or we can take two pictures, one for the object, the other for the identificator.

サインインしてコメントする。

 採用された回答

Image Analyst
Image Analyst 2020 年 4 月 24 日

0 投票

There is a whole family of functions to do this. In the Image Processing Toolbox, check out illumgray(), illumpca(), illumwhite(), and chromadapt().

6 件のコメント

LANG Wu
LANG Wu 2020 年 4 月 24 日
Okay, thank you. I will check them out.
LANG Wu
LANG Wu 2020 年 4 月 25 日
It seems they are all auto white balance algorithms, which are not that helpful.
Image Analyst
Image Analyst 2020 年 4 月 25 日
I don't know why not. If you want to do it yourself, this is what I'd do
  1. Convert the image into lab colorspace with rgb2lab()
  2. Take the histogram of the L channel and threshold the channel to get your white/gray card. This will get you a mask
  3. Extract color channels: redChannel = rgbImage(:,:,1);, etc.
  4. Get the mean gray levels for every color channel using meanR = mean(redChannel(mask)), etc.
  5. Compute the max intensity maxGL = max([meanR, meanG, meanB])
  6. Compute the deltas : deltaR = uint8(maxGL - meanR), etc.
  7. Add the deltas to each color channel: newR = redChannel + deltaR, newG = greenChannel + deltaG, etc.
  8. Recombine into new RGB image newRGB = cat(3, newR, newG, newB)
This will color correct the image such that the brightest color channel of the white card does not change.
LANG Wu
LANG Wu 2020 年 4 月 28 日
Thanks for your answer. But can you explain more on how to implement step 2?
Image Analyst
Image Analyst 2020 年 4 月 28 日
Actually you can do steps 1 and 2 using rgb2gray()
grayImage = rgb2gray(rgbImage);
mask = grayImage > 180; % or whatever gray level your white card is.
% Extract the individual red, green, and blue color channels.
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
meanR = mean(redChannel(mask))
meanG = mean(greenChannel(mask))
meanB = mean(blueChannel(mask))
maxR = max(redChannel(mask))
maxG = max(greenChannel(mask))
maxB = max(blueChannel(mask))
deltaR = uint8(maxR - meanR)
deltaG = uint8(maxG - meanG)
deltaB = uint8(maxB - meanB)
newR = redChannel + deltaR;
newG = greenChannel + deltaG;
newB = blueChannel + deltaB;
newRGB = cat(3, newR, newG, newB);
imshow(newRGB);
See attached color standardization and calibration tutorial from my course I teach.
LANG Wu
LANG Wu 2020 年 4 月 28 日
Thanks again. Actually what I want to do is select the white card area, get its illumination and tell the algorithm this is 'white', and then normalize the image color considering the white card's illumination as standard. I don't see how you define the 'white' color in your code. Why do you choose 'grayscale>180" and what does 'delta' mean?

サインインしてコメントする。

その他の回答 (1 件)

darova
darova 2020 年 4 月 25 日

1 投票

Try this trick
I = imread('peppers.png');
imshow(I)
p = round(ginput(1));
for i = 1:3
I(:,:,i) = I(:,:,i) + (255 - I(p(2),p(1),i));
end
imshow(I)

1 件のコメント

LANG Wu
LANG Wu 2020 年 4 月 28 日
Thanks, but this can not achieve the requirements.

サインインしてコメントする。

カテゴリ

ヘルプ センター および File ExchangeCreating, Deleting, and Querying Graphics Objects についてさらに検索

質問済み:

2020 年 4 月 24 日

コメント済み:

2020 年 4 月 28 日

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by