Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

RedBook

.pdf
Скачиваний:
18
Добавлен:
11.06.2015
Размер:
7.43 Mб
Скачать

Цветовые таблицы задаются тем же образом, что и одномерные изображения. Как показано на рисунке 8-15, существует 3 цветовые таблицы для изменения цветовых величин, и все они задаются командой glColorTable().

void glColorTable (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *data);

Если target равно GL_COLOR_TABLE, GL_POST_CONVOLUTION_COLOR_TABLE или

GL_POST_COLOR_MATRIX_COLOR_TABLE, настраивает соответствующую цветовую таблицу, а если GL_PROXY_COLOR_TABLE, GL_PROXY_POST_CONVOLUTION_COLOR_TABLE или GL_ PROXY_POST_COLOR_MATRIX_COLOR_TABLE – проверяет, что заданная цветовая таблица может быть размещена в доступных ресурсах. Аргумент internalFormat используется, чтобы указать внутреннее представление данных в OpenGL. Он может принимать следующие символические значения – GL_ALPHA, GL_ALPHA4, GL_ALPHA8, GL_ALPHA12, GL_ALPHA16, GL_LUMINANCE, GL_LUMINANCE4, GL_LUMINANCE8, GL_LUMINANCE12, GL_LUMINANCE16, GL_LUMINANCE_ALPHA, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE6_ALPHA2, GL_LUMINANCE_8ALPHA8, GL_LUMINANCE12_ALPHA4, GL_LUMINANCE12_ALPHA12, GL_LUMINANCE16_ALPHA16, GL_INTENSITY, GL_INTENSITY4, GL_INTENSITY8, GL_INTENSITY12, GL_INTENSITY16, GL_RGB, GL_R3_G3_B2, GL_RGB4, GL_RGB5, GL_RGB8, GL_RGB10, GL_RGB12, GL_RGB16, GL_RGBA, GL_RGBA2, GL_RGBA4, GL_RGB5_A1, GL_RGBA8, GL_RGB10_A2, GL_RGBA12, GL_RGBA16. Параметр width, который должен быть степенью 2, индицирует количество пикселей в цветовой таблице. Аргументы format и type описывают формат и тип данных цветовой таблицы. Они имеют такое же значение, как и эквивалентные параметры команды glDrawPixels().

Внутренний формат таблицы определяет то, какие компоненты пикселей изображения будут заменены. Например, если вы задаете GL_RGB в качестве формата, то красный,

зеленый и синий компоненты каждого входящего пикселя будут искаться в соответствующей цветовой таблице и заменяться значениями оттуда. Таблица 8-8 описывает, какие компоненты пикселей будут заменяться при различных внутренних форматах.

Таблица 8-8 Замена значений пикселей цветовой таблицей

Базовый внутренний

Красный

Зеленый

Синий

Альфа

формат

компонент

компонент

компонент

компонент

GL_ALPHA

не изменяется

не изменяется

не изменяется

 

GL_LUMINANCE

 

 

 

не изменяется

GL_LUMINANCE_ALPHA

 

 

 

 

GL_INTENSITY

 

 

 

 

GL_RGB

 

 

 

не изменяется

GL_RGBA

 

 

 

 

 

 

 

 

 

В таблице 8-8 величины представляют собой светлоту в цветовой таблице, которая

влияет только на красный, зеленый и синий компоненты. представляет табличные интенсивности, которые одинаково влияют на красный, зеленый, синий и альфа компоненты.

После того как таблица была применена к изображению, пиксели могут быть смасштабированы и скошены, после чего, их значения приводятся к диапазону [0; 1].

Факторы GL_COLOR_TABLE_SCALE и GL_COLOR_TABLE_BIAS для каждой таблицы устанавливаются с помощью команды glColorTableParameter*().

void glColorTableParameter{if}v (GLenum target, GLenum pname, TYPE *param);

Устанавливаетпараметры GL_COLOR_TABLE_SCALE и GL_COLOR_TABLE_BIAS для каждой таблицы. target может быть равно GL_COLOR_TABLE, GL_POST_CONVOLUTION_COLOR_TABLE или GL_POST_COLOR_MATRIX_COLOR_TABLE и

задает целевую таблицу, для которой устанавливаются параметры. Возможными значениями для pnamee являются GL_COLOR_TABLE_SCALE и GL_COLOR_TABLE_BIAS.

Величина param указывает на массив из 4-ех величин, представляющих, соответственно, модификаторы для красного, зеленого, синего и альфа компонент.

Пример 8-5 показывает, как изображение может быть инвертировано посредством цветовой таблицы. Таблица настраивается таким образом, чтобы она заменяла каждый цвет на его инверсию. Пример инвертированного цветовой таблицей изображения приведен на рисунке 8-16.

Рисунок 8-16. Исходное изображение айсберга (слева) и то же изображение, инвертированное с помощью цветовой таблицы (справа))

Пример 8-5. Замена пикселей с использованием цветовой таблицы: файл colortable.cpp

#include <glut.h> #include <GL/glaux.h> #include "glext.h"

//Массив для исходного изображения

AUX_RGBImageRec *image;

//Тип и указатель для функции цветовой таблицы (EXTENSION) typedef void (APIENTRY * GLCOLORTABLE)

(GLenum target,GLenum internalFormat,GLsizei width, GLenum format, GLenum type, const GLvoid *data);

GLCOLORTABLE glColorTable=NULL;

void init()

{

int i;

GLubyte colorTable[256][3];

//Загрузить исходное изображение из 24-разрядного файла BMP

//(библиотека GLAUX) image=auxDIBImageLoad("peak.bmp");

//Получить адрес функции цветовой таблицы

//с помощью функции специфической для реализации OpenGL для

Windows glColorTable=(GLCOLORTABLE)wglGetProcAddress("glColorTable");

if (glColorTable==NULL)

{

MessageBox(NULL, "Function [glColorTable] from [GL_ARB_imaging] extension not supported!",

"Pixel Replacement Using Color Tables", MB_OK|MB_ICONSTOP);

exit(1);

}

glPixelStorei(GL_UNPACK_ALIGNMENT,1); glClearColor(0,0,0,0);

//Инвертирующая цветовая таблица for(i=0;i<256;++i)

{

colorTable[i][0]=255-i; colorTable[i][1]=255-i; colorTable[i][2]=255-i;

}

glColorTable(GL_COLOR_TABLE,GL_RGB,256, GL_RGB,GL_UNSIGNED_BYTE,colorTable);

glEnable(GL_COLOR_TABLE);

}

void deinit()

{

//Очислитьпамять delete image;

}

void reshape(int w, int h)

{

glViewport(0,0,(GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0,500,0,500);

}

void display()

{

glClear(GL_COLOR_BUFFER_BIT); glRasterPos2i(1,1); glDrawPixels(image->sizeX, image->sizeY,

GL_RGB,GL_UNSIGNED_BYTE,image->data);

glFlush();

}

int APIENTRY WinMain(HINSTANCE hInstance,

HINSTANCE

hPrevInstance,

LPSTR

lpCmdLine,

int

nCmdShow)

{

 

char* argv="";

 

int argc=0;

 

glutInit(&argc,&argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowSize(540,405);

glutCreateWindow("Pixel Replacement Using Color Tables"); init();

glutDisplayFunc(display);

glutReshapeFunc(reshape);

glutMainLoop();

deinit(); return 0;

}

Замечание: Поскольку загрузка изображения должна производиться способом, зависящим от вашей оконной системы, а также потому, что в GLUT нет подобных функций, в данном примере используется функция auxDIBImageLoad() из библиотеки GLAUX для Windows.

Вместо того, чтобы задавать цветовую таблицу непосредственно из вашего приложения, вам может понадобиться использовать в качестве нее изображение, созданное в буфере кадра. Команда glCopyColorTable() позволяет вам задать ряд пикселей, которые считываются из буфера кадра и используются в качестве цветовой таблицы.

void glCopyColorTable (GLenum target, GLenum internalFormat, GLint x, GLint y, GLsizei width);

Создает цветовую таблицу, используя данные из буфера кадра в качестве данных для цветовой таблицы. Пиксели считываются из текущего буфера для чтения (GL_READ_BUFFER) и обрабатываются так же как при вызове glCopyPixels(), но без последней конверсии. Учтите, что производятся также операции, заданные glPixelTransfer*(). Параметры target и internalFormat имеют то же значение, что и для glColorTable(). Цветовой массив будет состоять из width пикселей вправо, начиная с (x, y) буфера кадра.

8.2.5.1.2Замена всей цветовой таблицы или ее части

Если вам требуется заменить часть цветовой таблицы, вы можете загрузить ее секцию с помощью команд glColorSubTable() и glCopyColorSubTable().

void glColorSubTable (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);

Заменяет вхождения [start;start+count-1] цветовой таблица на величины, находящиеся в data. Параметр target может принимать значения GL_COLOR_TABLE, GL_POST_CONVOLUTION_COLOR_TABLE, GL_POST_COLOR_MATRIX_COLOR_TABLE.

Параметры format и type идентичны соответствующим параметрам glColorTable().

void glCopyColorSubTable (GLenum target, GLsizei start, GLint x, GLint y, GLsizei count);

Заменяет вхождения [start;start+count-1] цветовой таблица на countцветовых величин пикселей из ряда буфера кадра, начинающегося с позиции (x; y). Пиксели конвертируются в internalFormat оригинальной таблицы.

8.2.5.1.3Запрос величин цветовых таблиц

Величины пикселей, сохраненные в цветовой таблице, могут быть получены с помощью команды glGetColorTable().

8.2.5.1.4Проверка цветовых таблиц

Прокси цветовых таблиц позволяют заставить OpenGL выяснить, достаточно ли в системе ресурсов для размещения вашей цветовой таблицы. Если glColorTable() вызывается с одним из следующих аргументов:

GL_PROXY_COLOR_TABLE

GL_PROXY_POST_CONVOLUTION_COLOR_TABLE

GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE

OpenGL проверяет, есть ли ресурсы для размещения соответствующей таблицы. Если таблица не влезает, ее величины width, format и type устанавливаются в 0. Если вы хотите выяснить, достаточно ли ресурсов проверьте одну из этих величин. Например, так:

glColorTable(GL_PROXY_COLOR_TABLE, GL_RGB, 1024, GL_RGB, GL_UNSIGNED_BYTE, NULL);

glGetColorTableParameteriv(GL_PROXY_COLOR_TABLE, GL_COLOR_TABLE_WIDTH, &width);

if(width==0)

/*цветовая таблица не умещается*/

8.2.5.2Весовые модификаторы

Весовые модификаторы (convolutions) работают в качестве фильтров, заменяя каждый

пиксель изображения на взвешенное среднее соседствующих с ним пикселей и его самого. Размытие изображения, нахождение ребер и изменение контраста являются примерами применения весовые модификаторы.

На рисунке 8-18 показано, как пиксель и соседние с ним обрабатываются весовым модификатором размера 3x3 для получения пикселя .

Рисунок 8-17. Операция пиксельной фильтрации

Весовые модификаторы это массивы весов пикселей, и работают они только на RGBA пикселях. Фильтр, также известный как kernel, является простым двумерным массивом весов. Каждый пиксель изображения результата создается умножением группы

входящих пикселей на весовые коэффициенты фильтра и суммированием

получившихся произведений. Например, на рисунке 8-17 пиксель вычисляется суммированием произведений 9-ти пикселей из входящего изображения на 9 весовых коэффициентов из фильтра.

void glConvolutionFilter2D (GLenum target,GLenum internalFormat,GLsizei width,GLsizei height,

GLenum format,GLenum type,const GLvoid *image);

Задает двумерный фильтр. Параметр filter должен быть равен GL_CONVOLUTION_3D. internalFormat задает, над какими компонентами пикселей будет производиться фильтрация и может принимать одно из 38 значений, перечисленных для аргумента internalFormat команды glColorTable(). Аргументы width и height задают размеры

фильтра в пикселях. Максимальная ширина и высота для фильтров может быть получена с помощью команды glGetConvolutionParameter*(). Как и в случае glDrawPixels(), аргументы format и type задают формат пикселей, сохраненных в массиве, на который указывает image.

Как и для цветовых таблиц, внутренний формат фильтра определяет то, с какими компонентами пикселей требуется работать. Таблица 8-9 описывает, как различные

форматы влияют на пиксели. , , и представляют цветовые компоненты исходных пикселей. представляет собой величину светлоты фильтра

GL_LUMINANCE, а -- величину интенсивности фильтра GL_INTENSITY. Наконец, , , и представляют красный, зеленый, синий и альфа компоненты фильтра.

Таблица 8-9. Влияние фильтров на RGBA компоненты пикселей

Базовый формат

Результат по

Результат по

Результат по

Результат по

красному

зеленому

синему

альфа

фильтра

компоненту

компоненту

компоненту

компоненту

 

GL_ALPHA

не изменяется

не изменяется

не изменяется

 

GL_LUMINANCE

 

 

 

не изменяется

GL_LUMINANCE_ALPHA

 

 

 

 

GL_INTENSITY

 

 

 

 

GL_RGB

 

 

 

не изменяется

GL_RGBA

 

 

 

 

 

 

 

 

 

Чтобы активизировать 2D фильтрацию, используйте glEnable (GL_CONVOLUTION_2D).

Пример 8-6 демонстрирует использование нескольких 2D фильтров GL_LUMINANCE размером 3x3 для поиска ребер в RGBизображении. Клавиши ‘h’, ‘v’ и ‘l’ переключают режимы.

Результат работы программы можно увидеть на рисунке 8-18 (яркость и контрастность изображений увеличена для наглядности). Слева вверху находится исходное изображение пирамиды, справа вверху то же изображение, обработанное фильтром, позволяющим обнаружить горизонтальные ребра, внизу слева похожий фильтр, но на этот раз вертикальный, справа внизу изображение обработанное фильтром Лапласа.

Рисунок 8-18. Пример обработки изображения двумерным фильтром для обнаружения

ребер

Пример 8-6. Использование двумерных фильтров: файл convolution.cpp

#include <windows.h> #include <glut.h> #include <GL/glaux.h> #include "glext.h"

//Указатель на память, где будет содержаться картинка

AUX_RGBImageRec *image;

//Определить фильтры

GLfloat horizontal[3][3]={{0,-1,0},{0,1,0},{0,0,0}}; GLfloat vertical[3][3]= {{0,0,0},{-1,1,0},{0,0,0}}; GLfloat laplacian[3][3]= {{-0.125,-0.125,-0.125},

{-0.125,1,-0.125}, {-0.125,-0.125,-0.125}};

//Тип и указатель для фильтра (если конечно расширение поддерживается)

typedef void (APIENTRY * GLCONVOLUTIONFILTER2D)

(GLenum target,GLenum internalFormat,GLsizei width, GLsizei height,GLenum format, GLenum type, const GLvoid

*data);

GLCONVOLUTIONFILTER2D glConvolutionFilter2D=NULL;

void init()

{

//Проверяем, присутствует ли расширение GL_ARB_imaging (imaging subset)

if (glutExtensionSupported("GL_ARB_imaging")==0)

{

MessageBox(NULL,"ARB_imaging extension not supported", "Using Two-Dimensional Convolution

Filters",MB_OK|MB_ICONHAND); exit(1);

}

//Получаем указатель на функцию расширения glConvolutionFilter2D=(GLCONVOLUTIONFILTER2D)

wglGetProcAddress("glConvolutionFilter2D");

//Загружаем любую непалитровую картинку BMP image=auxDIBImageLoad("peak.bmp"); glPixelStorei(GL_UNPACK_ALIGNMENT,1); glClearColor(0,0,0,0);

}

void deinit()

{

//Освобождаемпамять delete image;

}

void keyboard(unsigned char key, int x, int y)

{

switch(key)

{

case 'h':

MessageBox(NULL,"Using horizontal filter", "Using Two-Dimensional Convolution

Filters",MB_OK);

glConvolutionFilter2D(GL_CONVOLUTION_2D,GL_LUMINANCE,3,3,

GL_LUMINANCE,GL_FLOAT,horizontal); glEnable(GL_CONVOLUTION_2D); break;

case 'v':

MessageBox(NULL,"Using vertical filter", "Using Two-Dimensional Convolution

Filters",MB_OK);

glConvolutionFilter2D(GL_CONVOLUTION_2D,GL_LUMINANCE,3,3,

GL_LUMINANCE,GL_FLOAT,vertical); glEnable(GL_CONVOLUTION_2D); break;

case 'l':

MessageBox(NULL,"Using laplacian filter", "Using Two-Dimensional Convolution

Filters",MB_OK);

glConvolutionFilter2D(GL_CONVOLUTION_2D,GL_LUMINANCE,3,3,

GL_LUMINANCE,GL_FLOAT,laplacian); glEnable(GL_CONVOLUTION_2D); break;

case 'r':

MessageBox(NULL,"No filter used", "Using Two-Dimensional Convolution

Filters",MB_OK);

glDisable(GL_CONVOLUTION_2D);

break; case 27:

exit(0);

}

glutPostRedisplay();

}

void reshape(int w, int h)

{

glViewport(0,0,(GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0,540,0,405);

}

void display()

{

glClear(GL_COLOR_BUFFER_BIT); glRasterPos2i(1,1); glDrawPixels(image->sizeX,image->sizeY,GL_RGB,

GL_UNSIGNED_BYTE,image->data);

glFlush();

}

int APIENTRY WinMain(HINSTANCE hInstance,

HINSTANCE

hPrevInstance,

LPSTR

lpCmdLine,

int

nCmdShow)

{

 

char* argv=""; int argc=0;

glutInit(&argc,&argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowSize(540,405);

glutCreateWindow("Using Two-Dimensional Convolution Filters"); init();

glutDisplayFunc(display);

glutReshapeFunc(reshape);

glutKeyboardFunc(keyboard);

glutMainLoop();

deinit(); return 0;

}

Как и в случае с цветовыми таблицами, вы можете задать фильтр с помощью пиксельных величин, взятых из буфера кадра. Команда glCopyConvolutionFilter2D() копирует прямоугольник пикселей из текущего буфера для чтения (GL_READ_BUFFER) для использования в качестве данных фильтра. Если в качестве внутреннего формата используется GL_LUMINANCE или GL_INTENSITY, то в качестве величин фильтра берутся красные компоненты пикселей.

void glCopyConvolutionFilter2D (GLenum target, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height);

Задает двумерный фильтр, инициализируя его пикселями из цветового буфера кадра. Аргумент target должен иметь значение GL_CONVOLUTION_2D, а internalFormat должен быть установлен в одно из значений, допустимых для glConvolutionFilter2D().

Прямоугольник пикселей с левым нижним углом в точке (x; y) и размерами width и height считывается из буфера кадра и конвертируется в internalFormat.

8.2.5.2.1Разделяемые двумерные фильтры

Соседние файлы в предмете Компьютерная Графика