Referenced White Balance of an image
5 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Hello,
I have a basic script for white balancing an image and it works quite okay. However now I am looking to modify it so it will correct a incorrectly balanced image by means of the analysis of a second image that will be used as white reference and have no idea where to even start.
This is the code I have and the effect:
% Read input image
img = imread('wb.jpg');
% Convert image to double precision
img = im2double(img);
% Get image dimensions
[rows, cols, channels] = size(img);
% Compute average channel values
Ravg = mean(mean(img(:,:,1)));
Gavg = mean(mean(img(:,:,2)));
Bavg = mean(mean(img(:,:,3)));
% Compute correction factors
Kavg = (Ravg + Gavg + Bavg) / 3;
Kr = Kavg / Ravg;
Kg = Kavg / Gavg;
Kb = Kavg / Bavg;
% Apply correction factors to each pixel
for i = 1:rows
for j = 1:cols
img(i,j,1) = Kr * img(i,j,1);
img(i,j,2) = Kg * img(i,j,2);
img(i,j,3) = Kb * img(i,j,3);
end
end
% Convert image back to uint8
img = im2uint8(img);
% Display original and corrected images
figure;
subplot(1,2,1); imshow('wb.jpg'); title('Original Image');
subplot(1,2,2); imshow(img); title('Corrected Image');

Now I am looking to modify the code so it takes both the image we are looking to white balance, and a second image that has the same lighting conditions as the first one.


The output should be a correctly white balanced image.
I will be thankful for any help.
0 commentaires
Réponse acceptée
DGM
le 28 Avr 2023
Modifié(e) : DGM
le 29 Avr 2023
I really have no familiarity with canonical white balancing techniques, but I'll shoot. First, let's simplify things
% Read input image
inpict = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1368389/image.png');
% Convert image to double precision
inpict = im2double(inpict);
% Compute average channel values
RGBavg = mean(inpict,1:2);
% Compute correction factors
Kgray = mean(RGBavg);
Krgb = Kgray./RGBavg;
% Apply correction factors
outpict = inpict.*Krgb;
% Convert image back to uint8
outpict = im2uint8(outpict);
% Display original and corrected images
figure
subplot(1,2,1); imshow(inpict); title('Original Image');
subplot(1,2,2); imshow(outpict); title('Corrected Image');
At that point, I don't see why you can't just use the calculated correction factors.
% Read test image
testpict = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1368394/image.png');
% Apply correction factors
outpict2 = im2double(testpict).*Krgb;
% Convert image back to uint8
outpict2 = im2uint8(outpict2);
% Display original and corrected images
figure
subplot(1,2,1); imshow(testpict); title('Original Image');
subplot(1,2,2); imshow(outpict2); title('Corrected Image');
1 commentaire
DGM
le 29 Avr 2023
Modifié(e) : DGM
le 30 Avr 2023
If you're asking "why is the output blue?", that's because the given process is heavily skewed by image content which is not nominally-white. In order to make the image mean neutral in the presence of red/brown content, white regions become blue.
Consider restricting the sampling to regions which can be considered white.
% Read input image
inpict = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1368389/image.png');
% Convert image to double precision
inpict = im2double(inpict);
% Convert to LAB and get thresholds
% these values split the distribution of L,C at their center
% for 50%, you could use mean(), but this can otherwise be generalized
[L A B] = imsplit(rgb2lab(inpict));
C = hypot(A,B);
Llimit = mean(stretchlim(L/100,0.49))*100;
Climit = mean(stretchlim(C/134,0.49))*134;
% create masks from L,C
lmask = L > Llimit; % brightest half of pixels
cmask = C < Climit; % least colorful half of pixels
whiteregion = repmat(lmask & cmask,[1 1 3]);
% Compute average channel values in selected region
thesepixels = reshape(inpict(whiteregion),[],1,3);
RGBavg = mean(thesepixels,1);
% Compute correction factors
Kgray = mean(RGBavg);
Krgb = Kgray./RGBavg;
% Apply correction factors
outpict = inpict.*Krgb;
% Convert image back to uint8
outpict = im2uint8(outpict);
% Display original and corrected image
% compare against the original global averaging method
op1 = imread('op1.png');
figure
imshow([im2uint8(inpict); op1; outpict],'border','tight')
% Read test image
testpict = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1368394/image.png');
% Apply correction factors
outpict2 = im2double(testpict).*Krgb;
% Convert image back to uint8
outpict2 = im2uint8(outpict2);
% Display original and corrected image
% compare against the original global averaging method
op2 = imread('op2.png');
figure
imshow([im2uint8(testpict); op2; outpict2],'border','tight')
Plus de réponses (1)
Image Analyst
le 30 Avr 2023
This is the best algorithm I've run across:
Sorry, I don't have code for it.
0 commentaires
Voir également
Catégories
En savoir plus sur Convert Image Type dans Help Center et File Exchange
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!



