conjuntos de dadostavares/ensino/visci/trabalhos/2003-2004... · qualquer outro que representam...
TRANSCRIPT
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