델파이/델파이관련

Graphic32 Contrast, Brightness

지병철 2014. 4. 29. 22:52

Here is one of the ways to get there:


var
F: Single;
I, V: Integer;
begin
for I := 0 to 255 do
begin
F := I / 255; // Scale to 0..1 range

F := Power(F, GAMMA); // Gamma
F := (F - 0.5) * (1 + CONTRAST) + 0.5; // Contrast
F := F + BRIGHTNESS; // Brightness

V := Round(F * 255); // Scale to 0..255 range

if V < 0 then V := 0
else if V > 255 then V := 255; // Clip to 0..255 range

LUT[I] := V;
end;
end;

If you use sliders/scroll bars or something similar to set
gamma/brightness/contrast values you pretty flexible on choosing
particular ranges.

Normally, you will want to have three sliders to set all three values:

Gamma:
a slider with -100...100 range;
GAMMA := Power(10, Slider.Position / 200);

Contrast:
a slider with -100...100 range;
CONTRAST := Slider.Position / 100;
or
CONTRAST := Power(10, Slider.Position / 100);

Brightness:
a slider with -100...100 range;
BRIGHTNESS := Slider.Position / 100;

You have lots of choices on selecting mapping functions and ranges
here, mostly depending on your particular application.

As for simple contrast stretching, as long as you know "white" and "black"
levels, building the LUT should be quite straightforward,
I'll give a slightly more advanced example here.

Suppose you have three levels for input image IN_LO, IN_MID and IN_HI and
you want to create a LUT whith the mapping:
IN_LO -> OUT_LO
IN_MID -> (OUT_LO + OUT_HI) / 2
IN_HI -> OUT_HI

(I've attached an image which might be a bit more explanatory)
This can be done pretty easily as well:

procedure BuildLUT(var LUT: TLUT8);
var
L, M, H, Lo, Hi: Single;
I: Integer;

function F(X: Single): Integer;
var
R: Single;
begin
if X < L then R := 0
else if X < M then R := (X - L) / 2 / (M - L)
else if X < H then R := (X - M) / 2 / (H - M) + 0.5
else R := 1;
R := Lo + R * (Hi - Lo);
Result := Round(R);
if Result < 0 then Result := 0
else if Result > 255 then Result := 255;
end;

begin
L := IN_LO / 255;
M := IN_MID / 255;
H := IN_HI / 255;
Lo := OUT_LO;
Hi := OUT_HI;
for I := 0 to 255 do LUT[I] := F(I / 255);
end;


Good luck,

Alex