Кудлатов Иван, Разработка методов визуализации и обработки

advertisement
Кудлатов Иван, студент
Научный руководитель проф. Г.Г. Швачич
Разработка методов визуализации и обработки двумерных научных данных
Задача наглядного представления и анализа больших массивов числовой
информации актуальна во многих областях науки и техники. Прежде всего, это
моделирование процессов, обработка научных экспериментов, анализ и синтез данных
многочастотного дистанционного зондирования, ультразвукового зондирования,
интерпретации томограмм, решения различных инженерных задач, а также медицинские
исследования. Многим специалистам часто приходится иметь дело с двумерными
наборами данных. Такими наборами могут являться как результаты численного
моделирования, так и данные, полученные с различных приборов.
Отдельным практически важным примером таких данных являются цифровые
изображения. Для получения, обработки и визуализации этих данных требуется
специальное программное обеспечение.
В настоящее время существует достаточно большое количество программных
средств, позволяющих реализовать визуализацию различных научных и инженерных
задач. Однако, как правило, это специальные дорогостоящие программные средства,
ориентированные на узкий класс задач. Типичным представителем такого класса является
программный комплекс Image Pro Plus компании Media Cybernetics, включающий: Image
Pro Plus Inspector, Image Pro Plus MDA, Image Pro Plus 3D, Image Pro Plus AMC и Image
Pro Plus Analizer. Указанный пакет строго ориентирован на исследования в области
медицины и частично на биометрические исследования. Стоимость этого пакета очень
высока, а также он предназначен для работы со специальным оборудованием.
Следует отметить тот факт, что задача обработки научных данных, несомненно,
шире задачи обработки художественной обработки изображений. Трактуя данные в
зависимости от их природы различным способом, например как алгебраические матрицы
или
, можно применять к ним ряд методов алгебры, анализа, математической
статистики, решать дифференциальные и интегральные уравнения. Например, в ряде
случаев, эффективно представлять двумерные данные в виде цифровых изображений.
Наиболее часто пользуются представлением в форме полутоновых или цветных образов,
где определенному диапазону чисел соответствует заданный цветовой оттенок.
Количество цветов и способы цветового сопоставления могут быть различными и зависят
от личных предпочтений и возможностей программных средств. Предположим, что в
результате некого численного эксперимента, получено поле распределение температур в
пластине. Целью его визуализации является получение наглядной информации о
физических явлениях, в результате которых оно сформировалось. Такое поле удобно
представить в виде изображения, сопоставив минимальной температуре - фиолетовый
цвет, а максимальной – красный (рис. 1).
Рис. 1 а) Синтезированное тепловое поле, б) Профиль нагревательного элемента,
создавшего тепловое поле.
После такого представления для интерпретации данных требуется дополнительная
обработка, например подчеркивание деталей, удаление случайных помех и т.п. На рисунке
(Рис.1б) представлен результат обработки этого изображения при помощи его свертки с
маской. На данном изображении четко просматривается контур нагревательного элемента.
В целом ряде случаев для моделирования процессов обработки изображений
можно использовать системы инженерных вычислений. Наиболее мощными из
распространенных систем такого рода можно выделить программные пакеты MatLab и
MathCad. Однако, в указанных пакетах есть серьезные ограничения: это низкая скорость, с
которой подобные пакеты ведут свои вычисления, и необходимость разрабатывать
программу на специализированном внутреннем языке. Более существенным недостатком
указанных систем является тот факт, что они не могут работать с двумерными массивами
данных больших объемов (зависают), например, с цифровыми фотографиями
(двумерными массивами) размером 5 - 10 mp. Также, указанные пакеты достаточно плохо
обеспечивают пространственную визуализацию процессов, объектов. Вследствие чего,
такие пакеты целесообразно использовать в случае, когда необходимо проверить
некоторый метод или возникшую идею.
Следует отметить тот факт, что целый ряд профессиональных приложений уже
изначально имеют дело с изображениями, например, оптическими или рентгеновскими
снимками, магниторезонансными или радиолокационными изображениями. Многие
приборы выдают информацию в форме готовых цифровых изображений.
Таким образом, создать универсальный программный комплекс, решающий
широкий класс научных и инженерных задач в области обработки изображений является
весьма сложной и трудно решаемой задачей, а вот разработать инструментальные базовые
средства и методы для средств разработки приложений является перспективной и
оправданной задачей.
В качестве базовой среды разработки для платформы Windows целесообразно
использовать среду Delphi исходя из того факта, что данная среда весьма популярна и
доступна, является долгожителем (1995 – Delphi 3, 2011 – Delphi XE2) в то время, как
проекты С++ Builder, MS С++, MS VB уже закрыты. Также следует отметить тот факт, что
последние версии Delphi поддерживают новые технологии и являются мультиязычными
(odject pascal, С++, С#).
Целью настоящей работы является разработка и отладка базовых методов
обработки изображений и визуализации информации и создание в перспективе Delphi
компонентов c открытым исходным кодом, позволяющим пользователю направить все
усилия на реализацию методов целевой задачи, а также быстро создавать небольшие и
дешевые приложения, реализующие поставленные задачи.
Стоит вопрос, какие же программные элементы требуются для обработки и
визуализации двумерных данных? Здесь необходимо отметить тот факт, что это не самый
простой вопрос. Известный тезис о том, что спрос рождает предложения, можно отнести к
научному программному и аппаратному обеспечению с некоторой оговоркой. Зачастую
появление новой возможности у вычислительной техники ведет к более широкому
применению научных методик, ранее остававшихся лишь чисто теоретическими. Однако
можно указать ряд возможностей, необходимость которых для обработки описываемых
данных уже на сегодняшний день является очевидной.
Первая из таких возможностей - это чтение исходных данных пользователя,
которые, как правило, хранятся в виде файлов различного типа. Способ хранения данных
во многом определяется способом их получения, например, данные могут являться
результатом работы пользовательской программы, или информацией, полученной от
некого прибора. Файлы, хранящие данные, могут быть текстовыми (матрицы или списки
чисел), двоичными (байтовые массивы, реализующие тот или иной тип данных),
представленными в специализированном научном или техническом формате (CEOS, HDF,
IPW, WSQ и т.п.), стандартными графическими файлами (BMP, TIFF и т.д.).
Второй задачей, следующей за чтением данных, является возможность их
просмотра. Просмотр может осуществляться в различном виде, например в форме таблиц
чисел, в форме изображений, трехмерных поверхностей, линий уровня и т.п. Задача
просмотра должна быть решена таким образом, чтобы пользователь мог охватить набор
данных, как в целом, так и подробно изучить их произвольный участок, вплоть до
значения конкретного элемента. Желательно чтобы этот просмотр, будучи наглядным,
являлся достаточно простым и быстрым, а также не замедлял работу пользователя.
Корректная визуализация чрезвычайно важна, поскольку от нее часто зависит
правильность интерпретации физических явлений, лежащих в основе представленных
данных.
Третья задача - это обработка и анализ данных. Не затрагивая вопросы
узкоспециализированной обработки и анализа, назовем те инструменты, без которых, как
правило, не обойтись. Это интерполяция, позволяющая получить массив данных большего
или меньшего размера. Трансформация, позволяющая осуществлять вырезание участка,
поворот, отражения и подобные преобразования массивов данных. Фильтрация,
удаляющая случайные всплески или шумы аппаратуры. Спектральный анализ,
позволяющий изучить данные в частотной области. Статистический анализ: вычисление
среднего, дисперсии, построение гистограммы. При этом желательно чтобы как
обработка, так и анализ производилась с той же точностью, с которой представлены
исходные данные.
Здесь следует отметить тот факт, что большинство из перечисленных задач
реализованы непосредственно в среде Delphi, либо имеются бесплатные компоненты и
библиотеки третьих лиц.
Важное место в процессе визуализации информации занимает ее трехмерное
представление, позволяющее более глубоко представить картину протекающего процесса
либо рельеф цифровой фотографии объекта. Например, на рисунке 2а представлена
цифровая фотография участка микросхемы, на рисунке 2б показан рельеф с четко
заметными изъянами технологического процесса.
Рис. 2 а) Фотография участка микросхемы
б) Видимые изъяны топологии
Особый интерес представляет собой получение карты высот (рис. 3б),
интерпретирующей некоторые физические свойства объекта (рис. 3а), например,
частотные характеристики (рис. 4а), чистоту спектра (рис. 4б), люминесценцию (рис. 4в),
распределение энергий на фоне реального образа, рельефа структуры материалов и т.д.
Алгоритмы построения карты высот HightMap широко освещены в литературе [2,6]
и в основном описаны для реализации задач в системах ГИС, создания различных
симуляторов и компьютерных игр. Как правило, в указанных системах с целью экономии
памяти и высокого быстродействия применяются малополигональные карты. Однако, для
представления научных данных требуется точное физическое моделирование (оцифровка)
высокополигональных карт.
Рис. 3 а) Капля холестерина в полимерной матрице, б) Нормализованная карта высот
Рис. 4 а) Карта высот канала H, б) Карта высот канала S, в) Карта высот канала L
цветовой модели HSL
Таким образом, для качественного синтеза карты высот из изображения требуется
представление каждого пикселя (элемента разрешения) как узла регулярной сетки. При
этом каждый узел должен соответствовать вершине в спецификации технологии OptnGL.
Следует отметить тот факт, что для повышения видимого разрешения эффективно
применение сплайновой интерполяции. Также важным фактом является нормализация
регулярной сетки, т.е. ее приведение из растровых координат пикселя и стандартной
цветовой модели RGB в GL представление координат и цветов. При этом следует
отметить тот факт, что в GL представлении может быть использована любая цветовая
модель, в том числе определенная пользователем. Таким образом, для точного
представления данных, содержащихся в двумерном массиве, потребуется как минимум
три N-мерных динамических массива, например:
vx:Array of Array of Extended; - массив узлов сетки;
nx:Array of Array of Array[1..3] of Extended; - нормализованный массив;
cx:Array of Array of Array[1..3] of GLfloat; - массив GL цветов.
Тогда, реализация методов построения карты высот будет иметь вид:
{Синтез карты высот}
procedure Reload;
var
i,j,k,n:Integer;
begin
n := 3*10;
SetLength(vx,w);
SetLength(nx,w);
SetLength(cx,w);
for i:=0 to w-1 do
begin
SetLength(vx[i],h);
SetLength(nx[i],h);
SetLength(cx[i],h);
end;
for i:=0 to w-1 do
for j:=0 to h-1 do
begin
vx[i,j]:=(GetRValue(bmp.Canvas.Pixels[i,j]) +
GetGValue(bmp.Canvas.Pixels[i,j]) +
GetBValue(bmp.Canvas.Pixels[i,j]))/n;
cx[i,j,1]:=GetRValue(bmp.Canvas.Pixels[i,j])/255;
cx[i,j,2]:=GetGValue(bmp.Canvas.Pixels[i,j])/255;
cx[i,j,3]:=GetBValue(bmp.Canvas.Pixels[i,j])/255;
end;
for i:=0 to w-1 do
for j:=0 to h-1 do
for k:=1 to 3 do
nx[i,j,k]:=1;
for i:=0 to w-2 do
for j:=0 to h-2 do
CalcNormals(i,vx[i,j],j,
i+1,vx[i+1,j],j,
i+1,vx[i+1,j+1],j+1,
nx[i,j,1],nx[i,j,2],nx[i,j,3]);
end;
{Нормализация сетки}
procedure CalcNormals(x1,y1,z1, x2,y2,z2, x3,y3,z3:Extended;
var nx,ny,nz:Extended);
var
wrki: Double;
vx1,vy1,vz1,vx2,vy2,vz2: Double;
begin
vx1:=x1-x2;
vy1:=y1-y2;
vz1:=z1-z2;
vx2:=x2-x3;
vy2:=y2-y3;
vz2:=z2-z3;
wrki:=sqrt(sqr(vy1*vz2-vz1*vy2)+sqr(vz1*vx2-vx1*vz2)+sqr(vx1*vy2-vy1*vx2));
nx:=-(vy1 * vz2 - vz1 * vy2)/wrki;
ny:=-(vz1 * vx2 - vx1 * vz2)/wrki;
nz:=-(vx1 * vy2 - vy1 * vx2)/wrki;
end;
{Построение карты высот}
procedure BuildMap;
var
i,j,k,dw,dh,dv:Integer;
ps:TPaintStruct;
begin
dw:=0; dh:=0; dv:=0;
if (w>0) and (h>0) then
begin
dw:=w div 2; dh:=h div 2; dv:=25 div 2;
end;
BeginPaint(DrPanel.Handle,ps);
wglMakeCurrent(MyPanels.DC,MyPanels.HRC);
glViewport(0,0,DrPanel.Width,DrPanel.Height);
BeginPaint(DrPanel.Handle,ps);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(30,DrPanel.Width/DrPanel.Height,1,10000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glLoadIdentity;
glTranslatef(0,0,-DBar.Position);
glRotatef(XBar.Position,1,0,0);
glRotatef(YBar.Position,0,1,0);
try
if (w>5) and (h>5) then
begin
if CheckBox1.Checked then // Заливка полигонов - освещенность
begin
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glColor3f(1,1,1);
glBegin(GL_TRIANGLES);
for j:=2 to w-2 do
for k:=2 to h-2 do
begin
glColor3f(cx[j,k,1],cx[j,k,2],cx[j,k,3]);
glNormal3f(nx[j,k,1],nx[j,k,2],nx[j,k,3]);
glVertex3f(j-dw,vx[j,k]-dv,k-dh);
glColor3f(cx[j+1,k,1],cx[j+1,k,2],cx[j+1,k,3]);
glNormal3f(nx[j+1,k,1],nx[j+1,k,2],nx[j+1,k,3]);
glVertex3f(j-dw+1,vx[j+1,k]-dv,k-dh);
glColor3f(cx[j+1,k+1,1],cx[j+1,k+1,2],cx[j+1,k+1,3]);
glNormal3f(nx[j+1,k+1,1],nx[j+1,k+1,2],nx[j+1,k+1,3]);
glVertex3f(j-dw+1,vx[j+1,k+1]-dv,k-dh+1);
end;
for j:=2 to w-2 do
for k:=2 to h-2 do
begin
glColor3f(cx[j,k,1],cx[j,k,2],cx[j,k,3]);
glNormal3f(nx[j,k,1],nx[j,k,2],nx[j,k,3]);
glVertex3f(j-dw,vx[j,k]-dv,k-dh);
glColor3f(cx[j,k+1,1],cx[j,k+1,2],cx[j,k+1,3]);
glNormal3f(nx[j,k+1,1],nx[j,k+1,2],nx[j,k+1,3]);
glVertex3f(j-dw,vx[j,k+1]-dv,k-dh+1);
glColor3f(cx[j+1,k+1,1],cx[j+1,k+1,2],cx[j+1,k+1,3]);
glNormal3f(nx[j+1,k+1,1],nx[j+1,k+1,2],nx[j+1,k+1,3]);
glVertex3f(j-dw+1,vx[j+1,k+1]-dv,k-dh+1);
end;
glEnd;
glDisable(GL_COLOR_MATERIAL);
end else
// Контуры полигонов
begin
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);
glColor3f(1,1,1);
glBegin(GL_LINES);
for j:=2 to w-2 do
for k:=2 to h-2 do
begin
glColor3f(cx[j,k,1],cx[j,k,2],cx[j,k,3]);
glVertex3f(j-dw,vx[j,k]-dv,k-dh);
glColor3f(cx[j,k+1,1],cx[j,k+1,2],cx[j,k+1,3]);
glVertex3f(j-dw,vx[j,k+1]-dv,k+1-dh);
end;
for j:=2 to w-2 do
for k:=2 to h-2 do
begin
glColor3f(cx[j,k,1],cx[j,k,2],cx[j,k,3]);
glVertex3f(j-dw,vx[j,k]-dv,k-dh);
glColor3f(cx[j+1,k,1],cx[j+1,k,2],cx[j+1,k,3]);
glVertex3f(j+1-dw,vx[j+1,k]-dv,k-dh);
end;
glEnd;
end;
end;
except
w:=0;
h:=0;
MessageBox(Handle,'Ошибка при прорисовке изображения',
'Ошибка',MB_OK or MB_ICONERROR);
end;
EndPaint(DrPanel.Handle,ps);
SwapBuffers(MyPanels.DC);
end;
Как уже отмечалось, весьма важным фактом является разработка методов
предварительной обработки изображения, которые состоят из методов доступа к данным и
методам пользователя. Выбор метода доступа к данным определяет общую
эффективность работы программы, ее быстродействие и возможности. Одним, из
наиболее быстрых методов доступа к данным является метод scanline[y], позволяющий
обращаться к данным непосредственно расположенным в оперативной памяти. Ниже
приводятся эффективные методы доступа к пикселю в массиве памяти:
{Установка значения пикселя}
procedure SetPixPoint(src: tbitmap; x,y:integer; B,G,R:byte);
p:pbytearray;
begin
src.PixelFormat :=pf24bit;
p:=src.scanline[y];
p[x*3]:= B; // Blue byte
p[x*3+1]:= G; // Green byte
p[x*3+2]:= R; // Red byte
end;
{Получение значения пикселя}
procedure GetPixPoint(src: tbitmap; x,y:integer; var B,G,R:byte);
var
p:pbytearray;
begin
src.PixelFormat :=pf24bit;
p:=src.scanline[y];
B := p[x*3]; // Blue byte
G := p[x*3+1]; //Green byte
R := p[x*3+2]; //Red byte
end;
На основании приведенных базовых методов весьма легко получить отдельные
характеристики изображения, например значения RGB каналов, либо конвертировать
изображение.
{Выделение цветового канала}
procedure RGBChannel(src: tbitmap; Channel:byte);
var
p0:pbytearray; x,y: Integer;
begin
if Channel <=2 then
begin
src.PixelFormat :=pf24bit;
for y:=0 to src.Height-1 do
begin
p0:=src.scanline[y];
for x:=0 to src.Width-1 do
begin
if Channel = 0 then
begin
p0[x*3+1]:=0; p0[x*3+2]:=0;
end;
if Channel = 1 then
begin
p0[x*3]:=0; p0[x*3+2]:=0;
end;
if Channel = 2 then
begin
p0[x*3]:=0; p0[x*3+1]:=0;
end;
end;
end;
end;
end;
{Серая шкала}
procedure GrayScale(src: tbitmap);
var
p0:pbytearray;
Gray,x,y: Integer;
begin
src.PixelFormat :=pf24bit;
for y:=0 to src.Height-1 do
begin
p0:=src.scanline[y];
for x:=0 to src.Width-1 do
begin
Gray:=Round(p0[x*3]*0.11+p0[x*3+1]*0.59+p0[x*3+2]*0.3);
p0[x*3]:=Gray;
p0[x*3+1]:=Gray;
p0[x*3+2]:=Gray;
end;
end;
end;
Важную роль в обработке научных данных является конвертирование цветовых
моделей. Например, данные представленные в цветовой модели HSL (рис.5 ) позволяют
легко реализовать пространственно-частотные фильтры. Согласно стандарту ICE данные
каналов представляются в диапазоне значений 0-1.
Рис. 5 Физический спектр (модель HSL)
R   R / 255 , G   G / 255 , B   B / 255 ;
Значение светимости определяется из выражения
Lum 
X max  X min
2
,
*
*
где: X max  Max( R , Y max) ; X min  Min ( R , Y min) .
Функции X max и X min представляют собой максимальные и минимальные значения
*
*
сигнала в каналах G , B .
Y max  Max(G * , B * ) , Y min  Min (G * , B * ) .
Степень насыщения определяется из условия:
Sat 
X max  X min
X max  X min , при: Lum  0,5 и X max  X min ;
Sat 
X max  X min
2  X max  X min , при: Lum  0,5 и X max  X min ;
Sat  0 , при: X max  X min .
Тогда цветовой оттенок равен:
Hue  0 , при: X max  X min ;
Hue 
G *  B*
X max  X min , при: R *  X max ;
Hue 
2  B*  R*
X max  X min , при: G *  X max ;
4  R*  G *
1
Hue 
*
X max  X min 6 , при: B *  X max .
Ниже приводятся реализация
реализованный методом scanline[y].
процедур
конвертирования
procedure SetPixHSL(src: tbitmap; x,y:integer; Hue,Sat,Lum:double);
function blimit(vv:integer):integer;
begin
if vv<0 then blimit:=0
else if vv>255 then blimit:=255
else blimit:=vv;
end;
function HueToRGB(m1,m2,h:double):double;
const C1=2/3;
begin
if h<0 then h:=h+1
else if h>1 then h:=h-1;
if 6*h<1 then
result:=(m1+(m2-m1)*h*6)
else if 2*h<1 then
result:=m2
else if 3*h<2 then
result:=(m1+(m2-m1)*(C1-h)*6)
else
result:=m1;
end;
const
C1=1/3;
var
r,g,b:double;
m1,m2:double;
p:pbytearray;
begin
src.PixelFormat :=pf24bit;
p:=src.scanline[y];
if Hue<0 then Hue:=0;
if Hue>1 then Hue:=1;
if Sat<0 then Sat:=0;
if Sat>1 then Sat:=1;
if Lum<0 then Lum:=0;
RGB
в
HSL
if Lum>1 then Lum:=1;
if Sat=0 then begin
r:=Lum; g:=Lum; b:=Lum;
end else
begin
if Lum<=0.5 then
m2:=Lum*(1+Sat)
else
m2:=Lum+Sat-Lum*Sat;
m1:=2*Lum-m2;
r:=HueToRGB(m1,m2,Hue+C1);
g:=HueToRGB(m1,m2,Hue);
b:=HueToRGB(m1,m2,Hue-C1);
end;
p[x*3]:= blimit(trunc(b*255)); // Blue
p[x*3+1]:= blimit(trunc(g*255)); // Green
p[x*3+2]:= blimit(trunc(r*255)); // Red
end;
procedure GetPixHSL(src: tbitmap; x,y:integer; var Hue,Sat,Lum:double);
function D_max(v1,v2:double):double;
begin
if v1>v2 then D_max:=v1 else D_max:=v2;
end;
function D_min(v1,v2:double):double;
begin
if v1<v2 then D_min:=v1 else D_min:=v2;
end;
var
p:pbytearray;
delta,r,g,b,cmax,cmin:double;
begin
src.PixelFormat :=pf24bit;
p:=src.scanline[y];
r:=p[x*3+2]/255; g:=p[x*3+1]/255; b:=p[x*3]/255;
cmax:=D_Max(r,D_Max(g,b)); cmin:=D_Min(r,D_Min(g,b));
Lum:=(cmax+cmin)/2;
if cmax=cmin then begin
Sat:=0;
Hue:=0;
end else begin
if Lum<0.5 then
Sat:=(cmax-cmin)/(cmax+cmin)
else
Sat:=(cmax-cmin)/(2-cmax-cmin);
delta:=cmax-cmin;
if r=cmax then
Hue:=(g-b)/delta
else if g=cmax then
Hue:=2+(b-r)/delta
else
Hue:=4+(r-g)/delta;
Hue:=Hue/6;
if Hue<0 then
Hue:=Hue+1;
end;
end;
С целью разработки и отладки основных методов предварительной обработки
изображений и визуализации научных данных разработано приложение, реализующее
следующую схему (рис. 6).
Рис. 6 Схема предобработки и визуализации данных
Указанная схема позволяет отладить базовые методы для создания компонента
обработки и представления научных данных класса TGLDRAWPANEL, имеющего
открытый интерфейс пользователя и открытый программный код, что в дальнейшем
позволит пользователю самостоятельно обогащать его собственными методами обработки
данных.
Общий вид тестового приложения приведен на рисунке 7, а полный исходный код
проекта приведен в приложении 1 на CD диске.
Рис. 7 Общий вид тестового приложения
Литература
1. Иващенко В.П., Швачич Г.Г., Овсянников А.В.. Основы информационных технологий
и программирование в среде Delphi. Днепропетровск, РВА ”Днiпро- VAL”, 2008, 464с.
2. В.Н.Порев. "Компьютерная графика". С.-Петербург: BHV-Петербург, 2002.
3. К.Линдли. "Практическая обработка изображений на языке Си". Москва: Мир, 1996.
4. Michael J. Laszlo. "Computation Geometry and Computer Graphics in C++". Prentice Hall,
Inc., A Simon & Schuster Company, 1996.
5. David S. Ebert (ed.), F. Kenton Musgrave, Darwyn Peachey, Ken Perlin, Steven Worley.
"Texturing and Modeling. A Procedural Approach", AP Professional, Academic Press, 1994.
6.
Е.В.Шикин, А.В.Боресков. "Компьютерная графика. Динамика, реалистические
изображения". М.: Диалог-МИФИ, 1995.
7. М.Ву, Т.Девис, Дж.Нейдер, Д.Шрайнер "OpenGL. Руководство по программированию",
4-е издание, С.-Петербург: Питер, 2006
Download