Hlavní navigace

OpenGL Imaging Subset (9)

Pavel Tišnovský

V předposlední části seriálu pojednávajícího o OpenGL Imaging Subsetu si popíšeme práci s minmax tabulkami, pomocí nichž je možné zjistit minimální a maximální hodnoty barvových složek pixelů zapisovaných do framebufferu. Tyto hodnoty lze použít, podobně jako hodnoty ukládané do histogramu, například ke kalibraci obrazu nebo pro jednoduché prahování. Oproti práci s histogramem je však práce s minmax tabulkami velmi jednoduchá a rychlá.

Obsah

Tabulka s hodnotami minim a maxim
Vytvoření minmax tabulky
Přečtení hodnot z minmax tabulky
Vymazání hodnot z minmax tabulky
Získání parametrů vytvořených tabulek
Povolení a zákaz používání minmax tabulek
Pokračování
Seznam funkcí OpenGL a OpenGL Imaging Subsetu zmíněných v této části
Nové funkce OpenGL Imaging Subsetu popsané v této části
Demonstrační příklady
Zkomprimovaný článek s přílohami

Tabulka s hodnotami minim a maxim

V předcházející části tohoto seriálu jsme si popsali způsob práce s histogramem. Ten představuje základní nástroj používaný při téměř libovolném zpracování rastrového obrazu. Někdy se však může jednat o nástroj příliš složitý – příkladem může být detekce příliš světlého či tmavého obrazu.

Další statistickou informací o obraze jsou minimální a maximální hodnoty barvových složek jednotlivých pixelů. Ty se mohou použít například pro úpravu jasu nebo kontrastu vykreslovaného obrázku. Minima a maxima lze sice zjistit přímo z histogramu, dále uvedené funkce jsou však jednodušší na použití a současně rychlejší a přesnější, protože v tabulce histogramu jsou samozřejmě uložené pouze četnosti indexů, tj. zaokrouhlených hodnot barvových složek. V tabulkách minim a maxim mohou být uloženy i hodnoty v pohyblivé řádové čárce.

Pro uložení minimálních a maximálních hodnot barvových složek obrazu jsou v paměti grafického akcelerátoru vytvořeny velmi malé tabulky, z nichž každá obsahuje pouze dvě položky. Tyto tabulky se nazývají minmax tabulky. Pro každou barvovou složku R, G nebo B může být vytvořena jedna minmax tabulka.

Minmax tabulky lze vytvořit pouze při práci s rastrovým obrazem, který je přenášen do framebufferu pracujícího v režimu RGB nebo RGBA, samotné pixely však mohou být uloženy v jiném formátu. Pro index-color (paletové) režimy není operace s minmax tabulkami definována – také by neměla žádný rozumný smysl.

Umístění minmax tabulek ve vykreslovacím řetězci je ukázáno na prvním obrázku, z něhož je patrné, že se zápis do minmax tabulek provádí až těsně před závěrečným ořezáním hodnot barvových složek před zápisem do framebufferu.

Hodnota každé barvové složky pixelu nebo jeho světlosti je porovnána s minimální a maximální hodnotou uloženou v minmax tabulce. Pokud je aktuální hodnota menší než hodnota uložená v minmax tabulce, přepíše se v tabulce hodnota minima, pokud je aktuální hodnota větší než ta v tabulce, přepíše se v tabulce hodnota maxima. Důležité je, že každá barvová hodnota pixelu se zpracovává samostatně, takže například čistě zelený pixel může přepsat minimální hodnotu modré a červené a současně maximální hodnotu zelené složky.

Umístění minmax tabulek ve vykreslovacím řetězci
Obrázek 1: Umístění minmax tabulek ve vykreslovacím řetězci

Vytvoření minmax tabulky

Před použitím minmax tabulek je nutné minmax tabulky vytvořit. To se provede příkazem:

void glMinmax(
    GLenum    target,
    GLenum    internalFormat,
    GLboolean sink
);

Význam argumentů funkce glMinmax():

  • V argumentu target musí být v současné verzi OpenGL Imaging Subsetu vždy předána hodnota GL_MINMAX – viz poznámku uvedenou níže.
  • Argumentem internalFormat se specifikuje vnitřní formát položek ukládaných do minmax tabulky. Tento argument může nabývat hodnot stejných jako u funkce glTexImage2D(), jsou však povoleny i další hodnoty, zejména GL_INTENSITY, GL_INTENSITY4, GL_INTENSITY8 a GL_INTENSITY16. Patrně nejpoužívanější je formát GL_RGB.
  • Pokud je hodnota argumentu sink nastavena na GL_TRUE, jsou pixely procházející vykreslovacím řetězcem po testu s minimální a maximální hodnotou odstraněny z dalšího zpracování. Pokud je však hodnota tohoto argumentu nastavena na GL_FALSE, jsou pixely po průchodu blokem minmax zapsány do framebufferu, protože vytvoření minmax tabulky je předposlední operací, která se před zápisem do framebufferu provádí.

Počet položek ukládaných do minmax tabulky není potřeba zadávat, protože je vždy nastaven pouze na dvě hodnoty – minimální a maximální.

Poznámka: Jak jste si již patrně všimli u dříve popsaných funkcí OpenGL Imaging Subsetu, jsou v prvních argumentech funkcí vždy předány konstantní hodnoty, které jsou vlastně zbytečné, protože prováděná operace je sama dostatečně specifikována názvem funkce. Příkladem může být právě funkce glMinmax(), v jejímž prvním argumentu se předává hodnota GL_MINMAX. V budoucnu se však počítá s dalším rozšířením funkčnosti OpenGL Imaging Subsetu, kde budou například minmax tabulky umístěny na několika místech vykreslovacího řetězce. Proto je nutné minmax tabulky i další objekty (histogramy, filtry apod.) nějakým způsobem pojmenovat, k čemuž slouží právě první parametry funkcí. Vždy je dobré si otestovat správnost zadání hodnot argumentů pomocí funkce glGetError(), která v případě špatně zadaných hodnot vrací hodnotu GL_INVALID_ENUM.

Přečtení hodnot z minmax tabulky

Po naplnění minmax tabulky, které se provede například po vykreslení rastrového obrazu pomocí známé funkce glDrawPixels() (viz článek OpenGL IX a OpenGL X), je možné načíst minimální a maximální přenášené hodnoty pomocí příkazu:

void glGetMinmax(
    GLenum    target,
    GLboolean reset,
    GLenum    format,
    GLenum    types,
    GLvoid    *values
);

Význam jednotlivých argumentů funkce glGetMinmax():

  • V argumentu target musí být v současné verzi Imaging Subsetu zapsána hodnota GL_MINMAX (jak vidíme, opět platí informace uvedené v poznámce u předchozího odstavce).
  • Argument reset může obsahovat buď hodnotu GL_TRUE, nebo GL_FALSE. Touto hodnotou je specifikováno, zda se mají hodnoty z minmax tabulky po přečtení vynulovat (resp. nastavit na nedefinovanou hodnotu), nebo zda se mají ponechat hodnoty stávající. To se hodí při zjišťování statistických údajů o skupině obrázků.
  • V argumentu format je možné specifikovat, v jakém formátu se mají hodnoty z minmax tabulky přečíst. Příklady používaných formátů:
    GL_RED – minmax hodnoty červené barvové složky
    GL_GREEN – minmax hodnoty zelené barvové složky
    GL_BLUE – minmax hodnoty modré barvové složky
    GL_ALPHA – minmax hodnoty alfa složky
    GL_RGB – společné minmax hodnoty barvových složek R, G a B uložené v tomto pořadí
    GL_BGR – společné minmax hodnoty barvových složek R, G a B uložené v opačném pořadí
    GL_RGBA – společné minmax hodnoty barvových složek R, G, B a A
    GL_LUMINANCE – minmax hodnoty luminance, tj. světlosti pixelů
    GL_LUMINANCE_AL­PHA – společné minmax hodnoty luminance a průhlednosti A
  • V argumentu type je uveden datový typ barvových složek. V případě, že se interní formát minmax tabulky neshoduje se zadaným typem, je provedena automatická konverze. Tento argument může nabývat stejných hodnot jako u funkce glReadPixels() a glGetHistogram(), tj.
    GL_UNSIGNED_BYTE,
    GL_BYTE,
    GL_BITMAP,
    GL_UNSIGNED_SHOR­T,
    GL_SHORT,
    GL_UNSIGNED_INT,
    GL_INT,
    GL_FLOAT,
    GL_UNSIGNED_BY­TE3_3_2,
    GL_UNSIGNED_BY­TE2_3_3_REV,
    GL_UNSIGNED_SHOR­T5_6_5,
    GL_UNSIGNED_SHOR­T5_6_5_REV,
    GL_UNSIGNED_SHOR­T4_4_4_4,
    GL_UNSIGNED_SHOR­T4_4_4_4_REV,
    GL_UNSIGNED_SHOR­T5_5_5_1,
    GL_UNSIGNED_SHOR­T1_5_5_5_REV,
    GL_UNSIGNED_IN­T8_8_8_8,
    GL_UNSIGNED_IN­T8_8_8_8_REV,
    GL_UNSIGNED_IN­T10_10_10_2 nebo
    GL_UNSIGNED_IN­T2_10_10_10_REV
  • Argument values musí obsahovat ukazatel na oblast paměti, do které se zapíšou minimální a maximální hodnoty. Typ hodnot je specifikovaný ve výše uvedených argumentech.

Vymazání hodnot z minmax tabulky

Vymazání hodnot z minmax tabulky je velmi jednoduché. Stačí zavolat funkci:

void glResetMinmax(
    GLenum target
);

s parametrem GL_MINMAX. Stejnou operaci provede i příkaz glGetMinmax() s argumentem reset nastaveným na hodnotuGL_TRUE.

Získání parametrů vytvořených tabulek

Parametry již zadaných minmax tabulek je možné zpětně získat pomocí dvou operací, které se liší pouze typem návratových hodnot:

void glGetMinmaxParameterfv(
    GLenum  target,
    GLenum  pname,
    GLfloat *params
);

void glGetMinmaxParameteriv(
    GLenum target,
    GLenum pname,
    GLint  *params
);

V argumentu target musí být opět předána hodnota GL_MINMAX. Do argumentu pname se zadává jméno parametru, který potřebujeme zjistit. Jedná se například o typ minmax tabulek apod. V argumentu params musí být ukazatel na oblast paměti, do které se argument uloží. Alokaci této paměti je nutné provést přímo ve vytvářené aplikaci.

Povolení a zákaz používání minmax tabulek

Zápis barvových hodnot pixelů do minmax tabulek lze jednoduše povolit pomocí příkazu:

void glEnable(
    GL_MINMAX
);

Opětovný zákaz se provede příkazem:

void glDisable(
    GL_MINMAX
);

Při inicializaci OpenGL Imaging Subsetu je zápis do minmax tabulek implicitně zakázán.

Pokračování

Další, už závěrečný díl seriálu o OpenGL Imaging Subsetu bude věnován soupisu všech témat a demonstračních příkladů uvedených v předchozích částech. Také si nastíníme zaměření dalších seriálů o programování multiplatformní počítačové grafiky.

Seznam funkcí OpenGL a OpenGL Imaging Subsetu zmíněných v této části

glTexImage2D()
glDrawPixels()
glReadPixels()
glGetHistogram()
glEnable()
glDisable()
 

Nové funkce OpenGL Imaging Subsetu popsané v této části

glMinmax()
glGetMinmax()
glResetMinmax()
glGetMinmaxPa­rameteriv()
glGetMinmaxPa­rameterfv()
 

Demonstrační příklady

Po přeložení a spuštění prvního demonstračního příkladu se načte z externího souboru lena.tga rastrový obrázek, který se posléze zobrazí pomocí funkce glDrawPixels() do okna aplikace. Po vykreslení rastrového obrázku se přečte a vykreslí i histogram (bližší popis je uveden v předcházející části) a vypíšou se minimální a maximální hodnoty z minmax tabulky. Hodnoty jsou vypsány pro každou barvovou složku zvlášť. Histogram je zobrazen pouze pro světlosti pixelů, podobně jako v demonstračním příkladu (8.1).

Zdrojový kód prvního demonstračního příkladu je dostupný zde, HTML verze se zvýrazněním syntaxe zde.

Screenshot prvního příkladu se zobrazeným histogramem a hodnotami  přečtenými z minmax tabulky
Obrázek 1: Screenshot prvního příkladu se zobrazeným histogramem a hodnotami přečtenými z minmax tabulky

Při přeložení a následném spuštění druhého demonstračního příkladu se opět načte z externího souboru lena.tga rastrový obrázek, který se posléze zobrazí pomocí funkce glDrawPixels() do okna aplikace. Složky v barvové paletě obrázku jsou nastaveny tak, že provádí gamma korekci s exponentem větším než 1. Aplikací barvové palety na vykreslovaný obrázek se změní i hodnoty ukládané do minmax tabulky. Pomocí klávesy P se povoluje a zakazuje použití barvové palety, což se projeví i na zobrazovaných hodnotách z minmax tabulky.

Zdrojový kód druhého demonstračního příkladu je dostupný zde, HTML verze se zvýrazněním syntaxe zde.

Screenshot druhého příkladu s minmax tabulkou ovlivněnou gamma korekcí
Obrázek 2: Screenshot druhého příkladu s minmax tabulkou ovlivněnou gamma korekcí

Pro spuštění demonstračních příkladů je nutné mít stažený i původní obrázek Leny, který pro jistotu opět přikládám i do zkomprimované verze článku, i když je totožný s obrázkem uvedeným v předchozích dílech.

Zkomprimovaný článek s přílohami

Zkomprimovaná verze tohoto článku spolu s demonstračními příklady a obrázky je umístěna zde.

Našli jste v článku chybu?

28. 4. 2004 8:20

Pavel Tišnovský (neregistrovaný)

ok, zkusim neco sesmolit :-)

27. 4. 2004 19:08

Radim Kolar (neregistrovaný)

objednavam u autora vyrobu dilu o multi layer texturach.

DigiZone.cz: TV Philips a Android verze 6.0

TV Philips a Android verze 6.0

Lupa.cz: Kdo pochopí vtip, může jít do ČT vyvíjet weby

Kdo pochopí vtip, může jít do ČT vyvíjet weby

Podnikatel.cz: Změny v cestovních náhradách 2017

Změny v cestovních náhradách 2017

120na80.cz: 5 nejčastějších mýtů o kondomech

5 nejčastějších mýtů o kondomech

Podnikatel.cz: K EET. Štamgast už peníze na stole nenechá

K EET. Štamgast už peníze na stole nenechá

Podnikatel.cz: Udávání kvůli EET začalo

Udávání kvůli EET začalo

120na80.cz: Horní cesty dýchací. Zkuste fytofarmaka

Horní cesty dýchací. Zkuste fytofarmaka

Měšec.cz: Kdy vám stát dá na stěhování 50 000 Kč?

Kdy vám stát dá na stěhování 50 000 Kč?

Vitalia.cz: Spor o mortadelu: podle Lidlu falšovaná nebyla

Spor o mortadelu: podle Lidlu falšovaná nebyla

Vitalia.cz: Jmenuje se Janina a žije bez cukru

Jmenuje se Janina a žije bez cukru

Vitalia.cz: Paštiky plné masa ho zatím neuživí

Paštiky plné masa ho zatím neuživí

Lupa.cz: Co se dá měřit přes Internet věcí

Co se dá měřit přes Internet věcí

Vitalia.cz: Pamlsková vyhláška bude platit jen na základkách

Pamlsková vyhláška bude platit jen na základkách

120na80.cz: Co všechno ovlivňuje ženskou plodnost?

Co všechno ovlivňuje ženskou plodnost?

Měšec.cz: U levneELEKTRO.cz už reklamaci nevyřídíte

U levneELEKTRO.cz už reklamaci nevyřídíte

Vitalia.cz: Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Podnikatel.cz: Podnikatelům dorazí varování od BSA

Podnikatelům dorazí varování od BSA

Vitalia.cz: Taky věříte na pravidlo 5 sekund?

Taky věříte na pravidlo 5 sekund?

DigiZone.cz: Rádio Šlágr má licenci pro digi vysílání

Rádio Šlágr má licenci pro digi vysílání

Vitalia.cz: Jsou čajové sáčky toxické?

Jsou čajové sáčky toxické?