29
1 Conteúdos 1. Introdução ......................................................................................................................... 2 2. The Visualization Toolkit ................................................................................................. 3 2.1. A Biblioteca VTK...................................................................................................... 3 2.2 Conjuntos de Dados .................................................................................................... 4 2.3 Organização do Volume de Dados ............................................................................. 5 2.4 A Estrutura de Classes do VTK.................................................................................. 6 3. Triangulação de Delaunay .............................................................................................. 10 3.1 Algoritmo quadrático................................................................................................ 10 4. Métodos Utilizados ......................................................................................................... 12 5. Resultados....................................................................................................................... 18 6- Conclusão ....................................................................................................................... 22 Apêndice ............................................................................................................................. 23 Visualização Científica Mª Mafalda Sousa

Conjuntos de Dadostavares/ensino/VISCI/Trabalhos/2003-2004... · qualquer outro que representam malhas planares irregulares. De facto, há filtros que

Embed Size (px)

Citation preview

1

Conteúdos

1. Introdução......................................................................................................................... 2 2. The Visualization Toolkit................................................................................................. 3

2.1. A Biblioteca VTK...................................................................................................... 3 2.2 Conjuntos de Dados.................................................................................................... 4 2.3 Organização do Volume de Dados ............................................................................. 5 2.4 A Estrutura de Classes do VTK.................................................................................. 6

3. Triangulação de Delaunay.............................................................................................. 10

3.1 Algoritmo quadrático................................................................................................ 10 4. Métodos Utilizados......................................................................................................... 12 5. Resultados....................................................................................................................... 18 6- Conclusão....................................................................................................................... 22 Apêndice............................................................................................................................. 23

Visualização Científica Mª Mafalda Sousa

2

1. Introdução

O objecto de trabalho insere-se na área de visualização científica e consiste na exploração

e aplicação do software VTK. Em particular serão focados métodos de triangulação e de

manipulação de dados.

Será usada a triangulação 2D de Delaunay a partir das ferramentas do vtk de forma a

construir uma topologia a partir de pontos não estruturados de uma imagem. Para tal é

feita a importação de uma imagem BMP e a obtenção das coordenadas dos pontos que a

definem. A partir desses pontos criada uma estrutura de pontos sobre a qual será feita a

triangulação.

Serão ainda exploradas técnicas de visualização como sendo a inserção de texto e a

renderização.

Visualização Científica Mª Mafalda Sousa

3

2. The Visualization Toolkit

2.1. A Biblioteca VTK

O Visualization ToolKit é um sistema de software de código aberto para computação

gráfica 3D, processamento de imagens, e visualização, usado por milhares de

pesquisadores e investigadores em todo o mundo. Consiste numa biblioteca de classes em

C++ e várias camadas de interfaces interpretadas, incluindo Tcl/Tk, Java, e Python, e

suporta uma ampla variedade de algoritmos de visualização para diferentes tipos de dados.

Também são implementadas técnicas de modelagem avançadas como modelagem

implícita, redução de polígonos, suavização de malhas e triangulação de Delaunay.

O projecto e a implementação da biblioteca foram fortemente influenciados pelos

princípios de orientação a objectos, e o software foi instalado e testado em quase todas as

plataformas baseadas em Unix e Windows.

O modelo de programação do VTK adopta o paradigma de fluxo de dados. Nesse

paradigma, módulos são conectados para formar uma rede que descreve um canal

(pipeline) de processamento de dados. Os módulos executam operações algorítmicas sobre

os dados enquanto eles fluem pelo pipeline.

No modelo VTK há dois tipos básicos de objectos: objectos de processos e objectos de

dados. Objectos de processo são os módulos do pipeline, e objectos de dados representam

os dados nos vários estágios no pipeline. Essencialmente, o investigador está ciente apenas

dos objectos de processos e os objectos de dados “vivem” entre os objectos de processo.

Figura 2.1: Modelo VTK. Objectos de processos A, B e C são objectos fonte,

filtro e mapeador, respectivamente.

Objectos de processo são de três tipos: fontes, filtros e mapeadores (ver figura 2.1).

Objectos fontes são encontrados no início do pipeline, e geram uma ou mais saídas de

dados. Um objecto fonte pode ser um leitor para um tipo de arquivo particular ou pode

gerar seu próprio dado, como o objecto vtkSphereSource, que cria uma representação

Visualização Científica Mª Mafalda Sousa

4

(objecto de dados) de uma esfera poligonal. A saída desse objecto fonte pode então ser

conectada à entrada de outro objecto de processo. O acto de conectar a entrada de um

objecto de processo à saída de outro objecto de processo define como o pipeline está

construído. Por exemplo, para conectar a saída do filtro A à entrada do filtro B, é usada a

seguinte construção:

B->SetInput( A->GetOutput( ) );

Como as conexões podem ser múltiplas (uma saída pode ser entrada de vários objectos), as

conexões podem, de facto, tornarem-se numa rede (network) de visualização, em vez de

um pipeline simples. Cada objecto de processo gera apenas uma saída. O pipeline ou rede

termina com mapeadores. Um mapeador mapeia a sua entrada para a tela (render).

Nesse estágio do pipeline, a entrada para o mapeador é a saída de algum filtro que gera

dados geométricos (vtkPolyData). Os dados geométricos são objectos de dados como

qualquer outro que representam malhas planares irregulares. De facto, há filtros que

trabalham com dados geométricos, como algoritmos de triangulação (vtkTriangleFilter). O

mapeador é associado a um objecto chamado vtkActor, que representa um objecto

geométrico e os seus atributos na cena. Informações num vtkActor incluem os atributos de

aparência do objecto (vtkProperty) e sua localização no espaço.

Como resultado, o investigador instancia pelo menos um vtkActor para cada mapeador no

pipeline do VTK, e um mapeador para cada objecto geométrico que deverá ser

renderizado. O investigador ajusta cada atributo de cada vtkActor e adiciona cada

vtkActor a uma janela de renderização, usada por uma instância da classe de

vtkRenderWindow. A janela resultante exibe todos os actores a ela associados.

Uma das principais vantagens do VTK são os seus recursos para interacção com os

gráficos 3D gerados. Tais recursos possibilitam que o usuário “navegue” através dessas

imagens, e, consequentemente, através dos dados. A classe do VTK chamada

vtkRenderWindowInteractor é a responsável por transformar eventos do rato e teclado em

modificações aos actores e câmaras que compõem a visualização. Operações como

rotação, translação, escala e “trackball” estão implementadas, entre outras.

2.2 Conjuntos de Dados

Os dados em visualização científica podem ser definidos sobre domínios 2D, 3D e,

genericamente, multidimensionais. Geralmente, um conjunto de dados possui uma certa

Visualização Científica Mª Mafalda Sousa

5

organização como uma malha (ou grade) de células. As células também são elementos de

volumes unitários, porém os dados estão posicionados nos seus vértices, enquanto que, nos

voxels, os dados estão armazenados em seu interior. Os valores podem ser obtidos no

interior de células através de interpolação. (figura 2.2).

Figura 2.2: (a) Malha regular volumétrica, (b) malha de voxels, (c) malha de

células.

Os dados também podem constituir um conjunto de pontos esparsos ou malhas

geométricas de outra natureza. Além disso, as informações associadas a cada ponto da

malha podem ser um ou mais valores escalares, vectoriais ou tensoriais.

Um conjunto de dados consiste de duas partes: uma estrutura de organização e atributos de

dados complementares associados à estrutura. A estrutura tem duas partes: uma topologia

e uma geometria. A topologia é um conjunto de propriedades invariantes sob certas

transformações geométricas (como por exemplo, rotação e translação). A geometria é a

instanciação da topologia, ou seja, a especificação da posição no espaço 3D. Por exemplo,

quando se declara que um polígono é um ``triângulo'', está-se a especificar a topologia. E

quando se fornece as coordenadas dos pontos, está-se a especificar a geometria. Os

atributos, por sua vez, são informações complementares que podem estar associadas tanto

à geometria como à topologia .

2.3 Organização do Volume de Dados

O volume de dados representa o trecho do espaço 3D onde se localiza o objecto, dado ou

cena a ser renderizada. Uma malha faz referência à organização do volume de dados.

Existem diferentes tipos de malhas: Em uma malha cartesiana todos os elementos são

quadrados (no caso 2D) ou cubos idênticos (no caso 3D), alinhados aos eixos principais. É

a forma ideal de estrutura, pois permite o acesso mais rápido aos dados. Uma malha

Visualização Científica Mª Mafalda Sousa

6

regular tem todos os seus elementos idênticos e alinhados aos eixos, mas esses elementos

são rectângulos ou paralelepípedos de dimensões constantes. Elementos de uma malha

rectilínea são quadriláteros ou hexaedros alinhados aos eixos, mas não necessariamente

idênticos. Elementos de uma malha estruturada são quadriláteros ou hexaedros não

alinhados aos eixos principais, como os que aparecem em grades esféricas ou curvilíneas.

Uma malha estruturada em blocos é um conjunto de malhas estruturadas agrupadas. Uma

malha não-estruturada contém polígonos ou poliedros sem qualquer padrão explícito de

conectividade. No caso 3D, as células podem ser tetraedros, hexaedros, pirâmides, etc.

Uma malha híbrida é uma combinação de quaisquer dos tipos anteriores (figura 2.3).

Figura 2.3: Tipos de malhas: (a) Cartesiana, (b) Regular, (c) Rectilínea,

(d) Estruturada, (e) Não-estruturada.

2.4 A Estrutura de Classes do VTK

Abaixo seguem algumas das classes presentes no VTK que representam os conjuntos de

dados suportados pela biblioteca e seus mapeadores. Todos os objectos criados no VTK,

com poucas excepções, são especializações (subclasses) da classe abstracta vtkObject ou

de um de seus filhos. Essa classe base fornece métodos de controlo para cada objecto

criado pela biblioteca, incluindo triagem do tempo de modificações, depuração e

impressão.

Os conjuntos de dados de visualização suportados pelo VTK são mostrados na figura 2.4.

Para a representação desses conjuntos de dados foi criada a classe genérica vtkDataObject.

Objectos do tipo “conjunto de dados” (datasets) implementam os tipos de dados

fundamentais tipicamente usados em visualização. Esses objectos de dados são entrada e

saída de fontes, filtros e mapeadores. A classe abstracta vtkDataSet especifica uma

interface que todas as classes derivadas precisam fornecer. Ela também provê métodos que

fornecem informações sobre os dados, tais como o centro do objecto, caixa de bordo

(limites espaciais do domínio de dados) e largura representativa (comprimento da diagonal

da caixa de borda). Um conjunto de dados no VTK consiste de uma estrutura definida por

Visualização Científica Mª Mafalda Sousa

7

geometria e topologia, e de atributos de dados associados, sendo composto por um ou mais

pontos e células. A figura 2.5 mostra o diagrama de classes do vtkDataSet e suas

subclasses. O tipo de um conjunto de dados é determinado pela sua estrutura de

organização, e especifica o relacionamento que as células e pontos têm entre si.

Figura 2.4: Tipos de conjuntos de dados (datasets) do VTK. A ``Malha Não

Estruturada'' consiste de todos os tipos de célula.

Para trabalhar com malhas do tipo cartesiana, o VTK possui uma classe chamada

vtkStructuredPoints. A vtkStructuredPoints representa uma estrutura geométrica que é

uma matriz de pontos topologicamente e geometricamente regular. Essa estrutura é

utilizada para o armazenamento de figuras bidimensionais, como texturas, e dados

Visualização Científica Mª Mafalda Sousa

8

volumétricos para a representação em DVR ou reconstrução. A classe vtkRectilinearGrid

representa uma malha rectilínea.

A classe abstracta vtkPointSet especifica a interface para conjuntos de dados que usam

explicitamente matrizes de pontos para representar geometria. Por exemplo, vtkPolyData e

vtkUnstructuredGrid requerem matrizes de pontos para especificar as posições dos pontos,

enquanto vtkStructuredPoints gera posições de pontos implicitamente.

A vtkStructuredGrid representa uma malha estruturada. A classe vtkUnstrucuredGrid

consiste de uma combinação arbitrária de células 2D e 3D, além de pontos. Geometria e

Topologias são explicitamente definidas.

Visualização Científica Mª Mafalda Sousa

9

Figura 2.5: Diagrama de objectos dos tipos de dados do VTK herdeiros de vtkDataSet.

A maioria das fontes do VTK gera objectos no formato ``dados poligonais'', ou PolyData,

que é um tipo de conjunto de dados que pode ser facilmente renderizado para bibliotecas

gráficas. A classe vtkPolyData representa esse tipo de estrutura geométrica, consistindo de

vértices, linhas, polígonos e faixa de triângulos. Ela é a estrutura utilizada durante o

processo de renderização dos conjuntos de dados geométricos do VTK, que ocorre através

da classe vtkPolyDataMapper.

A classe vtkPolyDataMapper é a classe que mapeia dados poligonais (PolyData) para

primitivas gráficas renderizáveis. Ela é uma super classe de mapeadores poligonais para

dispositivos específicos, como a biblioteca OpenGL. O usuário não precisa seleccionar

qual dispositivo o VTK usará. Ele simplesmente aloja um mapeador de dados poligonais e

o VTK escolhe o dispositivo adequado para a renderização.

Para os outros tipos de dados, é utilizada a classe vtkDataSetMapper, que é um mapeador

de conjuntos de dados (vtkDataSet e todas classes derivadas) para primitivas gráficas. A

classe vtkDataSetMapper não possui subclasses específicas. O processo de renderização

desse mapeador converte o conjunto de dados (DataSet) para dados poligonais (PolyData)

através de um filtro e renderiza utilizando o vtkPolyDataMapper.

Visualização Científica Mª Mafalda Sousa

10

3. Triangulação de Delaunay

A triangulação de um conjunto de pontos consiste em encontrar segmentos de recta que

conectam estes pontos de tal modo que nenhum desses segmentos cruze com nenhum

outro e que cada ponto seja vértice de pelo menos um triângulo formado por esses

segmentos. Esses segmentos particionam o conjunto de pontos em triângulos, daí o nome

Triangulação.

O grafo dual de um Diagrama de Voronoi constitui

uma triangulação cujos pontos são os pontos

construtores do diagrama de Voronoi. A esta

triangulação particular dá-se o nome de Triangulação

de Delaunay. De fato existe um algoritmo que, dado

um Diagrama de Voronoi, obtém a Triangulação de

algoritmo faz o serviço inverso, também em tempo O(n). Porém, existem algoritmos que

produzem a Triangulação de Delaunay directamente do conjunto de pontos.

Um triângulo da Trian

Delaunay em tempo linear. Outro

gulação de Delaunay tem a seguinte propriedade: determina um

.1 Algoritmo quadrático

m algoritmo quadrático que produz a Triangulação de Delaunay pode ser descrito da

círculo cujo interior não contém nenhum outro ponto do conjunto de pontos a não ser os

três pontos que determinam o triângulo.

3

U

seguinte forma: primeiro procura-se uma aresta qualquer do fecho convexo. Essa aresta

com certeza estará em qualquer triangulação pois o fecho convexo está sempre contido

numa triangulação. A ideia básica deste algoritmo é usar as arestas já determinadas para

encontrar as demais. Toda aresta da triangulação pertence a um ou dois triângulos. Uma

aresta só incide num triângulo se for uma aresta do fecho convexo. A partir de uma aresta

adjacente a uma face já conhecida (um triângulo ou a face externa) pode-se determinar o

outro triângulo que compartilha esta aresta da seguinte maneira: encontrar o ponto p do

lado apropriado do segmento para o qual o círculo determinado pelo triângulo contendo os

vértices do segmento e o ponto p não possui nenhum outro ponto do conjunto interno a

ele. Esse triângulo é uma componente da Triangulação de Delaunay.

Visualização Científica Mª Mafalda Sousa

11

O algoritmo é fácil de ser implementado pois não requer a utilização de estruturas de

dados complicadas. Basta uma fila de arestas não-inspecionadas e uma matriz de

adjacência.

Visualização Científica Mª Mafalda Sousa

12

4. Métodos Utilizados

Nesta secção estão descritas as classes do vtk utilizadas

// Leitura do ficheiro BMP

vtkBMPReader *imageIn = vtkBMPReader::New();

imageIn->SetFileName("C:\\WINDOWS\\Ambiente de trabalho\\d\\ice.bmp");

// Criação do actor para imagem

vtkImageActor *imgActor = vtkImageActor::New();

imgActor->SetInput(imageIn->GetOutput());

// Extrai o número de componentes escalares dos pontos da imagem

vtkImageConstantPad *pad = vtkImageConstantPad::New();

pad->SetInput(imageIn->GetOutput());

pad->SetOutputNumberOfScalarComponents(3);

pad->SetConstant(0);

// Criar um conjunto de pontos estruturados a partir da imagem

// e do número de componentes.

vtkImageToStructuredPoints *i2sp1 = vtkImageToStructuredPoints:: New();

i2sp1->SetInput(imageIn->GetOutput());

i2sp1->SetVectorInput(pad->GetOutput());

vtkStructuredPoints *pPoints = i2sp1->GetOutput();

pPoints->Update();

int n = pPoints->GetNumberOfPoints();

Visualização Científica Mª Mafalda Sousa

13

vtkDataArray *ptScalars;

ptScalars = (pPoints->GetPointData())->GetScalars();

float rgb[3];

float x[3];

printf("\n n=%d", n);

printf("\n size=%d", ptScalars->GetSize());

vtkMath *math = vtkMath::New();

vtkPoints *points = vtkPoints::New();

vtkCellArray *polys = vtkCellArray::New();

register int i;

// Criação de uma polydata com os pontos da imagem

for (i = 0; i < n; i++) {

pPoints->GetPoint(i, x);

((pPoints->GetPointData())->GetScalars())->GetTuple(i, rgb);

points->InsertPoint(i, x[0], x[1], (rgb[0]*20+rgb[1]*59+rgb[2]*11)/100);

polys->InsertNextCell(1);

polys->InsertCellPoint(i);

}

// Introdução da Polydata

vtkPolyData *profile = vtkPolyData::New();

profile->SetPoints(points);

profile->SetVerts(polys);

// Criação do actor de entrada relativo ao mapa de pontos

Visualização Científica Mª Mafalda Sousa

14

vtkPolyDataMapper *mapPoints = vtkPolyDataMapper::New();

mapPoints->SetInput(profile);

vtkActor *actorPoints = vtkActor::New();

actorPoints->SetMapper(mapPoints);

(actorPoints->GetProperty())->SetColor(0, 0, 1);

// Triangulação 2D Delaunay a partir dos pontos.

vtkDelaunay2D *del = vtkDelaunay2D::New();

del->SetInput(profile);

del->SetTolerance(0.1);

// Criação o actor de saída

vtkDataSetMapper *map = vtkDataSetMapper::New();

map->SetInput(del->GetOutput());

// map->SetInput(pPoints);

vtkActor *triangulation2d = vtkActor::New();

triangulation2d->SetMapper(map);

(triangulation2d->GetProperty())->SetColor(1, 0, 0);

// Criação de dados de texto

vtkVectorText *text1 = vtkVectorText::New();

text1->SetText("IMAGEM BMP");

vtkVectorText *text2 = vtkVectorText::New();

text2->SetText("PONTOS");

vtkVectorText *text3 = vtkVectorText::New();

Visualização Científica Mª Mafalda Sousa

15

text3->SetText("TRIANGULACAO");

// Mapeação dos vectores de texto

vtkPolyDataMapper *textMapper1 = vtkPolyDataMapper::New();

textMapper1->SetInput(text1->GetOutput());

vtkPolyDataMapper *textMapper2 = vtkPolyDataMapper::New();

textMapper2->SetInput(text2->GetOutput());

vtkPolyDataMapper *textMapper3 = vtkPolyDataMapper::New();

textMapper3->SetInput(text3->GetOutput());

// Criação do actor de texto

vtkActor *textActor1 = vtkActor::New();

textActor1->SetMapper(textMapper1);

(textActor1->GetProperty())->SetColor(0, 0, 0);

vtkActor *textActor2 = vtkActor::New();

textActor2->SetMapper(textMapper2);

(textActor2->GetProperty())->SetColor(0, 0, 0);

vtkActor *textActor3 = vtkActor::New();

textActor3->SetMapper(textMapper3);

(textActor3->GetProperty())->SetColor(0, 0, 0);

// Construção de renderers

vtkRenderer *ren1= vtkRenderer::New();;

ren1->AddActor(textActor1);

ren1->SetBackground(1, 1, 1);

ren1->SetViewport(0, 0.45, 0.33, 1);

Visualização Científica Mª Mafalda Sousa

16

vtkRenderer *ren4= vtkRenderer::New();;

ren4->AddActor(imgActor);

ren4->SetBackground(1, 1, 1);

ren4->SetViewport(0, 0, 0.33, 0.70);

vtkRenderer *ren2= vtkRenderer::New();

ren2->AddActor(textActor2);

ren2->SetBackground(1, 1, 1);

ren2->SetViewport(0.33, 0.60, 0.66, 1);

vtkRenderer *ren5= vtkRenderer::New();

ren5->AddActor(actorPoints);

ren5->SetBackground(1, 1, 1);

ren5->SetViewport(0.33, 0, 0.66, 0.70);

vtkRenderer *ren3= vtkRenderer::New();

ren3->AddActor(textActor3);

ren3->SetBackground(1, 1, 1);

ren3->SetViewport(0.66, 0.45, 1, 1);

vtkRenderer *ren6= vtkRenderer::New();

ren6->AddActor(triangulation2d);

ren6->SetBackground(1, 1, 1);

ren6->SetViewport(0.66, 0, 1, 0.70);

// renderwindow

vtkRenderWindow *renWin1 = vtkRenderWindow::New();

renWin1->AddRenderer(ren1);

renWin1->AddRenderer(ren2);

renWin1->AddRenderer(ren3);

renWin1->AddRenderer(ren4);

Visualização Científica Mª Mafalda Sousa

17

renWin1->AddRenderer(ren5);

renWin1->AddRenderer(ren6);

renWin1->SetSize(1024, 500);

// Janela de interação

vtkRenderWindowInteractor * interactor1 = vtkRenderWindowInteractor::New();

interactor1->SetRenderWindow(renWin1);

renWin1->Render();

interactor1->Start();

// apagar os objectos construídos

math->Delete();

points->Delete();

polys->Delete();

profile->Delete();

del->Delete();

map->Delete();

ren1->Delete();

ren2->Delete();

ren3->Delete();

ren4->Delete();

ren5->Delete();

ren6->Delete();

renWin1->Delete();

interactor1->Delete();

Visualização Científica Mª Mafalda Sousa

18

5. Resultados

A compilação do código elaborado foi feita através do Microsoft Studio C++. Os

resultados que se seguem ilustram não só o método de triangulação de Delaunay descrito

anteriormente como também as potencialidades do vtk como programa de visualização.

As figuras seguintes serviram de exemplo para utilizar como teste na obtenção dos pontos

estruturados.

Figura 5.1. Imagens BMP utilizadas na aplicação: à esquerda a figura

ice1.bmp e à direita a figura ice2.bmp

A compilação do projecto resulta na renderização de uma janela com 6 actores: 3 actores

de texto com o título dos outros 3 actores correspondentes às mapeações obtidas.

A utilização de duas imagens exemplo provém da necessidade de explicar a tolerância da

triangulação de Delaunay ao número de pontos obtidos.

A figura seguinte é o Output da renderização para a primeira imagem. O primeiro mapper

é simplesmente a visualização da imagem BMP com o respectivo título. No segundo é a

apresentada a estrutura de pontos obtida e por o resultado da triangulação.

O número de pontos obtidos e utilizados na triangulação foi de 576.000.

A figura 5.3. é resultado da rotação dos actores de forma a visualizar em pormenor o

resultado obtido.

Visualização Científica Mª Mafalda Sousa

19

Figura 5.2 Visualização da Triangulação de Delaunay na imagem ice1.bmp

Figura 5.3 Visualização da Triangulação de Delaunay na imagem ice1.bmp, depois de

aplicadas rotações sobre os actores.

As figura 5.4 e 5.5 ilustram o mesmo processo mas aplicado à imagem ice2.bmp. Neste

caso o número de pontos foi de 36.096.

Visualização Científica Mª Mafalda Sousa

20

Figura 5.4 Visualização da Triangulação de Delaunay na imagem ice2.bmp

Figura 5.5 Visualização da Triangulação de Delaunay na imagem ice2.bmp, depois de

aplicadas rotações sobre os actores.

Por comparação verifica-se que a resolução do segundo exemplo é muito maior do que a

do primeiro exemplo. Isto deve-se ao facto de que a tolerância da triangulação usada no

primeiro exemplo foi de 0.1 e neste caso de 0.01. No primeiro caso o número de pontos

era demasiado elevado para aplicar uma tolerância de 0.01 pois o esforço computacional

era inapropriado. Mas para perceber melhor a diferença de resultados na diminuição de

tolerância a figura 5.6 é o resultado da aplicação de uma tolerância de 0.1 na imagem

ice2.bmp.

Visualização Científica Mª Mafalda Sousa

21

Figura 5.5 Visualização da Triangulação na imagem ice2.bmp com tolerância 0.1.

Depois de feita a triangulação não é possível distinguir os dois icebergs presentes na

imagem, visto que o número de pontos utilizado foi muito pequeno.

Visualização Científica Mª Mafalda Sousa

22

6- Conclusão

A aplicação da triangulação 2D de Delaunay permite definir uma estrutura topológica a

partir de pontos de uma imagem. A determinação das coordenadas dos pontos da imagem depende directamente da

composição RGB da imagem. Isto é, quanto maior for a diferença cromática da imagem a

maior será a diferença de valores obtidos na terceira coordenada dos pontos.

O número de triângulos é estabelecido pelo número de pontos e pela tolerância da

triangulação. Quanto menor for a tolerância maior o número de triângulos.

Existe assim um compromisso entre a tolerância e o esforço computacional. É necessário

verificar o número de pontos de forma a definir uma tolerância adequada à capacidade de

processamento da máquina.

Visualização Científica Mª Mafalda Sousa

23

Apêndice

/*################################################################

// Trabalho realizado por: \\

// \\

// Maria Mafalda Sousa - MMCCE \\

// 30-07-2004 \\

// \\

// Triangulação 2D de Delaunay em pontos obtidos por uma imagem BMP. \\

// \\

// \\

#################################################################*/

#include "vtkVectorText.h"

#include "vtkBMPReader.h"

#include "vtkImageConstantPad.h"

#include "vtkImageToStructuredPoints.h"

#include "vtkStructuredPoints.h"

#include "vtkImageActor.h"

#include "vtkMath.h"

#include "vtkPoints.h"

#include "vtkPointData.h"

#include "vtkCellArray.h"

#include "vtkPolyData.h"

#include "vtkPolyDataMapper.h"

#include "vtkDelaunay2D.h"

#include "vtkDataSetMapper.h"

#include "vtkActor.h"

#include "vtkProperty.h"

#include "vtkRenderer.h"

#include "vtkRenderWindow.h"

#include "vtkRenderWindowInteractor.h"

int main( int argc, char *argv[] )

Visualização Científica Mª Mafalda Sousa

24

{

// Leitura do ficheiro BMP

vtkBMPReader *imageIn = vtkBMPReader::New();

imageIn->SetFileName("C:\\WINDOWS\\Ambiente de trabalho\\Trabalho

VTK\\TDelaunay2D_1\\ice1.bmp");

// Criação do actor para imagem

vtkImageActor *imgActor = vtkImageActor::New();

imgActor->SetInput(imageIn->GetOutput());

// Extrai o número de componentes escalares dos pontos da imagem

vtkImageConstantPad *pad = vtkImageConstantPad::New();

pad->SetInput(imageIn->GetOutput());

pad->SetOutputNumberOfScalarComponents(3);

pad->SetConstant(0);

// Criar um conjunto de pontos estruturados a partir da imagem

// e do número de componentes.

vtkImageToStructuredPoints *i2sp1 = vtkImageToStructuredPoints:: New();

i2sp1->SetInput(imageIn->GetOutput());

i2sp1->SetVectorInput(pad->GetOutput());

vtkStructuredPoints *pPoints = i2sp1->GetOutput();

pPoints->Update();

int n = pPoints->GetNumberOfPoints();

vtkDataArray *ptScalars;

Visualização Científica Mª Mafalda Sousa

25

ptScalars = (pPoints->GetPointData())->GetScalars();

float rgb[3];

float x[3];

printf("\n n=%d", n);

printf("\n size=%d", ptScalars->GetSize());

vtkMath *math = vtkMath::New();

vtkPoints *points = vtkPoints::New();

vtkCellArray *polys = vtkCellArray::New();

register int i;

// Criação de uma polydata com os pontos da imagem

for (i = 0; i < n; i++) {

pPoints->GetPoint(i, x);

((pPoints->GetPointData())->GetScalars())->GetTuple(i, rgb);

points->InsertPoint(i, x[0], x[1], (rgb[0]*20+rgb[1]*59+rgb[2]*11)/100);

polys->InsertNextCell(1);

polys->InsertCellPoint(i);

}

// Introdução da Polydata

vtkPolyData *profile = vtkPolyData::New();

profile->SetPoints(points);

profile->SetVerts(polys);

// Criação do actor de entrada relativo ao mapa de pontos

Visualização Científica Mª Mafalda Sousa

26

vtkPolyDataMapper *mapPoints = vtkPolyDataMapper::New();

mapPoints->SetInput(profile);

vtkActor *actorPoints = vtkActor::New();

actorPoints->SetMapper(mapPoints);

(actorPoints->GetProperty())->SetColor(0, 0, 1);

// Triangulação 2D Delaunay a partir dos pontos.

vtkDelaunay2D *del = vtkDelaunay2D::New();

del->SetInput(profile);

del->SetTolerance(0.1);

// Criação o actor de saída

vtkDataSetMapper *map = vtkDataSetMapper::New();

map->SetInput(del->GetOutput());

// map->SetInput(pPoints);

vtkActor *triangulation2d = vtkActor::New();

triangulation2d->SetMapper(map);

(triangulation2d->GetProperty())->SetColor(1, 0, 0);

// Criação de dados de texto

vtkVectorText *text1 = vtkVectorText::New();

text1->SetText("IMAGEM BMP");

vtkVectorText *text2 = vtkVectorText::New();

text2->SetText("PONTOS");

vtkVectorText *text3 = vtkVectorText::New();

Visualização Científica Mª Mafalda Sousa

27

text3->SetText("TRIANGULACAO");

// Mapeação dos vectores de texto

vtkPolyDataMapper *textMapper1 = vtkPolyDataMapper::New();

textMapper1->SetInput(text1->GetOutput());

vtkPolyDataMapper *textMapper2 = vtkPolyDataMapper::New();

textMapper2->SetInput(text2->GetOutput());

vtkPolyDataMapper *textMapper3 = vtkPolyDataMapper::New();

textMapper3->SetInput(text3->GetOutput());

// Criação do actor de texto

vtkActor *textActor1 = vtkActor::New();

textActor1->SetMapper(textMapper1);

(textActor1->GetProperty())->SetColor(0, 0, 0);

vtkActor *textActor2 = vtkActor::New();

textActor2->SetMapper(textMapper2);

(textActor2->GetProperty())->SetColor(0, 0, 0);

vtkActor *textActor3 = vtkActor::New();

textActor3->SetMapper(textMapper3);

(textActor3->GetProperty())->SetColor(0, 0, 0);

// Construção de renderers

vtkRenderer *ren1= vtkRenderer::New();;

ren1->AddActor(textActor1);

ren1->SetBackground(1, 1, 1);

ren1->SetViewport(0, 0.45, 0.33, 1);

Visualização Científica Mª Mafalda Sousa

28

vtkRenderer *ren4= vtkRenderer::New();;

ren4->AddActor(imgActor);

ren4->SetBackground(1, 1, 1);

ren4->SetViewport(0, 0, 0.33, 0.70);

vtkRenderer *ren2= vtkRenderer::New();

ren2->AddActor(textActor2);

ren2->SetBackground(1, 1, 1);

ren2->SetViewport(0.33, 0.60, 0.66, 1);

vtkRenderer *ren5= vtkRenderer::New();

ren5->AddActor(actorPoints);

ren5->SetBackground(1, 1, 1);

ren5->SetViewport(0.33, 0, 0.66, 0.70);

vtkRenderer *ren3= vtkRenderer::New();

ren3->AddActor(textActor3);

ren3->SetBackground(1, 1, 1);

ren3->SetViewport(0.66, 0.45, 1, 1);

vtkRenderer *ren6= vtkRenderer::New();

ren6->AddActor(triangulation2d);

ren6->SetBackground(1, 1, 1);

ren6->SetViewport(0.66, 0, 1, 0.70);

// renderwindow

vtkRenderWindow *renWin1 = vtkRenderWindow::New();

renWin1->AddRenderer(ren1);

renWin1->AddRenderer(ren2);

renWin1->AddRenderer(ren3);

renWin1->AddRenderer(ren4);

renWin1->AddRenderer(ren5);

Visualização Científica Mª Mafalda Sousa

29

renWin1->AddRenderer(ren6);

renWin1->SetSize(1024, 500);

// Janela de interação

vtkRenderWindowInteractor * interactor1 = vtkRenderWindowInteractor::New();

interactor1->SetRenderWindow(renWin1);

renWin1->Render();

interactor1->Start();

// apagar os objectos construídos

math->Delete();

points->Delete();

polys->Delete();

profile->Delete();

del->Delete();

map->Delete();

ren1->Delete();

ren2->Delete();

ren3->Delete();

ren4->Delete();

ren5->Delete();

ren6->Delete();

renWin1->Delete();

interactor1->Delete();

return 0;

}

Visualização Científica Mª Mafalda Sousa