Referenced White Balance of an image
5 次查看(过去 30 天)
显示 更早的评论
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 个评论
采纳的回答
DGM
2023-4-28
编辑:DGM
2023-4-29
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 个评论
DGM
2023-4-29
编辑:DGM
2023-4-30
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')
更多回答(1 个)
Image Analyst
2023-4-30
This is the best algorithm I've run across:
Sorry, I don't have code for it.
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Convert Image Type 的更多信息
产品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!



