Janusz Ganczarski
OpenGL
Przetwarzanie obrazów
Spis treści
Spis treści . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
1. Przetwarzanie obrazów . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
Transfer pikseli . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
Tablice kolorów . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
Tworzenie tablicy kolorów . . . . . . . . . . . . . . . . . . .
3
Skalowanie i przesunięcie składowych kolorów
. . . . . . . .
4
. . . . . . . . . . . . . . . .
5
Pobieranie tablicy kolorów . . . . . . . . . . . . . . . . . . .
5
Pobieranie właściwości tablic kolorów . . . . . . . . . . . . .
6
Filtry splotowe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
Definiowanie filtrów . . . . . . . . . . . . . . . . . . . . . . .
8
Właściwości filtrów . . . . . . . . . . . . . . . . . . . . . . .
10
Pobieranie maski filtra . . . . . . . . . . . . . . . . . . . . .
11
Pobieranie parametrów filtrów . . . . . . . . . . . . . . . . .
11
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
. . . . . . . . . . . . . . . . . . . . .
12
Pobieranie danych histogramu . . . . . . . . . . . . . . . . .
13
Pobieranie właściwości histogramu . . . . . . . . . . . . . . .
13
Zerowanie histogramu . . . . . . . . . . . . . . . . . . . . . .
14
Operacja minimum-maksimum . . . . . . . . . . . . . . . . . . . . .
14
Pobranie danych tablicy minimum-maksimum . . . . . . . .
14
Właściwości tablicy minimum-maksimum . . . . . . . . . . .
15
Zerowanie tablicy minimum-maksimum . . . . . . . . . . . .
15
Macierz koloru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
Program przykładowy . . . . . . . . . . . . . . . . . . . . . . . . . .
16
Plik filters.h . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
Plik przetwarzanie obrazow.cpp . . . . . . . . . . . . . . . .
26
Literatura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
38
1. Przetwarzanie obrazów
W wersji 1.2 biblioteki OpenGL dodano opcjonalny zbiór funkcji odpo-
wiedzialnych za przetwarzanie obrazów (ang. imaging subset). Funkcjonal-
ność tego podzbioru OpenGL obejmowały wcześniej rozszerzenia: EXT co-
lor table, EXT color subtable, EXT convolution, HP convolution bor-
der modes,
SGI color matrix,
EXT histogram,
EXT blend color,
EXT blend minmax i EXT blend subtract, przy czym dostępność całego pod-
zbioru określa jedno rozszerzenie ARB imaging. Oczywiście niedostępność
całego podzbioru przetwarzania obrazów nie wyklucza zaimplementowania
jednego lub kilku z powyższych rozszerzeń. Taka sytuacja występuje w przy-
padku wielu sterowników do kart graficznych z procesorem firmy ATI, któ-
re nie obsługują całego podzbioru obrazowania, ale wspierają rozszerzenie
SGI color matrix.
W wersji 1.4 OpenGL część funkcji z podzbioru przetwarzania obra-
zów przeniesiono do zasadniczej części biblioteki. Zmiany te zostały opisane
w odcinku kursu poświęconego mieszaniu kolorów.
Funkcjonalność podzbioru przetwarzania obrazów jest obszerna i obej-
muje m.in. operacje macierzowe na składowych kolorów, obsługę tablic kolo-
rów, jedno i dwuwymiarowe filtry splotowe oraz histogramy. Podzbiór prze-
twarzania obrazów zawiera także dodatkowe tryby transferu pikseli.
1.1. Transfer pikseli
Podzbiór przetwarzania obrazów wprowadza nowe tryby transferu pik-
seli określane przy użyciu funkcji glPixelTransferf i glPixelTransferi.
Dodatkowe tryby transferu pikseli związane są z filtrami splotowymi oraz
macierzą koloru i określają współczynniki skalowania (mnożenia) i przesu-
nięcia wartości składowych RGBA pikseli po wykonaniu tych operacji.
Dodatkowe tryby transferu pikseli określone są przez poniższe wartości
parametru param funkcji z grupy glPixelTransfer:
— GL POST CONVOLUTION RED SCALE - współczynnik skalowania składowych
R pikseli po obliczeniu filtra splotowego; wartość początkowa 1,
— GL POST CONVOLUTION GREEN SCALE - współczynnik skalowania składo-
wych G pikseli po obliczeniu filtra splotowego; wartość początkowa 1,
— GL POST CONVOLUTION BLUE SCALE - współczynnik skalowania składowych
B pikseli po obliczeniu filtra splotowego; wartość początkowa 1,
— GL POST CONVOLUTION ALPHA SCALE - współczynnik skalowania składo-
wych A pikseli po obliczeniu filtra splotowego; wartość początkowa 1,
— GL POST CONVOLUTION RED BIAS - wartość przesunięcia składowych R
pikseli po obliczeniu filtra splotowego; wartość początkowa 0,
1. Przetwarzanie obrazów
2
— GL POST CONVOLUTION GREEN BIAS - wartość przesunięcia składowych G
pikseli po obliczeniu filtra splotowego; wartość początkowa 0,
— GL POST CONVOLUTION BLUE BIAS - wartość przesunięcia składowych B
pikseli po obliczeniu filtra splotowego; wartość początkowa 0,
— GL POST CONVOLUTION ALPHA BIAS - współczynnik przesunięcia składo-
wych A pikseli po obliczeniu filtra splotowego; wartość początkowa 0,
— GL POST COLOR MATRIX RED SCALE - współczynnik skalowania składowych
R pikseli po przemnożeniu przez macierz koloru; wartość początkowa 1,
— GL POST COLOR MATRIX GREEN SCALE - współczynnik skalowania składo-
wych G pikseli po przemnożeniu przez macierz koloru; wartość począt-
kowa 1,
— GL POST COLOR MATRIX BLUE SCALE - współczynnik skalowania składo-
wych B pikseli po przemnożeniu przez macierz koloru; wartość począt-
kowa 1,
— GL POST COLOR MATRIX ALPHA SCALE - współczynnik skalowania składo-
wych A pikseli po przemnożeniu przez macierz koloru; wartość począt-
kowa 1,
— GL POST COLOR MATRIX RED BIAS - wartość przesunięcia składowych R
pikseli po przemnożeniu przez macierz koloru; wartość początkowa 0,
— GL POST COLOR MATRIX GREEN BIAS - wartość przesunięcia składowych
G pikseli po przemnożeniu przez macierz koloru; wartość początkowa 0,
— GL POST COLOR MATRIX BLUE BIAS - wartość przesunięcia składowych B
pikseli po przemnożeniu przez macierz koloru; wartość początkowa 0,
— GL POST COLOR MATRIX ALPHA BIAS - wartość przesunięcia składowych
A pikseli po przemnożeniu przez macierz koloru; wartość początkowa 0.
Wartości początkowe współczynników skalowania i wartości przesunięcia
składowych pikseli są tak dobrane, aby były neutralne dla wartości składo-
wych pikseli. Nie ma ograniczeń co do wartości przyjmowanych przez każdy
z powyższych współczynników.
Użycie filtrów splotowych lub macierzy koloru i związanych z nimi try-
bów transferu pikseli jest niezależne od opisanych wcześniej operacji na skła-
dowych pikseli z użyciem mapy (tablicy) przekształceń, określanych przy
użyciu funkcji z grupy glPixelMap.
1.2. Tablice kolorów
Tablice kolorów służą do zmiany wartości składowych pikseli i są w za-
sadzie działania podobne do tablic przekształceń map pikselowych. Tablice
kolorów są domyślnie wyłączone. Ich aktywacja wymaga wywołania funkcji
glEnable z parametrem GL COLOR TABLE.
1. Przetwarzanie obrazów
3
1.2.1. Tworzenie tablicy kolorów
Tablicę kolorów tworzy wywołanie funkcji:
void glColorTable (GLenum target,
GLenum internalformat,
GLsizei width,
GLenum format,
GLenum type,
const GLvoid *table)
Parametr target określa miejsce w potoku przekształceń fragmentów
obrazu (czyli elementów bufora obrazu wraz ze wszystkimi ich atrybutami)
i przyjmuje jedną z następujących wartości:
— GL COLOR TABLE - tablica kolorów zastosowana na początku potoku prze-
kształceń fragmentów,
— GL POST CONVOLUTION COLOR TABLE - tablica kolorów zastosowana po
operacjach filtra splotowego,
— GL POST COLOR MATRIX COLOR TABLE - tablica kolorów zastosowana po
operacjach macierzy koloru,
— GL PROXY COLOR TABLE - zastępcza (proxy) tablica kolorów zastosowana
na początku potoku przekształceń fragmentów,
— GL PROXY POST CONVOLUTION COLOR TABLE - zastępcza (proxy) tablica
kolorów zastosowana po operacjach filtra splotowego,
— GL PROXY POST COLOR MATRIX COLOR TABLE - zastępcza (proxy) tablica
kolorów zastosowana po operacjach macierzy koloru.
Wybór tablic zastępczych (proxy) faktycznie nie tworzy tablicy kolorów,
ale umożliwia sprawdzenie czy do utworzenia tablicy jest wystarczająca ilość
zasobów systemowych. Jest to mechanizm analogiczny do tekstur zastęp-
czych.
Parametr internalformat przyjmuje takie same wartości jak wewnętrz-
ne formaty tektury za wyjątkiem formatu podstawowego GL DEPTH COMPO-
NENT oraz związanych z nim formatów wewnętrznych GL DEPTH COMPONENT16,
GL DEPTH COMPONENT24 i GL DEPTH COMPONENT32.
Parametry format i type mają takie same znaczenie i przyjmują takie sa-
me wartości jak analogiczne parametry funkcji glDrawPixels, przy czym pa-
rametr format nie może przyjąć wartości GL COLOR INDEX, GL STENCIL IN-
DEX i GL DEPTH COMPONENT. Ponadto spośród wartości parametru type wy-
łączona jest stała GL BITMAP.
Właściwe dane tablicy kolorów wskazuje parametr table, a jej wielkość
określana jest w parametrze width i musi być potęgą liczby 2. Maksymal-
na obsługiwana wielkość tablicy kolorów zależy od implementacji biblioteki
OpenGL, ale nie może być mniejsza niż 32.
1. Przetwarzanie obrazów
4
Dane do tablicy kolorów można także pobrać z wybranego fragmentu
bufora kolorów. Służy do tego funkcja:
void glCopyColorTable (GLenum target,
GLenum internalformat,
GLint x, GLint y,
GLsizei width)
której parametr target, określający rodzaj tablicy kolorów, ograniczono do
trzech
wartości
(GL COLOR TABLE,
GL POST CONVOLUTION COLOR TABLE
i GL POST COLOR MATRIX COLOR TABLE), a parametry internalformat
i width przyjmują takie same wartości jak analogiczne parametry funkcji
glColorTable. Dwa ostatnie parametry x i y stanowią współrzędne położe-
nia pierwszego fragmentu obrazu, który zostanie pobrany jako tablica kolo-
rów. Kopiowanie tablicy kolorów odbywa się na takich samych zasadach jak
kopiowanie map pikselowych (funkcja glCopyPixels), przy czym oczywiście
wysokość kopiowanego fragmentu obrazu wynosi 1.
1.2.2. Skalowanie i przesunięcie składowych kolorów
Podobnie jak w przypadku transferu pikseli podzbiór przetwarzania ob-
razów biblioteki OpenGL umożliwia przy przekształcaniu pikseli z użyciem
tablicy kolorów określenie współczynników skalowania (mnożenia) i przesu-
nięcia wartości składowych RGBA pikseli. Wartości wynikowe składowych
kolorów pikseli są obcinane do przedziału [0, 1]. Ustawienie tych wartości
umożliwiają funkcje z grupy glColorTableParameter:
void glColorTableParameterfv (GLenum target,
GLenum pname,
const GLfloat *params)
void glColorTableParameteriv (GLenum target,
GLenum pname,
const GLint *params)
Parametr target określa rodzaj tablicy kolorów i może przyjąć jed-
ną z trzech wartości: GL COLOR TABLE, GL POST CONVOLUTION COLOR TABLE
i GL POST COLOR MATRIX COLOR TABLE.
Rodzaj modyfikowanego parametru określa pname, który przyjmuje jed-
ną z dwóch wartości:
— GL COLOR TABLE SCALE - współczynniki skalowania składowych pikseli
tablicy kolorów; wartości początkowe (1, 1, 1, 1),
— GL COLOR TABLE BIAS - wartości przesunięcia składowych pikseli tablicy
kolorów; wartości początkowe (0, 0, 0, 0).
Współczynniki skalowania i wartości przesunięcia składowych pikseli ta-
blicy kolorów umieszczane są w tablicy params, która musi zawierać ilość ele-
1. Przetwarzanie obrazów
5
mentów odpowiadającą ilości składowych elementów tablicy kolorów. Mak-
symalna wielkość obu tablic wynosi oczywiście cztery, a wartości domyślne
oby zestawów współczynników są neutralne dla wartości składowych pikseli.
1.2.3. Zmiana danych tablicy kolorów
Zmianę danych już istniejącej tablicy kolorów umożliwiają dwie funkcje.
Funkcja glColorSubTable:
void glColorSubTable (GLenum target,
GLsizei start,
GLsizei count,
GLenum format,
GLenum type,
const GLvoid *data)
pobiera dane zmienianych elementów tablicy kolorów z bufora przygotowa-
nego przez program (parametr data). Druga funkcja glCopyColorSubTable:
void glCopyColorSubTable (GLenum target,
GLsizei start,
GLint x, GLint y,
GLsizei width)
pobiera dane zmienianych elementów tablicy kolorów z bufora kolorów.
Zmiana elementów istniejącej tablicy kolorów nie wpływa na format we-
wnętrzny danych tablicy, stąd powyższe funkcje nie posiadają parametru
internalformat. Parametr target określa rodzaj tablicy kolorów i przyj-
muje jedną z trzech wartości: GL COLOR TABLE, GL POST CONVOLUTION CO-
LOR TABLE i GL POST COLOR MATRIX COLOR TABLE. Parametry format i type
funkcji glColorSubTable przyjmują takie same wartości jak analogiczne pa-
rametry funkcji glColorTable. Parametry x i y funkcji glCopyColorSub-
Table określają położenie pierwszego kopiowanego fragmentu bufora kolo-
rów. Zasady kopiowania danych z bufora kolorów są takie same jak w przy-
padku funkcji glCopyColorTable.
Pierwszy modyfikowany element tablicy kolorów określa wspólny dla obu
funkcji parametr start przy czym elementy tablicy numerowane są od zera.
Ilość zmienianych elementów tablicy wyznacza w funkcji glColorSubTable
parametr count, a w funkcji glCopyColorSubTable parametr width.
1.2.4. Pobieranie tablicy kolorów
Pobranie wybranej tablicy kolorów umożliwia funkcja glGetColorTable:
void glGetColorTable (GLenum target,
GLenum format,
1. Przetwarzanie obrazów
6
GLenum type,
GLvoid *table)
której parametry target, format i type mają takie same znaczenie jak ana-
logiczne parametry funkcji glColorTable. Wyjątkiem są zastępcze tablice
kolorów (proxy), z którymi nie są związane dane tablicy kolorów. Oczywi-
ście program musi zapewnić odpowiednią ilość miejsca na dane pobieranej
tablicy (parametr table).
1.2.5. Pobieranie właściwości tablic kolorów
Odczyt właściwości tablic kolorów umożliwiają funkcje z grupy glGetCo-
lorTableParameter:
void glGetColorTableParameterfv (GLenum target,
GLenum pname,
GLfloat *params)
void glGetColorTableParameteriv (GLenum target,
GLenum pname,
GLint *params)
Parametr target określa rodzaj tablicy kolorów, której właściwości po-
bieramy. Dopuszczalne są wszystkie rodzaje tablic kolorów, włączając w to
tablice zastępcze (proxy). Parametr pname wskazuje pobieraną właściwość
wybranej tablicy kolorów i przyjmuje jedną z poniższych wartości:
— GL COLOR TABLE BIAS - wartości przesunięcia składowych pikseli tablicy
kolorów; wartości początkowe (0, 0, 0, 0),
— GL COLOR TABLE SCALE - współczynniki skalowania składowych pikseli
tablicy kolorów; wartości początkowa (1, 1, 1, 1),
— GL COLOR TABLE FORMAT - format wewnętrzny tablicy kolorów; wartość
domyślna GL RGBA,
— GL COLOR TABLE WIDTH - ilość elementów zawartych w tablicy kolorów,
— GL COLOR TABLE RED SIZE - ilość bitów składających się na składową R
elementów tablicy kolorów,
— GL COLOR TABLE GREEN SIZE - ilość bitów składających się na składową
G elementów tablicy kolorów,
— GL COLOR TABLE BLUE SIZE - ilość bitów składających się na składową B
elementów tablicy kolorów,
— GL COLOR TABLE ALPHA SIZE - ilość bitów składających się na składową
A elementów tablicy kolorów,
— GL COLOR TABLE LUMINANCE SIZE - ilość bitów składających się na skła-
dową L elementów tablicy kolorów,
— GL COLOR TABLE INTENSITY SIZE - ilość bitów składających się na skła-
dową I elementów tablicy kolorów.
1. Przetwarzanie obrazów
7
1.3. Filtry splotowe
Filtracja to jedno z najważniejszych narzędzi w cyfrowym przetwarzaniu
obrazów. Zastosowanie odpowiednich filtrów pozwala na uzyskanie informa-
cji o obrazie, które nie są osiągalne w inny sposób.
Dostępne w bibliotece OpenGL filtry splotowe należą do najczęściej uży-
wanych filtrów. Splot oblicza nową wartość składowej piksela na podstawie
wartości składowych sąsiadujących pikseli. Każda ze składowych sąsiednich
pikseli wnosi swój udział w obliczeniu składowej nowego piksela w postaci
procentu swojej wartości - wagi. Wagi poszczególnych pikseli (składowych)
zapisywane są w postaci macierzy - maski splotu. Elementy maski splotu
nazywane są współczynnikami splotu.
Działanie filtra splotowego przeanalizujemy na przykładzie filtra z maską
o wymiarach 3 × 3. Są to typowe maski splotu filtrów dwuwymiarowych,
w przypadku których na wartość składowej piksela wpływa wartość skła-
dowych 8 sąsiednich pikseli. Maskę filtru najwygodniej opisać w postaci
macierzy:
f
−1,−1
f
0,−1
f
1,−1
f
−1,0
f
0,0
f
1,0
f
−1,1
f
0,1
f
1,1
Obliczenie wartości składowej piksela a
i,j
obrazu rozpoczynamy od po-
liczenia sumy iloczynów współczynników splotu przez wartości składowych
pikseli sąsiadujących z pikselem a
i,j
:
s = f
−1,−1
a
i−1,j−1
+ f
0,−1
a
i,j−1
+ f
1,−1
a
i+1,j−1
+
+f
−1,0
a
i−1,j
+ f
0,0
a
i,j
+ f
1,0
a
i+1,j
+
+f
−1,1
a
i−1,j+1
+ f
0,−1
a
i,j+1
+ f
1,1
a
i+1,j+1
Następnie należy dokonać normalizacji wartości składowej piksela co spro-
wadza się do podzielenia jej przez współczynnik normalizujący, czyli sumę
wszystkich współczynników splotu:
a
i,j
=
s
f
−1,−1
+ f
0,−1
+ f
1,−1
+ f
−1,0
+ f
0,0
+ f
1,0
+ f
−1,1
+ f
0,−1
+ f
1,1
Normalizacji nie przeprowadza się, jeżeli suma wartości współczynników
splotu wynosi 0.
Ważnym zagadnieniem związanym z filtrami splotu są warunki brzego-
we. Czytelnik z pewnością zauważy, że próba zastosowania przedstawionych
wyżej wzorów do pikseli znajdujących się na brzegu obrazu prowadzi do nie-
określonej sytuacji obliczeń na pikselach poza obrazem. Sytuacja ta stanie się
jeszcze bardziej widoczna, gdy maska filtra będzie miała większe rozmiary.
1. Przetwarzanie obrazów
8
Najczęstszym rozwiązaniem tego problemu jest pominięcie procesu fil-
tracji, dla tych pikseli obrazu, na których proces ten nie jest wykonalny.
Radykalnym (i w praktyce raczej niestosowanym) sposobem rozwiązania
opisanego problemu jest zmniejszenie wymiarów obrazu po filtracji. Za kom-
promisowe można uznać często stosowane w praktyce rozwiązanie polegające
na dodaniu do filtrowanego obrazu fałszywego brzegu, złożonego najczęściej
ze zduplikowanych pikseli brzegu obrazu.
1.3.1. Definiowanie filtrów
Poza przedstawionymi na wstępie filtrami dwuwymiarowymi bibliotek
OpenGL wspiera także filtry jednowymiarowe, które operują jedynie na
wierszach obrazu. Możliwe jest także zdefiniowanie maski splotu filtra dwu-
wymiarowego w postaci iloczynu dwóch masek filtrów jednowymiarowych:
−1
2
−1
(−1, 2, −1) =
1
−2
1
−2
4
−2
1
−2
1
Utworzenie filtra jednowymiarowego umożliwia funkcja:
void glConvolutionFilter1D (GLenum target,
GLenum internalformat,
GLsizei width,
GLenum format,
GLenum type,
const GLvoid *image)
Parametr target określa rodzaj tworzonego filtra jednowymiarowego ale
może przyjąć jedynie wartość GL CONVOLUTION 1D oznaczającą filtr splotowy.
Parametr internalformat przyjmuje takie same wartości jak wewnętrz-
ne formaty tektury za wyjątkiem formatu podstawowego GL DEPTH COMPO-
NENT oraz związanych z nim formatów wewnętrznych GL DEPTH COMPONENT16,
GL DEPTH COMPONENT24 i GL DEPTH COMPONENT32.
Parametry format i type mają takie same znaczenie i przyjmują takie sa-
me wartości jak analogiczne parametry funkcji glDrawPixels, przy czym pa-
rametr format nie może przyjąć wartości GL COLOR INDEX, GL STENCIL IN-
DEX i GL DEPTH COMPONENT. Ponadto spośród wartości parametru type wy-
łączona jest stała GL BITMAP.
Ilość elementów maski filtra określa parametr width. Maksymalny roz-
miar maski filtra jest zależny od implementacji (zmienna stanu GL MAX CON-
VOLUTION WIDTH) ale nie może być on mniejszy niż 3.
Ostatni parametr image zawiera oczywiście wskaźnik do tablicy z maską
filtra.
Utworzenie filtra dwuwymiarowego wymaga wywołania funkcji:
1. Przetwarzanie obrazów
9
void glConvolutionFilter2D (GLenum target,
GLenum internalformat,
GLsizei width,
GLsizei height,
GLenum format,
GLenum type,
const GLvoid *image)
W stosunku do poprzedniej funkcji parametr target może przyjąć je-
dynie wartość GL CONVOLUTION 1D (dwuwymiarowy filtr splotowy), a do-
datkowy parametr height określa oczywiście wysokość maski filtra. Mak-
symalna wysokość maski filtra jest zależna od implementacji (zmienna sta-
nu GL MAX CONVOLUTION HEIGHT) i podobnie jak jej szerokość nie może być
mniejsza od 3.
Utworzenie filtra z dwóch masek jednowymiarowych umożliwia funkcja:
void glSeparableFilter2D (GLenum target,
GLenum internalformat,
GLsizei width,
GLsizei height,
GLenum format,
GLenum type,
const GLvoid *row,
const GLvoid *column)
Parametr target określa rodzaj filtra i może przyjąć jedynie wartość
GL SEPARABLE 2D. Pionowa i pozioma maska filtra przekazywane są w para-
metrach row i column a ich wielkości określają parametry width i height.
Pozostałe parametry mają takie same znaczenie i podlegają takim samym
ograniczeniom jak analogiczne parametry funkcji glConvolutionFilter1D
i glConvolutionFilter2D.
Filtry splotowe są domyślnie wyłączone. Włączenie filtracji wymaga wy-
wołania funkcji glEnable z jednym z parametrów: GL CONVOLUTION 1D,
GL CONVOLUTION 2D lub GL SEPARABLE 2D.
Alternatywną metodą tworzenia filtrów jedno i dwuwymiarowych jest
pobranie maski filtra z bufora kolorów. Realizują to funkcje:
void glCopyConvolutionFilter1D (GLenum target,
GLenum internalformat,
GLint x, GLint y,
GLsizei width)
void glCopyConvolutionFilter2D (GLenum target,
GLenum internalformat,
GLint x, GLint y,
1. Przetwarzanie obrazów
10
GLsizei width,
GLsizei height)
których parametry target przyjmują wartości odpowiednio GL CONVOLU-
TION 1D lub GL CONVOLUTION 2D, a położenie i rozmiary kopiowanego frag-
mentu bufora obrazu określają parametry x, y, width i height. Kopiowanie
maski filtra odbywa się na takich samych zasadach jak kopiowanie map
pikselowych przy użyciu funkcji glCopyPixels). Tworzone w ten sposób
filtry mają maski w formacie GL RGBA (parametr format funkcji z grupy
glConvolutionFilter).
1.3.2. Właściwości filtrów
Regulację właściwości filtrów splotowych umożliwiają funkcje z grupy
glConvolutionParameter:
void glConvolutionParameterf (GLenum target,
GLenum pname,
const GLfloat *params)
void glConvolutionParameterfv (GLenum target,
GLenum pname,
const GLfloat *params)
void glConvolutionParameteri (GLenum target,
GLenum pname,
GLint params)
void glConvolutionParameteriv (GLenum target,
GLenum pname,
const GLint *params)
Parametr target określa rodzaj filtra, którego właściwości są modyfiko-
wane i przyjmuje jedną z trzech poznanych wartości: GL CONVOLUTION 1D,
GL CONVOLUTION 2D lub GL SEPARABLE 2D.
Parametr pname określa rodzaj modyfikowanej właściwości filtra sploto-
wego i przyjmuje jedną z poniższych wartości:
— GL CONVOLUTION BORDER MODE - sposób obsługi brzegu obrazu przez filtr;
możliwe działania to redukcja wymiarów obrazu o dwa piksele (stała
GL REDUCE), przyjęcie fikcyjnego koloru brzegu obrazu (stała GL CONS-
TANT BORDER), lub utworzenie fikcyjnego brzegu z pikseli brzegowych ob-
razu (stała GL REPLICATE BORDER); wartość domyślna to GL REDUCE,
— GL CONVOLUTION BORDER COLOR - składowe RGBA koloru brzegu obrazu
używane, gdy metodą obsługi brzegu obrazu jest GL CONSTANT BORDER;
domyślnie składowe koloru brzegu mają wartość (0, 0, 0, 0),
— GL CONVOLUTION FILTER SCALE - współczynniki skalowania (mnożenia)
wartości maski filtra; wartości domyślne (1, 1, 1, 1),
1. Przetwarzanie obrazów
11
— GL CONVOLUTION FILTER BIAS - wartości przesunięcia współczynników
maski filtra; wartości domyślne (0, 0, 0, 0).
Domyślne wartości współczynników skalowania i przesunięcia maski filtra
są dobrane w sposób neutralny dla działania filtra.
1.3.3. Pobieranie maski filtra
Pobranie maski filtra jedno lub dwuwymiarowego umożliwia funkcja:
void glGetConvolutionFilter (GLenum target,
GLenum format,
GLenum type,
GLvoid *image)
Parametr target oznacza rodzaj pobieranego filtra (wartość GL CONVO-
LUTION 1D lub GL CONVOLUTION 2D), a parametry format i type mają takie
same znaczenia jak analogiczne parametry funkcji z grupy glConvolution-
Filter. Maska filtra umieszczona jest w tablicy image, przy czym program
jest odpowiedzialny za odpowiednią jej wielkość.
Pobieranie maski filtra dwuwymiarowego określonego przez dwie maski
jednowymiarowe umożliwia funkcja:
void glGetSeparableFilter (GLenum target,
GLenum format,
GLenum type,
GLvoid *row,
GLvoid *column,
GLvoid *span)
której parametry target, format, type, row i column odpowiadają analo-
gicznym parametrom funkcji glSeparableFilter2D. Ostatni parametr span
nie jest używany.
1.3.4. Pobieranie parametrów filtrów
Pobieranie parametrów filtrów splotowych umożliwiają funkcje z grupy
glGetConvolutionParameter:
void glGetConvolutionParameterfv (GLenum target,
GLenum pname,
GLfloat *params)
void glGetConvolutionParameteriv (GLenum target,
GLenum pname,
GLint *params)
których parametry odpowiadają analogicznym parametrom funkcji z grupy
glConvolutionParameter.
1. Przetwarzanie obrazów
12
Dodatkowo parametr pname może przyjąć następujące wartości:
— GL CONVOLUTION FORMAT - format danych maski filtra,
— GL CONVOLUTION WIDTH - szerokość maski filtra,
— GL CONVOLUTION HEIGHT - wysokość maski filtra,
— GL MAX CONVOLUTION WIDTH - maksymalna szerokość maski filtra,
— GL MAX CONVOLUTION HEIGHT - maksymalna wysokość maski filtra.
1.4. Histogram
W statystyce histogramem nazywamy funkcję gęstości prawdopodobień-
stwa, która w przypadku obrazów cyfrowych histogram jest funkcją dyskret-
ną. Przykładowo histogram obrazu w odcieniach szarości wyznaczany jest
jako suma wszystkich pikseli o danej wartości odcienia szarości znormalizo-
waną (podzieloną) przez liczbę wszystkich pikseli.
1.4.1. Obliczanie histogramu
W bibliotece OpenGL do obliczania histogramu wykorzystywana jest
funkcja:
void glHistogram (GLenum target,
GLsizei width,
GLenum internalformat,
GLboolean sink)
Parametr target oznacza rodzaj docelowego histogramu. Dopuszczalne
są dwie wartości: GL HISTOGRAM - histogram właściwy i GL PROXY HISTOGRAM
- histogram zastępczy (proxy). Histogramy zastępcze przeznaczone są do
testu określającego czy tablica przechowująca dane histogramu pomieści się
w zasobach systemowych.
Parametr width oznacza ilość elementów w tablicy histogramu i musi być
potęgą liczby dwa. Maksymalna wielkość tablicy histogramu jest zależna od
implementacji, ale nie może być mniejsza niż 32.
Parametr internalformat określa wewnętrzny format tablicy z histogra-
mem i może przyjąć takie wartości jak wewnętrzne formaty tektury za wy-
jątkiem formatów podstawowych GL INTENSITY i GL DEPTH COMPONENT oraz
związanych z nimi formatów wewnętrznych: GL INTENSITY4, GL INTENSITY8,
GL INTENSITY12, GL INTENSITY16, GL DEPTH COMPONENT16, GL DEPTH COM-
PONENT24 i GL DEPTH COMPONENT32.
Ostatni parametr sink określa czy informacje o grupach pikseli mają być
dalej przekazywane do operacji minimum-maksimum (wartość GL FALSE)
czy też wykorzystane tylko do obliczenia histogramu (wartość GL TRUE).
Obliczanie histogramu jest domyślnie wyłączone. Aktywacja tych obli-
czeń wymaga wywołania funkcji glEnable z parametrem GL HISTOGRAM.
1. Przetwarzanie obrazów
13
1.4.2. Pobieranie danych histogramu
Po obliczeniu histogramu przez bibliotekę OpenGL trzeba pobrać jego
dane. Wymaga to wywołania funkcji:
void glGetHistogram (GLenum target,
GLboolean reset,
GLenum format,
GLenum type,
GLvoid *values)
Parametr target określa rodzaj histogramu i może przyjąć wyłącznie
wartość GL HISTOGRAM. Drugi parametr reset wskazuje, czy dane zgroma-
dzone w tablicy histogramu mają być wyzerowane po odczycie (GL TRUE),
czy też nie (GL FALSE).
Parametry format i type przyjmują takie same wartości jak odpowia-
dające im parametry funkcji z grupy glGetTexImage. Jedynym wyjątkiem
jest brak formatu GL DEPTH COMPONENT. Program musi oczywiście zapewnić
w tablicy values odpowiednią ilość miejsca na dane histogramu.
1.4.3. Pobieranie właściwości histogramu
Pobieranie wybranych właściwości histogramu umożliwiają funkcje z gru-
py glGetHistogramParameter:
void glGetHistogramParameterfv (GLenum target,
GLenum pname,
GLfloat *params)
void glGetHistogramParameteriv (GLenum target,
GLenum pname,
GLint *params)
Parametr target określa rodzaj histogramu i może przyjąć jedną z dwóch
wartości: GL HISTOGRAM - histogram właściwy i GL PROXY HISTOGRAM - hi-
stogram zastępczy (proxy).
Parametr pname określa rodzaj pobieranej właściwości histogramu i może
przyjąć jedną z wartości:
— GL HISTOGRAM WIDTH - ilość elementów w tablicy histogramu,
— GL HISTOGRAM FORMAT - wewnętrzny format elementów tablicy z histo-
gramem,
— GL HISTOGRAM RED SIZE - ilość bitów składowej R elementów tablicy hi-
stogramu,
— GL HISTOGRAM GREEN SIZE - ilość bitów składowej G elementów tablicy
histogramu,
— GL HISTOGRAM BLUE SIZE - ilość bitów składowej B elementów tablicy
histogramu,
1. Przetwarzanie obrazów
14
— GL HISTOGRAM ALPHA SIZE - ilość bitów składowej A elementów tablicy
histogramu,
— GL HISTOGRAM LUMINANCE SIZE - ilość bitów składowej L elementów ta-
blicy histogramu,
— GL HISTOGRAM SINK - znacznik przekazywania informacji o grupach pik-
seli.
1.4.4. Zerowanie histogramu
Zerowanie danych zawartych w tablicy histogramu realizuje funkcja:
void glResetHistogram (GLenum target)
której parametr target określający rodzaj histogramu może przyjąć wy-
łącznie wartość GL HISTOGRAM.
1.5. Operacja minimum-maksimum
Operacja minimum-maksimum oblicza minimalne i maksymalne wartości
składowych pikseli. Wykonanie tej operacji wymaga wywołania funkcji:
void glMinmax (GLenum target,
GLenum internalformat,
GLboolean sink)
Parametr target określa rodzaj wykonywanej operacji i może przyjąć
jedynie wartość GL MINMAX. Parametr internalformat określa wewnętrzny
format danych tablicy minimum-maksimum. Dopuszczalne są wszystkie we-
wnętrzne formaty tektury za wyjątkiem formatów podstawowych GL INTENS-
ITY i GL DEPTH COMPONENT oraz związanych z nimi formatów wewnętrz-
nych: GL INTENSITY4, GL INTENSITY8, GL INTENSITY12, GL INTENSITY16,
GL DEPTH COMPONENT16, GL DEPTH COMPONENT24 i GL DEPTH COMPONENT32.
Ostatni parametr sink określa czy informacje o grupach pikseli mają być
dalej przekazywane w potoku obrazowania (wartość GL FALSE) czy też wyko-
rzystane tylko do obliczenia tablicy minimum-maksimum (wartość GL TRUE).
Operacja minimum-maksimum jest domyślnie wyłączona. Jej aktywacja
wymaga wywołania funkcji glEnable z parametrem GL MINMAX.
1.5.1. Pobranie danych tablicy minimum-maksimum
Pobranie danych tablicy minimum-maksimum umożliwia funkcja:
void glGetMinmax (GLenum target,
GLboolean reset,
GLenum format,
GLenum type,
GLvoid *values)
1. Przetwarzanie obrazów
15
Parametr target określa rodzaj operacji i może przyjąć wyłącznie war-
tość GL MINMAX. Drugi parametr reset wskazuje, czy dane zgromadzone
w tablicy minimum-maksimum mają być wyzerowane po odczycie (GL TRUE),
czy też nie (GL FALSE).
Parametry format i type przyjmują takie same wartości jak odpowia-
dające im parametry funkcji z grupy glGetTexImage. Jedynym wyjątkiem
jest brak formatu GL DEPTH COMPONENT.
Tablica zwracana w parametrze values ma dwa elementy. Pierwszy za-
wiera minimalne wartości składowych pikseli, drugi maksymalne wartości
składowych pikseli.
1.5.2. Właściwości tablicy minimum-maksimum
Pobranie właściwości tablicy minimum-maksimum umożliwiają funkcje
z grupy glGetMinmaxParameter:
void glGetMinmaxParameterfv (GLenum target,
GLenum pname,
GLfloat *params)
void glGetMinmaxParameteriv (GLenum target,
GLenum pname,
GLint *params)
Parametr target określający rodzaj tablicy może przyjąć jedynie war-
tość GL MINMAX. Drugi parametr pname wskazuje rodzaj pobieranej właści-
wości tablicy i przyjmuje jedną z dwóch wartości:
— GL MINMAX FORMAT - format danych tablicy minimum-maksimum,
— GL MINMAX SINK - znacznik przekazywania informacji o grupach pikseli.
1.5.3. Zerowanie tablicy minimum-maksimum
Wyzerowanie danych tablicy minimum-maksimum wymaga wywołania
funkcji:
void glResetMinmax (GLenum target)
której parametr target może przyjąć wyłącznie wartość GL MINMAX.
1.6. Macierz koloru
Macierz koloru pozwala na wykonywanie operacji na składowych RGBA
kolorów, które są wówczas traktowane jak wektor. Wybór macierzy koloru
dokonuje się przy użyciu dobrze znanej funkcji glMatrixMode z parametrem
GL COLOR. Do dyspozycji programisty są oczywiście wszystkie funkcje ope-
rujące na macierzach. Minimalna głębokość stosu macierzy koloru wynosi 2.
1. Przetwarzanie obrazów
16
1.7. Program przykładowy
W przykładowym programie (plik przetwarzanie obrazow.cpp) pre-
zentowane są wybrane możliwości podzbioru przetwarzania obrazów. Efekt
zmniejszenie i zwiększenia jasności obrazu uzyskiwany jest za pomocą ma-
cierzy koloru, a negatyw obrazu tworzony jest przy użyciu tablicy kolorów.
Ponadto program umożliwia przetestowanie kilkudziesięciu różnego rodzaju
filtrów splotowych, których maski znajdują się w pliku filters.h. Efekty
działania kilku wybranych filtrów przedstawiono na rysunkach 3 - 8.
Ostatnim elementem podzbioru przetwarzania obrazów wykorzystanym
w przykładowym programie jest tworzenie histogramu obrazu. Do prezenta-
cji histogramu program tworzy dodatkowe okno którego wielkość zależy od
rodzaju obrazu. Histogram obrazu w odcieniach szarości jest prezentowany
w formie pojedynczego wykresu, a histogram obrazu RGB/RGBA przedsta-
wiany jest w formie trzech wykresów odrębnie dla każdej składowej RGB.
Histogramy obrazów Lena przedstawiono na rysunkach 1 i 2.
Rysunek 1. Program Przetwarzanie obrazów - histogram obrazu Lena w od-
cieniach szarości
W programie wykorzystano kilka dotąd nieopisywanych funkcji biblioteki
GLUT. Do przełączania pomiędzy oknami aplikacji służy funkcja:
void glutSetWindow (int win)
której parametr win zawiera unikatowy identyfikator (uchwyt) okna zwra-
cany przy jego tworzeniu przez funkcję glutCreateWindow.
Przy usuwaniu okna z wykresem histogramu stosowana jest funkcja:
void glutDestroyWindow (int win)
1. Przetwarzanie obrazów
17
Rysunek 2. Program Przetwarzanie obrazów - histogram obrazu Lena
1. Przetwarzanie obrazów
18
korzystająca z opisanego wcześniej uchwytu okna. Przed usunięciem okna
z histogramem usuwane jest jego menu podręczne. Wymaga to wywołania
funkcji:
void glutDestroyMenu (int menu)
której parametr menu to unikatowy identyfikator (uchwyt) manu zwracany
przez funkcję glutCreateMenu.
Rysunek 3. Program Przetwarzanie obrazów - filtr usuwający średną
1. Przetwarzanie obrazów
19
Rysunek 4. Program Przetwarzanie obrazów - filtr gradientowy wschód
1.7.1. Plik filters.h
/∗
( c )
J a n u s z
G a n c z a r s k i
h t t p : / / www . j a n u s z g . h g . p l
J a n u s z G @ e n t e r . n e t . p l
∗/
#i f n d e f
F I L T E R S
H
#d e f i n e
F I L T E R S
H
#i n c l u d e <GL/ g l . h>
//
f i l t r
u ś r e d n i a j ą c y
G L f l o a t
a v e r a g e
[ 9 ] =
{
0 . 1 1 1 1 1 1 1 1 ,
0 . 1 1 1 1 1 1 1 1 ,
0 . 1 1 1 1 1 1 1 1 1 ,
0 . 1 1 1 1 1 1 1 1 ,
0 . 1 1 1 1 1 1 1 1 ,
0 . 1 1 1 1 1 1 1 1 1 ,
0 . 1 1 1 1 1 1 1 1 ,
0 . 1 1 1 1 1 1 1 1 ,
0 . 1 1 1 1 1 1 1 1 1
} ;
//
f i l t r
LP1
G L f l o a t
l p 1
[ 9 ] =
1. Przetwarzanie obrazów
20
Rysunek 5. Program Przetwarzanie obrazów - filtr uwypuklający wschód
{
0 . 1 ,
0 . 1 ,
0 . 1 ,
0 . 1 ,
0 . 2 ,
0 . 1 ,
0 . 1 ,
0 . 1 ,
0 . 1
} ;
//
f i l t r
LP2
G L f l o a t
l p 2
[ 9 ] =
{
0 . 0 8 3 3 3 3 3 3 ,
0 . 0 8 3 3 3 3 3 3 ,
0 . 0 8 3 3 3 3 3 3 ,
0 . 0 8 3 3 3 3 3 3 ,
0 . 3 3 3 3 3 3 3 3 ,
0 . 0 8 3 3 3 3 3 3 ,
0 . 0 8 3 3 3 3 3 3 ,
0 . 0 8 3 3 3 3 3 3 ,
0 . 0 8 3 3 3 3 3 3
} ;
//
f i l t r
LP3
G L f l o a t
l p 3
[ 9 ] =
{
0 . 0 5 ,
0 . 0 5 ,
0 . 0 5 ,
0 . 0 5 ,
0 . 6 0 ,
0 . 0 5 ,
0 . 0 5 ,
0 . 0 5 ,
0 . 0 5
} ;
//
f i l t r
G a u s s a
1. Przetwarzanie obrazów
21
Rysunek 6. Program Przetwarzanie obrazów - filtr Laplace’a LAP1
G L f l o a t
g a u s s
[ 9 ] =
{
0 . 0 6 2 5 ,
0 . 1 2 5 0 ,
0 . 0 6 2 5 ,
0 . 1 2 5 0 ,
0 . 2 5 0 0 ,
0 . 1 2 5 0 ,
0 . 0 6 2 5 ,
0 . 1 2 5 0 ,
0 . 0 6 2 5
} ;
//
f i l t r
u s u w a j ą c y
ś r e d n i ą
G L f l o a t
m e a n r e m o v a l
[ 9 ] =
{
−1, −1, −1,
−1,
9 ,
−1,
−1, −1, −1
} ;
//
f i l t r
HP1
G L f l o a t
hp1
[ 9 ] =
{
0 ,
−1,
0 ,
−1,
5 ,
−1,
0 ,
−1,
0
} ;
1. Przetwarzanie obrazów
22
Rysunek 7. Program Przetwarzanie obrazów - filtr poziomy Sobela
//
f i l t r
HP2
G L f l o a t
hp2
[ 9 ] =
{
1 ,
−2,
1 ,
−2,
5 ,
−2,
1 ,
−2,
1
} ;
//
f i l t r
HP3
G L f l o a t
hp3
[ 9 ] =
{
0 . 0 0 0 0 ,
− 0 . 0 6 2 5 ,
0 . 0 0 0 0 ,
− 0 . 0 6 2 5 ,
1 . 2 5 0 0 ,
− 0 . 0 6 2 5 ,
0 . 0 0 0 0 ,
− 0 . 0 6 2 5 ,
0 . 0 0 0 0
} ;
//
f i l t r
p o z i o m y
G L f l o a t
h o r i z o n t a l
[ 9 ] =
{
0 ,
−1, 0 ,
0 ,
1 ,
0 ,
1. Przetwarzanie obrazów
23
Rysunek 8. Program Przetwarzanie obrazów - filtr poziomy Prewitta
0 ,
0 ,
0
} ;
//
f i l t r
p i o n o w y
G L f l o a t
v e r t i c a l
[ 9 ] =
{
0 ,
0 ,
0 ,
−1, 1 ,
0 ,
0 ,
0 ,
0
} ;
//
f i l t r
p o z i o m y / p i o n o w y
G L f l o a t
h o r i z o n t a l v e r t i c a l
[ 9 ] =
{
−1, 0 ,
0 ,
0 ,
1 ,
0 ,
0 ,
0 ,
0
} ;
//
f i l t r
g r a d i e n t o w y
w s c h ó d
G L f l o a t
g r a d i e n t e a s t
[ 9 ] =
{
1. Przetwarzanie obrazów
24
−1,
1 ,
1 ,
−1, −2, 1 ,
−1,
1 ,
1
} ;
//
f i l t r
g r a d i e n t o w y
p o ł u d n i o w y
w s c h ó d
G L f l o a t
g r a d i e n t s o u t h e a s t
[ 9 ] =
{
−1, −1, 1 ,
−1, −2, 1 ,
1 ,
1 ,
1
} ;
//
f i l t r
g r a d i e n t o w y
p o ł u d n i e
G L f l o a t
g r a d i e n t s o u t h
[ 9 ] =
{
−1, −1, −1,
1 ,
−2,
1 ,
1 ,
1 ,
1
} ;
//
f i l t r
g r a d i e n t o w y
p o ł u d n i o w y
z a c h ó d
G L f l o a t
g r a d i e n t s o u t h w e s t
[ 9 ] =
{
1 ,
−1, −1,
1 ,
−2, −1,
1 ,
1 ,
1
} ;
//
f i l t r
g r a d i e n t o w y
z a c h ó d
G L f l o a t
g r a d i e n t w e s t
[ 9 ] =
{
1 ,
1 ,
−1,
1 ,
−2, −1,
1 ,
1 , −1
} ;
//
f i l t r
g r a d i e n t o w y
p ó ł n o c n y
z a c h ó d
G L f l o a t
g r a d i e n t n o r t h w e s t
[ 9 ] =
{
1 ,
1 ,
1 ,
1 ,
−2, −1,
1 ,
−1, −1
} ;
//
f i l t r
g r a d i e n t o w y
p ó ł n o c
G L f l o a t
g r a d i e n t n o r t h
[ 9 ] =
{
1 ,
1 ,
1 ,
1 ,
−2,
1 ,
−1, −1, −1
} ;
//
f i l t r
g r a d i e n t o w y
p ó ł n o c n y
w s c h ó d
G L f l o a t
g r a d i e n t n o r t h e a s t
[ 9 ] =
{
1 ,
1 ,
1 ,
−1, −2, 1 ,
−1, −1, 1
} ;
//
f i l t r
u w y p u k l a j ą c y
w s c h ó d
G L f l o a t
e m b o s s e a s t
[ 9 ] =
{
−1, 0 ,
1 ,
−1, 1 ,
1 ,
−1, 0 , 1
} ;
//
f i l t r
u w y p u k l a j ą c y
p o ł u d n i o w y
w s c h ó d
G L f l o a t
e m b o s s s o u t h e a s t
[ 9 ] =
1. Przetwarzanie obrazów
25
{
−1, −1, 0 ,
−1,
1 ,
1 ,
0 ,
1 ,
1
} ;
//
f i l t r
u w y p u k l a j ą c y
p o ł u d n i e
G L f l o a t
e m b o s s s o u t h
[ 9 ] =
{
−1, −1, −1,
0 ,
1 ,
0 ,
1 ,
1 ,
1
} ;
//
f i l t r
u w y p u k l a j ą c y
p o ł u d n i o w y
z a c h ó d
G L f l o a t
e m b o s s s o u t h w e s t
[ 9 ] =
{
0 ,
−1, −1,
1 ,
1 ,
−1,
1 ,
1 ,
0
} ;
//
f i l t r
u w y p u k l a j ą c y
z a c h ó d
G L f l o a t
e m b o s s w e s t
[ 9 ] =
{
1 ,
0 ,
−1,
1 ,
1 ,
−1,
1 ,
0 , −1
} ;
//
f i l t r
u w y p u k l a j ą c y
p ó ł n o c n y
z a c h ó d
G L f l o a t
e m b o s s n o r t h w e s t
[ 9 ] =
{
1 ,
1 ,
0 ,
1 ,
1 ,
−1,
0 ,
−1, −1
} ;
//
f i l t r
u w y p u k l a j ą c y
p ó ł n o c
G L f l o a t
e m b o s s n o r t h
[ 9 ] =
{
1 ,
1 ,
1 ,
0 ,
1 ,
0 ,
−1, −1, −1
} ;
//
f i l t r
u w y p u k l a j ą c y
p ó ł n o c n y
w s c h ó d
G L f l o a t
e m b o s s n o r t h e a s t
[ 9 ] =
{
0 ,
1 ,
1 ,
−1,
1 ,
1 ,
−1, −1, 0
} ;
//
f i l t r
L a p l a c e ’ a LAPL1
G L f l o a t
l a p l a c i a n l a p l 1
[ 9 ] =
{
0 ,
−1,
0 ,
−1,
4 ,
−1,
0 ,
−1,
0
} ;
//
f i l t r
L a p l a c e ’ a LAPL2
G L f l o a t
l a p l a c i a n l a p l 2
[ 9 ] =
{
−1, −1, −1,
−1,
8 ,
−1,
−1, −1, −1
} ;
//
f i l t r
L a p l a c e ’ a LAPL3
1. Przetwarzanie obrazów
26
G L f l o a t
l a p l a c i a n l a p l 3
[ 9 ] =
{
1 ,
−2,
1 ,
−2,
4 ,
−2,
1 ,
−2,
1
} ;
//
f i l t r
L a p l a c e ’ a
s k o ś n y
G L f l o a t
l a p l a c i a n d i a g o n a l
[ 9 ] =
{
−1, 0 ,
−1,
0 ,
4 ,
0 ,
−1, 0 , −1
} ;
//
f i l t r
L a p l a c e ’ a
p o z i o m y
G L f l o a t
l a p l a c i a n h o r i z o n t a l
[ 9 ] =
{
0 ,
−1, 0 ,
0 ,
2 ,
0 ,
0 ,
−1, 0
} ;
//
f i l t r
L a p l a c e ’ a
p i o n o w y
G L f l o a t
l a p l a c i a n v e r t i c a l
[ 9 ] =
{
0 ,
0 ,
0 ,
−1, 2 ,
−1,
0 ,
0 ,
0
} ;
//
f i l t r
p o z i o m y
S o b e l a
G L f l o a t
s o b e l h o r i z o n t a l
[ 9 ] =
{
1 ,
2 ,
1 ,
0 ,
0 ,
0 ,
−1, −2, −1
} ;
//
f i l t r
p i o n o w y
S o b e l a
G L f l o a t
s o b e l v e r t i c a l
[ 9 ] =
{
1 ,
0 ,
−1,
2 ,
0 ,
−2,
1 ,
0 , −1
} ;
//
f i l t r
p o z i o m y
P r e w i t t a
G L f l o a t
p r e w i t t h o r i z o n t a l
[ 9 ] =
{
−1, −1, −1,
0 ,
0 ,
0 ,
1 ,
1 ,
1
} ;
//
f i l t r
p i o n o w y
P r e w i t t a
G L f l o a t
p r e w i t t v e r t i c a l
[ 9 ] =
{
1 ,
0 ,
−1,
1 ,
0 ,
−1,
1 ,
0 , −1
} ;
#e n d i f
//
F I L T E R S
H
1.7.2. Plik przetwarzanie obrazow.cpp
/∗
( c )
J a n u s z
G a n c z a r s k i
h t t p : / / www . j a n u s z g . h g . p l
1. Przetwarzanie obrazów
27
J a n u s z G @ e n t e r . n e t . p l
∗/
#i n c l u d e <GL/ g l u t . h>
#i n c l u d e <GL/ g l e x t . h>
#i f n d e f WIN32
#d e f i n e GLX GLXEXT LEGACY
#i n c l u d e <GL/ g l x . h>
#d e f i n e
w g l G e t P r o c A d d r e s s
glXGetProcAddressARB
#e n d i f
#i n c l u d e < s t d i o . h>
#i n c l u d e < s t d l i b . h>
#i n c l u d e
” t a r g a . h ”
#i n c l u d e
” f i l t e r s . h ”
//
w s k a ź n i k
na
f u n k c j ę
g l C o l o r T a b l e
PFNGLCOLORTABLEPROC g l C o l o r T a b l e = NULL ;
//
w s k a ź n i k
na
f u n k c j ę
g l C o n v o l u t i o n F i l t e r 2 D
PFNGLCONVOLUTIONFILTER2DPROC g l C o n v o l u t i o n F i l t e r 2 D = NULL ;
//
w s k a ź n i k
na
f u n k c j ę
g l C o n v o l u t i o n P a r a m e t e r i
PFNGLCONVOLUTIONPARAMETERIPROC g l C o n v o l u t i o n P a r a m e t e r i = NULL ;
//
w s k a ź n i k
na
f u n k c j ę
g l H i s t o g r a m
PFNGLHISTOGRAMPROC g l H i s t o g r a m = NULL ;
//
w s k a ź n i k
na
f u n k c j ę
g l G e t H i s t o g r a m
PFNGLGETHISTOGRAMPROC g l G e t H i s t o g r a m = NULL ;
//
s t a ł e
do
o b s ł u g i
menu
p o d r ę c z n e g o
enum
{
LIGHTNESS INC ,
//
z w i ę k s z e n i e
j a s n o ś c i
o b r a z u
LIGHTNESS DEC ,
//
z m n i e j s z e n i e
j a s n o ś c i
o b r a z u
NEGATIVE,
//
n e g a t y w
o b r a z u
HISTOGRAM,
//
h i s t o g r a m
o b r a z u
//
f i l t r y
s p l o t o w e
NONE,
//
b r a k
f i l t r a c j i
AVERAGE,
//
f i l t r
u ś r e d n i a j ą c y
LP1 ,
//
f i l t r
LP1
LP2 ,
//
f i l t r
LP2
LP3 ,
//
f i l t r
LP3
GAUSS,
//
f i l t r
G a u s s a
MEAN REMOVAL,
//
f i l t r
u s u w a j ą c y
ś r e d n i ą
HP1 ,
//
f i l t r
HP1
HP2 ,
//
f i l t r
HP2
HP3 ,
//
f i l t r
HP3
HORIZONTAL,
//
f i l t r
p o z i o m y
VERTICAL,
//
f i l t r
p i o n o w y
HORIZONTAL VERTICAL,
//
f i l t r
p o z i o m y / p i o n o w y
GRADIENT EAST,
//
f i l t r
g r a d i e n t o w y
w s c h ó d
GRADIENT SOUTH EAST,
//
f i l t r
g r a d i e n t o w y
p o ł u d n i o w y
w s c h ó d
GRADIENT SOUTH,
//
f i l t r
g r a d i e n t o w y
p o ł u d n i e
GRADIENT SOUTH WEST,
//
f i l t r
g r a d i e n t o w y
p o ł u d n i o w y
z a c h ó d
GRADIENT WEST,
//
f i l t r
g r a d i e n t o w y
z a c h ó d
GRADIENT NORTH WEST,
//
f i l t r
g r a d i e n t o w y
p ó ł n o c n y
z a c h ó d
GRADIENT NORTH,
//
f i l t r
g r a d i e n t o w y
p ó ł n o c
GRADIENT NORTH EAST,
//
f i l t r
g r a d i e n t o w y
p ó ł n o c n y
w s c h ó d
EMBOSS EAST,
//
f i l t r
u w y p u k l a j ą c y
w s c h ó d
EMBOSS SOUTH EAST,
//
f i l t r
u w y p u k l a j ą c y
p o ł u d n i o w y
w s c h ó d
EMBOSS SOUTH,
//
f i l t r
u w y p u k l a j ą c y
p o ł u d n i e
EMBOSS SOUTH WEST,
//
f i l t r
u w y p u k l a j ą c y
p o ł u d n i o w y
z a c h ó d
EMBOSS WEST,
//
f i l t r
u w y p u k l a j ą c y
z a c h ó d
EMBOSS NORTH WEST,
//
f i l t r
u w y p u k l a j ą c y
p ó ł n o c n y
z a c h ó d
EMBOSS NORTH,
//
f i l t r
u w y p u k l a j ą c y
p ó ł n o c
EMBOSS NORTH EAST,
//
f i l t r
u w y p u k l a j ą c y
p ó ł n o c n y
w s c h ó d
LAPLACIAN LAPL1 ,
//
f i l t r
L a p l a c e ’ a LAPL1
LAPLACIAN LAPL2 ,
//
f i l t r
L a p l a c e ’ a LAPL2
LAPLACIAN LAPL3 ,
//
f i l t r
L a p l a c e ’ a LAPL3
LAPLACIAN DIAGONAL,
//
f i l t r
L a p l a c e ’ a
s k o ś n y
LAPLACIAN HORIZONTAL,
//
f i l t r
L a p l a c e ’ a
p o z i o m y
LAPLACIAN VERTICAL ,
//
f i l t r
L a p l a c e ’ a
p i o n o w y
1. Przetwarzanie obrazów
28
SOBEL HORIZONTAL,
//
f i l t r
p o z i o m y
S o b e l a
SOBEL VERTICAL ,
//
f i l t r
p i o n o w y
S o b e l a
PREWITT HORIZONTAL,
//
f i l t r
p o z i o m y
P r e w i t t a
PREWITT VERTICAL,
//
f i l t r
p i o n o w y
P r e w i t t a
SAVE FILE ,
//
z a p i s
p l i k u TARGA
CLOSE,
//
z a m k n i ę c i e
o k n a
z
h i s t o g r a m e m
EXIT
//
w y j ś c i e
} ;
//
d a n e
o p i s u j ą c e
o b r a z
o d c z y t a n y
z
p l i k u TARGA
G L s i z e i
w i d t h ;
//
s z e r o k o ś ć
o b r a z u
G L s i z e i
h e i g h t ;
//
w y s o k o ś ć
o b r a z u
GLenum f o r m a t ;
//
f o r m a t
d a n y c h
o b r a z u
GLenum t y p e ;
//
f o r m a t
d a n y c h
p i k s e l i
o b r a z u
GLvoid ∗ p i x e l s ;
//
w s k a ź n i k
na
t a b l i c ę
z
d a n y m i
o b r a z u
//
w s p ó ł c z y n n i k
l i n i o w e g o
s k a l o w a n i a
w a r t o ś c i
s k ł a d o w y c h
k o l o r ó w
//
c z y l i
z w i ę k s z e n i e
j a s n o ś c i
o b r a z u
G L f l o a t
l i g h t n e s s s c a l e = 1 . 0 ;
//
z n a c z n i k
r y s o w a n i a
o b r a z u w n e g a t y w i e
bool
n e g a t i v e = f a l s e ;
//
n e u t r a l n a
maska
f i l t r a
s p l o t o w e g o
G L f l o a t
n e u t r a l
[ 9 ] =
{
0 , 0 , 0 ,
0 , 1 , 0 ,
0 , 0 , 0
} ;
//
w s k a ź n i k
na
b i e ż ą c ą
ma s k ę
f i l t r a
s p l o t o w e g o
G L f l o a t
∗ f i l t e r = n e u t r a l ;
//
d a n e
h i s t o g r a m u
GLint
h i s t o g r a m
[ 2 5 6 ∗ 3 ] ;
//
u c h w y t
o k n a
z
w y k r e s e m
h i s t o g r a m e m
i n t
h i s t o g r a m w i n d o w = 0 ;
//
u c h w y t menu o k n a
z
w y k r e s e m
h i s t o g r a m e m
i n t
h i s t o g r a m m e n u ;
//
w c z y t a n i e
p l i k u
g r a f i c z n e g o
w f o r m a c i e TARGA
void LoadTARGA ( i n t
a r g c ,
char ∗ a r g v [ ] )
{
//
s p r a w d z e n i e
c z y
j e s t
p a r a m e t r
i f
( a r g c < 2 )
{
p r i n t f
( ” Brak nazwy
p l i k u TARGA\n ” ) ;
e x i t
( 1 ) ;
}
//
o d c z y t
p l i k u TARGA i
e w e n t u a l n y
k o m u n i k a t
o
b ł ę d z i e
i f
( ! l o a d t a r g a
( a r g v [ 1 ] , width , h e i g h t , f o r m a t , t y p e , p i x e l s ) )
{
#i f d e f WIN32
p r i n t f
( ” Błąd
o d c z y t u
l u b
b ł ę d n y
f o r m a t
p l i k u : %s \n ” , a r g v [ 1 ] ) ;
#e l s e
p r i n t f
( ” B l ad
o d c z y t u
l u b
b l e d n y
f o r m a t
p l i k u : %s \n ” , a r g v [ 1 ] ) ;
#e n d i f
e x i t
( 1 ) ;
}
}
//
s p r a w d z e n i e
c z y
d a n y
f o r m a t
p l i k u TARGA j e s t
o b s ł u g i w a n y
void CheckImageFormat
( )
1. Przetwarzanie obrazów
29
{
//
o b r a z w f o r m a c i e BGR i BGRA
i f
( f o r m a t == GL BGR
| |
f o r m a t == GL BGRA)
{
//
o d c z y t
w e r s j i
OpenGL
const char ∗ v e r s i o n = ( char ∗ ) g l G e t S t r i n g
( GL VERSION ) ;
i n t
m a j o r = 0 ,
m i n o r = 0 ;
i f
( s s c a n f
( v e r s i o n , ”%d.%d ” ,& major ,& m i n o r )
!=
2 )
{
#i f d e f WIN32
p r i n t f
( ” Błędny
f o r m a t
w e r s j i
OpenGL\n ” ) ;
#e l s e
p r i n t f
( ” B l e d n y
f o r m a t
w e r s j i
OpenGL\n ” ) ;
#e n d i f
e x i t
( 1 ) ;
}
//
s p r a w d z e n i e
c z y
j e s t
c o
n a j m n i e j
w e r s j a
1 . 2
OpenGL
i f
( m a j o r <= 1 && m i n o r < 2 )
{
//
j e ż e l i
j e s t
s t a r s z a
w e r s j a
OpenGL
s p r a w d z e n i e
//
c z y
j e s t
o b s ł u g a
r o z s z e r z e n i a
GL EXT bgra
i f
( ! g l u t E x t e n s i o n S u p p o r t e d
( ” GL EXT bgra ” ) )
{
//
k o m u n i k a t
o
b ł ę d z i e − w tym
m i e j s c u
można
w y k o n a ć
//
k o n w e r s j ę
d a n y c h
z
f o r m a t u BGR/BGRA na RGB/RGBA
p r i n t f
( ” Brak
r o z s z e r z e n i a
GL EXT bgra \n ” ) ;
e x i t
( 1 ) ;
}
}
}
}
//
z a p i s
p l i k u
g r a f i c z n e g o
w f o r m a c i e TARGA
void SaveTARGA ( GLenum f o r m a t )
{
//
w y r ó w n y w a n i e
w i e r s z a
mapy do
p o j e d y ń c z e g o
b a j t a
g l P i x e l S t o r e i
(GL PACK ALIGNMENT , 1 ) ;
//
w s k a ź n i k
na
b u f o r
mapy
p i k s e l o w e j
GLvoid ∗ p i x e l s ;
//
s z e r o k o ś ć
i
w y s o k o ś ć
mapy
p i k s e l o w e j
G L s i z e i
w i d t h = g l u t G e t
(GLUT WINDOW WIDTH ) ;
G L s i z e i
h e i g h t = g l u t G e t
(GLUT WINDOW HEIGHT ) ;
//
u t w o r z e n i e
b u f o r a
mapy
p i k s e l o w e j
i f
( f o r m a t == GL BGRA)
p i x e l s = new unsigned char
[ w i d t h ∗ h e i g h t ∗ 4 ] ;
e l s e
i f
( f o r m a t == GL BGR)
p i x e l s = new unsigned char
[ w i d t h ∗ h e i g h t ∗ 3 ] ;
e l s e
i f
( f o r m a t == GL LUMINANCE)
p i x e l s = new unsigned char
[ w i d t h ∗ h e i g h t ] ;
e l s e
return ;
//
t y l k o
p l i k
w o d c i e n i a c h
s z a r o ś c i
i f
( f o r m a t == GL LUMINANCE)
{
//
o k r e ś l e n i e
p r z e k s z t a ł c e n i a
s k ł a d o w y c h RGB na
o d c i e n i e
s z a r o ś c i
g l P i x e l T r a n s f e r f
( GL RED SCALE , 0 . 2 2 9 ) ;
g l P i x e l T r a n s f e r f
(GL GREEN SCALE , 0 . 5 8 7 ) ;
g l P i x e l T r a n s f e r f
( GL BLUE SCALE , 0 . 1 1 4 ) ;
}
//
s k o p i o w a n i e
z a w a r t o ś c i
b u f o r a
k o l o r u
do
b u f o r a
mapy
p i k s e l o w e j
g l R e a d P i x e l s
( 0 , 0 , width , h e i g h t , f o r m a t , GL UNSIGNED BYTE , p i x e l s ) ;
//
t y l k o
p l i k
w o d c i e n i a c h
s z a r o ś c i
i f
( f o r m a t == GL LUMINANCE)
{
//
p o w r ó t
do
n e u t r a l n e g o
p r z e k s z t a ł c e n i a
s k ł a d o w y c h
g l P i x e l T r a n s f e r f
( GL RED SCALE , 1 . 0 ) ;
g l P i x e l T r a n s f e r f
(GL GREEN SCALE , 1 . 0 ) ;
g l P i x e l T r a n s f e r f
( GL BLUE SCALE , 1 . 0 ) ;
1. Przetwarzanie obrazów
30
}
//
z a p i s
mapy
p i k s e l o w e j
do
p l i k u TARGA
i f
( f o r m a t == GL BGRA)
s a v e t a r g a
( ” test BGRA . t g a ” , width , h e i g h t , f o r m a t , t y p e , p i x e l s ) ;
e l s e
i f
( f o r m a t == GL BGR)
s a v e t a r g a
( ” test BGR . t g a ” , width , h e i g h t , f o r m a t , t y p e , p i x e l s ) ;
e l s e
i f
( f o r m a t == GL LUMINANCE)
s a v e t a r g a
( ”test LUMINANCE . t g a ” , width , h e i g h t , f o r m a t , t y p e , p i x e l s ) ;
//
p o r z ą d k i
d e l e t e
[ ]
( unsigned char ∗ ) p i x e l s ;
}
//
w y ś w i e t l e n i e
i
s k a l o w a n i e
o b r a z u
void
D i s p l a y
( )
{
//
k o l o r
t ł a − z a w a r t o ś ć
b u f o r a
k o l o r u
g l C l e a r C o l o r
( 1 . 0 , 1 . 0 , 1 . 0 , 1 . 0 ) ;
//
c z y s z c z e n i e
b u f o r a
k o l o r u
g l C l e a r
( GL COLOR BUFFER BIT ) ;
//
w y b ó r
m a c i e r z y
k o l o r u
g l M a t r i x M o d e
(GL COLOR ) ;
//
m a c i e r z
r z u t o w a n i a = m a c i e r z
j e d n o s t k o w a
g l L o a d I d e n t i t y
( ) ;
//
l i n i o w e
s k a l o w a n i e
w a r t o ś c i
s k ł a d o w y c h
k o l o r ó w
//
c z y l i
z w i ę k s z e n i e
j a s n o ś c i
o b r a z u
g l S c a l e f
( l i g h t n e s s s c a l e , l i g h t n e s s s c a l e , l i g h t n e s s s c a l e ) ;
//
d e f i n i c j a
d w u w y m i a r o w e g o
f i l t r a
s p l o t o w e g o
g l C o n v o l u t i o n F i l t e r 2 D
(GL CONVOLUTION 2D , GL RGB, 3 , 3 , GL LUMINANCE, GL FLOAT , f i l t e r ) ;
//
o k r e ś l e n i e
b r z e g u
o b r a z u
g l C o n v o l u t i o n P a r a m e t e r i
(GL CONVOLUTION 2D , GL CONVOLUTION BORDER MODE, GL REPLICATE BORDER ) ;
//
w ł ą c z e n i e
d w u w y m i a r o w e g o
f i l t r a
s p l o t o w e g o
g l E n a b l e
(GL CONVOLUTION 2D ) ;
//
n e g a t y w
o b r a z u
i f
( n e g a t i v e == true )
{
//
p r z y g o t o w a n i e
t a b l i c y
k o l o r ó w
z
n e g a t y w e m
GLubyte
n e g a t i v e t a b l e
[ 2 5 6 ∗ 3 ] ;
f o r
( i n t
i
=0;
i < 2 5 6 ;
i ++)
{
n e g a t i v e t a b l e
[ 3 ∗ i +0] = 2 5 5 − i ;
n e g a t i v e t a b l e
[ 3 ∗ i +1] = 2 5 5 − i ;
n e g a t i v e t a b l e
[ 3 ∗ i +2] = 2 5 5 − i ;
}
//
u t w o r z e n i e
t a b l i c y
k o l o r ó w
g l C o l o r T a b l e
(GL COLOR TABLE, GL RGB, 2 5 6 , GL RGB, GL UNSIGNED BYTE , n e g a t i v e t a b l e ) ;
//
w ł ą c z e n i e
t a b l i c y
k o l o r ó w
g l E n a b l e
(GL COLOR TABLE ) ;
}
//
p o z y c j a
mapy
p i k s e l o w e j
g l R a s t e r P o s 2 i
( 0 , 0 ) ;
//
w y r ó w n y w a n i e
w i e r s z a
mapy
p i k s e l o w e j
do
p o j e d y ń c z e g o
b a j t a
g l P i x e l S t o r e i
(GL UNPACK ALIGNMENT, 1 ) ;
//
s k a l o w a n i e
mapy
p i k s e l o w e j
do
r o z m i a r ó w
o k n a
g l P i x e l Z o o m
( ( f l o a t ) g l u t G e t (GLUT WINDOW WIDTH) / ( f l o a t ) width ,
( f l o a t ) g l u t G e t (GLUT WINDOW HEIGHT) / ( f l o a t ) h e i g h t ) ;
//
w y ś w i e t l e n i e
o b r a z u
z a w a r t e g o w m a p i e
p i k s e l o w e j
g l D r a w P i x e l s
( width , h e i g h t , f o r m a t , t y p e , p i x e l s ) ;
//
w y ł ą c z e n i e
d w u w y m i a r o w e g o
f i l t r a
s p l o t o w e g o
g l D i s a b l e
(GL CONVOLUTION 2D ) ;
1. Przetwarzanie obrazów
31
//
w y ł ą c z e n i e
t a b l i c y
k o l o r ó w
g l D i s a b l e
(GL COLOR TABLE ) ;
//
s k i e r o w a n i e
p o l e c e ń
do
w y k o n a n i a
g l F i n i s h
( ) ;
//
z a m i a n a
b u f o r ó w
k o l o r u
g l u t S w a p B u f f e r s
( ) ;
}
//
z m i a n a
w i e l k o ś c i
o k n a
void
R esh ape
( i n t
Width , i n t
H e i g h t )
{
//
o b s z a r
r e n d e r i n g u − c a ł e
o k n o
g l V i e w p o r t
( 0 , 0 , Width , H e i g h t ) ;
//
w y b ó r
m a c i e r z y
r z u t o w a n i a
g l M a t r i x M o d e
(GL PROJECTION ) ;
//
m a c i e r z
r z u t o w a n i a = m a c i e r z
j e d n o s t k o w a
g l L o a d I d e n t i t y
( ) ;
//
p a r a m e t r y
b r y ł y
o b c i n a n i a
g l u O r t h o 2 D
( 0 . 0 , Width , 0 . 0 , H e i g h t ) ;
//
g e n e r o w a n i e
s c e n y
3D
D i s p l a y
( ) ;
}
//
w y ś w i e t l e n i e
o k n a
z
w y k r e s e m
h i s t o g r a m u
void
D i s p l a y H i s t o g r a m
( )
{
//
k o l o r
t ł a − z a w a r t o ś ć
b u f o r a
k o l o r u
g l C l e a r C o l o r
( 1 . 0 , 1 . 0 , 1 . 0 , 1 . 0 ) ;
//
c z y s z c z e n i e
b u f o r a
k o l o r u
g l C l e a r
( GL COLOR BUFFER BIT ) ;
//
p o b r a n i e
w y s o k o ś c i
o k n a
do
s k a l o w a n i a
w y k r e s u
h i s t o g r a m u
i n t
w i n h e i g h t = g l u t G e t
(GLUT WINDOW HEIGHT ) ;
//
h i s t o g r a m
o b r a z u w o d c i e n i a c h
s z a r o ś c i
i f
( f o r m a t == GL LUMINANCE)
{
//
o b l i c z e n i e
m a k s y m a l n e j
w a r t o ś c i
GLint max = h i s t o g r a m
[ 0 ] ;
f o r
( i n t
i = 1 ;
i < 2 5 6 ;
i ++)
i f
( h i s t o g r a m
[ i ∗ 3 ] > max )
max = h i s t o g r a m
[ i ∗ 3 ] ;
//
k o l o r
w y k r e s u
h i s t o g r a m u
g l C o l o r 3 f
( 0 . 0 , 0 . 0 , 0 . 0 ) ;
//
n a r y s o w a n i e
w y k r e s u
h i s t o g r a m u
g l B e g i n
( GL LINES ) ;
f o r
( i n t
i = 0 ;
i < 2 5 6 ;
i ++)
{
g l V e r t e x 2 f
( i , 0 . 0 ) ;
g l V e r t e x 2 f
( i , w i n h e i g h t
∗ h i s t o g r a m
[ i ∗ 3 ] / ( f l o a t ) max ) ;
}
g l E n d
( ) ;
}
//
h i s t o g r a m
d l a
o b r a z ó w w f o r m a c i e RGB/RGBA
i f
( f o r m a t == GL BGRA
| |
f o r m a t == GL BGR)
{
//
p o d z i e l e n i e
o k n a
na
t r z y
r ó w n e
c z ę ś c i
w i n h e i g h t /= 3 ;
//
o b l i c z e n i e
m a k s y m a l n e j
w a r t o ś c i
d l a
k a ż d e j
s k ł a d o w e j
GLint maxr = h i s t o g r a m
[ 0 ] ;
GLint maxg = h i s t o g r a m
[ 1 ] ;
GLint maxb = h i s t o g r a m
[ 2 ] ;
f o r
( i n t
i = 1 ;
i < 2 5 6 ;
i ++)
{
i f
( h i s t o g r a m
[ i ∗3+0] > maxr )
maxr = h i s t o g r a m
[ i ∗ 3 + 0 ] ;
1. Przetwarzanie obrazów
32
i f
( h i s t o g r a m
[ i ∗3+1] > maxg )
maxg = h i s t o g r a m
[ i ∗ 3 + 1 ] ;
i f
( h i s t o g r a m
[ i ∗3+2] > maxb )
maxb = h i s t o g r a m
[ i ∗ 3 + 2 ] ;
}
//
n a r y s o w a n i e
w y k r e s ó w
h i s t o g r a m u
d l a
k a ż d e j
s k ł a d o w e j
g l B e g i n
( GL LINES ) ;
//
s k ł a d o w a R
g l C o l o r 3 f
( 1 . 0 , 0 . 0 , 0 . 0 ) ;
f o r
( i n t
i = 0 ;
i < 2 5 6 ;
i ++)
{
g l V e r t e x 2 f
( i , 0 . 0 ) ;
g l V e r t e x 2 f
( i , w i n h e i g h t
∗ h i s t o g r a m
[ i ∗ 3 + 0 ] / ( f l o a t ) maxr ) ;
}
//
s k ł a d o w a G
g l C o l o r 3 f
( 0 . 0 , 1 . 0 , 0 . 0 ) ;
f o r
( i n t
i = 0 ;
i < 2 5 6 ;
i ++)
{
g l V e r t e x 2 f
( i , w i n h e i g h t ) ;
g l V e r t e x 2 f
( i , w i n h e i g h t+w i n h e i g h t
∗ h i s t o g r a m
[ i ∗ 3 + 1 ] / ( f l o a t ) maxg ) ;
}
//
s k ł a d o w a B
g l C o l o r 3 f
( 0 . 0 , 0 . 0 , 1 . 0 ) ;
f o r
( i n t
i = 0 ;
i < 2 5 6 ;
i ++)
{
g l V e r t e x 2 f
( i , 2 ∗ w i n h e i g h t ) ;
g l V e r t e x 2 f
( i , 2 ∗ w i n h e i g h t+w i n h e i g h t
∗ h i s t o g r a m
[ i ∗ 3 + 2 ] / ( f l o a t ) maxb ) ;
}
g l E n d
( ) ;
}
//
s k i e r o w a n i e
p o l e c e ń
do
w y k o n a n i a
g l F i n i s h
( ) ;
//
z a m i a n a
b u f o r ó w
k o l o r u
g l u t S w a p B u f f e r s
( ) ;
}
//
z m i a n a
w i e l k o ś c i
o k n a
z
w y k r e s e m
h i s t o g r a m u
void
R e s h a p e H i s t o g r a m
( i n t
Width , i n t
H e i g h t )
{
//
o b s z a r
r e n d e r i n g u − c a ł e
o k n o
g l V i e w p o r t
( 0 , 0 , Width , H e i g h t ) ;
//
w y b ó r
m a c i e r z y
r z u t o w a n i a
g l M a t r i x M o d e
(GL PROJECTION ) ;
//
m a c i e r z
r z u t o w a n i a = m a c i e r z
j e d n o s t k o w a
g l L o a d I d e n t i t y
( ) ;
//
p a r a m e t r y
b r y ł y
o b c i n a n i a
g l u O r t h o 2 D
( 0 . 0 , Width , 0 . 0 , H e i g h t ) ;
//
g e n e r o w a n i e
o k n a
z
h i s t o g r a m e m
D i s p l a y H i s t o g r a m
( ) ;
}
//
o b s ł u g a
menu
p o d r ę c z n e g o
void Menu ( i n t
v a l u e )
{
//
w s k a ź n i k i
na
m a s k i
p o s z c z e g ó l n y c h
f i l t r ó w
s p l o t o w y c h
G L f l o a t
∗ f i l t e r s
[ 3 9 ] =
{
n e u t r a l ,
a v e r a g e ,
l p 1 ,
l p 2 ,
l p 3 ,
g a u s s ,
m e a n r e m o v a l ,
hp1 ,
hp2 ,
hp3 ,
h o r i z o n t a l ,
v e r t i c a l ,
h o r i z o n t a l v e r t i c a l ,
g r a d i e n t e a s t ,
g r a d i e n t s o u t h e a s t ,
g r a d i e n t s o u t h ,
g r a d i e n t s o u t h w e s t ,
g r a d i e n t w e s t ,
g r a d i e n t n o r t h w e s t ,
g r a d i e n t n o r t h ,
g r a d i e n t n o r t h e a s t ,
e m b o s s e a s t ,
e m b o s s s o u t h e a s t ,
e m b o s s s o u t h ,
e m b o s s s o u t h w e s t ,
e m b o s s w e s t ,
e m b o s s n o r t h w e s t ,
e m b o s s n o r t h ,
e m b o s s n o r t h e a s t ,
l a p l a c i a n l a p l 1 ,
l a p l a c i a n l a p l 2 ,
l a p l a c i a n l a p l 3 ,
l a p l a c i a n d i a g o n a l ,
l a p l a c i a n h o r i z o n t a l ,
l a p l a c i a n v e r t i c a l ,
s o b e l h o r i z o n t a l ,
s o b e l v e r t i c a l ,
p r e w i t t h o r i z o n t a l ,
p r e w i t t v e r t i c a l
} ;
1. Przetwarzanie obrazów
33
switch
( v a l u e )
{
//
z a p i s
p l i k u
w f o r m a c i e TARGA
c a s e SAVE FILE :
SaveTARGA ( f o r m a t ) ;
break ;
//
z w i ę k s z e n i e
j a s n o ś c i
o b r a z u
c a s e LIGHTNESS INC :
l i g h t n e s s s c a l e += 0 . 1 ;
//
w y ś w i e t l e n i e
s c e n y
D i s p l a y
( ) ;
break ;
//
z m n i e j s z e n i e
j a s n o ś c i
o b r a z u
c a s e LIGHTNESS DEC :
i f
( l i g h t n e s s s c a l e > 0 )
l i g h t n e s s s c a l e −= 0 . 1 ;
//
w y ś w i e t l e n i e
s c e n y
D i s p l a y
( ) ;
break ;
//
f i l t r y
s p l o t o w e
c a s e NONE:
c a s e AVERAGE:
c a s e LP1 :
c a s e LP2 :
c a s e LP3 :
c a s e GAUSS :
c a s e MEAN REMOVAL:
c a s e HP1 :
c a s e HP2 :
c a s e HP3 :
c a s e HORIZONTAL :
c a s e VERTICAL :
c a s e HORIZONTAL VERTICAL :
c a s e GRADIENT EAST :
c a s e GRADIENT SOUTH EAST :
c a s e GRADIENT SOUTH :
c a s e GRADIENT SOUTH WEST :
c a s e GRADIENT WEST :
c a s e GRADIENT NORTH WEST :
c a s e GRADIENT NORTH :
c a s e GRADIENT NORTH EAST :
c a s e EMBOSS EAST :
c a s e EMBOSS SOUTH EAST :
c a s e EMBOSS SOUTH :
c a s e EMBOSS SOUTH WEST :
c a s e EMBOSS WEST :
c a s e EMBOSS NORTH WEST :
c a s e EMBOSS NORTH :
c a s e EMBOSS NORTH EAST :
c a s e LAPLACIAN LAPL1 :
c a s e LAPLACIAN LAPL2 :
c a s e LAPLACIAN LAPL3 :
c a s e LAPLACIAN DIAGONAL :
c a s e LAPLACIAN HORIZONTAL :
c a s e LAPLACIAN VERTICAL :
c a s e SOBEL HORIZONTAL :
c a s e SOBEL VERTICAL :
c a s e PREWITT HORIZONTAL :
c a s e PREWITT VERTICAL :
f i l t e r
= f i l t e r s
[ v a l u e −NONE ] ;
//
w y ś w i e t l e n i e
s c e n y
D i s p l a y
( ) ;
break ;
//
n e g a t y w
o b r a z u
c a s e NEGATIVE :
n e g a t i v e
=! n e g a t i v e ;
//
w y ś w i e t l e n i e
s c e n y
D i s p l a y
( ) ;
break ;
//
h i s t o g r a m
o b r a z u
1. Przetwarzanie obrazów
34
c a s e HISTOGRAM:
//
u s t a w n i e n i e
p a r a m e t r ó w
h i s t o g r a m u
g l H i s t o g r a m
(GL HISTOGRAM, 2 5 6 , GL RGB, GL TRUE ) ;
//
w ł ą c z e n i e
o b l i c z e ń
h i s t o g r a m u
g l E n a b l e
(GL HISTOGRAM ) ;
//
w y ś w i e t l e n i e
s c e n y
D i s p l a y
( ) ;
//
p o b r a n i e
d a n y c h
h i s t o g r a m u
g l G e t H i s t o g r a m
(GL HISTOGRAM, GL TRUE, GL RGB, GL INT , h i s t o g r a m ) ;
//
w y ł ą c z e n i e
o b l i c z e ń
h i s t o g r a m u
g l D i s a b l e
(GL HISTOGRAM ) ;
//
u t w o r z e n i e
o k n a
z
w y k r e s e m
h i s t o g r a m u
i f
( h i s t o g r a m w i n d o w == 0 )
{
//
r o z m i a r y
o k n a
z
w y k r e s e m
h i s t o g r a m
u z a l e ż n i o n e
//
s ą
od
f o r m a t u
w y ś w i e t l e n a g o
p l i k u
g r a f i c z n e g o
i f
( f o r m a t == GL BGRA
| |
f o r m a t == GL BGR)
g l u t I n i t W i n d o w S i z e
( 2 5 6 , 2 5 6 ∗ 3 ) ;
e l s e
g l u t I n i t W i n d o w S i z e
( 2 5 6 , 2 5 6 ) ;
//
u t w o r z e n i e
o k n a
z
w y k r e s e m
h i s t o g r a m u
h i s t o g r a m w i n d o w = g l u t C r e a t e W i n d o w
( ” H i s t o g r a m ” ) ;
//
d o ł ą c z e n i e
f u n k c j i
g e n e r u j ą c e j
w y k r e s
h i s t o g r a m u
g l u t D i s p l a y F u n c
( D i s p l a y H i s t o g r a m ) ;
//
d o ł ą c z e n i e
f u n k c j i
w y w o ł y w a n e j
p r z y
z m i a n i e
r o z m i a r u
o k n a
g l u t R e s h a p e F u n c
( R e s h a p e H i s t o g r a m ) ;
//
u t w o r z e n i e
menu
p o d r ę c z n e g o
h i s t o g r a m m e n u = g l u t C r e a t e M e n u
( Menu ) ;
//
d o d a n i e
p r z y c i s k u
z a m y k a j ą c e g o
o k n o
z
w y k r e s e m
h i s t o g r a m u
glutAddMenuEntry
( ” Z a m k n i j ” ,CLOSE ) ;
//
o k r e ś l e n i e
p r z y c i s k u
m y s z k i
o b s ł u g u j ą c e j
menu
p o d r ę c z n e
g l u t A t t a c h M e n u
(GLUT RIGHT BUTTON ) ;
}
//
w y b r a n i e
o k n a
z
w y k r e s e m
h i s t o g r a m u
g l u t S e t W i n d o w
( h i s t o g r a m w i n d o w ) ;
//
w y ś w i e t l e n i e
o k n a
z
w y k r e s e m
h i s t o g r a m u
g l u t P o s t R e d i s p l a y
( ) ;
break ;
//
z a m k n i ę c i e
o k n a
z
h i s t o g r a m e m
c a s e CLOSE :
//
w y b r a n i e
o k n a
z
w y k r e s e m
h i s t o g r a m u
g l u t S e t W i n d o w
( h i s t o g r a m w i n d o w ) ;
//
u s u n i ę c i e
menu
p o d r ę c z n e g o
o k n a
z
w y k r e s e m
h i s t o g r a m u
g l u t D e s t r o y M e n u
( h i s t o g r a m m e n u ) ;
//
u s u n i ę c i e
o k n a
z
w y k r e s e m
h i s t o g r a m u
g l u t D e s t r o y W i n d o w
( h i s t o g r a m w i n d o w ) ;
//
w y z e r o w a n i e
u c h w y t u
o k n a
z
w y k r e s e m
h i s t o g r a m u
h i s t o g r a m w i n d o w = 0 ;
break ;
//
w y j ś c i e
c a s e EXIT :
e x i t
( 0 ) ;
break ;
}
}
//
s p r a w d z e n i e
i
p r z y g o t o w a n i e
o b s ł u g i
w y b r a n y c h
r o z s z e r z e ń
void
E x t e n s i o n S e t u p
( )
{
1. Przetwarzanie obrazów
35
//
p o b r a n i e
numeru
w e r s j i
b i b l i o t e k i
OpenGL
const char ∗ v e r s i o n = ( char ∗ ) g l G e t S t r i n g
( GL VERSION ) ;
//
o d c z y t
w e r s j i
OpenGL
i n t
m a j o r = 0 ,
m i n o r = 0 ;
i f
( s s c a n f
( v e r s i o n , ”%d.%d ” ,& major ,& m i n o r )
!=
2 )
{
#i f d e f WIN32
p r i n t f
( ” Błędny
f o r m a t
w e r s j i
OpenGL\n ” ) ;
#e l s e
p r i n t f
( ” B l e d n y
f o r m a t
w e r s j i
OpenGL\n ” ) ;
#e n d i f
e x i t
( 0 ) ;
}
//
s p r a w d z e n i e
c z y
j e s t
o b s ł u g i w a n e
r o z s z e r z e n i e
ARB imaging
i f
( g l u t E x t e n s i o n S u p p o r t e d
( ” GL ARB imaging ” ) )
{
//
p o b r a n i e
w s k a ź n i k ó w
w y b r a n y c h
f u n k c j i
r o z s z e r z e n i a
ARB imaging
g l C o l o r T a b l e = (PFNGLCOLORTABLEPROC) w g l G e t P r o c A d d r e s s
( ” g l C o l o r T a b l e ” ) ;
g l C o n v o l u t i o n F i l t e r 2 D =
(PFNGLCONVOLUTIONFILTER2DPROC)
w g l G e t P r o c A d d r e s s
( ” g l C o n v o l u t i o n F i l t e r 2 D ” ) ;
g l C o n v o l u t i o n P a r a m e t e r i = (PFNGLCONVOLUTIONPARAMETERIPROC)
w g l G e t P r o c A d d r e s s
( ” g l C o n v o l u t i o n P a r a m e t e r i ” ) ;
g l H i s t o g r a m = (PFNGLHISTOGRAMPROC) w g l G e t P r o c A d d r e s s
( ” g l H i s t o g r a m ” ) ;
g l G e t H i s t o g r a m = (PFNGLGETHISTOGRAMPROC)
w g l G e t P r o c A d d r e s s
( ” g l G e t H i s t o g r a m ” ) ;
}
e l s e
{
p r i n t f
( ” Brak
r o z s z e r z e n i a
ARB imaging ! \ n ” ) ;
e x i t
( 0 ) ;
}
}
i n t
main
( i n t
a r g c ,
char ∗ a r g v [ ] )
{
//
o d c z y t
p l i k u
g r a f i c z n e g o TARGA
LoadTARGA ( a r g c , a r g v ) ;
//
i n i c j a l i z a c j a
b i b l i o t e k i
GLUT
g l u t I n i t
(& a r g c , a r g v ) ;
//
i n i c j a l i z a c j a
b u f o r a
r a m k i
g l u t I n i t D i s p l a y M o d e
(GLUT DOUBLE | GLUT RGB | GLUT ALPHA ) ;
//
r o z m i a r y
g ł ó w n e g o
o k n a
p r o g r a m u − r ó w n e wymiarom
//
o d c z y t a n e g o
p l i k u
g r a f i c z n e g o TARGA
g l u t I n i t W i n d o w S i z e
( width , h e i g h t ) ;
//
u t w o r z e n i e
g ł ó w n e g o
o k n a
p r o g r a m u − n a zw a
o k n a
t a k a
// sama
j a k
na z w a
o d c z y t a n e g o
p l i k u
g r a f i c z n e g o TARGA
g l u t C r e a t e W i n d o w
( a r g v [ 1 ] ) ;
//
d o ł ą c z e n i e
f u n k c j i
g e n e r u j ą c e j
s c e n ę
3D − o b r a z
z a w a r t y w
p l i k u TARGA
g l u t D i s p l a y F u n c
( D i s p l a y ) ;
//
d o ł ą c z e n i e
f u n k c j i
w y w o ł y w a n e j
p r z y
z m i a n i e
r o z m i a r u
o k n a
g l u t R e s h a p e F u n c
( Re sha pe ) ;
//
s p r a w d z e n i e
c z y
d a n y
f o r m a t
p l i k u TARGA j e s t
o b s ł u g i w a n y
CheckImageFormat
( ) ;
// podmenu ” F i l t r y ”
i n t
M e n u F i l t e r s = g l u t C r e a t e M e n u
( Menu ) ;
#i f d e f WIN32
glutAddMenuEntry
( ” F i l t r
u ś r e d n i a j ą c y ” ,AVERAGE) ;
glutAddMenuEntry
( ” F i l t r
LP1” , LP1 ) ;
glutAddMenuEntry
( ” F i l t r
LP2” , LP2 ) ;
glutAddMenuEntry
( ” F i l t r
LP3” , LP3 ) ;
glutAddMenuEntry
( ” F i l t r
Gaussa ” ,GAUSS ) ;
glutAddMenuEntry
( ” F i l t r
u s u w a j ą c y
ś r e d n i ą ” ,MEAN REMOVAL) ;
glutAddMenuEntry
( ” F i l t r
HP1” , HP1 ) ;
glutAddMenuEntry
( ” F i l t r
HP2” , HP2 ) ;
glutAddMenuEntry
( ” F i l t r
HP3” , HP3 ) ;
glutAddMenuEntry
( ” F i l t r
poziomy ” ,HORIZONTAL ) ;
glutAddMenuEntry
( ” F i l t r
pionowy ” ,VERTICAL ) ;
glutAddMenuEntry
( ” F i l t r
poziomy / pionowy ” ,HORIZONTAL VERTICAL ) ;
1. Przetwarzanie obrazów
36
glutAddMenuEntry
( ” F i l t r
g r a d i e n t o w y
wschód ” ,GRADIENT EAST ) ;
glutAddMenuEntry
( ” F i l t r
g r a d i e n t o w y
p o ł u d n i o w y
wschód ” ,GRADIENT SOUTH EAST ) ;
glutAddMenuEntry
( ” F i l t r
g r a d i e n t o w y
p o ł u d n i e ” ,GRADIENT SOUTH ) ;
glutAddMenuEntry
( ” F i l t r
g r a d i e n t o w y
p o ł u d n i o w y
z a c h ó d ” ,GRADIENT SOUTH WEST ) ;
glutAddMenuEntry
( ” F i l t r
g r a d i e n t o w y
z a c h ó d ” ,GRADIENT WEST ) ;
glutAddMenuEntry
( ” F i l t r
g r a d i e n t o w y
p ó ł n o c n y
z a c h ó d ” ,GRADIENT NORTH WEST ) ;
glutAddMenuEntry
( ” F i l t r
g r a d i e n t o w y
p ó ł n o c ” ,GRADIENT NORTH ) ;
glutAddMenuEntry
( ” F i l t r
g r a d i e n t o w y
p ó ł n o c n y
wschód ” ,GRADIENT NORTH EAST ) ;
glutAddMenuEntry
( ” F i l t r
u w y p u k l a j ą c y
wschód ” ,EMBOSS EAST ) ;
glutAddMenuEntry
( ” F i l t r
u w y p u k l a j ą c y
p o ł u d n i o w y
wschód ” ,EMBOSS SOUTH EAST ) ;
glutAddMenuEntry
( ” F i l t r
u w y p u k l a j ą c y
p o ł u d n i e ” ,EMBOSS SOUTH ) ;
glutAddMenuEntry
( ” F i l t r
u w y p u k l a j ą c y
p o ł u d n i o w y
z a c h ó d ” ,EMBOSS SOUTH WEST ) ;
glutAddMenuEntry
( ” F i l t r
u w y p u k l a j ą c y
z a c h ó d ” ,EMBOSS WEST ) ;
glutAddMenuEntry
( ” F i l t r
u w y p u k l a j ą c y
p ó ł n o c n y
z a c h ó d ” ,EMBOSS NORTH WEST ) ;
glutAddMenuEntry
( ” F i l t r
u w y p u k l a j ą c y
p ó ł n o c ” ,EMBOSS NORTH ) ;
glutAddMenuEntry
( ” F i l t r
u w y p u k l a j ą c y
p ó ł n o c n y
wschód ” ,EMBOSS NORTH EAST ) ;
glutAddMenuEntry
( ” F i l t r
L a p l a c e ’ a LAPL1” , LAPLACIAN LAPL1 ) ;
glutAddMenuEntry
( ” F i l t r
L a p l a c e ’ a LAPL2” , LAPLACIAN LAPL2 ) ;
glutAddMenuEntry
( ” F i l t r
L a p l a c e ’ a LAPL3” , LAPLACIAN LAPL3 ) ;
glutAddMenuEntry
( ” F i l t r
L a p l a c e ’ a
s k o ś n y ” ,LAPLACIAN DIAGONAL ) ;
#e l s e
glutAddMenuEntry
( ” F i l t r
u ś r e d n i a j ą c y ” ,AVERAGE) ;
glutAddMenuEntry
( ” F i l t r
LP1” , LP1 ) ;
glutAddMenuEntry
( ” F i l t r
LP2” , LP2 ) ;
glutAddMenuEntry
( ” F i l t r
LP3” , LP3 ) ;
glutAddMenuEntry
( ” F i l t r
Gaussa ” ,GAUSS ) ;
glutAddMenuEntry
( ” F i l t r
u s u w a j a c y
s r e d n i a ” ,MEAN REMOVAL) ;
glutAddMenuEntry
( ” F i l t r
HP1” , HP1 ) ;
glutAddMenuEntry
( ” F i l t r
HP2” , HP2 ) ;
glutAddMenuEntry
( ” F i l t r
HP3” , HP3 ) ;
glutAddMenuEntry
( ” F i l t r
poziomy ” ,HORIZONTAL ) ;
glutAddMenuEntry
( ” F i l t r
pionowy ” ,VERTICAL ) ;
glutAddMenuEntry
( ” F i l t r
poziomy / pionowy ” ,HORIZONTAL VERTICAL ) ;
glutAddMenuEntry
( ” F i l t r
g r a d i e n t o w y
wschod ” ,GRADIENT EAST ) ;
glutAddMenuEntry
( ” F i l t r
g r a d i e n t o w y
p o l u d n i o w y
wschod ” ,GRADIENT SOUTH EAST ) ;
glutAddMenuEntry
( ” F i l t r
g r a d i e n t o w y
p o l u d n i e ” ,GRADIENT SOUTH ) ;
glutAddMenuEntry
( ” F i l t r
g r a d i e n t o w y
p o l u d n i o w y
z a c h o d ” ,GRADIENT SOUTH WEST ) ;
glutAddMenuEntry
( ” F i l t r
g r a d i e n t o w y
z a c h o d ” ,GRADIENT WEST ) ;
glutAddMenuEntry
( ” F i l t r
g r a d i e n t o w y
p o l n o c n y
z a c h o d ” ,GRADIENT NORTH WEST ) ;
glutAddMenuEntry
( ” F i l t r
g r a d i e n t o w y
p o l n o c ” ,GRADIENT NORTH ) ;
glutAddMenuEntry
( ” F i l t r
g r a d i e n t o w y
p o l n o c n y
wschod ” ,GRADIENT NORTH EAST ) ;
glutAddMenuEntry
( ” F i l t r
u w y p u k l a j a c y
wschod ” ,EMBOSS EAST ) ;
glutAddMenuEntry
( ” F i l t r
u w y p u k l a j a c y
p o l u d n i o w y
wschod ” ,EMBOSS SOUTH EAST ) ;
glutAddMenuEntry
( ” F i l t r
u w y p u k l a j a c y
p o l u d n i e ” ,EMBOSS SOUTH ) ;
glutAddMenuEntry
( ” F i l t r
u w y p u k l a j a c y
p o l u d n i o w y
z a c h o d ” ,EMBOSS SOUTH WEST ) ;
glutAddMenuEntry
( ” F i l t r
u w y p u k l a j a c y
z a c h o d ” ,EMBOSS WEST ) ;
glutAddMenuEntry
( ” F i l t r
u w y p u k l a j a c y
p o l n o c n y
z a c h o d ” ,EMBOSS NORTH WEST ) ;
glutAddMenuEntry
( ” F i l t r
u w y p u k l a j a c y
p o l n o c ” ,EMBOSS NORTH ) ;
glutAddMenuEntry
( ” F i l t r
u w y p u k l a j a c y
p o l n o c n y
wschod ” ,EMBOSS NORTH EAST ) ;
glutAddMenuEntry
( ” F i l t r
L a p l a c e ’ a LAPL1” , LAPLACIAN LAPL1 ) ;
glutAddMenuEntry
( ” F i l t r
L a p l a c e ’ a LAPL2” , LAPLACIAN LAPL2 ) ;
glutAddMenuEntry
( ” F i l t r
L a p l a c e ’ a LAPL3” , LAPLACIAN LAPL3 ) ;
glutAddMenuEntry
( ” F i l t r
L a p l a c e ’ a
s k o s n y ” ,LAPLACIAN DIAGONAL ) ;
#e n d i f
glutAddMenuEntry
( ” F i l t r
L a p l a c e ’ a poziomy ” ,LAPLACIAN HORIZONTAL ) ;
glutAddMenuEntry
( ” F i l t r
L a p l a c e ’ a pionowy ” ,LAPLACIAN VERTICAL ) ;
glutAddMenuEntry
( ” F i l t r
poziomy
S o b e l a ” ,SOBEL HORIZONTAL ) ;
glutAddMenuEntry
( ” F i l t r
pionowy
S o b e l a ” ,SOBEL VERTICAL ) ;
glutAddMenuEntry
( ” F i l t r
poziomy
P r e w i t t a ” ,PREWITT HORIZONTAL ) ;
glutAddMenuEntry
( ” F i l t r
pionowy
P r e w i t t a ” ,PREWITT VERTICAL ) ;
glutAddMenuEntry
( ” Brak ” ,NONE ) ;
//
u t w o r z e n i e
menu
p o d r ę c z n e g o
g l u t C r e a t e M e n u
( Menu ) ;
#i f d e f WIN32
glutAddMenuEntry
( ” Z w i ę k s z e n i e
j a s n o ś c i
o b r a z u ” , LIGHTNESS INC ) ;
glutAddMenuEntry
( ” Z m n i e j s z e n i e
j a s n o ś c i
o b r a z u ” , LIGHTNESS DEC ) ;
glutAddMenuEntry
( ” Negatyw ” ,NEGATIVE ) ;
glutAddMenuEntry
( ” H i s t o g r a m ” ,HISTOGRAM ) ;
glutAddSubMenu
( ” F i l t r y ” , M e n u F i l t e r s ) ;
glutAddMenuEntry
( ” Z a p i s z ” , SAVE FILE ) ;
glutAddMenuEntry
( ” W y j ś c i e ” , EXIT ) ;
#e l s e
glutAddMenuEntry
( ” Z w i e k s z e n i e
j a s n o s c i
o b r a z u ” , LIGHTNESS INC ) ;
glutAddMenuEntry
( ” Z m n i e j s z e n i e
j a s n o s c i
o b r a z u ” , LIGHTNESS DEC ) ;
1. Przetwarzanie obrazów
37
glutAddMenuEntry
( ” Negatyw ” ,NEGATIVE ) ;
glutAddSubMenu
( ” F i l t r y ” , M e n u F i l t e r s ) ;
glutAddMenuEntry
( ” Z a p i s z ” , SAVE FILE ) ;
glutAddMenuEntry
( ” W y j s c i e ” , EXIT ) ;
#e n d i f
//
o k r e ś l e n i e
p r z y c i s k u
m y s z k i
o b s ł u g u j ą c e j
menu
p o d r ę c z n e
g l u t A t t a c h M e n u
(GLUT RIGHT BUTTON ) ;
//
s p r a w d z e n i e
i
p r z y g o t o w a n i e
o b s ł u g i
w y b r a n y c h
r o z s z e r z e ń
E x t e n s i o n S e t u p
( ) ;
//
w p r o w a d z e n i e
p r o g r a m u
do
o b s ł u g i
p ę t l i
k o m u n i k a t ó w
g l u t M a i n L o o p
( ) ;
return
0 ;
}
Literatura
38
Literatura
[1] Mark Segal, Kurt Akeley: The OpenGL Graphics System. A Specification
Version 2.0
[2] Jackie Neider, Tom Davis, Mason Woo: OpenGL Programming Guide „The
Red Book”
[3] Richard S. Wright jr, Michael Sweet: OpenGL Księga eksperta, Helion 1999
[4] Richard S. Wright jr, Michael Sweet: OpenGL Księga eksperta Wydanie III,
Helion 2005
[5] The official OpenGL web page,
[6] Piotr Andrzejewski, Jakub Kurzak: Wprowadzenie do OpenGL. Programowa-
nie zastosowań graficznych, Kwantum 2000
[7] Kevin Hawkins, Dave Astle: OpenGL. Programowanie gier, Helion 2003
[8] Mark J. Kilgard: The OpenGL Utility Toolkit (GLUT) Programming Interface
API Version 3. Silicon Graphics, Inc. 1996
[9] Mark J. Kilgard: All About OpenGL Extensions,
resources/features/OGLextensions/
[10] Jon Leech: How to Create OpenGL Extensions,
projects/ogl-sample/registry/doc/rules.html
[11] Silicon Graphics, Inc: OpenGL
R
Extension Registry,