Hisztogram operációk

Hisztogramról általánosságban

A hisztogram megmutatja, hogy mely világosságértékekből mennyi található a fotónkon. Ez azt jelenti, hogy minden egyes pixelnek a világosságértékét kiszámítjuk és az azonos világosságértékhez tartozó pixelek számát összeadjuk, majd a kapott értéket egy grafikonon ábrázoljuk. Ha le akarjuk egyszerűsíteni a dolgot, akkor azt mondhatjuk, hogy bal oldalon a sötét tónusok (árnyékok), középen a középtónusok, jobb oldalon pedig a világos tónusok (csúcsfények) láthatóak a hisztogramon. Az általunk használt hisztogram vízszintesen 256 értéket tud megjeleníteni, melyben a 0 a legsötétebb (fekete), míg a 255 a legvilágosabb (fehér) értéket jelenti. A hisztogram rajzolásánál megszámoljuk, hogy hány pixel tartozik a 0 értékhez, majd ezt az értéket (a hisztogram függőleges tengelyének felosztását figyelembe véve) felrajzoljuk. Ezután megnézzük, hogy az 1 értékhez, hány pixel tartozik, majd a 2-höz és így tovább. Ebből előáll a világosságértékeket tartalmazó grafikon.

Hisztogram megjelenítése

A kód:
Megtalálható a mathlab függvényei között.
I = imread('kep.png');
A = squeeze(I(:,:,1));
imhist(A)

Példák:

Kindulási kép: Ez lett belőle:

Hisztogram széthúzás

Ha a hisztogram min és max között vesz fel csak 0-tól különböző értéket, ahol min > 0 és/vagy max < L-1 Ebben az esetben a hisztogramot széthúzhatjuk a teljes [0,L-1] intervallumra, így javítva a kép láthatóságát.

A kód: function[out] = histogram_stretch_grey(image)
image = double(image);
maxVal = max(max(image));
minVal = min(min(image));
diff = maxVal - minVal;
image = image-minVal;
image = image ./ diff .* 255;
out = uint8(image);
end

Példák:

Kindulási kép: Ez lett belőle:

Hisztogram kiegyenlítés

Azt az eljárást, ami a képet úgy transzformálja, hogy a világosságkódok egyenletes eloszlásúakká váljanak, hisztogram-kiegyenlítésnek nevezzük. Ez főként olyan képeknél hasznos, amelyek valamilyen ok miatt (például rossz megvilágítás) kevésbé kontrasztosak, azaz az intenzitásértékek az intenzitástartomány kisebb részére koncentrálódnak. Az eljárás lényegében analóg módon a folytonos és diszkrét térben egyaránt elvégezhető.
A kód:
Megtalálható a mathlab függvényei között.
hhisteq = video.HistogramEqualizer;
x = imread('tire.tif');
y = step(hhisteq, x);
imshow(x);
figure, imshow(y);

hhisteq = video.HistogramEqualizer;
x = imread('kolyok.png');
A = squeeze(x(:,:,1));
y = step(hhisteq, A);
figure, imshow(y);

Példák:

Kindulási kép: Ez lett belőle:

Kontraszt széthúzás

Nagyon hasonló a hisztogram széthúzáshoz, azonban itt a széthúzandó intervallum a legkisebb és legnagyobb intenzitású pontok által meghatározott intervallumon belül van. Speciális esetben, amikor a széthúzandó intervallumot a legkisebb és legnagyobb intenzitású pontok határozzák meg, hisztogram széthúzásról beszélünk.

A kód: function [array_out] = ContrastStretchNorm(array_in, low_thr, high_thr)
if nargin ==1, low_thr = 0.01; end
if nargin <3, high_thr = low_thr; end
abs_max = max(array_in(:));
abs_min = min(array_in(:));
if (abs_max == abs_min), array_out = array_in; return; end
array_in = array_in - abs_min;
marr = abs_max*(array_in == 0)+ array_in;
next_min = min(marr(:));
marr = (array_in < abs_max).* array_in;
next_max = max(marr(:));
imrange = next_max - next_min;
low_thr = low_thr * imrange;
high_thr = high_thr * imrange;
low_thr = next_min + low_thr;
high_thr = next_max - high_thr;
mask_lo = (array_in < low_thr);
array_in = mask_lo .*low_thr + (~mask_lo) .* array_in;
mask_hi = (array_in > high_thr);
array_in = mask_hi .*high_thr + (~mask_hi) .* array_in;
array_in = array_in - low_thr;
array_out = array_in ./(high_thr - low_thr);

Példák:

Kindulási kép: Ez lett belőle:

Lokális hisztogram-kiegyenlítés

A hisztogram kiegyenlítést a kép kisebb részein külön-külön végezzük, így elérhetjük, hogy a globálistól eltérően, a lokális homogén rész relatívan kisebb különbségeit kiemeljük.

A kód: A=imread('tire.tif');
figure,imshow(A);
Img=A;
M=10;
N=20;
mid_val=round((M*N)/2);
in=0;
for i=1:M
for j=1:N
in=in+1;
if(in==mid_val)
PadM=i-1;
PadN=j-1;
break;
end
end
end
B=padarray(A,[PadM,PadN]);
for i= 1:size(B,1)-((PadM*2)+1)
for j=1:size(B,2)-((PadN*2)+1)
cdf=zeros(256,1);
inc=1;
for x=1:M
for y=1:N
if(inc==mid_val)
ele=B(i+x-1,j+y-1)+1;
end
pos=B(i+x-1,j+y-1)+1;
cdf(pos)=cdf(pos)+1;
inc=inc+1;
end
end
for l=2:256
cdf(l)=cdf(l)+cdf(l-1);
end
Img(i,j)=round(cdf(ele)/(M*N)*255);
end
end
figure,imshow(Img);
figure,
subplot(2,1,1);title('Before Local Histogram Equalization'); imhist(A);
subplot(2,1,2);title('After Local Histogram Equalization'); imhist(Img);

Példák:

Kindulási kép: Ez lett belőle:

Érdekesség