Úpravy obrazu

Kurz počítačové grafiky

Autor: Jiří Hnídek / jiri.hnidek@tul.cz

Omezování barevného prostoru

Snahou tohoto procesu je dosáhnout podobného obrazového vjemu při omezení počtu barev v obraze.

  • Použití barevné palety s omezenou velikostí
  • Filtry v grafických programech
  • Barevný i černobílý tisk

Obecně platí:

$$ V_{in} -> V_{out}; V_{in} \in \langle 0, s \rangle; \quad V_{out} \in \langle 0, t \rangle; t \leq s $$

RGB na stupně šedi

Existuje několik metod, které jsou vhodné pro různé případy.

RGB na stupně šedi (YUV)

Formáty splňující BT.601

$$ Y = 0.299 R + 0.587 G + 0.114 B $$

RGB na stupně šedi (Y'IQ)

Formáty splňující BT.709

$$ Y = 0.2126 R + 0.7152 G + 0.0722 B $$

RGB na stupně šedi (HSV)

$$ V = \max(R, G, B) $$

Omezení barevného prostoru černobílých obrázků

Nejprve si ukážeme omezení obrázků, které jsou v šedotónové stupnici na obrázky, které obsahují pouze černé a bílé body.

Příklady jednotlivých metod

Prahování

Základní jednoduchá metoda vhodná například pro vytváření jednoduché masky.


for V_in in pixels.values():
	if V_in > threshold:
		V_out = max
	else:
		V_out = min

Náhodný rozptyl

Výsledný obrázek více připomíná výslednou předlohu, ale je zatížen velkým šumem.


for V_in in pixels.values():
	if V_in > random(min, max):
		V_out = max
	else:
		V_out = min

Maticový rozptyl

  • Tato metoda se stále používá v tiskárnách.
  • Vstupní hodnota je nahrazena odpovídající maticí.
  • Základní metoda násobně zvětšuje velikost obrázku podle velikosti použité matice.
  • Způsob generování matice se liší podle použití (tisk/monitor).

Algoritmus nezvětšujícího maticového rozptylu

Vstupní hodnoty i hodnoty v matici k.M musí být ve stejném rozsahu.


for pixel in pixels:
	V_in = pixel.value
	x = pixel.x
	y = pixel.y
	if V_in > k*M[x mod n, y mod n]:
		V_out = max
	else:
		V_out = min

Matice vhodná pro displeje

Matice je čtverocvá a její řád je vždy mocnou 2. Lze ji generovat rekurzivně pomocí:

$$ M_{(2n)} = \begin{bmatrix} 4M_{(n)} & 4M_{(n)} + 3J_{(n)} \\ 4M_{(n)} + 2J_{(n)} & 4M_{(n)} + J_{(n)} \\ \end{bmatrix} $$

kde $J_{(n)}$ čtvercová matici obsahující samé jedničky a $M_{(1)}$ je jednoprvková matice obsahující nulu.

Příklady matice pro displeje

$$ M_{2} = \begin{bmatrix} 0 & 3 \\ 2 & 1 \\ \end{bmatrix} $$

$$ M_{4} = \begin{bmatrix} 0 & 12 & 3 & 15 \\ 8 & 4 & 11 & 7 \\ 2 & 14 & 1 & 13 \\ 10 & 6 & 9 & 5 \\ \end{bmatrix} $$

Příklad matici pro tiskárny

Povšimňete si, že hodnoty narůstají v zavírající se spirále. Ve výsledku výsledný obrázek obsahuje puntíky.

$$ M_{4} = \begin{bmatrix} 1 & 5 & 9 & 2 \\ 8 & 12 & 13 & 6 \\ 4 & 15 & 14 & 10 \\ 0 & 11 & 7 & 3 \\ \end{bmatrix} $$

Distribuce zaokrouhlovací chyby

Tato metoda vychází z prahování a základní myšlenka algoritmu spočívá v tom, že chyba způsobená omezením vstupní barevné informace jednoho pixelu se distribuuje na dosud nezpracované okolní pixely.


for pixel in pixels:
	V_in = pixel.value
	x = pixel.x
	y = pixel.y
	if V_in > threshold:
		V_out = max
	else:
		V_out = min
	chyba = V_out - V_in
	pixels[x+1,y] += (7/16)*chyba
	pixels[x-1,y+1] += (3/16)*chyba
	pixels[x,y+1] += (5/16)*chyba
	pixels[x+1,y+1] += (1/16)*chyba

Disribuční matice

Distribuci zaokrouhlovací chyby lze použít i u maticového rozptylu.

$$ \frac{1}{16} \begin{bmatrix} 0 & 0 & 0 \\ 0 & 0 & 7 \\ 3 & 5 & 1 \end{bmatrix} $$

Příklad distribuce zaokrouhlovací chyby

Adaptivní barevná paleta

Barevná paleta je vytvořena, tak aby v ní byly zastoupeny nejčastěji se vyskytující barvy ve vstupním obrázku.

V algoritmu se využívá RGB krychle. Nejprve krychli naplníme body podle pixelů v daném obrázku a určíme krajní body ohraničující obálky:


x_min = y_min = z_min = 1.0
x_max = y_max = z_max = 0.0
for pixel in pixels:
	pnt.x, pnt.y, pnt.z = pixel.r, pixel.g, pixel.b
	x_min = (x_min > pnt.x) ? pnt.x : x_min
	y_min = ...
	x_max = (x_max < pnt.x) ? pnt.x : x_max
	y_max = ...
						

Následne určíme nejdelší stranu ohraničující obálky:


diff_x = x_max - x_min
diff_y = y_max - y_min
diff_z = z_max - y_min
						

Ohraničující obálku rozděl kolmým řezem na vybranou souřadnicovou osu. Místo řezu nutné volit tak, aby v obou nových částech byl přibližně stejný počet barev (lze předpočítat v předchozím kroku).

Následně aktualizujeme ohraničující obálky pro nové oblasti.

Dělení ohraničujících obálek se opakuje dokud celkový počet ohraničujících obálek není roven požadovanému počtu barev v barevné paletě.

Každé ohraničující obálce přiřaď barvu (medián, případně průměrná barva).

Geometrické transformace

Často se místo kartézské soustavy souřané používají homogenní souřadnice. Každý bod $P=[X, Y]$ má učitou váhu: w

Převod z homogenních souřadnice do kartézské soustavy souřadné:

$$ \begin{align} X' &= \frac{X}{w} \\ Y' &= \frac{Y}{w} \\ \end{align} $$

Transformační matice

Obecná transformační matice pro 2D transformace má následující tvar:

$$ \begin{bmatrix} X' \\ Y' \\ w' \\ \end{bmatrix} = \begin{bmatrix} m_{1,1} & m_{1,2} & m_{1,3} \\ m_{2,1} & m_{2,2} & m_{2,3} \\ m_{3,1} & m_{3,2} & m_{3,3} \\ \end{bmatrix} \begin{bmatrix} X \\ Y \\ w \\ \end{bmatrix} $$

Posun

Posun můžeme vyjádřit vektorem posunutí $(dx, dy)$ a maticovým násobením:

$$ \begin{bmatrix} X' \\ Y' \\ w' \\ \end{bmatrix} = \begin{bmatrix} 1 & 0 & dx \\ 0 & 1 & dy \\ 0 & 0 & 1 \\ \end{bmatrix} \begin{bmatrix} X \\ Y \\ w \\ \end{bmatrix} $$

Zvětšení/zmenšení

Zvětšení nebo zmenšení může být ve směru os různé a je vztažené vůči počátku soustavy souřadné:

$$ \begin{bmatrix} X' \\ Y' \\ w' \\ \end{bmatrix} = \begin{bmatrix} S_{x} & 0 & 0 \\ 0 & S_{y} & 0 \\ 0 & 0 & 1 \\ \end{bmatrix} \begin{bmatrix} X \\ Y \\ w \\ \end{bmatrix} $$

Zkosení

Zkosení ve směru jedné osy. V tomto případě ve směru osy x

$$ \begin{bmatrix} X' \\ Y' \\ w' \\ \end{bmatrix} = \begin{bmatrix} 1 & s_{x} & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \\ \end{bmatrix} \begin{bmatrix} X \\ Y \\ w \\ \end{bmatrix} $$

Otočení

Transformační matice pro otočení vůči počátku soustavy souřadné:

$$ \begin{bmatrix} X' \\ Y' \\ w' \\ \end{bmatrix} = \begin{bmatrix} \cos\alpha & -\sin\alpha & 0 \\ \sin\alpha & \cos\alpha & 0 \\ 0 & 0 & 1 \\ \end{bmatrix} \begin{bmatrix} X \\ Y \\ w \\ \end{bmatrix} $$

Skládání transformací

Transformační matice se skládají násobením matice, ale v opačném pořadí než se aplikují.

Příklad: Chceme-li vytvořit matici otočení o $\pi$ vůči bodu $P=[3,4]$, tak výslednou matici vytvoříme následovně:

$$ M = \begin{bmatrix} 1 & 0 & 3 \\ 0 & 1 & 4 \\ 0 & 0 & 1 \\ \end{bmatrix} \begin{bmatrix} \cos\pi & -\sin\pi & 0 \\ \sin\pi & \cos\pi & 0 \\ 0 & 0 & 1 \\ \end{bmatrix} \begin{bmatrix} 1 & 0 & -3 \\ 0 & 1 & -4 \\ 0 & 0 & 1 \\ \end{bmatrix} $$

Převzorkování

Lineární interpolace

V případě, že máme pouze 1D signál:

$$ y = \frac{y_{1} - y_{0}}{x_{1} - x_{0}}(x - x_{0}) + y_{0} $$

Bilineární interpolace

V případě, že máme 2D signál, tak hodnotu $v_{R}$ na souřadnici $R = [x_{R}, y_{R}]$ spočítáme pomocí 3 lineárních interpolací ze 4 okolních bodů $P_{i} = [x_{Pi}, y_{Pi}]$:

$$ \begin{align} v_{Q0} &= \frac{v_{P1} - v_{P0}}{x_{P1} - x_{P0}}(x - x_{P0}) + v_{P0} \\ v_{Q1} &= \frac{v_{P3} - v_{P2}}{x_{P3} - x_{P2}}(x - x_{P2}) + v_{P2} \\ v_{R} &= \frac{v_{Q1} - v_{Q0}}{y_{Q1} - y_{Q0}}(y - y_{Q0}) + v_{Q0} \\ \end{align} $$

Alfa míchání

Uvažujme, že všechny hodnoty jsou v rozsahu $\langle 0, 1\rangle$

$$ c = \alpha_{1} c_{1} + \alpha_{2} c_{2}; \quad \alpha_{1} + \alpha_{2} = 1 $$

Alpha Over

Rastr s nenulovým alfa kanálem (fg) umisťujeme na rastr, kde uvažujeme všechny pixely neprůhledné (bg).

$$ c = \alpha c_{fg} + (1 - \alpha) c_{bg} $$

Prolínačka

Mějme animovanou sekvenci (start) a tu chceme od času $t_{0}$ postupně prolnout s animovanou sekvencí (end) za dobu: $\Delta t$

$$ \begin{align} \alpha_{end} &= \frac{1}{\Delta t}(t - t_{0}) \\ \alpha_{start} &= 1 - \alpha_{end} \\ c &= \alpha_{end} c_{end} + \alpha_{start} c_{start} \end{align} $$

Klíčování

Uvažujeme klíčování na zelené pozadí a rozsah hodnot barevných kanálů je: $\langle 0, 1\rangle$. Dále si stanovíme hodnoty $\alpha_{min}$ a $\alpha_{max}$, které odlišují pozadí od popředí. Přechod mezi popředím a pozadím je pozvolný a určený alfa kanálem:

$$ \alpha = 1 - G - \max(R,B) $$

Pak je možné spočítat barvu jednotlivých barevných kanálů:

$$ c = \begin{cases} \alpha > \alpha_{max}; & c_{fg} \\ \alpha < \alpha_{min}; & c_{bg} \\ \alpha \in \langle \alpha_{min}, \alpha_{max} \rangle; & \alpha c_{fg} + (1 - \alpha) c_{bg} \end{cases} $$

Histogram

Histogram lze vytvořit vždy pouze pro jeden barevný kanál (jas, R, G, B, apod.). Hodnoty v daném kanále mohou nabývat pouze určitého počtu hodnot: N


for i in range(0, N):
	hist[i] = 0

for V_in in pixels.values():
	hist[V_in] += 1
					

Děkuji za pozornost