Change brightness in images
11 views (last 30 days)
Show older comments
Hey there,
i have a video where some frames are brighter than others and i want to set it all to the same level. I created a mask on a specific area of the images and converted the images to hsv, since the video is in rgb. Then i calculate the mean of the v-Channel in that specific area to get something like a brightness of every frame, and write that value in a matrix. After every image is processed I'm calculating the mean of all the images to get a brightness of the video in total. In a second loop I'm calculation the difference between the brightness of each image and the mean brightness of the complete video and add that difference to a new v-Channel and convert it back to rgb. The code is working fine but there doesn't seem to be any effect on the brightness of the frames. Does anyone have another idea?
imDouble = im2double(vidRGB);
imHSV = rgb2hsV(imDouble);
vChannel = imHSV(:,:,3);
vChannelMasked = vChannel .* maskLight;
lightnessMeanHSV(k,:) = sum(lChannelMasked, 'all')/nnz(vChannelMasked);
% Second Loop :
lightnessMeanHsvAll = mean2(lightnessMeanHSV);
imRGB = read(vid, iii);
imDouble = im2double(imRGB);
imHSV = rgb2hsv(imDouble);
hChannel = imHSV(:,:,1);
sChannel = imHSV(:,:,2);
vChannel = imHSV(:,:,3);
lightnessDiff = lightnessMeanHsvAll - lightnessMeanHSV(ii,:);
vChannelNew = vChannel + lightnessDiff;
imHsvNew = cat(3, hChannel, sChannel, vChannelNew);
imRgbNew = hsl2rgb(imHsvNew);
1 Comment
DGM
on 29 Mar 2021
Edited: DGM
on 29 Mar 2021
When you say there doesn't seem to be any effect, do you mean that it's insufficient for your requirements or is it actually a measured zero change? It's hard to tell what's going on when half the code is missing. For all I can tell, imRgbNew is never saved to anything. What's lChannelMasked? What are the dimensions of lightnessMeanHSV?
I also don't know why you're using hsl2rgb to back convert an hsv image.
Accepted Answer
DGM
on 29 Mar 2021
Edited: DGM
on 29 Mar 2021
Long story short, I don't know where your problem is, unless it's part of the missing code or the aforementioned questions.
I can reconstruct a basic test of the code with an animated gif:
inpict=gifread('sources/fluffball.gif'); % this isn't a standard function
inpict=inpict(:,:,1:3,:);
nframes=size(inpict,4);
lightnessMeanHSV=zeros([1 nframes]); % this is a vector now
for f=1:nframes
imDouble = im2double(inpict(:,:,:,f));
imHSV = rgb2hsv(imDouble); % rgb2hsV() isn't rgb2hsv(). idk how you got that to run
vChannelMasked = imHSV(:,:,3); % i'm not doing any masking for this test
lightnessMeanHSV(f) = mean(vChannelMasked(:));
end
outpict=zeros(size(inpict),'uint8');
for f=1:nframes
lightnessMeanHsvAll = mean2(lightnessMeanHSV);
imDouble = im2double(inpict(:,:,:,f));
imHSV = rgb2hsv(imDouble);
% don't bother splitting the array
lightnessDiff = lightnessMeanHsvAll - lightnessMeanHSV(f);
imHSV(:,:,3) = imHSV(:,:,3) + lightnessDiff;
imRgbNew = hsv2rgb(imHSV); % why were you using hsl2rgb?
outpict(:,:,:,f)=im2uint8(imRgbNew);
end
Of course, I don't know why anybody uses HSV for anything, especially for a brightness metric. The same thing can be done with luma instead:
inpict=gifread('sources/fluffball.gif');
inpict=inpict(:,:,1:3,:);
nframes=size(inpict,4);
Al=[0.299 0.587 0.114];
A=[0.299 0.587 0.114;-0.168735891647856 -0.331264108352144 0.5;0.5 -0.418687589158345 -0.0813124108416548];
Ai=[1 0 1.402;1 -0.344136286201022 -0.714136286201022;1 1.772 0];
meanluma=zeros([1 nframes]);
for f=1:nframes
imDouble = im2double(inpict(:,:,:,f));
Y = imapplymatrix(Al,imDouble);
% you'd have to implement your masking here too
meanluma(f) = mean(Y(:));
end
outpict=zeros(size(inpict),'uint8');
for f=1:nframes
globalmeanluma = mean(meanluma);
imDouble = im2double(inpict(:,:,:,f));
YPP = imapplymatrix(A,imDouble);
lumaDiff = globalmeanluma - meanluma(f);
YPP(:,:,1) = YPP(:,:,1) + lumaDiff;
imRgbNew = imapplymatrix(Ai,YPP);
outpict(:,:,:,f)=im2uint8(imRgbNew);
end
So what's the result? Well, both examples result in brightness adjustment; whether it's sufficient for any particular purpose, I don't know. The standard deviation of mean frame brightness is reduced. The HSV method sees a ~85% reduction, where the luma method sees a ~96% reduction.
The luma method unsurprisingly has less of a tendency to cause gross chroma distortion than the HSV method does. It's also about 40% faster. From left to right: original, HSV, luma

If the images don't show up, right-click > view image. This site is flaky sometimes.
2 Comments
More Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!