How to normalize two images which have different lighting conditions?

조회 수: 33 (최근 30일)
mahendra kumar
mahendra kumar 2012년 4월 12일
댓글: Pietro Ibba 2021년 2월 10일
how to normalize two images with different lighting conditions

채택된 답변

Geoff
Geoff 2012년 4월 12일
Histogram normalisation can work quite well in some cases.
First, you take a histogram of your reference image (where each bucket is a count of pixel value). For colour, you can do one histogram per channel.
Now, for successive images, you are going to try to match their histograms to your reference.
Let's say your reference histogram is an array R, which is 256-elements long (one for each intensity 0..255), and your new frame's histogram is H.
If you plot these two profiles, you'll possibly see they have a different shape. Here's a contrived example using two completely different scenes from your MatLab demos folder...
Rim = importdata('street1.jpg');
Him = importdata('street2.jpg');
R = histc( reshape(Rim, size(Rim,1)*size(Rim,2), []), 0:255 );
H = histc( reshape(Him, size(Him,1)*size(Him,2), []), 0:255 );
clf;
subplot(2,1,1); plot(R);
subplot(2,1,2); plot(H);
What you want to do is remap your pixel intensities so that they roughly fill the buckets in the same distribution as the reference. Think of having the cumulative sum of intensities at any point in H being the same as the cumulative sum of intensities at some other point in R. You want to find how we map an intensity in H to R.
I suppose in MatLab this is pretty easy. There might even be a MatLab function for it, but I don't know one so here goes.
Rc = cumsum(R);
Hc = cumsum(H);
Now, for each index h into Hc, your remapped pixel value is the index r at which Rc first exceeds Hc(h). MatLab can do this in a couple of lines:
Hmap = arrayfun( @(val) find(Rc >= val, 1), Hc );
Hadj = uint8(Hmap(Him(:,:,1)+1)-1);
Compute the histogram for Hadj to confirm that it lines up with Rim.
As for a version of this that can do all channels at the same time, maybe that's a fun exercise, but I don't see a problem with keeping it conceptually simple:
function [Hadj] = HistNorm( Rim, Him, chan )
if nargin > 2
R = histc(reshape(Rim(:,:,chan),1,[]), 0:255);
H = histc(reshape(Him(:,:,chan),1,[]), 0:255);
Rc = cumsum(R);
Hc = cumsum(H);
Hmap = arrayfun( @(val) find(Rc >= val, 1), Hc );
Hadj = uint8(Hmap(Him(:,:,chan)+1)-1);
else
Hadj = uint8(zeros(size(Him)));
for c = 1:3
Hadj(:,:,c) = HistNorm( Rim, Him, c );
end
end
end
Usage:
Hadj = HistNorm(Rim,Him);
image(Hadj);
With my example images, this gives a lot of rubbishy colour artifacts, but that's because the scenes are totally different. You'll see why if you plot the histogram of Hadj using my first section of code. If you have a scene that doesn't tend to change much, this approach works okay. What I've described is really simplistic. You can get smoother results if you choose the nearest bucket to each cumulative sum.
But the benefit of simplicity is it's fast. I used this approach to do automatic irising and gain control on four cameras running at 230fps with no measurable performance hit.
Give it a go. Geez, I even gave you the code =)
  댓글 수: 2
Pietro Ibba
Pietro Ibba 2021년 2월 10일
Thank you that is excactly what I was looking for, great work!

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Giorgio
Giorgio 2015년 8월 31일
Great answer! Ty.

카테고리

Help CenterFile Exchange에서 Display Point Clouds에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by