capitulo i - apresentaçãotavares/downloads/publications/relatorios/... · capitulo i -...

324

Upload: vandan

Post on 07-Nov-2018

213 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe
Page 2: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo I - Apresentação

1

Page 3: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo I - Apresentação

PD 77 - Alinhamento de Imagens Médicas

Relatório final submetido ao Departamento de Engenharia Electrotécnica e

de Computadores para satisfação parcial dos requisitos do:

Projecto, Seminário, Trabalho de Fim de Curso

Por:

Nuno José Sá Couto Sérgio Vasconcelos de Barros

Finalistas do curso de Engenharia Electrotécnica e de

Computadores da Universidade do Porto

Orientador:

Armando Jorge Padilha

Prof. Associado do Departamento de Engenharia Electrotécnica e de Computadores da Faculdade de Engenharia da Universidade do Porto

2

Page 4: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo I - Apresentação

Agradecimentos

Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe por todo o seu apoio e disponibilidade, em particular na pessoa do Eng. Ingo de Boer.

Ao Prof. A. Jorge Padilha pela orientação e oportunidade que nos deu de trabalharmos numa área que sempre nos motivou.

Ao Eng. João Tavares por toda a sua disponibilidade e pela disponibilização de funções por si desenvolvidas.

Ao INEB e em particular aos Eng. Pimenta Monteiro e Eng. Miguel Velhote por toda a disponibilidade e apoio prestado ao longo deste projecto.

Ao Dr. Lusitano pelo estabelecimento da ligação ao Instituto de Química Fisiológica, laboratório de radioisótopos da Faculdade de Medicina de Coimbra, em particular ao Prof. Adriano Rodrigues, e ao departamento de medicina nuclear do Hospital de S. João, em particular ao director de serviço Dr. Jorge Rodrigues.

3

Page 5: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo I - Apresentação

Índice

Capítulo I - Apresentação

1. Proposição 1 1.1 Objectivos do Projecto 2 1.2 Estrutura do Relatório 3

2. Etapas do Projecto 4

Capítulo II – Medicina Nuclear, SPECT e PET

Introdução 7

1. Medicina Nuclear 8 1.1 Introdução 8 1.2 História 8 1.3 Factos 9 1.4 Computadores em Medicina Nuclear 10 1.4.1 Introdução 10 1.4.2 Imagens Digitais 10 1.4.3 Aquisição de Imagem 11 1.4.4 Conclusão 11 1.5 Segurança e Controlo da Qualidade 11 1.6 Futuro 12

2. Single Photon Emission Computed Tomography (SPECT) 13

2.1 Introdução ao SPECT 13 2.2 História do SPECT 14 2.3 Teoria e Instrumentação 15 2.4 Aquisição e Processamento de Imagem em SPECT 15

2.5 Reconstrução de Imagem 17 2.5.1 Projecção Inversa Filtrada 17 2.5.2 Método dos Parâmetros Directos 18 2.5.3 Método dos Mínimos Quadrados com Restrição Linear 18 2.5.4 Reconstrução Iterativa 19

2.6 A Câmara Gama 19 2.6.1 Características da Câmara Gama 19 2.6.2 Controlo de Qualidade da câmara 20 2.7 Colimador 20 2.7.1 Resolução e Sensibilidade 21 2.7.2 Tipos de Colimadores 21 2.7.2.1 Converging Hole 21

I

Page 6: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo I - Apresentação

2.7.2.2 Convergência e divergência 21

2.7.2.3 Pin- Hole 22 2.8 Detector de Cintilação 22 2.9 Tubos Fotomultiplicadores 22 2.10 Circuitos de Posicionamento 23 2.11 Computador para Análise de Dados 23 2.12 Visualização SPECT 23 2.12.2 Artefactos que influenciam a visualização SPECT 23 2.13 Protocolos de Aquisição 25 2.13.1 Imagem Planar 25

2.13.1.1 Aquisição de imagem planar dinâmica 26

2.13.2 Aquisição de Imagem SPECT 26 2.13.2.1 Aquisição de Imagem SPECT Dinâmica 26

2.13.3 Aquisição SPECT GATED 26 2.14 Aplicações SPECT 26 2.15 Avanços Técnicos do SPECT 28 2.15.1 Câmara de Compton 29 2.16 Conclusão 29

3. Positron Emission Tomography (PET) 29 3.1 Introdução ao PET 29 3.2 Aspectos Históricos do PET 30 3.3 Teoria e Instrumentação 30 3.4 Radionuclidos 31 3.5 Metabolismo da glucose 31 3.6 Aquisição e Processamento de Imagem em PET 32 3.7 Funções do PET 32 3.8 Aplicações e Investigação Associada ao PET 32

Capítulo III – Fundamentos Teóricos

1. Introdução à Visão por Computador 35 1.1 Introdução 35 1.2 Visão por Computador 35 1.3 Áreas Associadas à Visão por Computador 36

1.3.1 Processamento de imagem 36 1.3.2 Gráficos Computadorizados 36 1.3.3 Reconhecimento de Padrões 36 1.3.4 Inteligência Artificial 36 1.3.5 Psicofísica 37

1.4 Áreas de Aplicação 37

2. Técnicas de Aquisição de Informação Tridimensional 37 2.1 Introdução 37 2.2 Técnicas Activas de Aquisição Tridimensional 38 2.3 Técnicas Passivas de Aquisição Tridimensional 38

II

Page 7: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo I - Apresentação

3. Processamento e Análise de Imagem 39 3.1 Thresholding 39 3.2 Filtragem de Imagem 40 3.2.1 Filtros de Suavização e Realce 40 3.2.1.1 Filtro de média 40

3.2.1.2 Filtro de mediana 41

3.2.1.3 Filtro Gaussiano 42 3.2.2 Filtros Derivativos 43 3.2.2.1 Operadores de Gradiente 43

3.2.2.2 Operadores Laplacianos 44 3.3 Detecção de Orlas de Intensidade 45 3.3.1 Detecção de Orlas de Intensidade Canny 45 3.3.2 Detecção de Orlas de Intensidade Deriche 45 3.3.3 Operações Complementares 46 3.4 Transformação de Hough 47 3.4.1 Detecção de Linhas 47 3.4.2 Detecção de Círculos 48 3.4.3 Detecção de Elipses 49 3.5 Transformações e Coordenadas Homogéneas 50 3.6 Modelos Deformáveis 50 3.6.1 Snakes 51 3.6.2 Balloons 52

Capítulo IV – Sistema Desenvolvido

1. Introdução ao Sistema Desenvolvido 53 1.1 Problemática do Projecto 53 1.2 Método 53 1.3 Conceitos Básicos 55

1.3.1 Esteroscopia Passiva 55 1.3.2 Triangulação 55 1.3.3 Óptica 56 1.3.3.1 Equação da Lente 56

1.3.3.2 Resolução da Imagem 56

1.3.3.3 Profundidade de Campo 57

2. Sistema Desenvolvido 57 2.1 Material Utilizado 57 2.1.1 Câmaras e Lentes 57 2.1.2 Suporte para Câmaras 58 2.1.3 Frame Grabber 58 2.1.4 PC 59 2.1.5 Alvo a Colocar no Paciente 59 2.1.6 Alvo para Calibração das Câmaras 59 2.1.7 Transformadores e Cabos de Ligação 59

2.1.8 Interruptor Porta Série 60 2.2 Aquisição de imagens Estereoscopicas 60

III

Page 8: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo I - Apresentação

2.2.1 Introdução 60 2.2.2 Software Desenvolvido 60 2.2.2.1 Opções de Aquisição 60

2.2.2.2 Esquemas de Aquisição 62

2.2.2.3 Configuração de Níveis de Referência 63

2.2.2.4 Análise do Software Desenvolvido 63 2.3 Calibração das Câmaras 63 2.3.1 Introdução 63 2.3.2 Fundamentos Teóricos 64 2.3.3 Abordagem seguida no Projecto 65

2.3.3.1 Introdução 66

2.3.3.2 Modelo de Câmara 66

2.3.3.3 Calibração de uma Câmara 69

2.3.3.4 Considerações sobre o Modelo Utilizado 72

2.3.3.5 Influência de uma Determinação Incorrecta do Centro de Imagem 72

2.3.3.6 Determinação das Coordenadas dos Pontos de Calibração 73

2.3.4 Software Desenvolvido 74 2.3.4.1 Calibração de uma Câmara 74

2.3.4.2 Determinação das Coordenadas na Memória Frame 76

2.3.4.3 Formatação dos Pontos de Calibração 77

2.3.4.4 Simulador de uma Câmara 78

2.3.5 Resultados Experimentais 80 2.3.5.1 Determinação das Coordenadas dos Pontos de Calibração 80

2.3.5.2 Simulação de Calibrações de Câmaras 83

2.3.5.3 Formatação dos Pontos de calibração 85

2.3.5.4 Calibração de Câmaras 86

2.4 Detecção de Alvos e Obtenção de Informação 3D 86 2.4.1 Introdução 86 2.4.2 Detecção de Pontos Característicos 87 2.4.2.1 Dimensionamento do Alvo 87

2.4.2.2 Detecção do Alvo 89

2.4.3 Emparelhamento de Pontos Característicos 91 2.4.4 Obtenção de Informação Tridimensional 92

2.4.4.1 Princípio da Triangulação Estereoscopica 92

2.4.4.2 Implementação Desenvolvida 93 2.4.5 Software Desenvolvido 93

2.4.5.1 Comprovação dos Algoritmos Desenvolvidos 93

2.4.5.2 Implementação do software 96

2.5 Estimação e Correcção de Movimento 100 2.5.1 Introdução 100 2.5.2 Método Utilizado 100 2.5.3 Software Desenvolvido 103

2.5.3.1 Comprovação dos algoritmos desenvolvidos 103

2.5.3.2 Implementação do Software 104

IV

Page 9: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo I - Apresentação

Capítulo V – Análise de Resultados 1. Introdução 105 2. Estimação do Ângulo de Visão das Câmaras 106

3. Testes Efectuados 107

4. Influência dos Parâmetros de Calibração 116

Capítulo VI – Conclusões e Trabalho Futuro

1. Pesquisa de Informação 119 2. Etapas do Projecto 119

3. Abordagem Seguida 120

4. Equipamento utilizado 120

5. Algoritmos desenvolvidos 121

Bibliografia_____________________________________

1. Publicações 123 2. Internet 126

V

Page 10: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo I - Apresentação

Capítulo I

1 – Proposição Cada vez mais a Engenharia torna-se uma aliada poderosa da Medicina. Os sistemas de apoio à

decisão contribuem significativamente para um melhor e mais rápido diagnóstico por parte do pessoal médico. Isto deve-se ao facto da capacidade de processamento e de armazenamento de informação dos computadores actuais ser de tal ordem elevada, que estes conseguem processar e analisar grandes quantidades de informação em espaços de tempo extremamente curtos. Se essa mesma informação fosse analisada por pessoas, além de levar um tempo de processamento e análise muito superior, levaria a que as conclusões fossem imprecisas e variáveis, devido a influências externas tais como cansaço, más condições de visualização, etc.

Assim, no âmbito deste projecto foi desenvolvido um sistema de apoio à decisão médica através do processamento e análise de imagens digitais, em parceria com um exame de medicina nuclear SPECT planar. Este exame de medicina nuclear tem como objectivo estudar o funcionamento dos órgãos, como por exemplo os rins. O funcionamento do órgão é avaliado através da análise da quantidade de um determinado radionuclido que está presente nesse órgão durante um determinado período de tempo. Este tipo de exame necessita de alguns requisitos para que o diagnóstico final seja o mais preciso possível, sendo um desses requisitos, o paciente permanecer imóvel durante todo o período de tempo do exame médico. Se esse requisito não for preenchido, a capacidade de diagnóstico deteriora-se de tal forma que a solução geralmente usadas nestes casos é a repetição do exame. Assim a motivação para este trabalho é dimensionar e implementar um sistema de aquisição de imagem com duas câmaras para detectar movimentos do paciente de modo a efectuar a correcção desse movimento nas imagens médicas finais.

Para a implementação torna-se assim importante obter informação tridimensional. Existem actualmente várias técnicas para tornar possível esta obtenção utilizando visão por computador. Normalmente as técnicas existentes são divididas em duas categorias: activas e passivas. O sistema a desenvolver será um sistema do tipo passivo. Neste caso irão ser utilizadas duas câmaras, ligadas a um computador (que será responsável pela aquisição das imagens digitais), com um suporte físico e alvos para detecção devidamente dimensionados.

O presente trabalho enquadra-se assim numa técnica passiva de estereoscopia de obtenção de informação tridimensional. Quando se pretende obter informação tridimensional de uma cena, a partir de uma sequência de pares de imagens obtidas simultaneamente por duas câmaras, torna-se indispensável o prévio conhecimento do modelo da câmara utilizada. Assim, é necessário conhecer previamente o modo como os pontos no espaço tridimensional são transformados em pontos plano imagem da câmara, para cada par de imagens ao longo da sequência. Essa determinação do modelo da câmara – isto é, a

1

Page 11: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo I - Apresentação

determinação da geometria interna e das características ópticas (parâmetros intrínsecos) e a orientação e posição da câmara relativamente a um certo sistema de coordenadas mundo (parâmetros extrínsecos) – é designada por calibração da câmara. Estes parâmetros são conseguidos através da análise da posição de diversos pontos ao longo de um plano de calibração propriamente dimensionado para este efeito. A calibração é geralmente realizada apenas uma vez e constitui a primeira fase da abordagem seguida neste projecto.

Após a calibração da câmara, é então possível obter-se a sequência de pares de imagens, ou a sequência de imagens - dado que, a abordagem seguida teve como maior preocupação a execução de um sistema modular e flexível de modo a ser possível a sua utilização em diversas situações (não só especificamente direccionada para os exames médicos) e de diversas formas (por exemplo, ser possível a utilização de uma ou de duas câmaras). Em cada imagem surge a necessidade de determinar as entidades que irão ser consideradas, sendo estas entidades, formas geométricas colocadas num cinto. Este cinto por sua vez será colocado no paciente e será este o alvo que vai permitir a análise do movimento do paciente.

Para a detecção destas entidades, decidiu-se empregar um detector de orlas de intensidade (como por exemplo, os detectores de Sobel, Roberts, Laplaciano, Laplaciano do Gaussiano, Canny, Deriche, Shen, etc.), após o que é executado um seguimento das linhas determinadas e consequente determinação da forma geométrica detectada. Desta forma para o dimensionamento do alvo a colocar no paciente procurou-se colocar o maior número de formas diferentes geométricas, de maneira a que a identificação de cada uma destas entidades fosse mais eficiente facilitando o emparelhamento destas nos pares de imagens e consequentemente a extracção de coordenadas 3D. Assim como candidatos surgiram as seguintes figuras geométricas: triângulos, quadrados, rectângulos, losângulos e cruzes. Destas figuras existem algumas que se destacam por algumas características internas, que por si só facilitam a sua detecção. Como é perceptível existem muitas hipóteses para o dimensionamento deste alvo, que serão objecto de estudo deste relatório.

Estando o emparelhamento das várias figuras geométricas (em pares de imagens sucessivas) devidamente realizado, torna-se então possível extrair as coordenadas 3D dos pontos de cada figura. Determinadas as coordenadas 3D destes pares de imagens é possível estimar se houve movimento do paciente ao comparar essas coordenadas 3D com as coordenadas 3D do par de imagens inicial. Assim os movimentos detectados podem ser classificados em dois grandes grupos: rotação e translação.

Finalmente, após a classificação do movimento efectuado pelo paciente é feita a correcção das imagens médicas. Esta correcção é feita através de um modelo fisiológico que associa os movimentos dos pontos detectados das figuras geométricas com o movimento efectuado pelo órgão. Este modelo inicialmente vai ser um modelo simplificado, que poderá ser refinado adquirindo-se mais informação acerca da posição relativa dos rins no corpo humano, e se se verificam e quais os tipos de movimentos solidários que se efectuam com o movimento do corpo humano.

Este projecto foi realizado no INEB – Instituto de Engenharia Biomédica– no laboratório de Sinal de Imagem Biomédica, situado na Faculdade de Engenharia da Universidade do Porto.

1.1 Objectivos do projecto:

Este projecto tem como objectivo geral a concepção e implementação de métodos de captura de informação posicional (3D) para alinhar imagens renais de medicina nuclear obtidas em sequência temporal, com vista a potenciar a capacidade de análise diagnóstica.

Para ser atingido este objectivo, foram realizadas várias etapas, etapas estas que definiram as linhas mestras do que tem que ser feito para atingir o objectivo acima mencionado. Estas etapas foram:

1. Pesquisa de informação relevante para o projecto, em particular no que respeita ao processo

de obtenção de imagens de radioisótopos e aos métodos passivos de aquisição de informação tridimensional.

2. Implementação do sistema de aquisição 3D, incluindo concepção de alvos e/ ou marcas corporais.

3. Realização do alinhamento geométrico da sequência de imagens, a partir da estimação da posição e pose da zona renal.

4. Montagem e ensaios práticos em exames clínicos reais e, se necessário, com recurso a fantomas.

2

Page 12: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo I - Apresentação

1.2 Estrutura do relatório: Pretendeu-se estruturar este relatório em secções que se apresentem de forma completamente

autónoma e independente, de maneira a permitir uma fácil leitura e compreensão deste relatório. Em seguida, de forma resumida, são apresentados os restantes capítulos e anexos deste relatório.

��Capítulo II – Medicina Nuclear e seus Protocolos de Aquisição

Neste capítulo é apresentada a recolha de informação realizada sobre a área de medicina nuclear e dos seus protocolos de aquisição, SPECT e PET. É feita uma pequena introdução, onde é referida como e quais as condições em que se fez esta recolha de informação.

O objectivo deste capítulo é dar a conhecer esta área específica da medicina, a sua missão, suas condicionantes, os princípios físicos e de funcionamento dos protocolos, seus constituintes e suas problemáticas e também aquilo que se está a fazer para que este tipo de análise chegue cada vez mais a um maior número de pessoas sem que isso implique um custo económico (para as pessoas e para as instituições que detêm os equipamentos) incomportável. ��Capítulo III – Fundamentos Teóricos

Neste capítulo é abordado o tema da visão por computador, importância e riqueza de

informação que este tipo de visão nos faculta, informação esta que permite a detecção e o seguimento de alvos. De uma forma geral existem várias áreas associadas à visão por computador tal como o processamento e análise de imagem, reconhecimento de padrões, etc. Serão também apresentadas as áreas de aplicação da visão por computador.

Como área associada da visão por computador é apresentada o processamento e análise de imagem. Nesta secção são apresentados as ferramentas de análise e extracção de informação das imagens. São assim apresentados vários tipos de filtros e seus critérios de desempenho, transformações para detecção de formas geométricas, coordenadas homogéneas e uma introdução aos modelos deformáveis. O objectivo deste capítulo é fornecer as bases do processamento e análise de imagem, bases estas que constituem os pilares deste projecto. ��Capítulo IV – Sistema Desenvolvido

Neste capítulo é apresentada uma solução global para a problemática do projecto. É feita

uma descrição detalhada do material usado e suas características. Em seguida são apresentados os diversos módulos que constituem a solução apresentada. Pretendeu-se que estes módulos fossem independentes entre si, de modo a poderem, por si só, ser acompanhadas e utilizadas independentemente em outros domínios da visão por computador. Os módulos a apresentar são os de: aquisição de imagem, calibração de câmaras, detecção e obtenção de informação 3D e correcção das imagens de medicina nuclear. Em cada um dos módulos é feita a apresentação do método utilizado, abordagem seguida no projecto e é demonstrado o software desenvolvido assim como alguns resultados experimentais obtidos. ��Capítulo V – Análise de resultados e conclusões.

Após a apresentação da abordagem global utilizada, neste capítulo são apresentados

resultados desse processo. São assim apresentados resultados experimentais obtidos para a calibração das câmaras, aquisição simultânea, determinação das entidades a considerar em cada imagem da sequência e para a obtenção de informação tridimensional, assim como para a estimação e correcção do movimento. Na apresentação destes resultados serão feitas análises e conclusões dos resultados obtidos.

Será também apresentada uma análise crítica, onde será referido aquilo que foi feito e o que deveria ter sido feito, o que faltou (ou não) fazer e condições a nível de equipamento e acessibilidades. Serão também apresentadas conclusões globais referentes a todo o projecto em si.

3

Page 13: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo I - Apresentação

��Capítulo VI – Trabalho Futuro

Neste capítulo serão apresentadas métodos para o desenvolvimento da solução apresentada assim como alternativas à solução apresentada.

Como anexos ao relatório, serão apresentados os seguintes:

��Anexo A – Manual do Utilizador ��Anexo B - Características da câmara ��Anexo C - Características do frame grabber ��Anexo D - Transformações geométricas em 2D e 3D ��Anexo E - Exemplo de imagens obtidas por exame SPECT planar ��Anexo F - Radionuclidos ��Anexo F - Código implementado

2 – Etapas do projecto Nesta secção serão apresentadas, em ordem cronológica, todas as etapas que simbolizam o progresso

do projecto: 12/03/2001: Início do Projecto 15/03/2001: Publicação do site PD-77 Alinhamento de Imagens de Medicina Nuclear no seguinte

URL: http://www.fe.up.pt/~nuclear, para satisfação parcial dos requisitos da disciplina de Projecto Seminário Trabalho Fim de Curso.

22/03/2001: Conclusão da primeira fase do projecto: pesquisa de informação acerca dos

processos de obtenção de imagens de radioisótopos e aos métodos passivos de aquisição de informação tridimensional.

31/03/2001: Compra e montagem do material necessário à elaboração do projecto. Início do

desenvolvimento, em paralelo, das rotinas de calibração e de aquisição 6/04/2001: Implementação da rotina de simulação de calibração. 10/04/2001: Implementação da rotina de determinação de parâmetros extrínsecos e intrínsecos do

modelo das câmaras. 16/04/2001: Implementação das rotinas de aquisição de imagens ou sequências de imagens de

uma ou duas câmaras. 20/04/2001: Implementação da rotina de detecção dos pontos de calibração. 28/04/2001: Dimensionamento em paralelo dos alvos de calibração e de aquisição de coordenadas

3D. 5/05/2001: Elaboração do relatório de progresso para satisfação parcial dos requisitos das regras

do Projecto Seminário Trabalho Fim de Curso. 10/05/2001: Correcção e optimização das rotinas de calibração e aquisição. 12/05/2001: Desenvolvimento das rotinas de detecção de pontos característicos em imagens. 15/05/2001: Concentração numa só aplicação de todos os módulos desenvolvidos até ao

momento.

4

Page 14: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo I - Apresentação

20/05/2001: Implementação e conclusão da rotina de detecção de pontos característicos numa imagem.

27/05/2001: Implementação da rotina de emparelhamento de pontos característicos em pares de

imagens. 5/06/2001: Implementação da rotina de detecção e emparelhamento de pontos característicos em

pares de imagens ao longo de uma sequência de imagens. 6/06/2001: Criação do laço institucional entre o INEB e o Serviço de Medicina Nuclear do

Hospital S. João do Porto, com o objectivo de obtermos mais informações acerca dos exames a que no propusemos a corrigir e ter um contacto directo com o ambiente clínico.

10/06/2001: Implementação da rotina que permite fazer a actualização dos dados de calibração a

partir de ficheiro em disco. 15/06/2001: Dimensionamento do suporte para as câmaras e desenvolvimento das rotinas para o

cálculo de coordenadas 3D. 20/06/2001: Implementação da rotina para cálculo de coordenadas 3D 22/06/2001: Ida ao serviço de radiologia do Hospital Universitário de Coimbra com o intuito de

obter exames do tipo SPECT planar em formato de imagem .bmp e .img 28/06/2001: Implementação da rotina de cálculo de coordenadas 3D numa sequência de pares de

imagem. Conclusão da 2ª fase do projecto. 2/07/2001: Desenvolvimento das rotinas de estimação e correcção de movimento.

Implementação física do sistema de duas câmaras através do suporte. 10/07/2001: Inicio da elaboração do relatório. 15/07/2001: Finalização das rotinas de estimação e correcção de movimento. Conclusão da 3ª

fase. 16/07/2001: Elaboração do poster de apresentação do projecto. 17/07/2001: Obtenção de dados para análise e conclusões acerca da validade do projecto.

Realização de testes laboratoriais. 18/07/2001: Conclusão da 4ª fase do projecto.

19/07/2001: Finalização do relatório final do projecto. De referir também que houve sempre uma actualização periódica da página do projecto, com novas imagens, software, vídeos, informação acerca de eventos, etc..

5

Page 15: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo I - Apresentação

6

Page 16: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

Capítulo II Introdução:

Neste segundo capítulo é apresentada a recolha de informação efectuada sobre os temas de medicina nuclear e seus protocolos de aquisição: Single Photon Emission Computed Tomography (SPECT) e Positron Emission Tomography (PET). A recolha de informação foi dividida em duas fases: 1) a recolha propriamente dita da informação 2) organização da informação.

A recolha propriamente dita da informação teve início durante o 1º semestre do 5º ano lectivo de 2000/01, semestre esse que foi realizado por ambos os membros do grupo em Karlsruhe – Alemanha, prolongando-se pelo início do segundo semestre desse ano lectivo. Nesse primeiro semestre lectivo foi nos dada a oportunidade de realizar um projecto de investigação no IBT (Institut fur Biomedzisniche Technik), sobre o tema da segmentação do tórax da Visible Female, com base no dataset do Visible Human Project da National Library of Medicine. Desta maneira, aproveitando do facto de estarmos a trabalhar na mesma área do nosso projecto final de curso e das condições óptimas de acesso à informação, tentamos retirar o máximo de informação possível acerca da medicina nuclear e seus protocolos de aquisição. De salientar toda a disponibilidade das pessoas que trabalham nesse Instituto em nos tentar esclarecer todas as nossas dúvidas que foram surgindo durante a recolha de dados, e de nos alertar para as dificuldades com nos iríamos defrontar ao longo deste projecto, não só nos aspectos técnicos relativos ao sistema que nos proponhamos a desenvolver, mas também para as dificuldades inerentes ao trabalho nesta área (tais como, a falta de informação por parte dos fabricantes das máquinas de aquisição nuclear). Da fase de recolha de informação também faz parte uma visita à MEDICA 2000 em Dusseldorf (maior exposição mundial sobre equipamentos de aquisição, tratamento e diagnóstico médico).

A segunda fase já foi realizada no segundo semestre do referido ano lectivo e consistiu na compilação da informação adquirida, retirando para este relatório apenas a informação que consideramos essencial à percepção daquilo que se faz nesta área e suas linhas mestras para o presente / futuro. De referir ainda que a informação que foi adquirida tanto no primeiro como no segundo semestre não se restringiu apenas à medicina nuclear e seus protocolos, mas também foi adquirida informação que irá ser exposta nos capítulos seguintes, informação essa que forma os pilares teóricos do sistema que nos propusemos a desenvolver.

Assim neste capítulo irá ser feita uma breve descrição do que consiste a medicina nuclear como uma disciplina específica da medicina geral, seus aspectos históricos, suas preocupações, aplicações e futuro. Em seguida é feita uma descrição dos protocolos de aquisição existentes na medicina nuclear: SPECT e PET, sendo dado mais relevo ao SPECT, dado que é esse o protocolo para o qual foi

7

Page 17: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

desenvolvido o sistema deste projecto. Desta maneira, é feita um pequeno sumário do SPECT, seus aspectos históricos, teoria e instrumentação inerentes ao SPECT, seus constituintes, problemas e artefactos existentes nos diversos exames, avanços tecnológicos e são feitas algumas conclusões. Da mesma maneira é feita uma pequena abordagem ao PET onde os itens expostos são semelhantes aos expostos no SPECT embora sem o mesmo nível de detalhe.

É assim nosso objectivo que o leitor no final deste capítulo seja capaz de entender esta área específica da medicina, a sua missão, suas condicionantes, os princípios físicos e de funcionamento dos protocolos, seus constituintes e suas problemáticas e também aquilo que se está a fazer para que este tipo de análise chegue cada vez mais a um maior número de pessoas sem que isso implique um custo económico (para os utentes e para as instituições que detêm os equipamentos) incomportável.

1 – Medicina Nuclear 1.1 - Introdução à Medicina Nuclear

Medicina Nuclear é uma especialidade médica que usa técnicas seguras, indolores e com custo eficaz tanto para processamento e análise de imagem de todo o corpo humano, assim como para o tratamento de doenças. O processamento e análise de imagem em Medicina Nuclear, é único no facto de que documenta e estrutura funções dos orgãos, em contraste com diagnósticos feitos em radiologia, diagnósticos estes que são baseados na anatomia dos orgãos. É uma maneira de adquirir informação médica, que doutra forma seria provavelmente impossível, ou então, requerendo intervenções cirúrgicas ou testes diagnósticos mais caros. O campo da medicina nuclear é uma mistura de muitas áreas da matemática e ciência, tais como a física, química, matemática, tecnologia de computadores e medicina.

Como parte de um tratamento integral de um paciente, a medicina nuclear é usada no diagnóstico, gestão, tratamento e prevenção de doenças graves. Os procedimentos utilizados na análise de imagem em medicina nuclear frequentemente identificam anormalidades numa fase precoce no progresso de uma doença, muito antes do que os outros testes consigam detectá-los. Esta detecção precoce permite o tratamento da doença numa fase em que o prognóstico tem mais probabilidades de ter sucesso.

Medicina nuclear usa uma pequena quantidade de material radioactivo ou rádiofarmaco para o diagnóstico e tratamento de doenças. Rádiofarmacos são substâncias que são atraídas para orgãos, ossos ou tecidos específicos. Os rádiofarmacos usados em medicina nuclear emitem raios gama que podem ser detectados externamente por tipos especiais de câmara: gama ou PET câmaras. Estas câmaras funcionam em conjunção com computadores que são usados para formar imagens que providenciam dados e informação acerca da área do corpo que está sujeita a exame. O físico pode então visualizar a anatomia do paciente a partir do resultado da câmara. O rádioisótopo tem que ter uma meia - duração de vida curta de modo a que não permaneça no corpo, por um período de tempo muito prolongado. Meio-tempo de vida é o tempo necessário para que metade do material radioactivo presente deixe de emitir. Assim a medicina nuclear é essencialmente a criação mapas anatómicos de orgãos. O material radioactivo é administrado oralmente, intra venosamente ou inter cavitalmente. O material radioactivo é absorvido pela região doente e pode então destruir as células ou promover a cura dessa região. A quantidade de radiação de um procedimento de medicina nuclear e comparável com aquele que é recebido durante um diagnóstico raio-X. As imagens de medicina nuclear têm mais definição e são capazes de mostrar mais partes da anatomia do que as máquinas de raio-x usuais.

Físicos licenciados são as únicas pessoas autorizadas a praticar medicina nuclear. De modo a alguém estar certificado para tal, deverá ter um curso médico e pelo menos 1 ou mais anos de. Os físicos tem assim 2 anos de treino em medicina nuclear para no final fazer um exame de certificação. Uma vez certificado o físico será então assistido por outros físicos e farmacologistas especialmente treinados.

Hoje em dia, medicina nuclear oferece procedimentos que são de grande ajuda para uma vasta área de especialidades médicas, desde pediatria ate cardiologia passando pela psiquiatria. Existem quase cem tipos de processamento e análise de imagem em medicina nuclear disponíveis e não existe nenhum sistema do corpo humano que não seja adquirido por medicina nuclear. Hipertiroidismo, cancro da tiróide, desequilíbrios sanguíneos, e alívio da dor de certos tipos de cancro de ossos são tratados através da medicina nuclear. 1.2 - História da Medicina Nuclear

8

Page 18: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

De acordo com Hamilton a descoberta da radioactividade artificial foi um ponto fulcral na medicina nuclear. A história da medicina nuclear pode ser seguida ate aos anos 1800. O primeiro marco surgiu quando Becquerel descobriu actividade radioactiva natural em 1896. Isto foi seguido pela descoberta do Rádio por Marie Cury em 1898. Um dos primeiros tipos de medicina nuclear foi o raio-x desenvolvido em 1890. Material radioactivo foi usado para constituir a imagem dos ossos sem técnicas invasoras ao corpo. O uso de radionuclidos foi outro desenvolvimento inicial da medicina nuclear. Os radioisótopos são pequenas quantidades de material radioactivo colocadas num corpo, sendo inicialmente usados com finalidade terapêutica. Mais tarde viriam a constituir-se como instrumentos para diagnósticos. A primeira utilização de radioisótopos num humano com finalidade de diagnóstico, foi o Pa (228) para estudar o tempo de circulação do sangue no corpo humano ( Colombetti 1979).

A radioactividade artificial foi descoberta em 1934. O primeiro uso clínico foi em 1937 quando um material radioactivo foi usado, para tratar um paciente com leucemia na Universidade de Berkeley na Califórnia. O acontecimento que é considerado como sendo o marco da medicina nuclear moderna foi o uso de iodo radioactivo para tratar doenças da tiróide. O iodo radioactivo foi injectado no paciente e seguiu o trajecto normal que o iodo seguiria. Foi absorvido pela tiróide onde era usado tanto para fins terapêuticos como para obtenção de imagens.

Durante a segunda guerra mundial, foram recrutados biologistas para o campo do radar. Este trabalho preparou-os para o desenvolvimento da electrónica na medicina nos anos pós guerra. No entanto surgiram dois problemas. A geração seguinte de biologistas não tiveram o benefício desses conhecimentos e a tecnologia avançou tão rapidamente que depressa ultrapassou até os conhecimentos da geração da guerra.

Obviamente uma ponte sobre a lacuna entre conhecimento técnico e biologia era necessária. Assim médicos e biologistas com interesse e compreensão da engenharia para além de engenheiros electrotécnicos com interesse na biologia, transformaram-se assim nos primeiros bioengenheiros. Aqueles que se interessavam principalmente com medicina tornaram-se nos primeiros engenheiros biomédicos.

2.1 - Medicina Nuclear no passado

Em 1946 foi relatado que após um tratamento com iodo radioactivo o crescimento do cancro no paciente tinha completamente desaparecido. Na década de 1950 o uso da medicina nuclear alargou-se e na década de 60 tornou-se numa especialidade de estudos médicos. Nos anos 70 era utilizada para visualizar o baço, fígado, cérebro, e sistema gastrointestinal. Os rádiofarmacos começaram então a ser usados para o diagnóstico de doenças do coração nos anos 80.

Avanços tecnológicos tinham que ser feitos de modo a acompanhar os avanços na área médica. Câmaras tinham que ser desenvolvidas de modo a poder detectar material radioactivo e fazer imagens da anatomia que sustinha o material radioactivo. O primeiro exame rectilíneo foi o engenho de Cassen. Um grande desenvolvimento nesta área deveu-se ao aparecimento da câmara gama. Esta foi a primeira câmara estacionária que conseguiu ver um órgão por inteiro. Esta evolução fez com que nos anos mais recentes protocolos de aquisição tais como PET, SPECT e MRI fossem desenvolvidos. Tanto o PET como o SPECT fornece uma visão tridimensional da região de interesse.

Hoje em dia existem mais de 100 procedimentos de medicina nuclear e a medicina nuclear pode ser aplicada a qualquer órgão do corpo humano. Se os avanços na medicina nuclear continuarem a avançar ao ratio actual a possibilidade de novos desenvolvimentos e interminável. 1.3 - Factos acerca da Medicina Nuclear

��Nos EUA 10 a 12 milhões de exames de medicina nuclear são efectuados anualmente ��Os procedimentos da medicina nuclear são dos procedimentos mais seguros, mais eficientes do

ponto de vista de custos e únicos por si só. ��Informação acerca da função e estrutura de qualquer órgão pode ser obtido pela medicina

nuclear.

9

Page 19: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

��A quantidade de radiação recebida num procedimento de analise nuclear pode ser equiparada a quantidade de radiação recebida num exame de raio-x.

��Existem cerca de 2,700 físicos de medicina nuclear a tempo inteiro e 14000 técnicos em toda a nação (1997).

��Existem mais de 100 exames disponíveis em medicina nuclear. ��Os exames de medicina nuclear estão catalogados como sendo dos mais seguros teste /

diagnóstico existentes. 1.4 - Computadores na Medicina Nuclear 1.4.1 - Introdução

Medicina nuclear conta com os computadores para adquirir, processar, transferir informação e imagens. A história dos computadores na medicina nuclear e radiologia é mesmo assim bastante curta. Nos anos 60 e princípios da década de 1970, CT (Tomografia Computorizada) e subtracção angiográfica digital foram introduzidos na prática clínica pela primeira vez. A subtracção angiográfica digital usa computadores para digitalmente subtrair de uma angiografia padrão os efeitos de tecidos moles e ossos circundantes, levando assim a uma melhoria das imagens disponíveis para diagnóstico. Tomografia Computorizada (CT) usa os computadores para reconstruir digitalmente informação seccionada usando vários tipos de algoritmos de reconstrução de imagem tais como a projecção inversa filtrada.

O pior elemento numa unidade CT era sem dúvida nessa altura o computador, mas sem ele não era possível executar um CT. SPECT e MRI foram desenvolvidas tecnologias alguns anos após o CT e também necessitam de um computador para ser possível a execução de um exame. No caso do MRI o computador tem um papel de maior importância, dado que controla o movimento da torre e todo o equipamento mecânico relacionado. No caso do SPECT, como no CT, a reconstrução da imagem tem que ser feita por computador. O uso de computadores em medicina nuclear tem também as suas raízes na física das partículas de grande energia e também na física nuclear. Estas duas disciplinas usam análises estatísticas de grandes números de contagem de fotões, colectados e processados por um computador. É primeiramente através dessa análise e processamento que descobertas experimentais em medicina nuclear são feitas. O objectivo da medicina nuclear não é a descoberta de novas leis da física ou de partículas, mas sim a de detecção e diagnóstico de uma doença, mas como todos os outros métodos, não se baseia na detecção de uma grande número de fotões para atingir uma conclusão acerca do objecto em estudo. O problema de arquivar e transmitir essa larga quantidade de informação começou a ser resolvida na década de 1970.

Tentativas anteriores de transmitir imagens médicas de um hospital para outro ou de uma clínica para outra para a visualização e análise foram encorajadas, mas a perda de qualidade de sinal, e em particular resolução, degrada severamente a qualidade de imagem final. Então em 1981 um projecto na Universidade de Arkansas usou a Ethernet como meio de transmitir com sucesso imagens digitais de CT e de Ultra-sons. Desde esse tempo muita pesquisa tem vindo a ser dedicada para o desenvolvimento do arquivo de imagens e sistemas de computadores ou PACS (Picture Archiving and Communications Systems) com a esperança de criar um departamento de radiologia digital totalmente controlado por computador. 1.4.2 - Imagens Digitais

De maneira a uma melhor compreensão dos requisitos na aquisição e transferência de imagem em radiologia e em particular medicina nuclear, alguma terminologia básica é necessária. Para início uma imagem digital é essencialmente uma disposição ou colecção de valores inteiros que representam o espectro de graus de cinzento ou cor que aparecem numa imagem. Num computador, uma imagem digital pode ser uma matriz de duas ou três dimensões constituída por valores inteiros que fazem um número variável de bits. Dependendo do formato e do sistema computacional usado, uma imagem representada por uma matriz de números num computador terá ligada a si informação na forma de um cabeçalho, informação esta que fornece detalhes sobre a imagem tais como: dia do exame, nome do paciente e número de estudo. Cada valor inteiro pertencente a matriz é chamado de pixel. A quantidade de preto, branco ou cor em cada pixel da matriz é representada pelo valor inteiro nesse elemento de matriz. A qualidade de uma imagem digital é afectada pelo tamanho da matriz usada para representar a imagem, o número de bits para representar cada pixel e o nível de ruído presente na imagem.

10

Page 20: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

Se a matriz da imagem é composta por apenas por poucos pixels e de grande dimensão, a resolução resultante será baixa. Se a matriz da imagem é composta por muitos pixels de reduzida dimensão, e a falta de nitidez subjacente à imagem não é muito severa, a resolução será boa. Se o tamanho do pixel é muito inferior a falta de nitidez da imagem subjacente, a imagem irá aparecer com algo parecido a borrões. O número de bits usado para representar cada pixel deverá idealmente depender da quantidade de ruído presente na imagem. Quanto maior for o nível de ruído na imagem inicial, menor será o número de bits necessários para definir a informação que esta contém. Assim as imagens digitais podem ser degradadas de duas maneiras: 1. poucos pixels ou 2. poucos bits usados por cada pixel. O uso de muitos pixels ou de muitos bits por pixel para uma dada aquisição de imagem exige um processamento de imagem muito mais elevado, além de maior capacidade de armazenamento e manipulação, sem que isso implique necessariamente uma melhoria na qualidade final da imagem. Isto significa um aumento do custo sem um correspondente aumento na capacidade de diagnóstico (no caso de imagens médicas).

A maneira na qual uma imagem de medicina nuclear é adquirida e o protocolo de aquisição de imagem associado devem ser seleccionados cuidadosamente de maneira a maximizar a qualidade de imagem, conforto do paciente e maximizar o rendimento do hospital ou clínica. 1.4.3 - Aquisição de Imagem

Imagens de medicina nuclear podem ser adquiridas num formato digital usando, por exemplo, um scanner SPECT. A distribuição do radionucleido no corpo do paciente corresponde à imagem analógica. Uma imagem analógica é aquela que tem uma distribuição contínua da densidade representando a distribuição contínua de radionuclido acumulada num órgão particular. Um melhor exemplo de uma imagem digital será uma fotografia típica onde a distribuição contínua da densidade (preto, branco ou cor) representa na realidade a continuidade da densidade da luz. A contagem dos raios gama provenientes do corpo do paciente são digitalizados e guardados no computador na forma de uma matriz de imagem. As matrizes típicas usadas em aquisição de imagem SPECT são: 256x256, 128x128, 128x64, 64x64. A terceira dimensão corresponde ao numero de camadas transaxiais, frontais ou coronais usadas para definir o órgão que esta a ser pesquisado. Um exame típico SPECT tem um limite de armazenamento de 16 bits por pixel.

Quando um exame SPECT tiver sido completamente executado, a informação sem tratamento contida na matriz de imagem é denominada de informação projectada e está pronta a ser reconstruída. O processo de reconstrução coloca a informação a sua forma final digital pronta a ser transmitida para outro computador ou sistema para posterior visualização e análise física. 1.4.4 - Conclusão

O tratamento de imagens médicas moderno não seria possível sem os avanços que ocorreram no software e hardware nos últimos 30 anos. A radiologia automatizada oferece potencialidades de grande poupança de custos e reduzido trabalho humano. No entanto devemos ter em mente que os computadores não são perfeitos e até instrumentos como digitalizadoras (de extrema importância para a terapia de radiação) podem ter problemas. Sem os feitos tecnológicos que se iniciaram a 100 anos no dia 8 de novembro de 1895 e continuando hoje em dia com a evolução do hardware, software e equipamento, a radiologia como uma disciplina médica não existiria. 1.5 - Segurança e Controlo da Qualidade

Os procedimentos de medicina nuclear são actualmente considerados dos mais seguros para diagnósticos por imagem disponíveis aos pacientes actualmente.

É administrado aos pacientes apenas uma pequena quantidade de rádio fármaco. O procedimento de medicina nuclear expõe o paciente a menos radiação que um raio-x. A maioria das pessoas estão expostas a quantidades de radiação muito mais superiores diariamente do que pensam. Radiação do solo, rochas espaço e dos átomos de carbono e potássio nos seus próprios organismos perfazem 85 % da exposição anual de uma pessoa a radiações. Televisões a cores e detectores de fumo são alguns dos equipamentos do dia a dia que nos expõe a radiação.

O resto é contribuído pelos materiais radioactivos e raio-x usados na medicina. Por isso em média os procedimentos da medicina nuclear contribuem como que com alguns meses de vida diária em termos de radiação. Os físicos são especialmente treinados de modo a administrar as dosagens apropriadas de

11

Page 21: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

rádio fármacos para expor os pacientes apenas ao estritamente necessário protegendo-os de radiação desnecessária. 1.6 - Futuro

A área de medicina nuclear tornou-se muito diversa, sendo que se vai tornar numa das áreas de maior focus na medicina. Novos procedimentos e aplicações estão a ser desenvolvidas todos os dias por todo o mundo.

Uma das áreas de maior avanço é a área dos rádio fármacos. Actualmente o techtenium é o rádiofarmaco mais usado de momento para imagem na medicina nuclear. Ate à poucos anos tinha havido pouco esforço para tentar arranjar novos rádiofarmacos. Os cientistas aperceberam-se agora que certos procedimentos obteriam resultados mais satisfatórios se usassem rádiofarmacos com meio-tempo de vida mais longo, como por exemplo imagens de tumores. Pensa-se que se um paciente com cancro for injectado com um rádioisótopo com período de vida mais longo a imagem do tumor será visualizada mais tempo. Isto permitiria obter uma imagem mais precisa do tumor.

Outra área de desenvolvimento dos rádiofarmacos e a área das drogas orfãs. São drogas que são desenvolvidas para o tratamento de doenças raras. É estimado que 1 em cada 12 pessoas tem uma doença ou condição rara. estas condições raras não recebem tanta atenção por parte das empresas de investigação uma vez que estas se preocupam mais com as doenças dos pacientes da maior parte da população e ignoram os pacientes raros ou pequenos.

A medicina cardiovascular é também uma área de grande crescimento mas a ênfase nesta área vai para a instrumentação. Novos sistemas de câmaras estão a ser desenvolvidas de modo a obter imagens do coração muito mais pormenorizadas e precisas. As novas câmaras têm várias cabeças ao contrário das antigas que só tinham 2 cabeças. Estas câmaras são usadas nos sistemas SPECT.

Câmaras digitais estão também a ser desenvolvidas. Com as câmaras antigas o sinal captado a partir da emissão de radiação por parte do radio farmacêutico era um sinal analógico. O sinal era então convertido para um sinal digital por um processador na câmara. O uso de sinais analógicos produz alguns erros nas leituras que poderiam ser evitadas se usasse um sistema apenas digital. A primeira câmara totalmente digital foi produzida pela Summit Nuclear. Neste sistema há um conversor analógico para digital dentro do circuito de modo que o sinal de saída do circuito é digital. Estas câmaras permitem maior resolução espacial, resolução de energia e melhores capacidades de processamento.

2.2 - Equipamento SPECT actual (Hospital Universitário de Coimbra)

Com os avanços na medicina nuclear irá haver uma revolução no campo da medicina. Passar-se-á de uma visão de ver a doença como o ataque de um agente externo ao corpo para uma visão de que a doença e uma disfunção de produtos genético tais como substratos e enzimas. Os procedimentos médicos actuais consistem na medida do conteúdo de fluídos corporais ou biópsias de modo a determinar o tipo de doença. Com os avanços na medicina nuclear estes procedimentos irão ser substituídos por procedimentos que medem a química no interior do organismo. Os radioisótopos serão utilizados para ver exactamente a constituição química de todo o corpo. Será dado mais importância ao lado molecular da medicina. A medicina nuclear permite estudar a biologia humana e a doença a um nível genético. O uso de rádiofarmacos para determinar o excesso ou falta de actividade química em determinadas regiões do corpo. Assim os médicos poderão afirmar o que está errado a nível genético no paciente. Ao ser capaz de apontar especificamente a disfunção genética ou desordem o médico poderá prescrever medicamentos que irão contrabalançar o problema e a fonte do problema.

A nova perspectiva genética irá também criar uma nova necessidade para drogas que possam interagir com os genes. O campo da medicina nuclear espera abrir uma nova era no tratamento de doenças neuronais e de comportamento pelo estabelecimento da relação das doenças com desequilíbrios químicos. De modo a estes desenvolvimentos ocorrerem tem que haver desenvolvimento na área de detecção de radiação, processamento de dados e sistemas de visualização.

12

Page 22: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

Um novo método que está a ser desenvolvido é a detecção dos níveis de oxigénio em tecidos. Se uma área tem um abastecimento deficiente de oxigénio e sinal de que poderá haver problemas a nível vascular ou de tumores.

Os rádiofarmacos que estão a ser usados são o iodo - 123 e o techtenium. Estes radioisótopos agregam-se a áreas de níveis de oxigénio baixos e podem então ser scannerizadas mostrando os tecidos que se encontram privados de oxigénio. Este tipo de obtenção de imagem é denominado de hypoxia. A hypoxia indica-nos se encontram células viáveis numa determinada área. Isto pode ser útil na determinação de que parte do cérebro foi afectada em pacientes que tenham sofrido um enfarte ou quanto do tecido muscular do coração foi afectado após um ataque cardíaco. De acordo com testes feitos em animais a hypoxia será extremamente útil no diagnostico e tratamento do coração, cérebro e extremidades.

Também se concluiu que os rádiofarmacos tal como strontium-89 podem ser utilizadas em terapia radionuclida. É administrado a pacientes que tenham dores de ossos intratáveis. Os radionuclidos diminuem a dor sentida pelo paciente reduzindo ao mesmo tempo a quantidade de narcóticos que este teria que tomar. Em 20% dos pacientes e mesmo eliminada a necessidade de uso de medicação. Quando a

dor reaparece após o tratamento geralmente não tem a mesma expressão que anteriormente.

Estudos de sono estão também, a ser efectuados na área de medicina nuclear. Os medicamentos actualmente no mercado para perturbações a esse nível induzem sono mas já se provou que este sono é menos reabilitativo que o sono biológico normal. Um estudo feito em gatos descobriu que existe uma molécula no corpo responsável por induzir sono. Pensa-se que esta molécula viajara pelo fluido da espinal medula passando pela barreira sangue cérebro agregando-se a receptores no cérebro. Pesquisadores de medicina nuclear estão a tentar etiquetar a molécula com carbono-11 ou nitrogenio-13. Uma vez a molécula etiquetada esta pode então ser scannerizada no cérebro para determinar quais os receptores no cérebro responsáveis por induzir sono. Esta investigação espera produzir uma droga que interaja com os receptores do sono no cérebro produzindo um sono verdadeiramente reabilitador

tal como o sono fisiológico normal.

2.3 - Resultado de exame SPECT

Com todos os avanços na medicina nuclear, é possível perder de vista o mais importante aspecto que é a qualidade de cuidados a preços acessíveis para todos os pacientes. Alguns físicos debatem actualmente se todos os detalhes de procedimento dos exames e obtenção de imagem são necessários. Olhando para a maioria da população, a maioria dos diagnósticos pode ser feita correctamente usando um mínimo de procedimentos. Por exemplo alguns médicos defendem exames aos ossos para pessoas que tenham dores nas costas. Um scan de ossos dá uma imagem muito detalhada mas é também um procedimento muito caro. Um procedimento alternativo é o MRI, porque é mais barato e fornece ainda assim uma imagem suficientemente boa para diagnosticar problemas.

Um estudo foi recentemente efectuado em pacientes com problemas coronários. Estes pacientes tinham passado por procedimentos de obtenção de imagens extensos de modo a determinar se a operação era necessária. Foi provado que muitos destes pacientes não necessitavam de estudos de imagem. A simples monitorização dos sinais vitais expressão sanguínea seriam suficientes. A medicina nuclear continuará a criar novas técnicas e novos procedimentos, mas o paciente e não a tecnologia terão que ser a principal preocupação.

2 – SPECT (Single Photon Emission Computed Tomography) 2.1 - Introdução ao Single Photon Emission Computed Tomography

13

Page 23: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

Emissão (3-D) tridimensional da tomografia computorizada (ECT) fornece um olhar qualitativo e quantitativo na distribuição de um volume de radioisótopo após a sua injecção no corpo humano. O ECT junto com (a 2-D) imagem planar bidimensional são as técnicas de aquisição de imagem principais, usadas em todos os departamentos de medicina nuclear. ECT tridimensional - um processo que envolve a rotação de até três câmaras foto - sensíveis (câmaras gama) em torno de um paciente - resulta numa imagem 3-D da distribuição de um rádioisótopo injectado que é apontado geralmente para um órgão em particular, como por exemplo o coração. A imagem 3-D obtida assim é o resultado da reconstrução de uma série de projecções 2 D, que de seguida " empilham-se " de modo a criar a terceira dimensão. SPECT corresponde a Single Photon Emission Computed Tomography. Em primeiro lugar SPECT é uma forma de Tomografia Computorizada. Como o nome sugere, a emissão de raios gama constituem a fonte de informação, em vez de transmissões de raios - X tal como é utilizado em Tomografia Computorizada. Ao contrário do raio X Computed Tomography (CT) ou Magnetic Resonance Imaging (MRI) o Single Photon Emission Computed Tomography (SPECT) permite-nos a aquisição de informação funcional sobre o orgão de um paciente ou o sistema específico do corpo. A radiação interna é administrada por meio de um fármaco que é etiquetado como um isótopo radioactivo. Este rádiofarmaco, ou tracer, é injectado, ingerido, ou inalado. Estes rádiofarmacos podem ser por exemplo o: Technetium-99m e Thallium-201. Um rádiofarmaco é uma proteína ou uma molécula orgânica que tem ligado a si um rádionuclido. As proteínas e moléculas orgânicas são seleccionadas com base nas suas propriedades de absorção dentro do corpo humano. Por exemplo alguns rádiofarmacos são colectados nos músculos do coração e são utilizados para aquisição de imagem SPECT cardíaca. Outros são dimensionados para os pulmões e são usados para exames SPECT de perfusão. Muitos mais são utilizados de maneira a possibilitar a execução de exames SPECT noutras áreas do corpo. Depois o isótopo radioactivo deteriora-se, tendo por resultado a emissão de raios gama. Estes raios gama dão-nos um retracto de o que está a acontecer dentro do corpo do paciente. Assim, num modo geral, um órgão saudável irá absorver uma determinada quantidade de rádiofarmaco, que irá aparecer como uma área brilhante numa imagem SPECT. Uma absorção anormal de rádiofarmaco irá ter como consequência um surgimento de uma área mais clara ou mais escura do que o brilho padrão na imagem SPECT, levando à suspeita da presença de um estado de doença.

Estes raios gama permitem-nos uma visão interna do corpo humano usando a ferramenta mais essencial na medicina nuclear, a câmara gama. A câmara gama pode ser usada no processamento latente planar de modo a adquirir imagens 2-D, ou em processamento latente SPECT para adquirir imagens 3-dimensionais. A câmara gama adquire os raios gama que são emitidos de dentro do paciente, permitindo-nos assim a reconstrução de uma imagem de onde os raios gama são emitidos. A partir desta informação podemos determinar como um orgão ou um sistema particular está a funcionar.

De salientar que existem vários centros SPECT em Portugal com particular incidência nos grandes centros urbanos (Lisboa e Porto). Mas como cada vez mais este tipo de exames se torna mais acessível a todos e se revelam como exames de extrema importância, mais pontos do país também já possuem ou estão prestes a ter centros SPECT, tais como: Coimbra e Braga. 2.2 - História do SPECT

O primeiro dispositivo de ECT foi denominado de MARK IV e foi desenvolvido por Edwards e Kuhl. A MARK IV consistia em diversos bancos de detectores de fotões de NaI arranjados de uma forma rectangular em torno da cabeça do paciente. O primeiro dispositivo comercial de Single Photon-ECT (SPECT) era similar no desenho ao projecto MARK IV mas tinha 32 detectores de fotões e foi chamado o Tomomatic-32. As primeiras aplicações do ECT resultaram em imagens que do ponto de vista do diagnóstico não eram usáveis, e a técnica não foi aceite de uma forma generalizada. É só quando os métodos evoluíram durante a introdução do raio-x CT por Hounsfield e Cormack no ECT da medicina nuclear, que esta modalidade passou a ganhar a atenção da comunidade médica que relacionada com análise de imagem. Os algoritmos de reconstrução inventados para o CT de raio-x tiveram que ser reformulados para o ECT de modo a ter em atenção efeitos de atenuação de fotões e de espalhamento no corpo humano para alem das limitações mecânicas e eléctricas dos detectores. Quando se conseguiu técnicas de reconstrução de imagem tais como o FBP (projecção inversa filtrada) produziram-se imagens de ECT que pela primeira vez permitiram análise qualitativa e que foram consideradas

2.4 - Exame de MRI

14

Page 24: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

quantitativamente válidas para uso clínico. Ao contrário de outras modalidades tais como MRI e raio-x, o ECT obtém imagens da função do

organismo e não da anatomia no sentido estrito. Isto é devido, por exemplo, o SPECT envolve a detecção de radiação gama emitidos somente

por átomos radioactivos, chamados radionuclidos, tais como o Techtenium -99m e Thalium-201. Um rádiofarmaco é uma proteína ou molécula orgânica com um radionuclido ligado a si. As

proteínas e moléculas orgânicas são seleccionadas baseadas no seu uso ou nas suas propriedades de absorção por parte do corpo humano. Por exemplo alguns rádiofarmacos acumulam - se no músculo do coração e são por isso usadas para fazer SPECT cardíacos. Assim no caso geral um coração, ou pulmões ou cérebro saudáveis irão absorver uma determinada quantidade do rádiofarmaco, que aparece como uma área mais clara nas imagens obtidas por SPECT.

Hoje em dia quase todos os pacientes cardíacos recebem um ECT planar ou um SPECT como parte dos seus exames para detectar e avaliar o estado de desenvolvimento de uma doença coronária. Os exames SPECT ao fígado e cérebro são também áreas de grande utilização do SPECT. O SPECT é usado de uma forma rotineira para ajudar no diagnóstico e avaliação de cancros, enfartes, doenças de fígado para alem de outras anormalidades funcionais. 2.3 - Teoria e Instrumentação

Assim como num exame raio-x CT, aquisição de imagem SPECT envolve a rotação de um detector de fotões em volta do corpo humano de maneira a adquirir informação de diversos ângulos. Usando esta técnica procuramos as posições e concentrações da distribuição de radionuclidos. Por causa das fontes de emissão (radionuclidos injectados) se encontrarem dentro da cavidade corporal, esta tarefa é de maior dificuldade de execução do que para o raio-x CT, onde a posição e força da fonte de emissão (exterior ao corpo humano) é sempre conhecida. Isto é, no raio-x CT a atenuação é medida, não a fonte de transmissão. De maneira a compensar a atenuação ocorrida pela emissão de fotões pelos tracers injectados no corpo, o SPECT contemporâneo usa algoritmos de reconstrução de maneira a aumentar a resolução.

A aquisição de imagem em SPECT é inferior a do PET por causa da sensibilidade e resolução alcançadas. Diferentes radionuclidos são usados em SPECT, sendo que todos eles emitem um fotão apenas (usualmente a volta dos 140keV), em vez de emissão de positrões (511 keV) como é usado em PET. Como apenas um fotão é emitido pelos radionuclidos usados em SPECT, uma lente especial denominada de colimador é usada para adquirir toda a informação resultante de vários ângulos a volta do corpo. O uso de um colimador resulta numa tremenda diminuição da eficiência de detecção quando comparada com PET. Para tomografias de emissão de positrões, a colimação é alcançada de uma maneira natural pelo facto de que um par de fotões detectados (raios gama) podem ser localizados na sua origem desde que sigam uma trajectória ao longo da mesma linha de produção. Em PET existem pelos menos 500 detectores capazes de detectar um isótopo PET a qualquer momento, enquanto que em SPECT existem apenas 1 a 3 colimadores. Resoluções superiores requerem sensibilidade superior e a resolução do SPECT é muitas vezes inferior que a atingida em PET. A resolução resultante que pode ser utilizada (cerca de 7mm) para SPECT é inferior à resolução do PET num factor de 3 ou 4.

Mesmo sendo a resolução resultante da aquisição de imagem em SPECT não tão boa como a obtida em PET, a disponibilidade de novos rádiofarmacos, particularmente para a cabeça e cérebro, e tendo em conta aspectos económicos (um exame SPECT custa cerca de um terço de um exame PET) e práticos da instrumentação SPECT faz deste método de emissao tomográfica atractiva para estudos clínicos. 2.4 - Aquisição e Processamento de imagem

O SPECT tem como base a determinação da concentração da quantidade de radionuclido num determinado e específico orgão em função do tempo. A introdução do rádioisótopo Tc-99m por Harper que emite um só fotão de raio gama de energia 140KeV, que tem como tempo de vida cerca de 12 horas assinalou um grande passo para o SPECT uma vez que este fotão é facilmente detectado pelas câmaras gama. No entanto um problema técnico de engenharia envolvendo a colimação destes raios gama, antes

15

Page 25: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

de entrarem propriamente na câmara gama, teve que ser resolvido antes do SPECT se poder afirmar como uma modalidade de imagem viável.

Sendo assim é essencial em SPECT, a colimação dos raios gama emitidos pela distribuição no corpo onde foram injectados os radionuclidos. Os colimadores para SPECT são tipicamente de chumbo e tem cerca de 4 a 5 cm de espessura e 20 a 40 cm de lado. Os colimadores contem milhares de canais quadrados, circulares ou hexagonais paralelos através dos quais e apenas através dos quais os raios gamas são permitidos passar. Tipicamente um colimador de baixa energia para o SPECT pesa cerca de 23 Kgs mas os modelos de energia elevada podem pesar acima de 92 Kgs. Apesar de pesados estes colimadores são colocados directamente por cima de um cristal muito delicado de NaI que existe em todas as câmaras gama. Qualquer câmara gama assim equipada com um colimador é apelidada de câmara Anger, devido ao nome do seu inventor.

Os raios gama que sejam emitidos numa direcção que coincida com os canais do colimador passarão pelo colimador sem serem absorvidas, e interagirão com o cristal de NaI criando luz. Por detrás do cristal, uma rede de tubos fotomultiplicadores (sensíveis a luz) receberão a luz para processamento, e a partir da análise destes sinais de luz são constituídas as imagens SPECT. Dependendo do tamanho da câmara de Anger orgãos inteiros tais como o coração ou fígado podem ser visualizados em imagens SPECT. Câmaras de Anger maiores são usadas para obter imagens de todo o corpo humano, como por exemplo para visualização da estrutura óssea.

Para os raios gama emitidos pelos rádiofarmacos típicos de SPECT há duas importantes interacções com a matéria. A primeira envolve o espalhamento dos raios gama resultante da interacção com as moléculas e átomos (DNA) no corpo humano. Este espalhamento é chamado como Compton Scattering. Alguns fotões que sofrem esta influência são deflectidos para fora da câmara Anger e perdidos para o processo de detecção. A segunda interacção consiste na absorção por parte de um átomo do corpo do fotão com a elevação do potencial energético ou até mesmo com a libertação de um electrão. Este processo é chamado de efeito fotoeléctrico e foi detectado por Einstein nos metais tendo recebido o prémio Nobel pela sua descoberta. Ambos os processos resultam em perdas ou degradação da informação acerca da distribuição do rádiofarmaco no corpo. O segundo processo cai no conceito geral de atenuação em termos de imagens médicas e é uma área de investigação activa.

A atenuação resulta na redução do numero de fotões que chegam a câmara de Anger. A quantidade de atenuação sentida por cada fotão depende no caminho que este percorre no corpo e da sua energia. Os fotões que experimentam o espalhamento são geralmente reflectidos, perdendo muitas vezes energia, acabando assim por ser absorvidas ou reflectidas para fora do ângulo de recepção da câmara de Anger. Em qualquer um dos casos, o fotão e a informação que este transporta consigo acerca da distribuição do rádiofarmaco no corpo, não vai ser detectado e é assim considerado perdido devido a atenuação. Aos 140KeV Compton Scattering é a causa mais provável de interacção de um fotão de radiação gama com a água ou tecidos do corpo. Uma percentagem mais pequena de fotões é perdida devido a interacção fotoeléctrica. É possível, que os fotões quando sujeitos ao efeito de Compton Scattering serem espalhados para o ângulo de visão da câmara de Anger. Estes fotões no entanto não transportam informação útil acerca da distribuição do rádiofarmaco no corpo uma vez que não indicam de onde no corpo foram emitidos. Como resultado a detecção de fotões espalhados no SPECT levam a perdas de contraste na imagem bem como imagens tecnicamente imprecisas.

A aquisição e processamento de uma imagem SPECT, quando correctamente efectuada, envolve compensações e ajustes de muitos parâmetros físicos e de parâmetros do sistema. Uma selecção destes inclui: atenuação, espalhamento, uniformidade e linearidade de resposta do detector, resolução geométrica espacial e sensibilidade do sistema, truncagem da imagem, shift mecânico da camera ou gantry, shift electrónico, eixo de rotação de calibração, ruído de imagem, espessura das fatias de imagem, tamanho da matriz de reconstrução e filtros, intervalos angulares e lineares de amostragem, variações estatísticas nas contagens de fotões detectados, mudanças no campo de visão da câmara de Anger com a distância à fonte e tempo morto do sistema.

A calibração e monitorização de muitos destes parâmetros caem na designação geral de Controlo de Qualidade e são usualmente efectuadas por um técnico de medicina nuclear certificado ou médico físico. Nesta lista a colimação tem o maior efeito em termos de resolução espacial e sensibilidade do sistema, sendo a sensibilidade relacionada com o número de fotões por segundo que são detectados. A resolução e a sensibilidade do sistema são as medidas físicas mais importantes na qualidade da performance de um sistema SPECT. A melhoria destes parâmetros é raramente conseguida simultaneamente na prática apesar de ser o grande objectivo de qualquer investigador na área SPECT.

A distribuição do radionuclido no corpo do paciente corresponde à imagem analógica (imagem que tem uma distribuição contínua de densidade) que representa a concentração de um radionuclido num

16

Page 26: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

determinado orgão. A radiação gama proveniente do paciente é digitalizada e armazenada numa matriz ou vector de imagem. A 3ª dimensão na matriz é o número de fatias transaxiais, coronais ou sagitais usadas para representar o orgão. uma vez o scan SPECT terminado, a informação obtida na matriz de imagem e chamada de dados de projecção e esta pronto para ser reconstruído. A reconstrução coloca essa informação no seu formato digital final de modo a poder ser analisada pelo físico. 2.5 - Reconstrução de Imagem 2.5.1 - Projecção Inversa Filtrada

O algoritmo mais comum usado na reconstrução tomográfica de informação clínica é o método da projecção inversa filtrada. Existem também outros métodos, mas estes serão discutidos na secção sobre métodos de reconstrução iterativos. Para a reconstrução da imagem final são necessárias cinco fases: projecção da informação, transformada de Fourier da informação, filtragem da informação e filtragem inversa. 1. Projecção da informação

À medida que a câmara SPECT gira em volta do paciente, cria uma série de imagens planares chamadas projecções. Em cada paragem, apenas fotões movendo-se perpendicularmente à face da câmara passam através do colimador. Como muitos desses fotões tem como origem várias zonas diferentes em profundidade do paciente, o resultado é uma sobreposição de todos os órgãos, sujeitos a acção do rádioisótopo, que se encontrem no mesmo caminho específico, da mesma maneira que uma radiografia raio-x é a sobreposição de todas as estruturas anatómicas de 3-D para 2-D.

Um estudo SPECT consiste em muitas imagens planares retiradas desta forma e tendo em conta vários ângulos diferentes. Após a aquisição de todas as projecções, estas são sub – divididas, tirando todas as projecções referentes a uma parte, a uma pequena fatia do paciente. Todas as projecções referentes a cada fatia são ordenadas e colocadas numa imagem chamada sinograma. 2. Transformada de Fourier da informação.

Se a informação contida no sinograma fosse reconstruída neste ponto, artefactos iriam aparecer na imagem reconstruída devido a natureza da subsequente operação de projecção inversa. Adicionalmente, devido a natureza da radioactividade, existe um ruído inerente na informação que faz com que as imagens reconstruídas tendam a ter um aspecto pouco suave. De maneira a evitar estes dois factores é necessário fazer uma filtragem da informação. Quando se efectua a filtragem da informação, esta pode ser feita directamente no espaço da projecção, que significa que temos de multiplicar a informação por um factor de suavização (smoothing kernel). Este processo é conhecido como convolucão.

A convolucão é uma tarefa muito intensiva do ponto de vista computacional e por isso é útil evitá-la sempre que possível. É sabido que a convolucão no domínio do tempo corresponde a uma multiplicação do domínio das frequências. Isto significa que qualquer filtragem feita por uma operação de convolucão do domínio dos tempos pode ser muito facilmente ser feita por uma multiplicação no domínio das frequências. Em SPECT faz-se uma transformação similar da informação projectada para o domínio das frequências, domínio este onde se pode fazer uma filtragem mais eficiente da informação. A transformada de que se faz uso para a passagem de domínio é denominada de Transformada de Fourier Unidimensional. 3. Filtragem da informação.

Uma vez que a informação tenha sido transformada para o domínio das frequências, é então filtrada de maneira a suavizar a acção do ruído estatístico. Existem muitos filtros diferentes disponíveis para efectuar esta operação e todos tem certas características diferentes. Por exemplo alguns filtros irão efectuar uma suavização tão forte que deixará de haver na imagem contornos afiados, e isso faz com que haja uma degradação na resolução da imagem final. Ha também filtros que mantém uma resolução final muito alta mas a suavização efectuada é muito ligeira.

17

Page 27: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

Assim os filtros tipicamente utilizados são: filtro de Hanning, Butterworth, Cosseno passa - baixo, Weiner, etc... . Independentemente do filtro utilizado, o resultado final será uma imagem que é relativamente sem ruído e agradável a visualização. 4. Transformada inversa da informação

Como a informação filtrada encontra-se no domínio das frequências temos que proceder a transformação inversa para colocar novamente a informação no domino espacial de maneira a obter a informação x,y,z da distribuição espacial obtida. Este procedimento é feito da mesma maneira que foi feito a primeira transformada, só que a esta transformada chamamos de transformada inversa de Fourier unidimensional. Neste ponto a informação resultante e similar a informação do sinograma original excepto no aspecto que a informação final se encontra suavizada e praticamente sem ruído. 5. Projecção inversa

O passo mais importante na reconstrução envolve um processo conhecido como projecção inversa. Como a informação original foi adquirida deixando apenas que os fotões emitidos perpendicularmente a face da câmara entrem na câmara, a projecção inversa faz um esbatimento da informação binária da câmara no sinograma filtrado ao longo das mesmas linhas de onde o fotão foi emitido. Regiões onde as linhas de diversos ângulos da projecção inversa se intersectam representam áreas que contêm uma alta concentração de rádioisótopo. 2.5.2 - Método dos parâmetros directos

Tem sido mostrado através da aquisição de imagem planar dinâmica que o metabolismo de tracers no miocárdio podem ser modelizados através de uma função exponencial dual no tempo. Este modelo corresponde ao tracer ser levado até um particular compartimento do coração, ser metabolizado e expelido desse compartimento. A taxa à qual o tracer é metabolizado e expelido é modelado por essa função no tempo. Tem sido também sugerido que os parâmetros desta função são uma boa indicação da viabilidade geral do coração, isto é, se o tracer for expelido com taxas elevadas que o coração se encontra num estado saudável enquanto zonas não saudáveis têm taxas baixas.

Se nós soubermos o tempo total do comportamento do coração, podemos ir um passo adiante e supor que regiões individuais do coração têm o mesmo comportamento funcional. Devido ao facto de que em SPECT, nós lidarmos com representações por pixels de objectos, é natural aplicar a nossa função exponencial dual a cada pixel do coração. Desta maneira a nossa função pode ser aplicada em ordem ao tempo a cada pixel, e assumir que cada pixel tem um comportamento específico. Para tal é necessário que cada pixel siga esta equação:

P(T) = A.e-l*t + B.e-m*t +C

É possível determinar os parâmetros através de optimização computacional. O resultado desta

reconstrução de imagem são cinco imagens representando as cinco variáveis desconhecidas. A partir deste método, os pixels com rápidas taxas cinéticas, representam regiões que podem ser facilmente diferenciadas de regiões mais lentas. 2.5.3 - Método dos mínimos quadrados com restrição linear

A desvantagem primária da aproximação dos parâmetros directos é o facto que nós termos que assumir uma determinada forma da funcionalidade do movimento do tracer. É ainda desconhecido se fazer essa suposição para todas as circunstâncias é verdade e também pode não ser verdade que o tracer pode ser descrito por uma função exponencial dual em todos os instantes de tempo. Por estas razões é extremamente vantajoso desenvolver um método de reconstrução totalmente dinâmica, que não faça qualquer tipo de suposições acerca do comportamento do tracer. Assim uma aproximação possívelé usar o método dos mínimos quadrados com restrições lineares (LLS).

A LLS aproximação não faz qualquer tipo de suposição quanto à forma funcional de alteração de actividade, mas supõe minimamente que a actividade de cada pixel apenas decresce no tempo. Este suposição é correcta no evento de que o tracer é administrado antes do exame ter lugar e que a maior parte do tracer está presente no orgão de interesse no início do exame.

18

Page 28: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

Quando reconstruído com LLS, o resultado é uma série de imagens, cada uma delas referindo a distribuição espacial do tracer a um dado instante de tempo. O problema é referido como uma restrição linear dos mínimos quadrados porque nós assumimos que a diferença nas actividades num pixel entre imagens consecutivas é apenas um valor positivo. Então, isto assegura que a actividade do pixel é continuamente decrescente ao longo tempo. 2.5.4 – Reconstrução iterativa De maneira a incorporar informação dos data sets morfológicos para o processo de reconstrução, são feitas as seguintes considerações: a radioactividade continua numa região anatómica tende a ser homogénea (isto é, matéria cinzenta), as fronteiras entre regiões anatómicas são também fronteiras entre regiões, nas quais, a absorção do tracer é similar e finalmente as fronteiras de regiões anatómicas podem ser extraídas através de informação à priori com um método apropriado de segmentação. O algoritmo da reconstrução iterativa consiste em combinar um método iterativo rápido com um método de reconstrução com informação à priori. Este último é baseado no método de reconstrução que incorpora informação morfológica para o modelo estatístico de Shepp e Vardi usando a regra estatística de Bayes. A primeira consideração feita no parágrafo anterior pode ser substituída por uma restrição menos severa, onde os pixels dentro de uma região extraída de informação à priori, tendem a ter todos o mesmo valor. Isto pode ser modelado através de cadeias de Markov (que é equivalente a uma descrição da distribuição de Gibbs). O método de reconstrução HOSP (High-Overrelaxation Single Projection) pode ser derivado do método anterior através de uma simplificação do modelo. As correcções efectuadas em cada iteração são não – simultâneas, e assim, permitem o uso o uso de parâmetros de grande relaxamento resultando num significativo aumento da velocidade do processo de reconstrução. Este método de reconstrução consiste nos seguintes passos: reconstrução da informação SPECT sem informação morfológica; emparelhamento destas imagens com imagens morfológicas; segmentação da informação morfológica; incorporação da informação morfológica através de cadeias de Markov; validação dos resultados da reconstrução através da comparação de perfis e variância nas regiões de interesse. 2.6 - A Câmara Gama

Sendo o rádiofarmaco administrado, é necessário detectar as emissões de raios gama de maneira a obter informação funcional. O instrumento usado em medicina nuclear para a detecção de raios gama é conhecido por câmara Gama. Os componentes que constituem a câmara gama são: colimador, detector de cristal, matriz de tubos fotomultiplicadores, circuitos lógicos de posição e um computador de análise de dados. 2.6.1 Características da Gama Câmara

Quando a radiação ionizada interage com matéria a energia absorvida é geralmente convertida em calor. Algumas substâncias emitem uma porção desta energia em excesso na forma de luz visível ou luz ultravioleta e são conhecidos como cintiladores. O brilho de cada emissão é proporcional à energia depositada no cristal, que por sua vez é proporcional à energia do fotão incidente. Por isso tanto o número e energia dos fotões incidentes podem ser registadas. Os detectores de cintilação consistem num cristal de cintilação e num tubo fotomultiplicador. O iodeto de sódio (NaI) é o cristal de cintilação mais utilizado. É o que tem a maior eficiência de conversão - cerca de 13 % da energia depositada no cristal é emitida como luz visível. A acção dos cristais de NaI é maximizada pela adição de pequenas quantidades de thalium iónico.

2.5 - Equipamento de Medicina Nuclear

- Resolução espacial

19

Page 29: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

A resolução espacial denota a capacidade de um instrumento de reproduzir finos detalhes. A resolução é geralmente expressa como a amplitude "Full-Width-at-Half-Maximum". Quanto maior o valor de FWHM maior é o aspecto confuso da imagem (borrões).

Assim menores valores de FWHM indicam melhor resolução de detecção. A maioria das câmaras de cintilação de Anger tem resoluções espaciais de 6 a 8 mm na superfície de um colimador de orifícios paralelos de alta resolução. Os colimadores geralmente melhoram a resolução por exclusão da difusão. - Sensibilidade

A sensibilidade ou eficiência demonstra a fracção de fotões incidentes que um sistema de aquisição realmente regista. Fotões de alta energia são mais penetrantes e assim tem menos probabilidade de interagir que os de baixa energia. Câmaras gama modernas funcionam melhor quando trabalham com fotões no intervalo de 100 a 200 KeV. Cristais de maior espessura interceptam uma fracção de fotões mais elevada do que cristais menos espessos. No entanto, infelizmente, cristais de maior espessura degradam a resolução pois a luz difunde-se num caminho mais longo antes de atingir os tubos foto multiplicadores.

As câmaras de Anger localizam cintilações por comparação dos pulsos de todos os tubos fotomultiplicadores de modo a determinar a posição do maior sinal. A melhor troca entre sensibilidade e resolução para visualizar Technetium ou Thalium é cerca de 0.6 cm de espessura para o cristal. Esta espessura no entanto é ineficiente para maiores emissões gama tais como Gallium, Indium e Iodine. Como compromisso geralmente é usado um cristal de espessura de 0.95 cm. - Resolução temporal

A resolução temporal de um sistema típico de detecção de cintilação é de aproximadamente 1.5 a 3 microsegundos. Perdas por tempo morto (tempo entre processamento de sinal no qual não pode registar outros sinais) são de cerca de 10 a 30 % com uma taxa de contagem máxima de 300000 contagens por segundo.

Câmaras de multi-cristal podem registar ate 50000 contagens em cada - cristal/tubo fotomultiplicador - resultando assim em contagens de 600000 a 1 milhão de contagens por segundo. O cristal mais espesso usado em detectores de multi cristal (1cm) limita no entanto a resolução espacial. 2.6.2 - Controlo da qualidade da Câmara

Cada câmara deveria ser optimizada diariamente e antes de mudar de radionuclido, de modo a que a sua janela de energia esteja sempre correcta. A uniformidade também deveria ser verificada numa base diária usando uma contagem de alto fluxo. Este fluxo pode ser extrínseco (com o colimador ligado) ou intrínseco (com o colimador desligado). Para um fluxo intrínseco o colimador é removido e um ponto fonte é colocado afastado pelo menos 5 vezes o diâmetro do detector. A esta distância essencialmente um fluxo uniforme de fotões atingirá o detector. Um ponto fonte não pode ser usado para efectuar um fluxo extrínseco pois o colimador ira excluir radiação fora de eixos. O fluxo extrínseco deve ser efectuado com uma fonte em forma de disco ou um fantoma cheio de agua.. A vantagem de um fluxo extrínseco é que se pode detectar a presença de um colimador defeituoso. A resolução de câmara e a linearidade deveriam ser verificadas numa base semanal no mínimo.

Imagens incorrigidas irão demonstrar geralmente uma ligeira heterogeneidade devido a desequilíbrios dos tubos foto multiplicadores ou do próprio cristal. Circuitos de correcção são utilizados para tornar a imagem uniforme. Uma variação em uniformidade ate 10 % pode ser tolerada para aquisição planar sem grandes perdas de detalhe. Para aquisição SPECT no entanto variações na uniformidade ao longo do detector devem ser menores que 1 %. 2.7 - Colimador

Uma vez que o tempo que um paciente passa num departamento de medicina nuclear está directamente relacionado com a sua comodidade, existe pressão para efectuar todos os exames nucleares dento de um tempo aceitável. Para o SPECT isto pode resultar em relativamente elevado ruído estatístico na imagem devido ao número limitado de fotões detectados num intervalo de tempo pelo scan.

20

Page 30: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

Este facto não impede a capacidade clínica para prognosticar o estado da doença usando o SPECT mas levanta questões de investigação interessantes.

Por exemplo uma câmara de Anger típica equipada com um colimador de energia baixa detecta aproximadamente 1 em cada 10 000 fotões gama emitidos pela fonte na ausência de atenuação. Este número depende do tipo de colimador usado. A resolução espacial do sistema também depende do tipo de colimador e da resolução intrínseca da câmara Anger utilizada. Uma câmara Anger moderna tem tipicamente uma resolução de 3 a 9 milímetros. Independentemente do colimador a resolução não consegue ficar melhor do que a resolução intrínseca. A mesma ideia se pode aplicar a sensibilidade: a sensibilidade do sistema é sempre pior ou igual na melhor das hipóteses à sensibilidade intrínseca.

Os colimadores têm um papel fulcral na definição das características extrínsecas de imagem de um sistema. A taxa de energia de um colimador indica a máxima energia dos fotões que pode ser eficientemente tratada pelo colimador. Isto é geralmente definido como sendo a energia a que menos de 5% dos fotões fora de eixos passam pelo colimador. Colimadores de baixa energia são desenhados para um máximo de energia de 140m a 200 KeV, enquanto colimadores de energia media são eficientes ate 300 a 400 KeV. A taxa de energia do colimador também denominada de espessura septal. Apesar do tungsténio absorver fotões mais eficazmente, a maioria dos colimadores são feitos de chumbo devido a estes serem mais baratos. 2.7.1 - Resolução e Sensibilidade

A resolução e a sensibilidade de um colimador estão inversamente relacionadas. A melhor resolução espacial é conseguida com um colimador com buracos compridos de pequeno diâmetro pois o ângulo de aceitação é menor e mais dispersão é rejeitada. A sensibilidade destes colimadores de alta resolução é no entanto menor, pois menos fotões atingem o cristal. Sensibilidade ou eficiência refere-se à fracção de fotões emitidos que passam realmente pelo colimador atingindo o detector. A sensibilidade aumenta com o quadrado do tamanho do buraco e diminui com o quadrado do comprimento do buraco.

Quando a resolução espacial não é crítica e o fluxo de fotões ou o tempo de aquisição é limitado, um colimador de alta sensibilidade pode ser usado. O colimador que sirva ambas as características é um colimador que atinja um compromisso entre sensibilidade e resolução espacial. Quando se usa qualquer colimador a resolução espacial diminui com o aumento da distância ao paciente. Genericamente a resolução decresce de 1mm por cada centímetro adicional de distância a que o paciente se coloque da face do colimador de buracos paralelos.

Assim a resolução melhora com a diminuição do diâmetro dos buracos do colimador, aumento do comprimento efectivo dos buracos do colimador e diminuição da distância do paciente ao colimador.

A sensibilidade teve francas melhorias devido aos sistemas de SPECT de múltiplas câmaras. Um sistema SPECT de três câmaras equipado com colimador parallel hole de resolução ultra-elevada consegue obter uma resolução (medida a full width half maximum -FWHM) de 4 a 7 mm. 2.7.2 - Tipos de colimadores:

A sensibilidade geométrica no entanto está relacionada com a resolução geométrica de modo inverso, ou seja a melhoria de uma equivale a piorar a outra característica. É claro que ambas estas características são os objectivos principais do SPECT, por isso os investigadores de SPECT têm sempre que considerar ambas as características quando desenham novos colimadores. Tem havido vários desenhos de colimadores nos passados 10 anos que optimizaram a relação inversa sensibilidade / resolução pelos seus desenhos particulares.

Existem 3 tipos de colimadores. Estes são: parallel-hole, converging hole e pin-hole: 2.7.2.1 - Buracos paralelos- parallel hole

Um colimador com milhares de canais paralelos de chumbo é chamado de colimador parallel-hole, e tem uma resolução geométrica (ou de colimador) que aumenta com a distância da fonte de radiação gama. A resolução geométrica pode ser melhorada através do uso de canais mais pequenos. Os colimadores de buracos paralelos não introduzem distorção e fornecem um campo de vista constante. A resolução é melhor quando o objecto é colocado contra o colimador, mas a sensibilidade é independente da distância ao colimador. 2.7.2.2 Convergência e divergência

21

Page 31: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

Os colimadores de convergência e divergência são assim chamados devido a visionarem os

buracos com a perspectiva dos detectores. Os colimadores de convergência podem na realidade permitir a detecção de estruturas mais pequenas do que a resolução intrínseca da câmara (aumentando a resolução do sistema). Na prática a ampliação é limitada a cerca de 15%, no entanto colimadores convergentes introduzem distorção de imagem, uma vez que a ampliação varia de acordo com a profundidade do objecto. A sensibilidade (eficiência) aumenta com a distância ao colimador mas isto irá diminuir a resolução.

Estes colimadores foram construídos para melhorar a relação entre resolução e sensibilidade através do aumento da superfície da câmara Anger que se encontra exposta a fonte de radionuclido. Isto vem aumentar o número de contagens, que provoca o aumento da sensibilidade. Colimadores de desenho mais moderno tal como half-cone beam e astigmático, também foram concebidos.

Um colimador divergente reduz a imagem e degrada tanto a sensibilidade como a resolução, que irão piorar com o aumento da distância ao colimador. Este tipo de colimador é útil somente quando é necessário visionar uma estrutura maior que o tamanho do detector. 2.7.2.3 Pinhole

Outros tipos de colimadores com apenas um ou poucos canais, chamados colimadores pin-hole e foram desenhados para pequenos orgãos ou extremidades humanas tais como o pulso ou a glândula tiróide ou até para investigação em animais tais como os ratos.

Um colimador pinhole pode também ser utilizado para ampliar a imagem. A ampliação máxima ocorre quando o pinhole esta mais próximo do objecto e diminui quando este se afasta do objecto. Uma vez que a magnificação é determinada pela distância à abertura, um objecto espesso contem áreas que irão ser visualizadas a diferentes ampliações. Esta ampliação diferencial produz distorção da imagem que é maior na ampliação máxima. Imagens de pinhole aumentam também a resolução espacial do sistema de câmara. A resolução está relacionada com o tamanho da abertura, no entanto pequenas aberturas que produzem melhores resoluções limitam o número de contagens adquiridas. A resolução é também melhorada pelo aumento do comprimento da abertura. As imagens de pinhole são melhores para ampliações de objectos pequenos e finos. A magnificação electrónica é mais fácil de ser efectuada mas não aumenta a resolução do sistema. 2.8 - Detectores de Cintilação

De maneira a detectar os fotões gama utiliza-se detectores de cintilação. Um detector de cristal é constituído por uma liga de Tallium activado, Sódio e Iodo, sendo esta uma solução generalizada empregue nas Gama câmaras. Esta solução é devida à detecção eficiente do cristal em relação a energia proveniente da emissão radionucleica dos raios gama comum na medicina nuclear. O detector de cristal circular tem tipicamente 9 mm de espessura e um diâmetro de 30-50cm.

Um fotão de raios gama interage com o detector através do Efeito Fotoeléctrico ou Compton Scattering com os iões de iodo do cristal. Esta interacção causa a libertação de electrões que por sua vez interagem com a matriz do cristal resultam a produção de luz, num processo conhecido como cintilação. 2.9 - Tubos Fotomultiplicadores

Apenas uma pequena parte de luz é extraída do detector de cintilação, por isso os tubos multiplicadores são colocados atrás do cristal. O topo do tubo foto multiplicador é constituído por um foto cátodo que quando estimulado por fotões luminosos, ejecta electrões. O PMT (Photo Multiplicator Tube) é um instrumento que detecta e amplifica os electrões que são produzidos pelo foto cátodo. Por cada 7 a 10 fotões incidentes no foto cátodo apenas um electrão é gerado. Este electrão proveniente do cátodo é localizado num dínodo que absorve este electrão e reemite muitos mais electrões (usualmente 6-10). Estes novos electrões são localizados no próximo dínodo e o processo volta a repetir – se por toda a matriz de dínodos. A base do PMT é constituída por um ânodo que atrai o grande bloco final de electrões e os converte em impulso eléctrico.

Cada câmara tem vários PMTs colocados numa forma geométrica conhecida. A câmara típica contém 37 a 91 PMTs.

22

Page 32: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

2.10 - Circuitos de posicionamento

Os circuitos lógicos de posicionamento seguem-se imediatamente aos PMTs e recebem os impulsos eléctricos provenientes dos tubos num circuito denominado matriz somadora (SMC- Summing Matrix Circuit). Isto permite aos circuitos de posicionamento determinar aonde e quando cada evento de cintilação ocorreu no detector de cristal. 2.11 - Computador de análise de dados

Finalmente, para tratar da informação projectada 3 D que contém a distribuição espacial da actividade dentro do paciente, proveniente dos circuitos mencionados acima e consequentemente processá-la para um formato legível, é usado um computador com grandes capacidades de processamento. O computador pode usar vários tipos de métodos de reconstrução de imagem, como projecção inversa filtrada ou reconstrução iterativa. 2.12 - Visualização SPECT

O SPECT é superior à visualização planar no que diz respeito a localização da doença. A visualização SPECT melhora o contraste do objecto por eliminação de tecidos sobrepostos. Com uma órbita circular o detector estará por vezes mais afastado do paciente o que resulta em perdas da resolução espacial. Órbitas elípticas ou de seguimento de contorno manterão o detector mais próximo do paciente e por isso não deverão sofrer da mesma perda de resolução espacial. Infelizmente, especialmente em SPECT cardíaco, as órbitas elípticas resultam numa maior probabilidade de obtenção de artefactos. Apesar do detector estar mais próximo do coração há no entanto uma maior variação na distância do detector ao coração do que com órbitas circulares, pois com uma órbita circular apesar da distancia ser maior, esta é mais uniforme ao longo do arco. Esta variação de resolução espacial é mais visível em pacientes magros, e não é visualizada se for utilizado uma órbita de 360 graus. 2.12.1 Artefactos que influenciam a visualização SPECT

Em SPECT existem várias condicionantes de vários tipos que podem influenciar a imagem médica final e consequentemente o diagnóstico médico. Estas condicionantes vão desde o tipo de paciente sujeito ao exame, condições físicas onde é realizado o exame e também características internas do próprio aparelho. Em seguida, é feita uma caracterização de cada um dos artefactos existentes neste tipo de exames. - Uniformidade do campo

A uniformidade do campo do detector é o parâmetro mais crucial na performance do SPECT. Flutuações aleatórias no fluxo de sensibilidade de campo (não uniformidade do campo) devem ser mantidas abaixo dos 1%. Para garantir uniformidade de fluxo e um desvio standard percentual relativo de 1 % com 10000 contagens por pixel requer um fluxo de contagem de 30 milhões para uma matriz de 64x64 (120 milhões de contagens seriam necessárias para uma matriz de 128x128). Geralmente estes fluxos são efectuados semanalmente com 3 milhões de contagens de fluxo diárias. O fluxo deve ser obtido com o colimador ligado. - Centro de rotação

Os detectores de uma câmara SPECT rodam em torno de um eixo central. O computador assume conhecer a posição desse eixo durante a reconstrução da imagem. Se o verdadeiro eixo não corresponde ao eixo assumido serão criados artefactos durante a reconstrução da imagem. A maioria dos departamentos verifica a posição do eixo de rotação semanalmente. Quando o detector é um detector de cabeças múltiplas fixos em gantry rotativos não é necessário fazer verificações do eixo de rotação tão frequentes. A aquisição do centro de rotação consiste de um ponto fonte colocado fora do centro do campo de vista. Este deve ser calculado com uma precisão de pelo menos 1 décimo de pixel. Um

23

Page 33: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

deslocamento de meio pixel no centro de rotação pode resultar numa apreciável degradação da imagem final. Um erro de alinhamento no centro de rotação irá resultar na reconstrução de um ponto como um anel pelo que erros de alinhamento de centro de rotação resultam em artefactos do tipo cauda de cometa ou forma de anel. - Alinhamento de detectores

A cabeça da câmara deve ser nivelada antes de cada aquisição. Uma cabeça não nivelada provocará um erro do tipo de erro de alinhamento do centro de rotação. Para avaliar o alinhamento do detector, o ponto fonte deve mover-se para trás e para a frente numa linha recta. Se oscilar para cima e para baixo na imagem final, a cabeça da câmara não está nivelada ou o suporte da câmara não e realmente vertical. - Movimento do paciente

Para a realização de um exames do tipo planar ou SPECT, é estritamente necessário que o paciente se mantenha imóvel durante todo o tempo de realização do exame. O movimento do paciente pode ser verificado de variadas formas: sinograma, display cinemático e imagem das projecções somadas.

- O sinograma consiste em linhas correspondentes de cada vista planar (projecções equivalentes tais como as usadas para um plano topográfico) são colocadas construtivamente numa matriz bidimensional. - O display cinemático é basicamente o hardware onde é feita a visualização das imagens adquiridas e é onde são constatados os movimentos através de visualização directa. - A imagem das projecções somadas consiste nas imagens de projecção múltiplas. Estas imagens de projecção múltipla são somadas de forma a compor uma imagem de projecção. Se não tiver ocorrido movimento o objecto constituirá uma linha.

Este tipo de artefactos é habitual em exames SPECT, sendo uma constante se os pacientes forem

crianças ou pessoas que não consigam manter-se imóveis durante a duração dos exames. O movimento do paciente, deteriora de tal forma a imagem como a posterior análise e diagnóstico, que obriga à repetição do exame na maior parte dos casos. - Reconstrução Tomográfica

Como regra, e de modo ao SPECT obter a mesma precisão estatística como as imagens planares convencionais, são necessárias cerca de 5 vezes mais contagens. No entanto é melhor ter uma contagem um pouco mais pobre mas mais nítida do que uma imagem com mais contagens mas mais esborratada. O uso de detectores múltiplos fornecem sensibilidade suficiente para se poder utilizar colimadores de alta resolução, adquirindo ainda assim informação suficiente sobre a densidade. - Correcção de Atenuação

A atenuação dos fotões degrada significativamente a precisão quantitativa de uma imagem SPECT devido a introdução de artefactos e distorções.

O factor mais importante a degradar a resolução da imagem SPECT é a distância da câmara ao paciente. O segundo factor mais importante é a dispersão devido a auto absorção dentro do paciente. O radionuclido Tc-99m tem um meio valor de camada (half value layer) de aproximadamente 4 cm em tecidos moles. Regiões próximas do centro do corpo ou cérebro estão pelo menos 2 meios valores de camada acima da câmara gama do que a maioria das estruturas superficiais. Esta profundidade extra resulta em significativas variações de emissão, que chegam a câmara devido a auto absorção. Estas perdas por auto - absorção devem ser corrigidas durante a reconstrução uma vez que a verdadeira correcção de atenuação para SPECT não existe ainda. Os dois métodos mais usados para fazer a correcção são o método de pré - processamento de Sorenson e o método de pós - processamento de Chang. Estes métodos não funcionam bem no tórax, uma vez que este se encontra rodeado de tecidos de densidade variável, que possuem factores de atenuação diferentes. A correcção óptima de atenuação requer o uso de um scan de transmissão para determinar correcções apropriadas. O scan de transmissão pode ser alcançado pela

24

Page 34: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

obtenção de uma imagem SPECT de 10 min de uma fonte oposta ao paciente. Aí então as imagens de emissão do paciente podem ser corrigidas adequadamente. Um estudo combinado emissão / transmissão pode ser efectuado usando uma câmara de 3 cabeças, usando 2 cabeças para adquirir dados de emissão e uma para receber informação de transmissão. Este sistema encontra-se presentemente em desenvolvimento. - Projecção inversa filtrada

A projecção inversa filtrada é usada para a reconstrução de imagem. A projecção inversa sem filtragem resulta em indesejável esborratamento (image blur) de imagens e presença de artefactos em forma de estrela. O nível a que os artefactos de projecção inversa podem ser removidos deve ser compensado pelo grau a que o ruído de imagem pode ser tolerado. A frequência refere-se as mudanças do numero de contagens de pixel para pixel. Sinais de imagem reais decaem rapidamente com o aumento da frequência enquanto o ruído contido se mantém constante. O ruído de background é considerado de alta frequência, pois encontra-se uma variabilidade demarcada no número de contagens de pixel para pixel. A nitidez da imagem (fino detalhe e detecção de orlas) é também considerada de alta frequência enquanto o alvo é de baixa frequência.

Filtros RAMP (filtros de alta frequência) impulsionam as altas frequências de modo a tornar mais nítidos os detalhes da imagem, infelizmente também aumentam o ruído, devido a este ser também de alta frequência. Assim apesar dos filtros RAMP produzirem os melhores detalhes na reconstrução as imagens são frequentemente interpretáveis devido a propagação de ruído associada a baixas contagens estatísticas. Para limitar este efeito um segundo filtro (passa baixo) é utilizado para reduzir ruído estatístico. Os filtros passa baixo aumenta a relação sinal ruído, mas às custas de perdas de contraste e resolução de imagem. Alguns exemplos de filtros passa baixo comuns são: Butterworth , Hanning, Shepp-Logan e Parzen. Quando se selecciona um filtro para processamento há sempre um acordo entre contraste e uniformidade de imagem.

A frequência de corte é a frequência acima da qual toda a informação é removida. Quanto mais baixa for a frequência de corte mais suave será a imagem reconstruída e maior a perda de contraste e resolução devido a perda de nitidez (sharpness) contida nas altas frequências. Altas contagens estatísticas são cruciais uma vez que quanto maior o número de contagens nos dados projectados maior poderá ser a frequência de corte. Um filtro com alta frequência de corte produz imagens com muito contraste que podem resultar em alta sensibilidade mas baixa especificidade. A ordem do filtro refere-se ao declive da curva do filtro. Altas ordens implicam variações acentuadas que produzem imagens mais nítidas mas também com mais distorções.

A filtragem anterior à reconstrução é preferível pois reduz a propagação de ruído num nível precoce do processo de formação de imagem e promove a implementação de um filtro simétrico em 3 dimensões.

Apesar de uma matriz de maiores dimensões (128x128) com pixels mais pequenos ter teoricamente mais resolução espacial, cada pixel terá proporcionalmente menos contagens e a imagem será degradada por ruído estatístico. A variação percentual em contagens de pixels devido a efeitos estatísticos ou ocasionais é aproximadamente de (100 / N1/2 )%, onde N é o numero de contagens por pixel. A variabilidade estatística em exames SPECT e de 5 a 10 % para matrizes de (64x64). Duplicando o tamanho da matriz de modo a melhorar a resolução espacial irá aproximadamente duplicar o erro estatístico em cada contagem estatística por pixel. Este aumento em ruído estatístico irá diminuir tanto a resolução, como o contraste e pode obscurecer detalhes da imagem.. - Correcção do tamanho da imagem

A resolução tomográfica para uma câmara com uma cabeça é de aproximadamente 16 - 18mm para o thalium e de 13 mm para o technetium. Para objectos mais pequenos que 2 elementos de resolução do detector as contagens recuperadas dos tomogramas reconstruídos são muito dependentes do tamanho do objecto (o numero máximo de contagens é proporcional a espessura do objecto). 2.13 - Protocolos de Aquisição 2.13.1 - Aquisição de imagem planar

25

Page 35: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

O protocolo mais simples de aquisição é o planar. Com aquisição de imagem planar, a matriz de detecção encontra-se estacionária sobre o paciente, e apenas adquire dados de um determinado ângulo. A imagem então criada com este tipo de aquisição é similar a uma radiografia raio-x. Exames a ossos são feitos primariamente desta maneira. 2.13.1.1 - Aquisição de imagem planar dinâmica

Seguindo a mesma filosofia do protocolo anterior temos a aquisição planar dinâmica. Este protocolo basicamente consiste em adquirir imagens planares (2 D) acrescentando-lhes uma terceira dimensão que é o tempo. Assim irão ser adquiridas várias imagens planares ao longo de um determinado intervalo de tempo. Para isso basta que a câmara fique sempre numa determinada posição.

Num estudo planar, é possível observar a deslocação de um rádioisótopo ao longo do corpo através da aquisição de uma série de imagens planares do paciente ao longo do tempo. Cada imagem é o resultado da soma de informação durante um intervalo de tempo curto, tipicamente 1-10 segundos. Se varias projecções forem tiradas durante um intervalo de tempo mais longo, então é possível fazer uma animação visual do trajecto percorrido pelo rádioisótopo e uma análise desta informação pode ser realizada. O exame planar dinâmico mais comum tem a finalidade de medir o ratio de filtração glomerular nos rins. 2.13.2 - Aquisição de imagem SPECT

Se rodarmos a câmara em volta do paciente, a câmara irá adquirir vistas da distribuição do rádioisótopo numa grande variedade de ângulos. Após a observação de todos os ângulos, é possível reconstruir uma visualização 3D da distribuição do rádioisótopo dentro do corpo. A reconstrução de imagem em 3 D está explicada em detalhe no ponto 2.5 deste capítulo. 2.13.2.1 Aquisição de imagem SPECT dinâmico

Enquanto a aquisição de imagem planar funciona bem para determinados estudos, a falta de informação acerca da profundidade significa que tem uma aplicabilidade limitada. O método baseado em imagem dá-nos a requerida informação de terceira dimensão, mas o facto de requerer hardware especial e um complicado protocolo de aquisição impossibilita a sua aplicação clínica.

O objectivo do SPECT dinâmico é ser capaz de usar câmaras SPECT de uma só cabeça convencionais com um protocolo de aquisição típico. Como o tempo requerido para uma aquisição convencional é muito longo quando comparado com a cinética envolvida na maior parte dos processos, a projecção inversa filtrada não pode ser usada para a reconstrução da imagem final. Se a projecção inversa filtrada for usada, artefactos surgirão nas reconstruções como resultado de projecções inconsistentes e assim pode levar a diagnósticos errados. Por estas razões novos métodos de reconstrução devem ser desenvolvidos, métodos estes que devem ser capazes de ter em conta a alteração de actividade nas várias projecções.

Para efectuar a reconstrução de imagem são utilizados métodos como o método de parâmetros directos e o método dos mínimos quadrados com restrição linear. Estes métodos encontram-se explicados no ponto 2.5 deste capítulo. 2.13.3 - Aquisicao SPECT GATED

Como o coração é um objecto em constante movimentação, ao fazermos um exame regular SPECT ao coração, a imagem final obtida irá representar a posição média ao longo do tempo que o exame foi feito. É possível visualizar o coração nas várias etapas do ciclo de contracção, sendo isto conseguido ao subdividirmos cada vista projectada SPECT numa serie de sub - vistas, cada uma definindo os contornos do coração a uma etapa diferente do ciclo em estudo. Este protocolo exige que a câmara SPECT esteja ligada a uma maquina ECG, da maneira a poder extrair informação do electrocardiograma para a reconstrução de imagem. 2.14 - Aplicações SPECT

26

Page 36: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

Esta secção tem como objectivo mostrar quais os estudos que se podem fazer com SPECT. Estes sao: aquisição de imagem do coração, aquisição de imagem de cérebro, aquisição de imagem renal, exames ósseos e exames sobre o fígado. Em seguida é fornecida uma breve descrição destes exames. Exames Renais

O estudo mais usual em medicina nuclear SPECT é o exame dinâmico renal. No sistema renal, o sangue é continuamente passado pelos rins, onde é filtrado e purificado antes de passar pelo resto do corpo. Produtos indesejáveis são então extraídos do sangue e expelidos do corpo como urina. Em condições normais de funcionamento, os rins são capazes de filtrar sangue rapidamente, e assim através de uma medição do ratio da filtração sanguínea, é possível obter uma medida quantitativa do funcionamento renal. Este tipo de medição é denominado ratio de filtração glomerular (GFR). Funcionamento do coração

Considerando o caso de shunting cardíaco entre ventrículo esquerdo e direito, quando um tracer é injectado numa veia periférica, passa através do átrio direito e em seguida ventrículo direito onde é bombeado para os pulmões. O sangue retorna novamente para o coração através da veia pulmonar para o átrio esquerdo e ventrículo esquerdo. Por causa do shunting no ventrículo esquerdo, resultante de um defeito septal atrial ou de um defeito septal ventricular, uma parte significativa de tracer toma um curto caminho de volta para o coração através da artéria pulmonar e outras veias. Este retorno é útil no sentido que possibilita a determinação da quantidade de shunting que está a acontecer de maneira a planear futuros tratamentos. A quantidade de shunting é determinada através de modelização. Metabolismo Cerebral

Estudos dinâmicos cerebrais são muito comuns em SPECT devido à natureza do procedimento de aquisição de imagem. Com a introdução de um radionuclido que seja levado até ao cérebro através das células e que seja concentrado pelas células do cérebro é então possível observar o seu funcionamento. As partes activas do cérebro irão concentrar mais radionuclido do que aquelas que não estejam activas, e assim é possível observar como as diferentes partes do cérebro reagem a estímulos locais. Como exemplo, se um paciente que está a ser sujeito a um exame funcional ouvir música em simultâneo, as partes do cérebro responsáveis pelo processamento da informação proveniente da função auditória, estarão mais activas e concentrarão mais radionuclido que as outras células cerebrais.

2.6 - Exame SPECT cerebral

Exames ósseos

Os exames ósseos podem ser realizados de duas formas: através de um exame planar ou através de um exame SPECT. Através da injecção de um radionuclido apropriado, este será transportado pela corrente sanguínea a toda a estrutura óssea do corpo humano. Nas áreas onde houver qualquer anormalidade, haverá uma maior concentração de radionuclido, sendo assim possível localizar a lesão. Esta localização com um exame planar é uma localização relativa, dado que, não temos a indicação de profundidade e assim é impossível aferir com exactidão a localização exacta da lesão. Com um exame SPECT, como temos acesso a informação sagital, transversal e coronal, é então possível aferir com precisão a localização da lesão. Esta filosofia de análise é também aplicável aos exames pulmonares, onde uma concentração elevada de radionuclido indica uma obstrução pulmonar, e que quanto maior for a concentração de radionuclido maior será o brilho na imagem final e maior será a gravidade da lesão (neste tipo de exames, maior será a obstrução).

2.7 - Exame SPECT ósseo

27

Page 37: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

2.15 - Avanços Técnicos do SPECT

A nível de instrumentação os detectores de estado sólido e a electrónica de semicondutores foram desenvolvidos para substituir os cristais de cintilação e os tubos fotomultiplicadores (PMT’s). A emissão de um fotão a partir de um determinado orgão atinge o cristal de estado sólido, como é o caso do teluride- cádmio de zinco (CZT), que é um semicondutor que converte o fotão directamente num sinal digital electrónico. Isto corresponde a um processo de uma etapa apenas enquanto no tradicional SPECT este processo corresponde a duas etapas nos cristais de NaI. Mais ainda, num detector semicondutor, cada localização no detector dista exactamente um pixel digital, e quando for atingido por um fotão, providencia a posição da interacção com grande resolução espacial e energética. Isso significa uma detecção muito mais directa da posição da posição e energia do fotão emitido em vez do processo tradicional em SPECT. O aumento da resolução espacial e energética destes detectores de estado sólido provoca resoluções superiores de contraste e detecção mais eficaz de anormalidades. A grande desvantagem desta solução, como é de esperar é o seu elevado preço de manufactura.

Outra aproximação aos detectores de estado sólido é o uso de elementos pixel de 3 x 3 mm cada um destes pixels consistindo num thalluim – iodide de cesium activado CsI(tI), sendo o cristal de cintilação um fotodíodo de silicone. Embora esta solução não seja um clássico detector de estado sólido, como foi definido previamente, oferece a maior parte dos benefícios destes. Estes benefícios incluem uma resolução intrínseca espacial fixa e alta a qualquer energia assim como um verdadeiro posicionamento digital. Como os PMT’s não são usados, estes sistemas podem ser realizados bastante mais leves (23 kg) que os convencionais, que podem chegar a pesar cerca de 2300 kg! Estes detectores podem também ser feitos com um sódio – iodide de cesium activado cristal (CsI(Na)) para diferentes propriedades.

Existem fenómenos físicos que degradam o grau com qual são detectadas as contagens que representam a actividade do tracer e consequentemente a precisão do diagnóstico. Estes são: a) a atenuação variável (absorção e espalhamento) pelo corpo dos fotões emitidos do orgão de interesse, b) a contagem incorrecta dos fotões provenientes do espalhamento para dentro do detector de cristal, e c) a limitada e variável natureza da resolução espacial através da distribuição do tracer no orgão. A correcção destes fenómenos irá reduzir ou eliminar a atenuação presente em imagens de perfusão de pessoas com densos tecidos, e também a atenuação diafragmática observada em vários homens. Estas correcções também corrigirão uma série de artefactos mais subtis e permitirão para um uso mais previsível o contorno do corpo humano.

Os métodos de correcção da atenuação variável estão a ser presentemente comercializados para compensar a atenuação variável através do tórax. O algoritmo de correcção requer um mapa (uma imagem de transmissão) dos coeficientes de atenuação, que não é nada mais do que uma imagem de baixa qualidade de um exame CT. Para gerar este exame de transmissão, uma fonte transmissão radioactiva é montada no sistema SPECT, que emitirá fotões que irão passar através do paciente antes de serem gravados no detector de cintilação. Numa nova aproximação, um tubo de raio-x foi montado no sistema SPECT de maneira a produzir imagens CT de qualidade superior. Idealmente, os estudos da transmissão e recepção são adquiridos simultaneamente de maneira a prevenir um acréscimo do tempo de aquisição e discrepâncias entre exames. Esta aquisição simultânea requer correcção para o espalhamento gerado adicionalmente pela fonte de emissão para a janela de energia da fonte de transmissão.

Como não existem soluções analíticas para o problema da atenuação em SPECT, algoritmos de reconstrução iterativa são usados para progressivamente reduzir a degradação da imagem causada por este fenómeno físico. Embora estes algoritmos sejam bastante conhecidos desde há vários anos, o tempo computacional requerido para se atingir convergência é proibitivo e não pode ser implementado clinicamente. O advento de ter computadores rápidos a preços acessíveis com memórias de grande capacidade permitiu a sua implementação de maneira que agora é possível que um estudo completo pode ser processado num espaço de tempo de poucos minutos ou segundos, dependendo do tamanho da matriz e do número de projecções adquiridas. Em ordem a corrigir tanto a atenuação variável e espalhamento, pelo menos três janelas de energia independentes são requeridas pelo detector. Uma janela é necessária para adquirir as contagens de emissão provenientes do pico de energia do tracer. Outra janela é necessária para efectuar a contagem dos fotões de transmissão através do posicionamento da janela por cima do pico de energia da fonte de transmissão (como o Gd – 153 com97 e 103 keV de pico). A terceira janela é a janela de espalhamento, sendo necessário que esta seja posicionada entre as duas janelas de maneira a corrigir os fotões espalhados do paciente tanto para os picos de transmissão como de emissão. Aproximações que usam mais do que três janelas estão a ser desenvolvidas para correcções mais precisas. Experiências a nível clínico revelam que a correcção da atenuação teve um aumento significativo no diagnóstico de certo tipo de doenças.

28

Page 38: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

2.15.1 – Câmara de Compton A limitação primária em aquisição de imagem SPECT é a sua fraca resolução espacial e a grande dosagem a que o paciente é submetido. Esta dosagem é necessária de maneira a haver contagens suficientes detectadas pela câmara de maneira a providenciar uma imagem estatisticamente precisa. O colimador típico de chumbo permite apenas que um fotão em 10000 emitidos do corpo do paciente seja detectado. Assim, sem o colimador a performance do sistema deverá melhorar substancialmente. Isto pode ser alcançado através do uso de uma câmara de Compton. Os ganhos potenciais que uma câmara de Compton oferece em relação à câmara de Anger são devidos primariamente à inexistência do colimador de chumbo. Com este facto espera-se que existam ganhos substanciais na sensibilidade do sistema e permitir a aquisição da informação representando as vistas de múltiplos ângulos da fonte de distribuição de uma posição apenas e desta maneira reduzir o necessário movimento da câmara. Ambos os efeitos podem reduzir a dose que empregue ao paciente para formar uma imagem final útil. Primeiro, os sistemas com elevada sensibilidade irão permitir o uso de níveis de actividade mais baixos e/ou isótopos com meias – vidas mais curtas. Segundo, a reduzida moção angular da câmara irá resultar em menos tempo perdido entre paragens angulares. A complexidade mecânica do sistema irá também ser reduzida devido à ausência do colimador de chumbo maciço. 2.16 - Conclusão

O SPECT tal como o seu nome sugere baseia-se fortemente em computadores para adquirir processar e visualizar as imagens SPECT. À medida que o software e hardware se tornam mais pequenos, mais rápidos e melhores o SPECT irá adaptar e incorporar esses avanços. Como exemplo, as propriedades estatísticas de Bayes foram recentemente aplicadas a reconstrução de imagem do SPECT criando imagens excepcionais à custa de grandes tempos de processamento e memória de computador. Espera-se que um dia as melhorias no processamento paralelo e na arquitectura de computadores farão a reconstrução de Bayes mais rápida a custa de menor memória de computador tornando-a assim mais atractiva para o seu potencial uso em ambiente clínico.

As técnicas de fusão de imagem têm sido desenvolvidas nos casos de estudo cerebrais e de tumores para registar distribuições 3D SPECT com correspondência a distribuições de outras modalidades tais como CT e MRI. O avanço mais notável ocorreu na aplicação de técnicas computacionais ao electrocardiograma (ECG) associado ao estudo de perfusão do miocárdio gated SPECT.

3 – Positron Emission Tomography (PET) 3.1 - Introdução ao PET

PET - positron emission tomography - é uma técnica usada para medir as concentrações de radioisótopos positrões emitidos dentro dos tecidos de sujeitos vivos. Estas medições são feitas fora do sujeito vivo. A maior parte dos isótopos radioactivos decaiem por ibertação de um raio gama e electrões, outros decaiem por libertação de um positrão. Um positrão pode ser pensado com um electrão positivo.

Uma grande motivação e interesse generalizado, aliado a uma grande aceleração na tecnologia PET, foram factores estimulados pelo desenvolvimento de algoritmos de reconstrução associados com o raio-x CT e melhorias nas tecnologias de detecção nuclear. Em meados da década de 80, PET tornou-se uma ferramenta para diagnóstico médico, estudos dinâmicos do metabolismo humano e é também utilizado para estudos de actividade cerebral.

Assim o PET pode ser dividido em vários passos: 1. etiquetar o composto escolhido com um rádioisótopo com emissão de positrões. 2. administrar este composto ao sujeito em estudo.

29

Page 39: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

3. adquirir a imagem da distribuição da actividade dos positrões como função do tempo por emissão tomográfica. 4. deduzir, através da aplicação do modelo adequado, da informação adquirida uma percepção do comportamento biológico do composto. De salientar que ainda não existem centros PET em Portugal ao invés da vizinha Espanha que já

possui 6 centros PET. Isto deve-se ao facto do ainda preço elevado de um centro PET, custos associados com pessoal e preços incomportáveis para os pacientes. Todos estes factores tornam impossível a rentabilização deste tipo de centros e consecutivamente a sua implementação em ambiente clínico. 3.2 - Aspectos Históricos do PET

O interesse nos elementos Carbono – 11, Nitrogénio – 13 e Flourine - 18 não existia nos anos 40 e início da década de 50, talvez devido à descoberta do carbono-14 em 1940 por Carmen e Ruben. O carbono-14 provou ser um isótopo mais versátil e eficiente, pelo que este período parecia inconsequente em termos de investigação biomédica seguindo a linha de radionuclidos emissores de positrões. Em meados dos anos 50 Ter-Pogossian promoveu a ideia de apesar das curtas meias - vidas destes radionuclidos emissores de positrões, estes ofereciam um método atractivo para o estudo regional do metabolismo, devido a serem comuns.

Entre os meados dos anos 50 e inicio dos anos 70 a utilização destes radionuclidos emissores de positrões foi lenta. Estes radionuclidos passaram a ganhar alguma popularidade apenas quando alguns centros começaram a utilizar ciclotrões. Três factores contribuíram para o desenvolvimento desta tecnologia:

1. o facto da maioria dos processos de metabolismo no corpo ocorrem rapidamente o suficiente para serem marcados por este radionuclidos de meia - vida curta. 2. o sucesso de alguns químicos na etiquetagem rápida de moléculas complexas com etiquetas fisiológicas apesar das suas curtas meias vidas. 3. A conclusão de que a radiação penetrante resultante da aniquilação dos positrões tornara óbvio que a localização destes positrões era possível.

Desde o inicio dos anos 70 PET tem sido usado como ferramenta de investigação, e nos anos

mais recentes mostrou potencialidades na medicina clínica. Os primeiros scanners PET usavam fatias únicas quando efectuam tomografia. Estas tomografias eram produzidas no inicio dos anos 60 em vários institutos de investigação usando sistemas com anéis de 32 detectores NaI (Tl). A resolução de cada fatia era maior que dois centímetros FWHM. A geração de scanners seguinte reduziu a dimensão dos detectores e acrescentou anéis adicionais para aquisição simultânea de varias fatias. A resolução de fatia melhorou de mais de 2 centímetros FWHM para menos que 1 centímetro FWHM. A maioria destes sistemas complicados eram máquinas únicas. No final dos anos 70 o marketing começou finalmente a disponibilizá-las comercialmente. A medida que o tempo foi passando mais detectores e PMT’s foram adicionados a estas máquinas de modo a aumentar a sua sensibilidade e resolução. Após muitos anos de estudo uma máquina de nome PENN-PET foi desenvolvida na universidade da Pensilvânia. Esta máquina consistia numa matriz estacionaria de 6 detectores de positrões distribuídos de uma forma hexágono em torno de um diâmetro de 50 cm a volta do paciente. Esta máquina oferecia alta sensibilidade e uma resolução de 5.5 mm FWHM e era menos complexa e menos cara que os sistemas com detectores de anel.

De salientar que esta máquina ainda se encontra comercialmente disponível. Após anos de avanço feitos na investigação PET apenas pouco mais de cem centros existem em todo o mundo. A maioria destes centros dedicam-se a investigação e poucos dedicam-se ao seu uso clinico. 3.3 - Teoria e instrumentação

A aquisição de imagem PET começa com a injecção de um tracer metabolicamente activo de emissão (por exemplo, Carbono 11, Azoto 13, Oxigénio 15 ou Flour 18). Em minutos, o isótopo acumula numa área do corpo para a qual a molécula tem uma afinidade. Como exemplo, glucose etiquetada com Carbono 11 (meia – vida, 20 minutos), ou uma glucose análoga etiquetada com Flour 18 (meia-vida, 1.8 horas), acumula no cérebro, onde a glucose é usada como fonte primária de energia. O núcleo radioactivo decai por emissão de positrão. O positrão emitido colide com um electrão livre, usualmente em menos de

30

Page 40: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

um 1mm de distância do ponto de emissão. A interacção das duas partículas sub – atómicas resulta numa conversão de matéria para energia na forma de dois raios gama. Estes raios gama de alta energia emergem do ponto de colisão em direcções opostas, e são detectados por uma matriz de detectores que rodeiam o paciente.

Quando os dois fotões são gravados simultaneamente por um par de detectores, significa que a colisão que originou os dois fotões ocorreu algures ao longo da linha que liga os detectores. É claro, se um dos fotões provem, não da colisão, mas sim do espalhamento a linha de coincidência será incorrecta. Após 500,000 contagens, a distribuição do tracer emissor de positrões é calculada através de procedimentos de reconstrução tomográfica. Assim o PET gera uma imagem de duas dimensões. Reconstruções a três dimensões podem ser realizadas usando projecções 2-D de múltiplos ângulos. 3.4 - Radionuclidos

Os compostos utilizados em PET têm uma grande diversidade. Estes radionuclidos com emissão de positrões tem meias vidas muito curtas e energias de radiação muito altas quando comparadas com outros radioisotopos usados em pesquisa biomédica. Os radionuclidos com emissão de positrões mais usados em PET incluem Carbono-11, Nitrogenio-13, Oxigénio - 15, e Flúor-18, com meias vidas de 20, 10, 2 e 110 minutos respectivamente. Estes compostos são conhecidos em PET como sendo compostos de rastreio e é cada vez mais importante os cientistas aprender como trabalhar com as meias vidas extremamente curtas dos compostos.

Devido ao facto de estes elementos serem encontrados em quase, senão todos, os compostos que são consumidos pelo corpo humano apenas faz sentido que o exame PET e uma técnica obvia para o estudo do destino destes componentes in vivo. Estes compostos de rastreio são administrados por meios de injecção ou inalação, com o propósito de simplesmente aceder a corrente sanguínea. É a curta meia vida destes componentes que permite que se possa administrar grandes doses no paciente com uma exposição radioactiva mínima e também dá-nos a possibilidade de executar exames repetidamente. No passado, estas meias - vidas representavam graves problemas, e ainda agora representam. De maneira a facilitar a produção destes radionuclidos é necessário que o centro esteja equipado com um acelerador de partículas, uma equipa de físicos nucleares, especialistas em computadores, rádiofarmacos, especialistas de isótopos e clínicos. Se um laboratório não tiver meios de levar a cabo este processo sintético os radionuclidos tem que ser transportados ate o sitio onde serão usados.

Dos quatro radionuclidos mencionados acima mencionados o Flúor-18 é o ideal para transporte. Nestes anos passados, PET tem tido um desenvolvimento muito rápido, devido principalmente as novas substâncias de rastreio disponíveis para estudo em humanos. 3.5 - Metabolismo da glucose

Os estudos PET têm incluído medições do metabolismo da glucose, fluxo de sangue cerebral, metabolismo do oxigénio, assim como a aquisição de imagem de outros processos fisiológicos. Correntemente o metabolismo da glucose é medido através de [Flúor-18], o fluxo cerebral através de do [Oxigénio-15] em combinação com um seu isótopos.

Em condições normais, o cérebro humano depende da glucose como sua única fonte de energia. A maioria da glucose é usada para manter os níveis de potencial das membranas e para restaurar gradientes iónicos a nível celular. Quando clinicamente se mede o metabolismo da glucose, o paciente fica numa posição imóvel durante 40 minutos após a injecção intravenosa de FDG (Flúor – Desoxi – Glucose). Durante este espaço de tempo, o FDG é levado através das células e é atingido um equilíbrio.. A distribuição do Flúor - 18 é então medida em várias secções tomográficas, e esta distribuição é baseada na utilização da glucose debaixo de condições específicas patológicas de condição cerebral. Uma das maiores razões de medição de glucose, é devido ao facto do grande ratio glucólico da maior parte das doenças. A aquisição PET tem a habilidade de detectar a presença de tecidos malignos e consegue quantificar alterações na concentração de glucose num tumor durante e após tratamento.

A técnica Cerebral Blood Flow (CBF) utiliza as alterações fisiológicas e patológicas em regiões de fornecimento de sangue. É assumido que aumentos no fluxo sanguíneo são associados com o aumento da actividade funcional. Após activação, a distribuição oxigénio - 15 pode ser medida e através do uso de imagens coloridas codificadas de CBF, e é então possível visualizar quais as áreas do cérebro estão activadas aquando sujeito a certas actividades. Por exemplo, quando uma pessoa lê ou fala, o hemisfério direito fica ‘iluminado’.

31

Page 41: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

3.6 - Aquisição e processamento de imagem em PET

A aquisição de imagem em PET é totalmente indirecta. Tal como no CT, MRI e SPECT, PET conta com a reconstrução computorizada para proceder a produção de imagens tomográficas. É executado com meios de detecção de emissão de positrões através do uso de tomografia. Duas maneiras nas quais os radionuclidos decaem e que irão reduzir a carga positiva excessiva no núcleo, inclui a neutralização de uma carga positiva com uma carga negativa de um electrão ou a emissão de um positrão do núcleo. Então o positrão irá combinar-se com um electrão das redondezas e anular-se. Após a aniquilação de tanto o positrão como o electrão são convertidos em radiação electromagnética. Esta radiação electromagnética está na forma de dois fotões de grande energia que são emitidos com um desfasamento de 180 graus um do outro. É esta radiação de aniquilação que será detectada externamente e será usada para medir tanto a quantidade e a localização do emissor de positrões.

A detecção simultânea de dois destes fotões por detectores em lados opostos do sujeito coloca o sítio de aniquilação numa linha ligando os centros dos dois detectores. Neste ponto o mapeamento da distribuição da aniquilação por computador é permitido. Se a aniquilação for originada fora do volume entre os dois detectores apenas um dos fotões pode ser detectado. Uma vez que a detecção de um único fotão não satisfaz a condição de incidência o evento é rejeitado. A detecção simultânea fornece um campo de visão preciso com sensibilidade uniforme. Isto acontece uma vez que quer a desintegração tenha lugar entre os dois detectores, ou não, os fotões em soma tem que ter viajado a distância total entre detectores de modo a que o evento seja gravado.

A imagem geralmente obtida é apresentada como uma imagem de níveis de cinzento de uma secção cruzada do objecto em que a intensidade de cada elemento de imagem é proporcional a concentração do isótopos no objecto. Quando se obtém imagens não claras isto pode causado pela qualidade da medida da correcção de atenuação ou por estatísticas de fotão pobres. Um método para corrigir imagens PET usa uma relação tabulada determinada empiricamente, entre profundidade de interacção e mais que provável altura de pulsação para cada raio gama detectado.

2.8 - Doença de Parkinson – Exame PET

3.7 - Funções do PET

A utilidade do PET é que dentro de certos limites tem a capacidade de detectar mudanças bio químicas dentro do corpo. Qualquer região do corpo que esteja a experimentar mudanças bioquímicas anormais pode ser visto por PET. O PET teve um impacto enorme em aplicações clínicas para doenças neurológicas, incluindo doenças cérebro - vasculares, epilepsia e tumores cerebrais. O PET é importante na pesquisa e desenvolvimento de drogas e pode ser usado para estudar a distribuição de certas drogas, a farmacocinética e farmacodinâmica. Para além de tumores cerebrais o PET é usado e localizar metastases linfogenéticas bem como outros tumores.

Uma das funções mais importantes do PET é a sua capacidade para modelizar funções fisiológicas e biológicas do corpo, protecção e modelização das concentrações de radioactividade regional num orgão particular. Actualmente é possível obter localizações anatómicas melhoradas de actividade, adicionando a informação do PET a imagens mais detalhadas CT e MRI. Quando o trabalho com PET se iniciou, o equipamento consistia em aparelhos tais como: scanners de radiação, sensores múltiplos e câmaras de cintilacao. Carbono-11, Carbono-13 e Flúor-18 foram pela primeira reconhecidos como úteis para estudos biológicos logo após a sua disponibilização por irradiação ciclotron dos seus elementos estáveis. 3.8 - Aplicações e investigação associada ao PET Mecanismos cerebrais em condicionamento clássico:

32

Page 42: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

Aqui o PET tem sido usado para estudar o mecanismo cerebral que supervisiona o

condicionamento humano clássico. Este estudo é realizado através da medição da distribuição do fluxo sanguíneo no cérebro. A experiência consiste em três fases, pré – condicionamento, condicionamento, e pós - condicionamento. O scanning PET é realizado na primeira e terceira fase. A fase de condicionamento é usada para enviar ligeiros choques eléctricos para os sujeitos. Após visualização da primeira e terceira fase é então constatado que a fase de condicionamento resultou numa fase de acréscimo de activação nas regiões frontais e temporal do cérebro especialmente na zona do hemisfério direito cerebral. Receptores de estrogéneo em cancro da mama:

PET tem sido usado para estudar vários aspectos de patofisiologia do cancro dos seios. FDG tem sido largamente utilizado em estudos PET de cancro devido às observações que quase todos os tumores malignos exibem, sendo registado um aumento de concentração de FDG, presumindo-se assim um aumento do ratio da glucose no tecido do tumor. FDG-PET mostrou em estudos clínicos ser um meio fiável para distinguir massas mamárias entre benigno e maligno e também para avaliar a extensão regional do tumor. Correcção de atenuação em corpo inteiro PET

Correcção de atenuação é um procedimento de rotina em PET através do uso de factores derivados de um scan de transmissão ou assumindo uma densidade de tecido constante. No entanto aquisição PET de corpo inteiro é uma excepção a isto. Aquisição de corpo inteiro entende o campo axial de visão do scanner PET através da movimentação da cama em passos através do tomógrafo. A informação é adquirida tipicamente em espaços de tempo entre 4 a 10 minutos em cada posição.

Por causa disso, uma quantificação precisa não é possível e imagens reconstruídas incluem artefactos, tais como um aparente decréscimo na acumulação do tracer em direcção ao centro do corpo. Aquisição PET em doenças Renais

Os rins são distinguíveis por altos níveis de metabolismo e fluxo sanguíneo. Este estudo prova que excelentes imagens de rins podem ser obtidas com Carbono - 11 - acetato e aquisição PET. Devido ao alto fluxo sanguíneo nos rins uma transição alta do tipo alvo - para - fundo é muito esperado. Mesmo quando este fluxo sanguíneo é reduzido bastante devido à doença renal, a correspondente redução na acumulação do tracer não exclui a visualização dos rins ou suficiente actividade do tracer para análise da cinética do tracer. Mecanismos cerebrais para respostas de memória

A resposta de informação da memória de uma pessoa envolve não só a resposta com sucesso da informação armazenada (cephory), mas também invoca todos os processos relativos à tentativa de lembrar. Estudos recentes PET do retorno da memória humana mostram que o retorno da informação armazenada provoca o encadeamento de várias zonas cerebrais. Estas regiões incluem o córtex direito pré – frontal assim como as regiões corticais posteriores. Este estudo foi capaz de mostrar que a activação destas regiões está associada com a tentativa de retorno de informação, não necessariamente com o sucesso desse retorno. Evolução de redes metabólicas anormais no cérebro

Para visualizar a informação complexa retornada por exame PET, combina-se o método standard PET com modelização estatísticas aproximadas e técnicas de visualização para melhor demonstrar os resultados das análises. Perfis topográficos representam funcionamento implícito de redes de regiões metabolicamente covariantes, que não são perceptíveis através dos processos convencionais de aquisição e processamento de imagem e técnicas estatísticas devido à sua pequena magnitude quando comparada com os efeitos globais. Através da quantificação, identificação e ilustração da existência dessas redes implícitas de funcionamento, marcadores independentes neuronais são providenciados para diferenciação

33

Page 43: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo II - Medicina Nuclear, SPECT e PET

entre desordens neuro - generativas similares assim como uma visão profunda dos mecanismos fisiológicos destas doenças.

34

Page 44: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo III - Fundamentos Teóricos

Capítulo III

1 – Introdução à Visão por computador

1.1 - Introdução

O sistema de visão é o elemento sensorial mais importante para a sobrevivência de uma grande

percentagem de seres vivos. A informação adquirida por este elemento sensorial é de facto importante quer a nível qualitativo quer a nível quantitativo, fornecendo informação sobre o meio que condiciona e influencia toda a atitude e interacção da entidade que a possui.

A importância do sistema de visão tem assim vindo a ganhar uma importância cada vez maior junto da comunidade cientifica de modo a criar sistemas automáticos, computadorizados, que sejam capazes de executar funções do sistema de visão tal como se encontram nos seres vivos. Esta área de desenvolvimento científico (visão por computador ou visão artificial) surge assim associada a outras áreas tais como processamento de imagem, gráficos computadorizados, reconhecimento de padrões, inteligência artificial e psicofísica. 1.2 - Visão por computador

O objectivo de um sistema de visão por computador é criar um modelo do mundo real a partir de

imagens. Um sistema de visão por computador adquire informação útil de uma cena a partir das suas projecções bidimensionais. Uma vez que as imagens são projecções bidimensionais do mundo tridimensional, a informação não está directamente disponível e tem que ser recuperada. Este facto implica a inversão de um mapeamento de muitos para um. Para recuperar a informação tridimensional é necessário termos conhecimentos acerca das características dos objectos envolvidos na cena bem como de geometria projectiva. Consideremos os seguintes exemplos: 1) No diagnóstico de uma doença usando tomografia computadorizada a visão por computador permite ao físico recuperar informação fazendo a melhoria das imagens adquiridas, medidas quantitativas em regiões de interesse podem ser efectuadas facilmente. Estes sistemas têm vindo a ser desenvolvidos para todo o tipo de visionamento útil na área da saúde. Sistemas de visão por computador têm sido usados para controle de qualidade de todo o tipo de produtos nas mais variadas áreas. 2) Um par de imagens é adquirido por um robot móvel cada par representa um par stéreo de um instante particular de imagem. Estas imagens são usadas para obter informação tridimensional do ambiente envolvente para aí se movimentar autonomamente. A informação adquirida é usada para mapear

35

Page 45: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo III - Fundamentos Teóricos

o ambiente envolvente de uma forma robusta e com a precisão suficiente para a função desejada. Tais sistemas são úteis para a navegação automática de automóveis, aviões e robots entre outros. 3) A imagem obtida a partir de um satélite de uma região pode fornecer informação importantíssima para a previsão da metrologia, análise de mudanças globais e agricultura entre outros. Os sistemas de visão computadorizados assumem cada vez mais um papel importante na análise e gestão de informação dos grandes volumes de dados adquiridos por satélite. A visão por computador produz medidas ou abstracções de características geométricas, pelo que

Visão = Geometria + Medidas + Interpretação 1.3 - Áreas associadas à visão por computador

De seguida referimos as áreas que se encontram associadas à visão por computador e que com ela têm evoluído. 1.3.1 - Processamento de imagem

É um campo bem desenvolvido que transforma imagens noutras, onde se realçam as

características desejadas. Por outro lado os algoritmos de visão por computador usam imagens como base de partida mas produzem outros tipos de informação, tais como representações do contorno de objectos numa imagem; ou seja na visão por computador o ênfase é dado na obtenção de informação automaticamente com o mínimo de interacção humana. Assim os algoritmos de processamento de imagem tornam-se úteis em estágios iniciais da visão por computador, para realçar informação particular e suprimir ruído. O processamento de imagem envolve as seguintes áreas entre outras:

��Melhoramento de imagens – melhoramento e realce subjectivo de certas características de uma dada imagem.

��Restauração de imagens – restaurar imagens que tenham sido degradadas na sua qualidade por um qualquer processo (distorção geométrica, movimento..)

��Compressão de imagens – representação de imagens de forma a ocupar menos espaço físico, podendo ou não perder informação de acordo com o fim a que se propõe a imagem. 1.3.2 - Gráficos computadorizados Criação de imagens a partir de primitivas geométricas tais como linhas, círculos e outras superfícies de forma variada. Têm um papel importante nos campos da visualização e da realidade virtual. A visão por computador têm no entanto uma função inversa, ou seja estimação de primitivas geométricas a partir da imagem. Ou seja os gráficos computadorizados sintetizam imagens enquanto a visão por computador faz a análise das mesmas. Estes campos têm-se aproximado mais nos últimos anos graças em parte à realidade virtual e aos avanços feitos na visualização. 1.3.3 - Reconhecimento de padrões Classifica dados simbólicos e numéricos. Muitas técnicas estatísticas e sintácticas têm sido desenvolvidas para a classificação de padrões. Estas técnicas de reconhecimento de padrões têm um papel importante em visão por computador no reconhecimento de objectos. 1.3.4 - Inteligência artificial Preocupa-se com o projecto de sistemas que sejam inteligentes e que possuam aspectos de estudo computacional inteligente. É usada para analisar cenas pelo cálculo de representações simbólicas dos conteúdos das cenas após o processamento das imagens de forma a obter tais características. Podemos encarar a inteligência artificial, como sendo constituída por três passos: percepção, cognição e acção. A percepção transforma os sinais do mundo exterior em símbolos, a cognição manipula esses

36

Page 46: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo III - Fundamentos Teóricos

mesmos símbolos e a acção transforma esses símbolos em sinais externos que influenciam o próprio mundo exterior. Muitas técnicas de inteligência artificial são usadas em visão por computador sendo que muitas vezes a visão por computador é mesmo considerada um sub - campo da inteligência artificial. Um caso de uma técnica de inteligência artificial que tem sido muito desenvolvidas nos últimos anos são as redes neuronais que começam agora a ser usadas em visão por computador. 1.3.5 - Psicofísica A psicofísica junto com a ciência cognitiva tem vindo a estudar a visão humana há já algum tempo. Muitas das técnicas usadas em visão por computador estão relacionadas com conhecimentos adquiridos da visão humana. Muitos investigadores preocupam-se mesmo mais em desenvolver modelos computacionais da visão humana do que sistemas de visão por computador. 1.4 - Áreas de aplicação

Actualmente surgem cada vez mais aplicações associadas à visão por computador, tais como: ��Inspecção industrial - o controle de qualidade é cada vez mais importante nos dias que correm e uma vez que as funções de inspecção visual humana são bastante rotineiras, cansativas e morosas originando frequentemente erros e falhas surge a necessidade de as automatizar por meio de sistemas computadorizados que possuam “visão”. Assim a visão por computador é usada no controlo dimensional de componentes, controle de qualidade superficial ou verificação de integridade dos componentes. ��Guiamento de veículos autónomos – a substituição de operários humanos por veículos, robots ou manipuladores no desempenho de funções fisicamente exigentes ou mesmo perigosas é cada vez mais frequente, tornando-se essencial que estes equipamentos possuam “visão” de modo a poderem interagir com o meio que os rodeia de uma forma correcta e segura seguindo a melhor trajectória possível e da forma mais rápida. ��Aplicações médicas – A análise de imagens médicas não é geralmente pretendida com um sentido perfeitamente autónomo mas como um auxiliar importante para o diagnóstico clinico. Torna-se assim normal encontrar sistemas de visão por computador na área da saúde que auxiliam a análise de exames de diagnóstico e consequentes análises clínicas. ��Meteorologia – a análise de imagens obtidas por satélite efectuada por sistemas de visão permitem efectuar previsões de tempo. ��Sistemas de tráfego automóvel – a incorporação de sistemas de visão por computador na gestão de tráfego automóvel permitem torná-los mais flexíveis, eficientes e rápidos. ��Agricultura – as imagens de detecção remota permitem efectuar análise e controlo do crescimento e grau de maturação das plantações.

2 - Técnicas de aquisição de informação tridimensional 2.1 - Introdução

A necessidade de aquisição de informação tridimensional de uma cena levou ao desenvolvimento de várias técnicas que directa ou indirectamente determinam as coordenadas tridimensionais dos pontos das cenas, a distância destes pontos a um determinado referencial ou a orientação local das superfícies que a constituem através de um sistema de medida de distância.

Um sistema de medida de distância ou sensor de distância é em geral um sistema integrado que engloba equipamentos diversos: computadores, câmaras, fontes de luz, dispositivos de aquisição e processamento de sinais...

Estes sensores de distância podem ser caracterizados por diversos parâmetros tais como a resolução, precisão, exactidão, velocidade de aquisição e campo de visão. Geralmente estes parâmetros terão que estar associados a uma determinada distância de referência pois alguns deles poderão depender dessa

37

Page 47: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo III - Fundamentos Teóricos

distância. A definição de resolução, precisão e exactidão são bem conhecidos. A velocidade de aquisição é avaliada pelo número de pontos calculados por segundo. O campo de visão deve ser especificado por uma medida linear ou gama de distâncias e por uma medida angular ou ângulo de visão.

Todos este parâmetros são importantes para a avaliação de um sensor de distância , no entanto nem sempre são especificados , ou então são avaliados de formas diferentes pelo que se torna mais complicado avaliar um sensor de distância comparativamente a outros.

Podemos dividir de uma forma genérica as técnicas de aquisição de informação tridimensional em duas categorias:

�� Activas – através da projecção controlada de energia sobre a cena obtemos a informação

desejada. A energia reflectida é detectada por sensores que directa ou indirectamente fornecem a informação tridimensional.

�� Passivas – usando a iluminação ambiente obtém-se a informação tridimensional. É de uso mais geral mas no entanto também é de utilização mais difícil. 2.2 - Técnicas activas de obtenção de informação tridimensional

De um modo geral as técnicas activas são adequadas em cenas onde não se encontrem pontos característicos e quando comparadas com as técnicas passivas podemos afirmar que a extracção de pontos característicos e o estabelecimento de correspondências vêm simplificadas. Estas técnicas apresentam problemas quando se usam padrões não codificados ou a cena apresenta superfícies com descontinuidades, uma vez que têm dificuldades em estabelecer as correspondências; quando é utilizado um feixe ou plano de luz existe a necessidade de varrer a cena pelo que torna o processo moroso e passível de pequenas falhas mecânicas; quando são utilizados vários planos de luz o emparelhamento torna-se mais difícil principalmente em cenas com descontinuidades; surgem geralmente problemas na utilização destas técnicas nas partes ocultas da cena em questão.

Como exemplo de técnicas activas encontramos: �� Esteroscopia activa – consiste na projecção de um padrão de luz sobre a cena em questão e

obtenção de uma imagem de intensidades com a câmara afastada da fonte de luz utilizada. De seguida obtém-se a correspondência entre os pontos do padrão de luz projectado e os obtidos na imagem. Recorrendo ao principio da triangulação obtém-se a informação tridimensional desejada, ou seja fazendo uso das equações de projecção do ponto tridimensional em questão para a fonte de luz e para a câmara utilizada obtemos um sistema de equações sobredimensionado que pode ser resolvido de modo a obter a informação tridimensional do ponto.

�� Interferometria – consiste na projecção sobre a cena de riscas de sombra igualmente espaçadas . De seguida deve-se adquirir uma imagem da cena com uma câmara deslocada lateralmente em relação ao projector e em frente da qual se encontra uma grelha idêntica a usada para obter as riscas. A imagem obtida apresenta os contornos dos pontos que estão à mesma distância , mas não dá indicação acerca do sinal de variação de distância entre linhas de contornos adjacentes. A deslocação de objectos num sentido conhecido ou o uso de uma segunda grelha permitem-nos obter tal informação. Esta técnica é usada essencialmente para obter informação acerca de distâncias relativas.

�� Detecção de ecos – consiste na projecção de energia sobre a cena e na medida do tempo que decorre entre a emissão dessa energia e a recepção da mesma após reflexão na cena. 2.3 - Técnicas passivas de obtenção de informação tridimensional As técnicas passivas caracterizam-se por fazer uso apenas de luz ambiente para iluminar a cena. A informação de distância é obtida a partir de uma ou mais imagens de intensidade da cena. A principal vantagem que estas técnicas apresentam deve-se ao facto de serem de aplicabilidade genérica , mesmo em ambientes naturais não controlados. As desvantagens apresentadas são as seguintes: dificuldade de aplicação em caso de cenas sem pontos característicos; dificuldade quando pontos são vistos numa imagem mas não em outra; lentidão do processo na obtenção de informação tridimensional ou quando se pretende informação mais densa.

Como exemplo de técnicas passivas encontramos:

38

Page 48: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo III - Fundamentos Teóricos

��Esteroscopia passiva – obtenção de imagens em instantes simultâneos por parte de duas câmaras que deverão estar posicionadas de forma adequada. De seguida estabelece-se correspondências entre pontos característicos das duas imagens e fazendo uso do principio da triangulação, a partir das equações de projecção dos pontos característicos em questão e da geometria do sistema podemos assim obter a informação tridimensional desejada. ��Usando uma câmara – é semelhante ao exemplo anterior no entanto as duas imagens são obtidas pela mesma câmara em duas posições distintas. ��Forma com base em X – procura-se extrair a informação de distância a partir de uma ou mais imagens monoculares de intensidade, obtidas com uma câmara fixa. Estas técnicas podem ser baseadas no brilho , na perspectiva, na textura, na ocultação ou noutras características que de forma indirecta traduzem a geometria da cena.

3 - Processamento e Análise de Imagem

Nesta secção são fornecidos os princípios básicos matemáticos para os métodos de processamento e análise de imagem utilizados no sistema desenvolvido assim como alternativas à implementação realizada. Assim serão explicadas diferentes transformações, filtros e métodos para extrair informação essencial das imagens iniciais. Esta informação essencial consiste em orlas de intensidade, linhas e forma de objectos detectados.

3.1 - Thresholding Um método simples para segmentação de imagem é o thresholding, que faz com que uma imagem de cinzentos se torne numa imagem binária. Pode ser definido por

1 ( , )( , )

0se f x y t

z x youtros casos

��� ��

,

onde f(x,y) representa a função original, z(x,y) a função binária e t o valor do threshold. O valor do threshold tem que ser determinado de acordo com cada imagem. Existem várias possibilidades para atribuir valores a esta variável. A maneira mais simples é um valor estático: cada valor de cinzento menor que um determinado valor t fica com o valor zero na imagem final e qualquer outro valor fica como 1 na imagem final. Em semi thresholding não transita o valor um para a imagem final, mas sim o valor de cinzento da imagem original. Outro método para efectuar o thresholding usa os métodos acima mencionados em intervalos – incluindo os limites do intervalo – em vez de usar a toda a gama de valores. Também é usada informação de histograma para procurar o valor a aplicar de threshold (por exemplo, o valor de threshold a aplicar é o mínimo valor presente no histograma da imagem). Se valores de cinzento pertencentes ao fundo da imagem aparecem também no próprio objecto, podem surgir alguns problemas quando é usado o método mais simples de threshold. Para resolver este tipo de problemas, os threshold dinâmicos usam janelas de m x m centradas numa posição (x,y). Se a área de fundo e a área de objecto têm a mesma frequência de ocorrência, então o valor médio é um bom valor de threshold:

���

�������

1

0

1

02 2

1),(1 m

i

m

j

mkcomjkyikxfm

t

Uma extensão possível deste método pode ser feita usando informação do histograma paralelamente com o uso das janelas acima mencionadas. Métodos menos ‘elegantes’ não calculam um novo valor de threshold para cada pixel e assim conseguem ser muito mais rápidos.

39

Page 49: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo III - Fundamentos Teóricos

3.2 - Filtragem de imagem Ainda na fase de pré – processamento, operações em imagens com filtros são adoptadas para suprimir o ruído e artefactos e ainda para extrair a informação necessária. 3.2.1 - Filtros de suavização e realce Todos os filtros passa - baixo tem um efeito de suavização. Estes filtros são especialmente desenhados para eliminar ruído ou estruturas subtis e provocam nas imagens uma perda de precisão. Estes filtros também são usados como filtros fundamentais na construção de filtros mais complexos. Para propósitos de estimação da qualidade do filtro, a sua função de transferência (a resposta impulsional da transformada de Fourier) é analisada nos seguintes pontos: um filtro de suavização preenche todos os seus propósitos, se a função de transferência tem um máximo global a partir do qual a função decresce monotonamente e torna-se zero a partir de uma determinada frequência, denominada de frequência de corte. As características do filtro são perfeitas, se a função de transferência tem também características isotrópicas (ou sem características sobrepostas).

a) b) c)

Figura 3.1: Imagem corrompida com ruído. a) Imagem original. b) Imagem com ruído Gaussiano. c) Imagem com ruído impulsivo

3.2.1.1 - Filtro de média Um dos mais simples filtros lineares é implementado através de uma operação local de média onde o valor de cada pixel é substituído pela média de todos os valores na sua vizinhança local:

� � � ���

Nlk

lkfM

jih),(

,1,

onde M é o número total de pixels numa vizinhança N. Por exemplo, tomando uma vizinhança de 3x3 em [i,j] resulta:

� � � �� ��

��

��

1

1

1

1

,91,

i

ik

j

jk

lkfjih .

Este filtro de média também pode ser implementado como um filtro de convolução, sendo que os pesos dos coeficientes da máscara de convolução têm que ser obrigatoriamente todos idênticos. O tamanho da vizinhança N controla a quantidade de filtragem. Uma vizinhança mais alargada, correspondendo a uma máscara de convolução mais alargada, irá resultar num grau de filtragem superior. É claro que, quanto maior for o grau de filtragem e consequentemente maior a quantidade de redução de ruído, maior será a perda de detalhes na imagem. Os resultados de filtros de média de vários tamanhos são mostrados na figura 3.2.

40

Page 50: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo III - Fundamentos Teóricos

41

a) b) c)

Figura 3.2: Resultados da aplicação de máscaras de, 3x3 a), 5x5 b) e 7x7 c) na imagem (b) da figura 3.1. Quando se desenham filtros de suavização, os pesos dos coeficientes devem ser escolhidos de maneira que o filtro tenha apenas um pico único, denominado lóbulo principal, e simétrico nas direcções verticais e horizontais. Um padrão típico de coeficientes para um filtro de suavização 3x3 é:

1/16 1/8 1/16 1/8 1/4 1/8

1/16 1/8 1/16 Filtros de suavização lineares removem as componentes de alta frequência, e assim a precisão de alguns detalhes da imagem são perdidos. Por exemplo, transições do tipo degrau, são transformadas em transições graduais, e a capacidade de localizar com precisão uma transição será sacrificada. Um filtro variando espacialmente ajusta os pesos dos coeficientes de modo a que a suavização seja feita numa área relativamente uniforme da imagem, e que pouca suavização seja feita em áreas com transições bruscas na imagem. 3.2.1.2 - Filtro de mediana O problema principal com operações de média locais, é o facto de que estas tendem a esborratar orlas bem demarcadas e estreitas. Uma aproximação alternativa é substituir todos os valores dos pixels com o valor da mediana de todos os valores de cinzento da sua vizinhança local. Os filtros que usam esta técnica são denominados de filtros de mediana. Os filtros de mediana são muitos eficazes a remover ruído impulsivo enquanto mantêm todos os detalhes da imagem devido ao facto de não dependerem de valores que são muito diferentes dos valores presentes na sua vizinhança local. Os filtros de mediana trabalham em sucessivas janelas de imagem de uma maneira muito similar à maneira como trabalham os filtros lineares. De qualquer forma, o processo deixa de ser uma soma pesada. Por exemplo, tomando em conta uma janela de 3x3 e computando a mediana do pixels de cada janela centrada em [i,j], vem:

1. Ordenar os pixels de uma forma ascendente por nível de cinzento. 2. Escolher o valor do pixel do meio como novo valor para o pixel [i,j].

Geralmente, uma vizinhança com tamanho ímpar é escolhida para calcular a mediana. Se no entanto, for uma escolhida uma vizinhança com tamanho par, a mediana é tomada como a média dos valores dos pixels do meio após ordenação ascendente. Os resultados da aplicação de várias máscaras de filtros de mediana são apresentados na figura 3.3.

Page 51: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo III - Fundamentos Teóricos

42

c) a) b)

Figura 3.3: Resultados das aplicação do filtro de mediana de várias máscaras à imagem (c) da figura 3.1. a) Máscara de 3x3, b) Máscara de 5x5 e c) Máscara de 7x7

3.2.1.3 - Filtro Gaussiano Uma das classes de filtros de suavização é o filtro Gaussiano. A função Gaussiana de uma dimensão é dada pela seguinte fórmula:

2

2

2

.21)( �

��

x

exg�

Esta fórmula define o filtro e é possível verificar que a forma deste é controlada pelo parâmetro �. A análise da imagem digital usa a forma discreta de duas dimensões desta fórmula:

� � 2

22

2)(

.21, �

��

yx

eyxg�

A função Gaussiana tem características que fazem com que seja extremamente útil o seu uso como filtro de suavização, mas também como a base de outros filtros mais complexos. Essas características são:

1. Mesma forma nos domínios espacial e das frequências: A função Gaussiana mantém a mesma

forma em ambos os domínios. A transformada de Fourier é computada através de

��

��

� dxexgxgF jwx).()}({

dxee jwxx

��

��

2

2

2

.21

��

dxwxjwxex

)sin(cos.21 2

2

2�� �

��

��

wxdxjewxdxexx

sin..21cos.

.21 2

2

2

2

22 ���

��

��

��

����

����

Page 52: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo III - Fundamentos Teóricos

O segundo integral é zero, devido à função seno e assim o integrando é anti-simétrico. Assim a

transformada de Fourier simplifica para:

wxdxexgFx

cos..21)}({ 2

2

2��

��

��

��

222 1,2

2

��

ve vw

.

2. Simetria na rotação: A isotropia da rotação garante uma suavização uniforme em todas as

direcções. 3. Factor de escala: Através do escalonamento do parâmetro �, é possível variar a largura da

função assim como o nível de suavização. 4. Separabilidade: Uma implementação eficaz (mesmo para filtros com bandas maiores) pode

ser realizada através da divisão da função em 2D para duas de 1D.

A aplicação de um filtro Gaussiano é mostrada na figura 3.4.

a) b) c)

Figura 3.4: Resultado da aplicação de filtros Gaussainos. (a) Imagem original. (b) Filtro Gaussiano com uma máscara 5x5. (c) Filtro Gaussiano com uma máscara 9x9

3.2.2 - Filtros Derivativos 3.2.2.1 - Operadores de gradiente Para detectar estruturas em imagens, tais como orlas e linhas, filtros são usados de maneira a extrair as derivadas da imagem. Os operadores de Roberts, Prewitt e Sobel são exemplos de tipos de filtros que fornecem o valor absoluto de um gradiente de várias formas. A aplicação de um filtro de gradiente é mostrada na figura 3.5. A sensibilidade perante o ruído pode ser decrementada de uma maneira bastante significativa através da construção da derivada de uma imagem suavizada (imagem que foi sujeita a um filtro passa-baixo). Assim em vez de se obter as derivadas da imagem directamente, a imagem inicialmente é sujeita a um filtro do tipo Gaussiano, e só depois são extraídas as suas derivadas. Este método é feito tendo em consideração o teorema da convolução:

),(*),()),(*),((),( yxgyxfyxfyxgyxf ����� com

43

Page 53: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo III - Fundamentos Teóricos

2

22

2)(

.21),( �

��

yx

eyxg�

A primeira equação mostra que se pode chegar ao mesmo resultado de duas formas distintas:

1. Fazer a convolução da imagem com o filtro Gaussiano e em seguida obter a sua derivada, ou 2. Derivar a função Gaussiana e em seguida fazer a convolução da imagem com a função

resultante. A derivação da função de Gauss pode ser calculada analiticamente e assim pode ser implementada de uma forma prática nos sistemas computacionais. Na utilização dos operadores acima referidos surgem algumas dificuldades:

1. A selecção do nível de amplitude a partir do qual se marcam as orlas pode dar origem ao aparecimento de traços largos em vez de orlas bem demarcadas e estreitas; nesse caso é necessária uma operação de adelgaçamento aplicada à imagem resultante da convolução. Esta operação consiste em eliminar todos os pontos que não sejam máximos locais, de preferência segundo a direcção da orla a que possam pertencer.

2. Outro efeito indesejável que surge na aplicação dos operadores de gradiente é a descontinuidade dos contornos detectados, inerente ao carácter discreto das máscaras de convolução. As orlas que apresentam uma amplitude elevada segundo uma direcção terão certamente variações fracas na direcção perpendicular e, como tal, um contorno curvilíneo poderá ser detectado como várias pequenas linhas descontínuas. Para evitar essas quebras podem-se utilizar métodos de limiarização específicos, como por exemplo, limiarização a dois níveis com histerese ou com base em histogramas locais.

3.2.2.2 - Operadores Laplacianos Outra alternativa para a detecção de orlas consiste em determinar as passagens por zero da segunda derivada da função – imagem, mas apenas segundo a direcção de variação máxima em cada ponto. Embora numa primeira análise seja uma operação idêntica à anterior, apresenta a vantagem de se poder usar um operador independente da orientação – o Laplaciano – cuja expressão num espaço bidimensional tem a forma:

2

2

2

22 ),(),()),((),(

yyxI

xyxIyxIyxI

��

������

Também neste caso, podemos passar ao domínio discreto e aproximar o Laplaciano por equações às diferenças, mas agora de segunda ordem, obtendo-se máscaras de convolução idênticas às que se ilustram na fig. 5. Estas máscaras resultam também de se considerarem aproximações diferentes; contudo, ao contrário das anteriores, têm um carácter não-direccional. O Laplaciano duma imagem obtém-se por uma única convolução I(x,y)*h(x,y), sendo h(x,y) uma máscara da qual se pode verificar o seu efeito na fig.5, da qual resultam as orlas presentes qualquer que seja a sua orientação. A máscara h14 na fig.5, no entanto, é pouco sensível às variações nas diagonais. A maior desvantagem das operações de diferenciação é a sua grande sensibilidade ao ruído e a pequenos detalhes presentes na imagem, que está bem patente quer no Laplaciano quer no Gradiente, conforme se ilustra nas imagens da figura 5. É por isso, comum fazer uma filtragem prévia para remoção do ruído que, no entanto, tem também efeitos sobre a própria localização das orlas.

44

Page 54: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo III - Fundamentos Teóricos

a) b) c)

Figura 3.5: Exemplo de aplicação de filtros de gradiente e Laplaciano. a) imagem original. b) Aplicação de um filtro Laplaciano e c) Aplicação de um filtro de Sobel.

3.3 - Detecção de orlas de intensidade 3.3.1 Detecção de orlas de intensidade Canny A detecção de orlas em conjunto com métodos como o region growing ou modelos deformáveis tornam possível descobrir regiões inter-relacionadas. A detecção de orlas melhora a robustez destes métodos, isto é, o conhecimento acerca das orlas permite uma melhor formulação do critério de truncagem. A ideia básica quando se procuram as orlas é descobrir regiões na imagem com um alto gradiente. Como é mostrado na secção de filtragem de imagem algumas pré-considerações têm que ser tomadas de maneira a ser possível extrair gradientes realizáveis. Um operador derivativo para a detecção de orlas tem que satisfazer dois requisitos principais:

1. Redução de ruído: A probabilidade do ruído ser detectado como uma orla tem que ser a mais baixa possível.

2. Localização exacta: A orla tem que ser encontrada numa posição o mais exacta possível a partir dos gradientes calculados

3. Unicidade de resposta: Deve existir uma relação unívoca entre orlas reais e orlas assinaladas ou, por outras palavras, uma orla real deve ser assinalada uma única vez.

A satisfação simultânea de todos os requisitos é difícil de obter, porque quanto mais efectiva é a suavização da imagem, menor é a possibilidade de se poder se determinar a posição da orla. A preposição que Canny faz para resolver este problema, subdivide este processo em três etapas:

Threshold por

Histerese Cálculo de Gradientes Locais

Supressão de Não – Máximos

Estas etapas serão explicadas na secção de operações complementares 3.3.2 - Detecção de orlas de intensidade Deriche Deriche em 1987, propôs um filtro idealizado com vista à detecção óptima de variações de intensidade em degrau. Assim modifica as condições de fronteira do filtro de Canny para as de um filtro de resposta impulsional infinita, o que conduz à equação:

)sin(. wxecf xD

��

��

Deste modo, este filtro fica totalmente definido por apenas dois parâmetros � e �, sendo o valor de c determinado pela condição de ganho que, normalmente, se pretende unitário. Este filtro de Deriche, para detecção de orlas de intensidade, é o mais recomendado devido a factores como:

45

Page 55: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo III - Fundamentos Teóricos

1. A sua implementação ser recursiva, sendo assim eficiente; 2. O tempo de execução depender apenas das dimensões da imagem na qual se pretende

empregar; 3. A afinação conseguida para diferentes tipos de imagem, pela utilização dos parâmetros � e

�. A afinação conseguida neste filtro é responsável pela preferência atribuída ao filtro de Deriche em detrimento do filtro de Shen e Castan: neste filtro apenas existe um parâmetro de ajuste, e por isso, a mesma afinação é mais difícil quando se utiliza este tipo de filtro. Na figura 6 apresenta-se o resultado da detecção de orlas em imagens pelo filtro de Deriche. É de notar a diferença entre a imagem obtida e as resultantes da aplicação dos operadores de Sobel e do Laplaciano apresentadas na imagem 5, nas quais, é manifestamente mais elevada a amplitude do ruído em toda a imagem. De notar também, na figura 6, que apesar de nos resultados finais, em termos de imagem, não haver grandes diferenças entre as imagens resultantes da detecção de Canny e de Deriche, o esforço computacional extremamente elevado da detecção de Canny torna-se numa grande desvantagem deste método, quando comparada com o método de Deriche. 3.3.3 - Operações complementares A imagem resultante da filtragem está longe de ser uma representação fidedigna e precisa das orlas de intensidade na imagem original, em particular, os problemas que surgem na diferenciação de imagens subsistem, embora em menor escala, nas imagens resultantes da aplicação de qualquer um dos filtros para detecção de orlas de intensidade, quer seja numa configuração de detecção por máximos (como é o caso do filtro de Deriche), quer seja numa configuração de detecção por passagens por zero. O tipo de filtragem utilizada – detecção por máximos ou detecção por passagens por zero – determina as operações aplicáveis. Nomeadamente, as operações de supressão de não máximos e de limiarização só são aplicáveis a imagens resultantes de uma filtragem por detector de máximos de amplitude do gradiente, enquanto que a operação de validação de passagens por zero, como o nome indica, é aplicável a imagens de orlas detectadas por derivações de segunda ordem. Calcular gradientes locais: O filtro recursivo Gaussiano desenvolvido por Deriche fornece as derivadas de uma imagem. Este filtro tem todos os requisitos necessários para preencher os critérios de qualidade acima referidos. Deriche estendeu também o método de Canny para o caso de três dimensões.

a) b) c)

Figura 3.6: Aplicação de filtros de detecção de orlas de intensidade. (a) Imagem original. (b) Detecção de orlas Canny. (c) Detecção de orlas Deriche.

Supressão de não - máximos Esta operação tem por objectivo remover todos os pontos que, não sendo máximos de amplitude na resposta do filtro à imagem original, se situam nas suas imediações e apresentam ainda um nível elevado que poderá conduzir a uma localização imprecisa da orla correspondente. O que se pretende é realizar uma espécie de adelgaçamento direccionado segundo o gradiente de intensidade em cada ponto da imagem. A implementação que está feita do filtro de Deriche usada neste trabalho inclui a supressão de não-máximos.

46

Page 56: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo III - Fundamentos Teóricos

Limiarização A limiarização de uma imagem de orlas de intensidade destina-se a tranformá-la numa representação gráfica ou mapa das orlas mais significativas presentes na imagem original, removendo-se todas aquelas que correspondem a pequenas transições de intensidade, vulgarmente associadas a ruído nos processos de aquisição e digitalização de imagens. Esta operação não está, todavia, isenta de dificuldades. O ruído na imagem de amplitudes de orlas, após as operações de filtragem, dá origem a flutuações de amplitude ao longo de uma mesma orla, de tal modo que a escolha de um limiar global de valor elevado poderá levar à quebra dos contornos detectados. Por outro lado, a escolha de um limiar de valor reduzido aumenta a sensibilidade havendo por isso maior probabilidade de assinala as orlas causadas pelo ruído. Validação das passagens por zero No que diz respeito à detecção de orlas pelas passagens por zero de um operador de derivação de segunda ordem, há que ter em conta que surgem com frequência detecções falsas. Estas não têm nenhuma correspondência directa com variações nos sinais originais e as suas causas são principalmente duas:

1. O ruído nos sinais ou imagens originais, introduzido possivelmente pelos dispositivos de captação, e que dão origem a desvios na resposta do operador;

2. As variações no sinal ou imagem serem tais que, devido à suas interferências, surjam mínimos locais na amplitude da primeira derivada.

Torna-se assim necessário validar as passagens por zero que correspondem efectivamente às variações existentes e remover as passagens por zero que surgiram indevidamente. 3.4 - Transformação de Hough A transformação de Hough define uma transformação de um domínio da informação para um outro domínio. Cada ponto sob uma determinada curva vota sobre determinados parâmetros; os parâmetros que ganham a maioria dos votos são declarados vencedores. Em seguida são apresentadas três transformações de três curvas distintas: rectas, círculos e elipses. 3.4.1 - Detecção de linhas Em geral uma linha pode ser definida por

y=m.x+b,

onde x e y representam os valores observados, e m e c representam os parâmetros. Se os valores dos parâmetros, a relação entre as coordenadas de um dado ponto é claramente especificada. Se rescrevermos a equação dada em cima por:

b= -m.x+y.

Agora, na equação de cima, vamos assumir que m e c são variáveis de interesse, e que x e y são constantes. A equação acima representa uma linha recta no espaço m-b. O declive e a intersecção com o eixo vertical são determinados através de x e y. Um ponto (x,y) corresponde a uma linha recta no espaço m-b. Este mapeamento é mostrado na figura 7. Deve ser mencionado aqui que a forma da curva no espaço dos parâmetros depende da função original usada para representar a curva. Na prática, a equação polar de uma linha:

0)sin(.)cos(. ��� ��� yx ,

é mais usada que a forma explícita para evitar problemas com linhas que são praticamente verticais. Pontos situados na fronteira (x,y) são mapeados para o espaço dos parâmetros (�,�).

47

Page 57: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo III - Fundamentos Teóricos

No caso de uma linha recta, tal como é representado em cima, se existirem n pontos que estão situados sobre essa mesma linha, então estes pontos irão corresponder a uma família de linhas rectas no espaço dos parâmetros, como é ilustrado na figura 3.7. Todas estas linhas irão passar pelo ponto (a’,b’) no espaço dos parâmetros. Este ponto dá os parâmetros da linha recta original. Se estamos interessados em encontrar a linha recta que melhor se adapta a n pontos numa imagem, então nós podemos utilizar o mapeamento mencionado em cima do espaço de imagem para o espaço dos parâmetros. Nesta aproximação, denominada de transformada de Hough, nós representamos o espaço dos parâmetros como um vector de acumuladores, representando valores paramétricos discretos. Cada ponto na imagem vota em vários parâmetros, de acordo com a equação de transformação. De maneira a encontrar parâmetros que caracterizam a linha, devemos detectar picos de acumulação no espaço dos parâmetros. A transformação de Hough não requer agrupamento à priori dos pontos situados em orlas, e também que esses pontos que ficam situados sobre a curva de interesse constituam uma fracção pequena de todas as orlas presentes na imagem. Em particular, o número de orlas que se situam ao longo da curva de interesse podem ser menos do que metade o número de orlas presentes na cena, facto este, que inviabiliza a utilização da maior parte dos algoritmos de regressão. O pressuposto por detrás da transformada de Hough é que na presença de grandes quantidades de ruído, o melhor que pode ser feito é encontrar o ponto no espaço dos parâmetros que satisfaça um maior número de orlas na imagem. Se o pico no espaço dos parâmetros cobre a mais do que um acumulador, o centróide da região providencia uma estimativa dos parâmetros. Se existem várias tipos de curvas na imagem que são encontradas pelo modelo, haverá vários picos no espaço dos parâmetros. É possível detectar cada pico, remover as orlas associadas com a instância da curva correspondendo ao pico, e continuar a detecção das curvas restantes, até que os picos serem não significativos. De qualquer forma, pode ser difícil de detectar se um pico é significativo.

Figura 3.7: Exemplo de uma tranformação de Hough. Estas imagens mostram a detecção de uma linha dos domínios espacial e de Hough.

(a) Linha do domínio espacial. (b) Transformação de Hough de uma linha. 3.4.2 - Detecção de círculos Outro problema com a transformada de Hough é que o tamanho do espaço dos parâmetros discretos aumenta muito rapidamente à medida que o número de parâmetros aumenta. Para um arco circular, o espaço dos parâmetros tem três dimensões; para outras curvas estas dimensões podem ser muito superiores. Como o número de acumuladores aumenta exponencialmente com a dimensão do espaço, a transformada de Hough pode ser computacionalmente muito ineficiente para modelos complexos. Vários métodos tem sido sugeridos de maneira a melhorar a performance da transformada de Hough. Um método usa a informação do gradiente para regiões de fronteira de maneira a reduzir o trabalho no espaço dos parâmetros. Supondo que o modelo de curva é um círculo. Este modelo tem três parâmetros: dois parâmetros para o centro do círculo e um parâmetro para o raio do círculo. Se o ângulo do gradiente para as orlas de intensidade está disponível, então este modelo providencia uma condicionante que reduz o número de graus de liberdade e consecutivamente o tamanho requerido para o espaço dos parâmetros. A direcção do vector que vai desde o centro do círculo para cada orla é determinado através do ângulo do gradiente, deixando o valor do raio como o único parâmetro desconhecido. Existem outros métodos que podem ser usados para reduzir o tamanho do espaço dos parâmetros. Os círculos são descritos através da seguinte fórmula genérica:

22222 )()()( axrybrbyax �������� ,

48

Page 58: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo III - Fundamentos Teóricos

onde a e b referem a posição do centro e r o raio do círculo. De modo a evitar os requisitos computacionais de uma transformação 3D de Hough, o problema é organizado de uma forma heurística em duas fases distintas e então é simplificado para uma transformação de Hough de duas dimensões. Essas fases são: 1) Encontrar todos os centros dos círculos. 2) Determinar o raio de cada círculo. O correspondente centro do círculo encontra-se na recta normal à tangente de um determinado ponto do círculo. Assim, as normais de vários pixels do mesmo círculo irão intersectar-se no centro do círculo. Para cada pixel a sua tangente é estimada como a linha que melhor se adapta a todos os pixels dentro de uma vizinhança pequena. Este método permite a computação da recta normal que é gravada no histograma. O máximo do histograma dá-nos a localização dos vários candidatos a centros do círculo processado. O próximo passo é encontrar o correspondente raio para cada centro através da computação de um histograma radial para cada centro. Para cada pixel na imagem a sua distância do centro é computada e guardada num histograma de uma dimensão. O máximo desse histograma corresponde ao raio dos círculos.

Figura 3.8: Detecção de um círculo usando a transformação de Hough.

3.4.3 - Detecção de elipses Uma elipse é definida por uma equação do tipo

1)())((.2)( 22������� qycqypxbpxa e 0. 2

�� bca

Aqui encontramos cinco parâmetros (a, b, c, p, q). Uma transformação de Hough de cinco parâmetros irá exigir muito esforço computacional. Assim, uma alternativa heurística reside no facto de simplificar o problema através da separação desta tarefa em duas fases: 1) Todos os centros das elipses são identificados. 2) Os restantes três parâmetros são determinados através da utilização de uma implementação focal da transformada de Hough. As tangentes de três pontos (x1, y1), (x2, y2) e (x3, y3) na elipse determinam o ponto de centro 0. O ponto de intersecção t1 e o meio de dois pontos (x1, y1) e (x2, y2) são calculados. O centro 0 encontra-se num raio dado por t1 e m1. O segundo e terceiro ponto formam t2 e m2.A intersecção dos dois raios determinam o ponto de centro 0. Raios formados a partir de diferentes pares de pontos de imagem de uma elipse intersectam-se no centro da elipse. Uma transformação de Hough de dois parâmetros acumula esses raios, com a intersecção desses raios a corresponder ao máximo do histograma. Para calcular os parâmetros restantes a,b,c a elipse é transformada para o centro do sistema de coordenadas. A equação da elipse simplifica para

1....2 22��� ycyxbax .

Substituindo estes três pontos na elipse o seguinte sistema linear de equações

49

Page 59: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo III - Fundamentos Teóricos

���

���

���

���

���

���

111

222

2333

23

2222

22

2111

21

cba

yyxxyyxxyyxx

pode ser resolvido em ordem a a, b e c. A equação ac-b2>0 tem que ser verificada também. Se este critério não for observado, os três pontos escolhidos não pertencem à elipse ou os cálculos das tangentes não foram precisos. Neste caso, os cálculos terão que ser refeitos. Finalmente, os parâmetros a,b,c são convertidos para r1, r2 e �, onde r1 representa o raio principal, r2 o raio secundário e � o ângulo entre r1 e o eixo dos xx.

a) b)

y

x0

r2 r1

(x1,y1) t1

0(x2,y2)m1

m2(x3,y3)

t2

Figura 3.9: Transformação de Hough – Detecção de uma elipse. (a) Detecção do centro da elipse. (b) Determinação dos parâmetros restantes.

3.5 Transformações e coordenadas homogéneas Adicionando um quarto componente a um vector de três dimensões leva às denominadas coordenadas homogéneas. Em geral, o quarto componente é definido como uma constante k (com k � 0). Assim o vector cartesiano p = (x,y,z)T transforma se no vector homogéneo p= (kx, ky, kz, k)T. A transformação do sistema de coordenadas homogéneo para o sistema de coordenadas cartesianas é alcançada através da divisão das primeiras três coordenadas homogéneas pela quarta coordenada homogénea.

Matrizes homogéneas têm como vantagem a facilidade de representação de transformações por multiplicações de matrizes. Uma das maiores vantagens é a possibilidade de fazer o escalonamento da perspectiva.

Figura 3.10: A matriz homogénea combina as formas de transformação rotação,

translação, perspectiva e escalonamento numa só matriz. 3.6 - Modelos Deformáveis Os modelos deformáveis são multidimensionais, baseados em modelos geométricos e capazes de deformações elásticas – dependendo nos seus graus de liberdade – de maneira a corresponder a uma dada quantidade de informação que se pretende avaliar. As forças elásticas provêm da sua energia interna de

50

Page 60: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo III - Fundamentos Teóricos

deformação, enquanto que as forças externas formam o modelo. Uma energia potencial dependendo da informação do modelo formam as forças externas. Os modelos deformáveis possuem a capacidade de segmentar estruturas anatómicas e segui-las em sequências de imagens através da combinação de informação derivativa da informação da imagem com um conhecimento à priori acerca da posição, tamanho e forma da estrutura. Muitos métodos seguem esta filosofia, sendo diferentes entre si nas seguintes características: comportamento e eficiência dos modelos, sua dimensão e equações de movimento. Muitas extensões e adaptações são reportadas desde a primeira publicação de Terzopoulos et al. Dois exemplos são explicados em seguida. 3.6.1 - Snakes A clássica aproximação aos modelos deformáveis é a denominada snake, que consiste num contorno parametrizável movendo-se num plano (x,y) � �2 com a finalidade de minimizar uma dada energia funcional. As funções de coordenada x(s) e y(s) constróem a descrição do parâmetro v(s)=(x(s),y(s))T do contorno. Estas funções tem o domínio de imagem (x,Y) � D2 como o domínio de valor e s � [0,1] como domínio de definição. A energia funcional

)()()( vPvSvE ��

descreve a forma do contorno. A forma final do contorno resulta da minimização desta energia. O termo de primeira energia corresponde à energia para a deformação elástica interna e é a soma da energia de tensão SD(v) e da energia de curvatura SK(v):

)()()( vSvSvS KD ��

� ��

��

��

1

0

1

0

2

2

22

)( dssvwSds

svwvS KKDD

O parâmetro wD define a tensão e consequentemente a eficiência de tensão, e o parâmetro wK regula a rigidez e consequentemente a suavização do contorno. Em

��1

0

))(()( dssvPvP

o escalar da função potencial é escolhido de forma, a que os seus mínimos coincidam com a posições das características da imagem. Estas características necessitam de ser encontradas.

))(( svP

As orlas presentes na imagem são um bom exemplo das características da imagem. Assim o gradiente de uma imagem suavizada I(x,y):

,),(*)( yxIGwvP B ����

forma a função potencial, com G

� a ser o filtro de suavização, cuja largura de banda influencia a expansão

dos mínimos locais. A função v(s) tem que preencher os requisitos da equação de Euler-Lagrange:

0))(()()( 2

2

2

2

����

��

�� svP

svw

ssvw

s KD

51

Page 61: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo III - Fundamentos Teóricos

sendo a condição necessária para a existência de uma solução para a equação. É então possível resolver esta equação numericamente, através do métodos das diferenças finitas e do método dos elementos finitos. 3.6.2 - Balloons Em contraste com uma segmentação por níveis morosa com modelos deformáveis planares, o uso de modelos de superfície tri-dimensionais podem acelerar o processo. Simultaneamente, a intensidade do ruído e a suavização entre níveis distintos aumenta. Especialmente, os modelos de três dimensões podem ser usados de uma maneira eficaz e precisa para segmentar volumes de imagens dependentes do tempo. O comportamento físico de um modelo deformável de três dimensões ou balloon é equivalente (dependendo da variação dos parâmetros) a uma placa fina ou a uma membrana sob tensão que se deforma igualmente por toda a sua superfície. O contorno activo de três dimensões é dado por

� �Tvuzvuyvuxvuxvu )),(),,(),,((),(,

1,0 32

��

��

A energia funcional

dudvvx

vux

ux

vx

uxxEp � �

��

��

��

��

��

��

1

0

2

2

2

02

22

11

2

2

2

20

2

01

1

010)( ����� (5)

descreve a deformação energética do contorno e corresponde ao termo S(v) na equação 4. Os factores não negativos �ij(u,v) e �ij(u,v) determinam a tensão e a rigidez da superfície. Um aumento de �ij(u,v) normalmente reduz a superfície, onde valores altos de �ij(u,v) restringem a flexibilidade do contorno. O factor �11 é específico para o modelo de contorno de três dimensões e classifica a torção da superfície.

52

Page 62: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

Capítulo IV 1 – Introdução ao Sistema Desenvolvido 1.1 – Problemática do projecto O objectivo principal deste projecto é a correcção de imagens de medicina nuclear, devido ao facto destas imagens se encontrarem desalinhadas. O movimento que o paciente executa, que provoca o desalinhamento das imagens, tem de ser detectado e classificado para se proceder à realização da correcção das referidas imagens. Esta detecção de movimento será realizada através de um sistema de inspecção visual estereoscópico passivo externo à sistema de aquisição de imagem médica.

De acordo com esta problemática, o factor com mais relevo é o cálculo da distância, através da determinação de coordenadas 3D dos pontos característicos presentes numa cena em relação a um determinado ponto de origem. Um método comum para obter tal informação de profundidade a partir de imagens obtidas por câmaras é a aquisição de uma par de imagens através de duas câmaras que se encontrem em localizações diferentes e que adquiram o par de imagens da cena em instantes simultâneos de modo a ser possível a aquisição de informação 3D dinâmica, à medida que o exame clínico vai decorrendo. O princípio usado para o cálculo de coordenadas 3D é o da triangulação.

Assim dentro da problemática global, acima mencionada, podem ser definidas várias fases do projecto. Estas fases estão relacionadas com: adquirir imagens digitais simultaneamente através do frame grabber, conhecer os parâmetros internos e externos das câmaras para inferir com precisão coordenadas 3D, dimensionamento de alvos de calibração e de detecção, detecção de entidades presentes nas imagens, emparelhamento das imagens, cálculo de coordenadas 3D de pontos característicos, estimação do movimento e correcção de imagens conforme o movimento estimado.

Foi também objectivo do projecto o dimensionamento de um sistema de aquisição de custo reduzido e de fácil acesso, ou seja, de modo a que se possa replicar o sistema de raiz sem que os custos económicos, por si só inviabilizassem a montagem deste sistema. 1.2 - Método

O método para o dimensionamento da aplicação de aquisição e correcção seguiu uma filosofia modular, isto é, tentou-se desenvolver a aplicação por módulos de maneira a que possam ser independentes por si só e assim ser reutilizados em outras aplicações. Assim a aplicação encontra-se

53

Page 63: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

dividida nos seguintes módulos: aquisição, calibração, detecção e estimação de coordenadas 3D, estimação e correcção do movimento.

Na figura 4.1 está representado o diagrama geral da abordagem global adoptada.

Determinação das entidades Determinação das entidades

Calibração das câmaras

Aquisição

Detecção e Obtenção de Informação 3D

Estimação e Correcção de movimento

Estimação e Correcção de movimento

Emparelhamento

Determinação das coordenadas 3D dos pontos

Imagem Esq. Imagem Dir.

Mundo 3D

Figura 4.1 – Diagrama geral da abordagem adoptada

54

Page 64: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

1.3 - Conceitos Básicos

Nesta secção serão introduzidas algumas definições e conceitos globais que permitem visualizar o sistema de visão por computador desenvolvido de uma forma mais completa.

1.3.1 - Estereoscopia passiva

A técnica para obtenção de informação tridimensional utilizada neste projecto foi a estereoscopia

passiva. Recorre-se assim a duas imagens de uma cena, tomadas de posições diferentes, para obter a informação de distância. A aquisição desta informação é dividida nos seguintes passos:

1º Aquisição – Aquisição de duas imagens da cena, tomadas de pontos diferentes e de modo a que exista alguma sobreposição entre elas.

2º Detecção e obtenção de informação 3D – Estabelecer correspondências entre pontos das duas imagens, isto é encontrar pares de pontos que sejam a projecção do mesmo ponto na cena. Para cada par de pontos correspondentes determinar o ponto de intersecção das rectas por eles determinados no espaço, obtendo assim as coordenadas do ponto da cena (triangulação).

1.3.2 - Triangulação A triangulação é o principio básico usado nas técnicas esteroscopicas para a obtenção de

informação tridimensional. Qualquer técnica que faça uso de um sistema de duas câmaras, que se encontrem em posições diferentes e obtenham um par de imagens da cena em cada instante, pode fazer uso deste princípio. Princípio este que também é aplicável na situação em que substituímos uma das câmaras por uma projecção de um padrão de luz sobre a cena. O padrão projectado pode assim ser encarado como uma imagem do padrão que a projecção gera na cena.

Um ponto de uma imagem determina, juntamente com o centro óptico da lente da câmara utilizada na sua aquisição, uma recta no espaço que passa pelo ponto da cena que lhe deu origem. A equação de recta correspondente é calculada a partir das coordenadas do ponto na imagem e dos parâmetros geométricos da câmara. Conhecendo dois pontos nas duas imagens que correspondam ao mesmo ponto na cena, é possível determinar as equações de duas rectas que se interseccionam num ponto ao qual correspondem as coordenadas tridimensionais do ponto da cena. Em geral as duas rectas não se intersectam pelo que geralmente o ponto solução será o ponto que minimiza a distância às duas rectas no sentido dos mínimos quadrados.

Geralmente as técnicas baseadas em triangulação requerem o estabelecimento de correspondências entre pontos de duas imagens constituindo-se como uma das suas principais limitações, devido ao seguintes factores:

Figura 4.2 – Geometria de um sistema stereo

- O custo computacional do estabelecimento das correspondências é em regra geral elevado. - Nem sempre é possível determinar o ponto correspondente na outra imagem, ou porque não foi captado nessa imagem (parte oculta) ou porque não foi possível identificá-lo. - Podem ser estabelecidas falsas correspondências, o que origina valores de distância errados.

A determinação das equações das rectas obriga a uma calibração geométrica prévia das câmaras

com o objectivo de determinar as equações que relacionam as coordenadas dos pontos da cena com as respectivas coordenadas imagem.

55

Page 65: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

1.3.3 - Óptica

O sistema de visão por computador baseia-se no modelo de câmara “pin-hole”, que modela a geometria da projecção perspectiva mas omite o efeito da profundidade de campo, uma vez que apenas os pontos dentro de um certo intervalo de distância se encontram focadas no plano da imagem. A projecção perspectiva assume que o volume a visionar é uma pirâmide infinita limitada apenas, pelo topo, fundo e lados do rectângulo de visão do plano da imagem. Efeitos ópticos tais como a profundidade de campo e atenuação de luz limitam o volume visível devido, à introdução de limites à distância à qual um objecto é visível. Objectos podem não ser visualizados de uma forma clara se estiverem muito próximos ou muito afastados.

O modelo “pin-hole” da câmara assume que os raios perspectivos passam por uma abertura infinitesimal na frente da câmara. Na realidade a abertura da câmara tem que ser maior para possibilitar a entrada de luz. São colocadas lentes na abertura de modo a focar o conjunto de raios provenientes de cada ponto na cena para a um ponto correspondente no plano imagem tal como é indicado pela geometria da projecção perspectiva.. A lente adquire assim mais luz, possibilitando um ambiente de funcionamento para a câmara com menor iluminação ou com uma velocidade de shutter superior, tendo como desvantagem a limitação da profundidade de campo. À excepção da limitação da profundidade de campo e da calibração da câmara as lentes não introduzem efeitos que violem as ideias base da projecção perspectiva, e a maioria dos algoritmos de visão por computador não dependem do desenho do sistema óptico para a formação de imagem. Pode ser necessário calcular a profundidade de campo de modo a seleccionar a lente para a câmara que melhor se adapte a uma aplicação especifica de visão por computador. 1.3.3.1 - Equação da lente A equação de lente relaciona a distância do plano da imagem ao centro da lente ( Z’), a distância do ponto na cena (Z) e a distância focal da lente ( f ).

fZZ11

'1

��

Quando Z tende para infinito a distância Z’ do plano da imagem à origem óptica é igual à distância focal. A distância focal é a distância do plano da imagem à origem do centro óptico quando raios paralelos estão focados num ponto único no plano da imagem. Quando a lente se encontra focada em pontos que não se encontram no infinito (Z’ < f) o uso de f para aproximar Z’ sobrestima a constante da câmara. A distância Z’ do plano da imagem à origem óptica aproxima melhor f à medida que a focagem da câmara é alterada para pontos mais distantes na cena. 1.3.3.2 - Resolução da imagem A resolução espacial da imagem é determinada pelo espaçamento entre pixels, aberrações da lente, difracção e profundidade de campo. Para a maioria das aplicações de visão por computador a distorção da lente e a difracção não são factores limitantes. A resolução espacial é determinada pela conjunção do espaçamento entre pixels e profundidade de campo.

Supondo que o espaçamento entre pixels no plano da imagem é de �, o limite de resolução é de 2�, uma vez que esta é a separação entre elementos que permite considerá-los diferentes. Ou seja é necessário pelo menos uma unidade de imagem para que dois elementos distintos possam ser distinguidos como tal. Em câmaras electrónicas usando fotodíodos, a resolução de imagem é limitada pelo espaçamento entre pixels na carga acoplada do sistema de aquisição da câmara. Filme fotográfico contém cristais de hálide prateado suspenso em gelatina clara. Quando um raio de luz atinge um grão de hálide prateado este muda para prateado metálico. Os grãos que não tiverem sido expostos à luz são eliminados durante o processo de revelação das fotografias. A resolução nas fotografias depende da distância mínima entre grãos de hálide prateado (geralmente 5 �m). No sistema de visão humano a resolução espacial é determinado por características internas ao globo ocular. O limite de resolução típico para o olho humano é de 0.3x10-3 radianos. Assim a distância ao olho pode ser multiplicada pelo limite de resolução em

56

Page 66: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

radianos para determinarmos o limite de resolução espacial do olho humano. Por exemplo à distância de 40 cm teremos 0.3x10-3 x 40 cm = 120 �m. O espaçamento entre pontos impressos numa página por uma impressora laser é de 85 �m. A visão humana consegue aperceber-se de separações abaixo do limite de resolução para o sistema de visão humano, por interpolação das zonas onde se encontram os diferentes elementos obtendo assim uma resolução sub pixel. 1.3.3.3 Profundidade de campo

A função de uma lente é possibilitar o uso de uma maior abertura na construção da câmara de

modo a que possa entrar mais luz na câmara, possibilitando o funcionamento da câmara com condições de luz ambiente mais fracas ou com velocidades de shutter mais rápidas. No entanto uma maior abertura leva a menores profundidades de campo. Há assim um equilíbrio a manter entre o tamanho da abertura e a profundidade de campo.

Na prática a profundidade de campo é determinada pela resolução espacial do aparelho de visionamento utilizado. Algum desfoque pode ser tolerado abaixo do limite de resolução do aparelho. Há um intervalo de distâncias ao plano de imagem (Z’) com um nível de desfoque aceitável e da mesma maneira um intervalo de distâncias à cena (Z), denominada profundidade de campo, com pontos da cena que se encontrem focados aceitavelmente. Quando um ponto da cena se encontra desfocado cria um circulo no plano da imagem em vez de um ponto. Se o diâmetro deste círculo se encontrar abaixo da resolução do aparelho de aquisição da imagem, então o desfoque pode ser considerado irrelevante.

2 - Sistema Desenvolvido 2.1 Material utilizado

Para o dimensionamento do sistema referido no ponto 1.1 deste capítulo foi utilizado o seguinte material:

- Duas câmaras e duas lentes. - Um suporte para as câmaras. - Um frame grabber. - Um PC com o software e carta de aquisição (frame grabber). - Um alvo com pontos característicos para extracção informação tridimensional. - Um alvo de calibração para o cálculo dos parâmetros intrínsecos e extrínsecos das câmaras. - Transformadores e cabos de ligação

2.1.1 Câmaras e lentes As câmaras utilizadas são câmaras CCD preto e branco, ilustradas na figura 5.3, uma vez que a cor não viria trazer nenhum acrescento em termos de aquisição de informação tridimensional, de um modelo genérico e fácil de adquirir no mercado.

Figura 4.3 -Câmara CCD preto e branco

57

Page 67: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

As características técnicas de algum relevo da câmara são as seguintes:

Caracteristicas Valores Dimensões 39 (W) x 43 (H) x 72 (L) mm Peso 150 g Elemento sensor Sensor CCD de 1/3 de polegada Número de pixels CCIR 500(H) x 582 (V) Tamanho da célula CCIR 9.8 �m(H) x 6.3 �m(V) Sistema de scan 2:1 entrelaçado Resolução 420 linhas horizontais de TV Corrente 120 mA

Verifica – se pelos dados que se trata de uma câmara de pequenas dimensões e peso, o que

facilita o seu manuseamento, sendo que as lentes escolhidas foram as de 2.1 mm. As outras características foram escolhidas seguindo critérios tendo em conta parâmetros económicos e funcionais de maneira satisfazer os requisitos necessários para o desenvolvimento da aplicação em causa para a aplicação em causa. 2.1.2 - Suporte para câmaras O suporte para as câmaras (figura 4.4.a) foi dimensionado de modo a obter–se um sistema configurável, flexível e que possa deste modo adaptar-se a diferentes situações e modos de operação. O suporte possui três posições reguláveis para cada câmara (figura 5.4.b), de modo a que fosse possível realizar testes para verificar a exequibilidade da calibração para diferentes posições e orientações.

Figura 4.4 - Suporte dimensionado (a) para as câmaras CCD, que inclui três posições reguláveis (b).

2.1.3 - Frame grabber O frame grabber escolhido foi a Matrox Meteor I, devido ao facto de ser uma placa de aquisição que já se encontrava nas instalações onde decorreu o desenvolvimento do projecto. As características desta placa estão sumarizadas no seguinte quadro:

Características Valores Número de canais 4 Características programáveis Saturação, Contraste, Brilho, Tonalidade Aquisição Cor standard, Video monocromático Formatos de aquisição NTSC/PAL/SECAM, CCIR/RS-170, Composto ou Y/C Transferências em Real-Time Até 45 MB/seg (Depende do sistema ou placa VGA utilizada)

58

Page 68: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

2.1.4 - PC O PC utilizado não tem uma importância de relevo no desenvolvimento do projecto, bastando a

este ter uma slot livre para colocar a placa de aquisição de imagem (frame grabber), e que tenha memória RAM suficiente para um processamento e análise mais rápido das imagens adquiridas.

2.1.5 - Alvo a colocar no paciente para detecção e cálculo de informação tridimensional

O alvo a colocar no paciente tem a forma

representada na figura 4.5. A escolha desta forma está directamente relacionada com o algoritmo de detecção dos pontos característicos da mesma, sendo que este alvo com este tipo de figuras geométricas se configura como sendo uma boa base para o algoritmo de detecção de pontos desenvolvido.

Figura 4.5 - Alvo a detectar.

O dimensionamento deste alvo é feito no ponto... deste capítulo.

2.1.6 - Alvo para calibração dos parâmetros das câmaras

A imagem de calibração foi escolhida de acordo como o

apresentado em [Tsai] uma vez que todo o modelo de câmara utilizado foi o modelo teórico desenvolvido por este. O alvo de calibração foi desenvolvido de forma a que seja possível calibrar as duas câmaras sem ter que alterar a posição do alvo, e de modo que as condições do algoritmo de calibração sejam satisfeitas. Este alvo de calibração foi dimensionado de forma a cobrir o volume onde se irá encontrar o alvo do paciente de forma a minimizar erros de cálculos de localização 3D de pontos que se afastam do volume de calibração.

Figura 4.6 – Alvo para calibração de câmaras

2.1.7 - Transformadores e cabos de ligação Foram escolhidos transformadores que permitissem fornecer a alimentação necessária para as câmaras (12V DC).

Os cabos foram escolhidos tendo em atenção o seu comprimento de modo a poderemos maior liberdade de colocação das câmaras.

Assim foram utilizados dois cabos RCA, e quatro adaptadores BNC – RCA, dado que a conexão dos cabos tanto às câmaras como ao frame grabber é feita através de conexões BNC.

(c) (b) (a)

Figura 4.7 Sistema de interface: (a) transformador para alimentação da câmara (b) cabo de ligação da câmara ao computador (c) adaptadores para os terminais da câmara e computador.

59

Page 69: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

2.1.8 Interruptor de porta série O interruptor de porta série foi implementado para poder fornecer ao software um evento que assinala um momento de aquisição. A sua construção é básica fazendo uso de um filtro passa-baixo RC de modo a evitar jitters de sinal e possíveis falsas activações de evento.

O filtro apresenta a configuração de ligação à porta série apresentada na figura 4.8 (a) .Fazendo uso dos pinos RTS(Pino 7) e DTR(Pino 4) da porta série, é injectado um sinal no CTS (Pino 8) , sinal este no qual são detectados as variações de sinal que originam, os eventos de trigger.

(b) (a)

Figura 4.8 - Interruptor de porta série: circuito eléctrico (a) e forma física (b). 2.2 - Aquisição de imagens estereoscópicas 2.2.1 - Introdução

A aquisição das imagens fazendo uso de duas câmaras afastadas uma da outra, e de um modo

simultâneo, constitui o que se designa de aquisição de imagens estereoscópicas. Todo o sistema de aquisição foi desenvolvido e pensado de modo a que esta aquisição possa ser

feita da melhor forma possível, isto é de modo que o alvo que se encontra ligado ao paciente seja perfeitamente visível nas duas câmaras de modo a evitar problemas na detecção dos pontos característicos do alvo que permitirá estabelecer a correspondência em termos de instante temporal de aquisição da imagem de exame clínico e movimento do paciente. 2.2.2 - Software desenvolvido

O módulo de aquisição permite obter imagens a partir de uma ou duas câmaras e seguindo diferentes esquemas de aquisição.

O desenvolvimento do software para este módulo baseou-se quase exclusivamente na livraria Mil Lite que é um subset da Mil - Matrox Imaging Library - que nos permite realizar aquisição, manipulação de dados, gráficos e controle de visualização fazendo uso de todas as potencialidades do frame grabber. 2.2.2.1 Opções de aquisição

A aquisição a partir de uma câmara ligada ao frame grabber envolve necessariamente a configuração

de parâmetros de aquisição de modo que a câmara tenha as suas características adaptadas ao sistema usado. Estes parâmetros podem ser configurados na aplicação antes de se realizar a aquisição, através do menu apresentado na figura 4.9, entre os quais:

1) Número de câmaras a utilizar pelo sistema. 2) Canal de aquisição associado a cada câmara. 3) Tipo de sinal a captar em ambas as câmaras. 4) Formato de imagem a captar. 5) Modo de display.

60

Page 70: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

6) Escala de imagem a utilizar na aquisição. 7) Formato de gravação da sequência e taxa de compressão da mesma. 8) Formato de gravação das imagens adquiridas. 9) Informação texto adicional a acrescentar às imagens adquiridas do tipo “ .BMP ” .

Figura 4.9 - Menu de configuração dos parâmetros de aquisição.

1) Número de câmaras a utilizar pelo sistema. A especificação do número de câmaras a utilizar permite a aquisição a partir de uma ou duas

câmaras, possibilitando assim a aquisição stereo utilizada no projecto ou a aquisição simples a partir de uma câmara de modo a que este módulo possa ser utilizado independentemente, e com outras funcionalidades que não as necessárias ao projecto.

2) Canal de aquisição associado a cada câmara. Indicação do canal do frame grabber a partir do qual é feita a aquisição do sinal vídeo das câmaras, potenciando assim a selecção de qualquer um dos quatro canais disponibilizado pelo frame grabber.

3) Tipo de sinal a captar em ambas as câmaras. Indicação do formato do sinal a captar pelo frame grabber dependendo to tipo de sinal vídeo

fornecido pela câmara. Opções:

Em caso de formato RGB - Aquisição a cor PAL SECAM NTSC Em caso de formato Gray - Aquisição em tons de cinzento CCIR RS-170 4) Formato de imagem a captar. Indicação do formato de imagem a captar do frame grabber, podendo esta ser feita a cores – 3 canais x 8 bits - ou em tons de cinzento - 1 canal x 8 bits.

Opções: RGB Cinzento

5) Modo de display. Indicação do tipo de display a utilizar durante a visualização. Opções:

61

Page 71: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

Modo Básico - este modo não há optimização de velocidade em imagens a cores, o que pode resultar numa performance mais lenta. Modo Básico optimizado - este modo faz uso de um algoritmo que permite aumentar a velocidade de visualização em imagens a cores.

Modo Superior - este modo faz uso de dithering melhorando particularmente o display de imagens a cores. 6) Escala de imagem a utilizar na aquisição. A escala a utilizar permite definir qual o tamanho da imagem a utilizar para a aquisição. Opções: Normal - adquire imagens com tamanho de 768 x 576 pixels. Metade - adquire imagens com tamanho de 384 x 288 pixels. Quarto - adquire imagens com tamanho de 192 x 144 pixels. 7) Formato de gravação da sequência e taxa de compressão da mesma. Foi disponibilizado a possibilidade de gravar imagens e colocá-las sequencialmente num ficheiro do tipo AVI ou AVI comprimido, apenas para potenciar o uso desta ferramenta como uma ferramenta independente. 8) Formato de gravação das imagens adquiridas. O formato em que é gravado o ficheiro de imagem de modo a terem um formato apropriado à sua utilização neste projecto - “.BMP” - ou de uma forma independente em outras aplicações. 9) Informação texto adicional a acrescentar às imagens adquiridas do tipo “ .BMP ” . Este parâmetro foi disponibilizado de forma a podermos referenciar, se desejado as imagens do tipo “ .BMP ” adquiridas com informação que o utilizador possa achar importante. Para o projecto fizemos uso de imagens em escala normal (768 x 576 pixels) de forma a termos uma

imagem que nos ofereça a possibilidade de visualizar as imagens adquiridas com o maior tamanho disponibilizado pelo frame grabber, usando o formato “.BMP” com um modo de aquisição a duas câmaras em formato CCIR em formato de tons de cinzento uma vez que estas são as características das câmaras utilizadas.

2.2.2.2 Esquemas de aquisição

Foram implementados vários esquemas de aquisição que permitem adquirir imagens de um modo

sequencial de acordo com vários parâmetros ajustáveis: Sequência - Este modo foi implementado apenas para potenciar o uso do software com outras finalidades que não a do projecto desenvolvido.

Multi-Shot - permite adquirir as imagens de um modo sequencial, podendo os instantes de aquisição serem activados de dois modos distintos:

Temporalmente - Fazendo uso do temporizador da placa de aquisição - frame grabber - podemos determinar de quanto em quanto tempo será adquirida uma imagem podendo ainda definir um instante de pausa inicial antes de se iniciar a aquisição em intervalos de tempo regulares.

A partir de um Trigger externo - Fazendo uso do pressionar de uma tecla no teclado ou de um interruptor que se encontra ligado à porta série é activado o momento de aquisição.

Este modo foi pensado de forma a utilizar um possível sinal de trigger da própria máquina de exames médicos, no caso da máquina possuir um sinal ao qual seja possível aceder externamente e que nos desse indicação dos instantes de aquisição das imagens SPECT planares da máquina em questão. Para o projecto desenvolvido o esquema de aquisição multi-shot em modo temporal é o

escolhido, uma vez que geralmente é difícil aceder a sinais da máquina que nos possibilitem saber quais os instantes de aquisição. Essa informação é difícil ou praticamente impossível de obter uma vez que tal

62

Page 72: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

informação não é disponibilizada pelo fabricante das máquinas de exames médicos SPECT. No entanto e conhecendo os protocolos de aquisição em exames SPECT o modo temporal é a alternativa segura uma vez que faz uso dos mesmos parâmetros utilizados nos protocolos de exame SPECT, podendo assim acompanhar o exame desde que não haja um desfasamento temporal significativo entre os relógios dos dois equipamentos: relógio do temporizador do frame grabber, relógio do temporizador da máquina de exames médicos SPECT.

Na figura 4.10 é feita uma ilustração da interface com o utilizador, onde podem ser visualizadas os esquema de utilização que o utilizador tem ao seu dispor. Figura 4.10 – Esquemas de utilização

2.2.2.3 Configuração de níveis de referência da aquisição de imagem Uma vez que as condições em termos de luminosidade podem variar dependendo do local e das condições circunstanciais onde se encontra a máquina desenvolvemos um módulo que nos permite alterar as referências da placa de aquisição no que concerne ao brilho, contraste, saturação e tonalidade das imagens adquiridas. Assim, ao variar esses parâmetros de acordo com as condições locais onde se encontra a câmara, adaptando assim o processo de aquisição e obtendo melhores resultados. É também possível retirar imagens instantâneas e aumentar / diminuir o zoom das imagens, através do interface utilizador / implementação ilustrado na figura 4.11.

Figura 4.11 – Configuração de níveis de referência

2.2.2.4 Análise do software desenvolvido

As imagens adquiridas pelo frame grabber apresentam faixas negras nas regiões superior e lateral direita da imagem que influenciam os algoritmos de calibração e detecção. Estas faixas são exteriores à imagem adquirida e têm que ser ignoradas pelas implementações de calibração e de detecção de modo a que tais problemas não se verifiquem.

Em termos de implementação todo o módulo foi desenvolvido de modo a obtermos um módulo multifuncional e adaptável a situações que não só as encontradas no desenvolvimento do projecto de forma a ser utilizável com outros fins que não os inerentes a este projecto. 2.3 - Calibração das câmaras 2.3.1 - Introdução

O processo de calibração é um pré - requisito importante para a maioria das aplicações de visão

por computador. Geralmente um sistema é calibrado por duas razões:

�� Retroprojecção – Inferir informação 3D a partir das coordenadas da memória frame. A calibração fornece a partir das coordenadas imagem na memória frame, a equação de recta de projecção no espaço 3D que passa pelo ponto. Obtendo duas imagens de posições diferentes podemos calcular a posição 3D do ponto através do cálculo do ponto que mais se aproxima da intersecção das duas rectas equacionadas a partir das duas imagens - triangulação estereoscópica.

63

Page 73: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

��Projecção – Inferir as coordenadas 2D imagem na memória frame a partir da informação 3D. Nas aplicações baseadas em modelos e utilizando visão por computador, uma hipótese do estado do mundo pode ou não ser confirmada pela verificação de que as coordenadas imagem do objecto estão de acordo com a hipótese.

A projecção é utilizada essencialmente em gráficos por computador onde geralmente é usado um

modelo de câmara ideal. Por outro lado o principal objectivo da retroprojecção é principalmente fazer medições de posição para aplicações 3D incluindo inspecção dimensional e manipulação robótica. Quando as câmaras são usadas na retroprojecção é necessária elevada precisão na calibração.

A maioria das técnicas de calibração inicialmente criadas empregavam o modelo de câmara “pin-hole” e os processo eram simples e rápidos quando aplicados. No entanto devido à simplificação, que não considerava as não linearidades inerentes ao processo de aquisição, era difícil obter resultados precisos. Assim assistiu-se ao desenvolvimento de modelos de câmaras mais precisos envolvendo correcção da distorção da lente, que é identificada como sendo a maior fonte de introdução de não linearidade no sistema. Tsai propôs uma técnica eficiente que faz uso de uma série de equações para determinar os parâmetros da câmara com um modelo simplificado da distorção radial da lente. 2.3.2 - Fundamentos teóricos - Modelo de Tsai Aqui se encontram reunidas as características mais importantes do modelo de Tsai: - O modelo de câmara de Tsai é baseado no modelo “pin-hole” de projecção de perspectiva 3D-2D com distorção radial de lente de primeira ordem. O modelo possui onze parâmetros, cinco internos ou intrínsecos e seis externos ou extrínsecos que são: Parâmetros intrínsecos

f - distancia focal efectiva do modelo de câmara “pin-hole” k - coeficiente de distorção radial de primeira ordem Cx,Cy - coordenadas do centro de distorção radial da lente e ponto de perfuração do eixo dos

Zs do sistema de coordenadas de frame com o plano do sensor da câmara. sx - factor de escala que compensa incertezas no escalamento efectuado pelo frame

grabber na linha de scan horizontal.

Parâmetros extrínsecos Rx, Ry, Rz - ângulos de rotação para a transformação entre o sistema de coordenadas mundo e os

sistema de coordenadas da câmara. Tx,Tzy,Tz - componentes de translação para a transformação entre o sistema de coordenadas

mundo e os sistema de coordenadas da câmara. Para além deste onze parâmetros o modelo de Tsai possui ainda 6 constantes intrínsecas à

câmara que são : Ncx - número de elementos sensores na direcção dos xx da câmara Nfx - número de pixels na direcção dos xx da câmara dx - a dimensão dos elementos sensores segundo a direcção dos xx dy - a dimensão dos elementos sensores segundo a direcção dos yy dpx - dimensão real segundo a direcção dos xx dos pixels no frame grabber dpy - dimensão real segundo a direcção dos yy dos pixels no frame grabber - As constantes intrínsecas Ncx, dx e dy podem ser encontradas na ficha técnica do equipamento.

Não é realmente essencial conhecer os valores das constantes intrínsecas para calibrar um modelo preciso de câmara. Para a maioria das aplicações a precisão requerida limita-se a prever, com a precisão adequada, a partir das coordenadas 3D do ponto na cena as coordenadas do ponto no frame buffer. Neste caso os verdadeiros valores das constantes intrínsecas não são necessários. Para fazer com que o modelo convirja para uma solução apenas é necessário o ratio câmara / frame grabber ou seja o ratio entre dpx e dpy. É possível obter uma boa estimativa para esse ratio a partir de uma imagem de um rectângulo simples. Medindo o rectângulo, o ratio

64

Page 74: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

Nº de pixel de comprimento do objecto da imagem/ Medida (mm) do comprimento do objecto da imagem Nº de pixels de altura do objecto da imagem/ Medida (mm) da altura do objecto da imagem

afigura-se como uma estimativa precisa o suficiente para estimar o ratio entre dpx e dpy de modo a

que a calibração convirja. Dado este ratio basta escolher para dpy um valor e faz-se uso desse valor para calcular os outros

parâmetros dpx, dy e dx.. de seguida iguala-se Ncx a Nfx , sx a 1 e Cx e Cy como sendo o centro das coordenadas do frame buffer.

Pode-se observar que duplicando dpx e dpy todos os parâmetros extrínsecos, Cx ,Cy e sx se mantêm constantes bem como o erro de calibração.

- Mesmo que se use o valor da distância focal fornecida pelo fabricante o valor exacto deste parâmetro não será o mesmo uma vez que o valor fornecido pelo fabricante é o de um modelo de câmara de lente espessa e não o correspondente ao modelo “pin-hole” utilizado. Apesar destes valores terem efeitos similares na imagem são quantitativamente bem diferentes. - Os dados de calibração para o modelo são constituídos pelas coordenadas 3D mundo de um ponto em (mm) e as correspondentes coordenadas frame 2D em pixels. As coordenadas 3D têm que ser especificadas num sistema de coordenadas que siga a regra da mão direita. Após a primeira calibração o processo de calibração para diferentes posições pode ser acelerado fazendo uso dos valores dos parâmetros intrínsecos obtidos na primeira calibração.

- O algoritmo de Tsai tem duas variantes: o coplanar e o não coplanar. Para os dados coplanares a componente segundo a direcção dos zz das coordenadas 3D dos pontos terá de ser igual para todos. A calibração coplanar básica requer pelo menos cinco pontos e a não coplanar pelo menos sete. A calibração completamente optimizada requer pelo menos onze pontos quer para o método coplanar quer para o método não coplanar. Nas rotinas de calibração seguindo o método coplanar o valor de sx mantém-se inalterado. - De modo a estimar com precisão a distorção radial da lente e o centro da imagem, os dados de calibração devem ser distribuídos uniformemente no campo de visão da câmara. Devendo também tentar cobrir o volume onde nos interessa efectuar as medidas. - O algoritmo de Tsai falha se a origem do sistema de coordenadas mundo estiver próximo do centro do campo de vista ou próxima do eixo dos yy do sistema de coordenadas da câmara, de modo a que ty no algoritmo de Tsai seja precisamente diferente de zero tal como deve ser garantido para o uso do algoritmo. No caso dos dados de calibração não verificarem a condição anterior é muito simples de criar um novo sistema de coordenadas artificial com um offset em relação ao sistema de coordenadas mundo de modo a que as condições para o algoritmo funcionarem sejam verificadas. - Para podermos separar os efeitos de f e tz na imagem há a necessidade de haver um efeito de

distorção perspectiva nos dados de calibração. Para obtermos uma distorção que possa ser usada a distância entre os pontos de calibração mais próximos e os mais afastados da câmara devem estar na mesma escala que a distância entre os pontos de calibração e a câmara. Para a calibração coplanar o pior caso é aquele em que os pontos se encontram num plano paralelo ao plano da imagem da câmara ( Ou seja todos os pontos à mesma distância). Nesse caso não conseguimos separar os efeitos de f e tz. Um ângulo relativo de 30º ou mais é recomendado para obtermos uma certa profundidade aos pontos de calibração. No caso não coplanar o pior caso é aquele em que os pontos se encontram num volume que é

relativamente pequeno em comparação com o volume de distância à câmara. - Para obter dados de calibração precisos necessitamos de medir a localização dos pontos característicos no plano da imagem com precisão sub pixel.

2.3.3 - Abordagem seguida no projecto

65

Page 75: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

2.3.3.1 - Introdução

O método utilizado neste projecto para efectuar a calibração das câmaras foi o método de calibração considerando projecção perspectiva, distorção radial da lente de primeira ordem e utilizando pontos coplanares, proposto em [Tsai,1987]. Neste método é considerado em termos de modelo teórico da câmara, projecção perspectiva e distorção radial de primeira ordem da lente.

A aproximação seguida baseia-se na procura de uma restrição ou equação que seja apenas função de um subconjunto dos parâmetros de calibração de modo a reduzir de uma dimensão o espaço dos parâmetros desconhecidos. Pode-se verificar que essa restrição existe e é designada de restrição de alinhamento radial. Esta restrição (ou equações que resultam de tal restrição física) é função da rotação e translação relativa à excepção da componente em z entre os pontos de calibração e a câmara. Apesar da restrição ser uma função não linear dos parâmetros de calibração anteriormente referidos, existe um modo simples e eficiente de os calcular. Os outros parâmetros de calibração são calculados com equações de projecção normais. Uma boa aproximação destes parâmetros pode ser obtida ignorando a distorção da lente e usando simples equações lineares com duas incógnitas. Os valores precisos desses parâmetros podem então ser calculados com uma ou duas iterações que minimizem o erro da equação de projecção perspectiva. 2.3.3.2 - Modelo de câmara Considerando quatro os passos que nos permitem transformar as coordenadas 3D mundo para coordenadas de câmara e tendo em atenção a geometria do modelo de câmara ilustrado na figura 4.12 vem:

f

P(xw,yw,z w) � P(x,y,z ) ow

xw

yw

zw

Pd ( Xd,Yd)

Pu ( Xu,Yu) o X

Y

y

x O

Figura 4.12 – Geometria do modelo de câmara.

Nesta figura é possível definir:

(xw,yw,z w) – coordenadas 3D do ponto P no sistema mundo (x,y,z ) – coordenadas 3D do ponto P no sistema de coordenadas câmara (X,Y) – representa o sistema de coordenadas imagem centrado em O i e com os eixos X e Y

paralelos respectivamente aos eixos x e y do sistema câmara. f – distância focal efectiva (Xu,Yu) – representa as coordenadas imagem de P se for utilizado um modelo “pin-hole”

perfeito para a câmara( coordenadas imagem sem distorção) (Xd,Yd) – representa as coordenadas da imagem real , ou seja com distorção.

66

Page 76: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

No entanto uma vez que as unidades utilizadas para definir as coordenadas (Xf,Yf) é a unidade pixel, é necessário especificar e calibrar outros parâmetros que relacionam o sistema de coordenadas imagem com o sistema de coordenadas na memória frame. Esquematizando a transformação das coordenadas (xw,yw,z w) em (Xf,Yf) obtemos o seguinte diagrama:

4

3

2

1

( xw,yw,z w) Sistema de coordenadas 3D mundo

( Xd, Yd ) Coordenadas imagem não ideal, distorcida

( Xu, Yu ) Coordenadas imagem ideal, não distorcida

( x, y, z) Sistema de coordenadas 3D câmara

Varrimento TV, amostragem, aquisição Parâmetros a calibrar : sx, ( Cx, Cy )

Distorção radial da lente Parâmetros a calibrar : k

Projecção perspectiva com modelo “pin-hole”. Parâmetros a calibrar : f

Transformação corpo rígido de ( xw,yw,z w ) para ( x,y,z ) Parâmetros a calibrar : R, T

( Xf, Yf ) Coordenadas imagem no frame buffer

O quarto passo é especifico para aplicações industriais onde são utilizadas câmaras de TV (CCD ou CID).

1) Transformação corpo rígido das coordenadas 3D do sistema de coordenadas mundo ( xw,yw,z

w) para o sistema de coordenadas câmara ( x,y,z )

Tzyx

Rzyx

���

���

���

���

w

w

w

Onde R é a matriz de rotação (3x3 ) ���

���

9

6

3

8

5

2

7

4

1

rrr

rrr

rrr

R

67

Page 77: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

ou

c

os� cos� sen� cos� -sen� -sen� cos�+ cos� sen� cos� cos� cos�+sen� sen� sen� cos� sen� sen� sen�+ cos� sen� cos� -cos� sen�+sen� sen� cos� cos� cos�

R =

e T é o vector translação:T ���

���

z

y

x

t

tt

Os parâmetros a calibrar são a matriz de rotação 3D R e o vector de translação 3D T. Devemos reparar que a transformação de corpo rígido de um sistema de coordenadas cartesiano

rígido para outro é único se a transformação for definida como sendo uma rotação 3D em torno da origem seguida de uma translação 3D.

2) Transformação das coordenadas 3D do referencial câmara ( x, y, z ) para as coordenadas ideais de imagem ( Xu, Yu ) usando projecção perspectiva com geometria de câmara “pin-hole”.

zxfX u �

zyfYu �

O parâmetro a calibrar é a distância focal efectiva f 3) A distorção radial da lente é: Xd + Dx = Xu , Yd + Dy = Yu

Onde ( Xd, Yd ) são as coordenadas da imagem real ou distorcida no plano da imagem e

Dx = Xd (k1r2+k2r4+...) Dy = Yd (k1r2+k2r4+...)

dd YXr 22��

Os parâmetros a serem calibrados são o factor de distorção k . Existem dois tipos de distorção:

radial e tangente. Para cada tipo de distorção é necessário uma série infinita. No entanto é opinião generalizada que para aplicações industriais de visão por computador basta considerar a distorção radial e com apenas um termo. Se tomarmos em conta modelos mais elaborados não só será desnecessário como causa instabilidade numérica.

4) Transformação das coordenadas reais imagem ( Xd, Yd ) para coordenadas imagem da memória frame ( Xf, Yf ). Xf = sx d’x

-1 Xd + Cx Yf = dy

-1 Yd+ Cy

Onde ( Xf,Yf ) - São as coordenadas discretas do ponto na memória frame. ( Cx,Cy ) - São as coordenadas discretas do centro óptico na memória frame.

68

Page 78: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

cy

cxxx N

Ndd' �

dx -É a distância entre centros dos elementos sensores vizinhos segundo a direcção x. dy -É a distância entre centros dos sensores CCD vizinhos segundo a direcção y. Ncx – número de elementos sensores na direcção x. Nfx - número de pixels numa linha tal como é amostrada pelo computador.

Normalmente os fabricantes das câmaras CCD fornecem na ficha técnica do equipamento os

parâmetros dx e dy com precisão de sub mícron. Contudo é necessário utilizar um parâmetro de incerteza horizontal sx devido a diversos factores tais como má sincronização temporal entre o frame grabber e a velocidade de varrimento da câmara ou imprecisões no sincronismo de varrimento TV.

O parâmetro a ser calibrado é assim o factor de incerteza horizontal de escala sx. 2.3.3.3 Calibração de uma câmara

Verificar pela figura 4.6 que o setup para a calibração de uma câmara utilizando um conjunto de pontos coplanares. O plano de calibração, cuja forma foi discutida na secção anterior consiste num conjunto de quadrados negros igualmente espaçados quer na vertical quer na horizontal cujos vértices são os pontos de calibração. Uma vez que os pontos de calibração ( xw,yw,z w ) se encontram no mesmo plano podemos escolher um referencial de coordenadas em que zw de todos os pontos seja constante e a sua origem não muito próxima do centro de visão ou do eixo dos yy do sistema de coordenadas da câmara de modo a que ty não seja nulo. Uma vez que o sistema de coordenadas é definido pelo utilizador de uma forma arbitrária não é difícil satisfazer essas condições. Neste método a calibração para determinação dos parâmetros pode ser dividida em dois estágios, o primeiro para determinação dos três ângulos de rotação e das componentes segundo x e y de translação 3D e o segundo para determinação da translação segundo z, do factor de distorção radial da lente k e a distância focal efectiva f. 1º Cálculo da rotação 3D e das translações segundo os eixos x e y.

� Cálculo de sx – factor de incerteza horizontal � Cálculo das coordenadas da imagem distorcida (Xd, Yd) � Cálculo das cinco incógnitas ty

-1r1, ty-1r2,ty

-1tx, ty-1r4, ty

-1r5 � Cálculo de r1, r2, r3, r4, r5, r6, r7, r8, r9, tx e ty a partir de ty

-1r1, ty-1r2,ty

-1tx, ty-1r4, ty

-1r5 � Cálculo de sx – factor de incerteza horizontal Não foi possível implementar o cálculo do factor de incerteza horizontal pelo processo de

calibração, definindo-se assim sx como sendo fx

cxx N

Ns �

� Cálculo das coordenadas da imagem distorcida (Xd, Yd)

1) Detecção de cada ponto de calibração i na memória frame, designado as respectivas coordenadas por ( Xfi, Yfi )

2) Obter d’x e dy , utilizando os dados respectivos fornecidos pelo fabricante da câmara e a d’x=sxdx com sx definido anteriormente.

3) Fazer ( Cx, Cy ) igual às coordenadas do centro da memória frame.

4) Calcular ( Xdi, Ydi ) utilizando Xdi=d’x( Xfi+Cx ) e Ydi=dyYi+Cy com i a variar entre 1 e N , em que N é o número total de pontos de calibração.

� Cálculo das cinco incógnitas ty

-1r1, ty-1r2,ty

-1tx, ty-1r4, ty

-1r5

69

Page 79: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

Para cada ponto de calibração i ( xwi, ywi, zwi ) e ( Xdi, Ydi ) representando respectivamente as coordenadas no sistema mundo e as coordenadas imagem distorcida , resolve-se o seguinte sistema de equações lineares com ty

-1r1, ty-1r2,ty

-1tx, ty-1r4, ty

-1r5 como incógnitas:

[ Ydixwi Ydiywi -Xdixwi -Xdiywi] = X

��������

��������

51

41

1

21

11

rt

rt

rt

rt

rt

y

y

xy

y

y

di

Se N – número de pontos de calibração – for maior que cinco então teremos um sistema sobre determinado que poderá ser resolvido em ordem às incógnitas utilizando por exemplo o método de regressão dos mínimos quadrados. Nota: A equação terá uma solução única se e só se as colunas dos coeficientes forem todos linearmente independentes, o que facilmente se pode verificar para N muito maior que cinco. � Cálculo de r1, r2, r3, r4, r5, r6, r7, r8, r9, tx e ty a partir de ty

-1r1, ty-1r2,ty

-1tx, ty-1r4, ty

-1r5

1) Calcular |ty| a partir de ty-1r1, ty

-1r2,ty-1tx, ty

-1r4, ty-1r5 .

Seja C uma sub matriz de 2x2 da matriz de rotação 3D R

Por exemplo C =

����

����

yy

yy

tr

tr

tr

tr

54

21

Se o determinante de C é diferente de zero

então

ty2 = 2

2451

22451

2

)''''(2)''''(4

rrrrrrrrSS rr

���

, com Sr = r’12 +r’2

2 + r’42+r’5

2

e r’i = y

i

tr

Ou então calcula-se ty por ty

2= ( r’i2+ r’j

2 )-1 com ri e rj sendo os elementos da linha ou coluna da matriz C que não apresenta nenhum elemento igual a zero, sendo que no entanto esta situação raramente se verifica.

2) Determinação do sinal de ty

� Escolhe-se um ponto i no sistema de coordenadas mundo ( xw,yw,z w ) cujas coordenadas imagem na memória frame ( Xf, Yf ) são afastadas das coordenadas imagem do centro óptico, na mesma memória, ( Cx, Cy )

�Fazer o sinal de ty positivo

� Calcular r1 = (ty

-1r1)ty, r2 = (ty-1r2)ty, r4 = (ty

-1r4)ty, r5 = (ty-1r5)ty,

tx = (ty-1tx)ty, xi = r1xwi + r2ywi +tx e yi = r4xwi+r5ywi+ty

70

Page 80: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

� Se xi e Xdi têm o mesmo sinal assim como yi e Ydi então o sinal de ty é positivo, caso contrário é negativo.

3) Cálculo da matriz de rotação 3D R, ou seja de r1,r2,r3,r4,r5,r6,r7,r8,r9

� Calcular r1 = (ty

-1r1)ty, r2 = (ty-1r2)ty, r4 = (ty

-1r4)ty, r5 = (ty-1r5)ty, tx = (ty

-1tx)ty

� Calcular a matriz R pela seguinte equação:

���

��

��

���

9

25

24

22

21

8

5

2

7

4

1

1

1

rrrs

rr

rrr

rrr

R

Onde s = - sinal(r1r4+ r2r5). A função sinal() significa o sinal do seu argumento. Os elementos da matriz de rotação 3D R: r7, r8, r9 são determinados usando o produto vectorial das duas primeiras linhas, utilizando a propriedade ortonormal da matriz R.

� Calcular uma aproximação para a distância focal efectiva f utilizando:

[yi -Ydi] = w��

���

ztf

iYdi , onde yi = r4xwi + r5ywi + ty e wi = r7xwi + r8ywi

Se esta aproximação for menor que que zero então:

���

���

���

�����

9

25

24

22

21

8

5

2

7

4

1

1

1

rrrs

rr

rrr

rrr

R

2º Calcular a distância focal efectiva f, coeficiente de distorção radial k e a translação segundo o eixo z, tz.

� Calcular uma aproximação para f e para tz ignorando a distorção da lente. � Cálculo da solução exacta para f, tz e k

� Calcular uma aproximação para f e para tz ignorando a distorção da lente.

Para cada ponto de calibração i, estabelecer a seguinte equação linear com f e tz como i ncógnitas:

[yi -Ydi] = w��

���

ztf

iYdi , onde yi = r4xwi + r5ywi + ty e wi = r7xwi + r8ywi

Com vários pontos de calibração, obtém-se um sistema de equações lineares sobredeterminado que pode ser resolvido para a determinação das incógnitas f e tz. O plano de calibração não pode ser exactamente paralelo ao plano da imagem pois senão a equação acima referida tornar-se-ia linearmente dependente.

� Cálculo da solução exacta para f, tz e k

71

Page 81: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

Resolver a equação:

Yd(1+k1r2) = f zwww

ywww

tzryrxrtzryrxr

���

���

987

654

fazendo f, tz e k como incógnitas por um método de optimização standard como por exemplo o método Levenberg-Marquardt. Utilizar como solução inicial a aproximação para f e tz encontrada pela resolução do sistema de equações lineares anterior e igualando k a zero.

2.3.3.4 - Considerações sobre o modelo utilizado e alterações ao mesmo

Este método tem como grandes vantagens a inclusão no modelamento da câmara da distorção radial da lente e um factor de incerteza radial, a utilização de equações lineares e não lineares de pequena dimensão e de pontos coplanares. No entanto como desvantagens devemos referir que as coordenadas da imagem do centro óptico na memória frame coincidem com as coordenadas do centro desta e a impossibilidade do factor de incerteza ser calculado pelo processo de calibração e a necessidade do plano de calibração não ser paralelo ao plano da câmara, que podem constituir dificuldades em certas aplicações. O desenvolvimento do sistema de calibração tem no entanto algumas alterações em relação ao proposto por [Tsai]. Tendo como principal vantagem o facto da determinação das coordenadas do centro da imagem na memória frame serem calculadas pelo próprio processo de calibração [Lens]. O método utilizado tem assim como grandes vantagens, tal como referido em [Tavares]:

�� Inclusão da distorção radial da lente e projecção perspectiva. �� Utilização de pontos coplanares. �� Não necessidade de estimativas iniciais para qualquer parâmetro �� Possibilidade de determinação das coordenadas do centro da imagem na memória frame

conjuntamente com os restantes parâmetros, à excepção do factor de incerteza horizontal.

Apresentando como desvantagens:

- Necessidade do plano de calibração não ser paralelo ao plano da câmara, o que em certas aplicações pode ser desvantajoso.

- Não consideração da possibilidade dos eixos segundo a direcção x e y do referencial de coordenadas na memória frame, não serem paralelos ao eixo respectivos do referencial imagem.

- Necessidade de determinar o factor de incerteza horizontal por um processo independente, que apesar de apenas ser necessário efectuar uma vez para um determinado sistema câmara / lente pode ser difícil ou mesmo impossível.

2.3.3.5 - Influência de uma determinação incorrecta do centro da imagem

O centro da imagem é definido pelas coordenadas (Cx, Cy ) na memória frame do ponto de

intersecção do eixo óptico com o plano imagem. Geralmente é utilizado como ponto de origem do processo de formação de uma imagem e pertence aos parâmetros presentes nas equações de projecção perspectiva. Em várias aplicações utilizam-se estas coordenadas como sendo as do centro da imagem frame, no entanto existem desvios que levam a que seja necessário calculá-los em aplicações de maior precisão como os de visão tridimensional por computador. Pode facilmente ser calculado o erro residual devido a uma determinação incorrecta do centro da imagem obtendo-se a seguinte equação:

ERRO = )( 2221 yyxx CKCKk ��� Em que Kx e Ky dependem do setup experimental que

está a ser utilizado [Tsai].

72

Page 82: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

Uma maneira de estimar o centro da imagem baseia-se em minimizar o erro residual. Apesar de ser uma optimização não linear com duas incógnitas, é uma abordagem que se demonstra ser eficaz uma vez que com poucas iterações se pode chegar à solução final., devido à dependência sistemática do erro residual com e . A equação acima indicada dá-nos indicação que este método apenas resulta na presença de distorção radial da lente e quando o erro residual devido à extracção das coordenadas imagem na memória frame dos pontos de calibração for pequeno em comparação com ERRO.

xC� yC�

2.3.3.6 - Determinação das coordenadas dos pontos de calibração Para se efectuar a calibração é necessário determinar as coordenadas dos pontos de calibração na memória frame. Todo o processo de calibração se inicia aqui , sendo que a precisão dos valores tem um peso importante na qualidade dos resultados a obter.

A técnica utilizada para a detecção dos pontos de calibração baseado em [Tsai] considera um conjunto de quadrados igualmente distribuídos, sendo os vértices dos quadrados os pontos de calibração a considerar.

A detecção dos pontos é efectuada do seguinte modo: 1) Realizar a aquisição da imagem de cinzentos 2) Binarização da imagem por threshold sendo que o valor do limiar não é critico uma vez que

pode ser obtido manualmente pela observação do histograma da imagem de calibração. 3) Efectuar a ligação entre os pontos fronteira dos quadrados de modo a obter o conjunto dos

lados aproximados dos quadrados. 4) Percorrer a imagem inicial nas direcções perpendiculares às dos lados aproximados dos

quadrados anteriormente determinados de modo a obter os verdadeiros pontos dos lados dos quadrados utilizando para o efeito interpolação

5) Ajuste de linhas rectas aos verdadeiros pontos dos lados dos quadrados.

6) Determinação da intersecção entre linhas rectas de ajuste de modo a obter-se a localização dos pontos de calibração com precisão ao nível de ½ a 1/3 de pixel

O método utilizado neste projecto seguiu o método

concebido em [Tavares] e que consiste no seguinte: 1) Realizar a aquisição da imagem de cinzentos. 2) Sujeitar a imagem de calibração a um detector de

orlas de intensidade, para classificar os pixels da imagem inicial em termos de amplitude e de direcção �.

3) Determinar as duas direcções principais �1 e �2 que sejam diferentes de pelo menos um valor �d , isto é |�1-�2| � �d considerando nesta determinação apenas os pixels cujo valor de amplitude Ai seja superior a um determinado valor de modo a desprezar-se pontos de ruído.

Figura 4.6 – Alvo para calibração de câmaras

4) Classificação dos pixels resultantes da detecção das orlas de intensidade na imagem de calibração em duas classes C1 e C2 Uma constituída pelos pixels que apresentam, um valor de amplitude Ai igual ou superior ao limiar e uma direcção �i aproximadamente igual a �1 e outra constituída pelos pixels que apresentem um valor de amplitude Ai igual ou superior a um dado limiar e cuja direcção �i seja aproximadamente igual a �2.

5) Determinar as linhas rectas constituídas pelos lados das figuras geométricas na classe C1 sendo esta determinação efectuada do seguinte modo:

i) Determinar o primeiro elemento da classe C1 não considerado e classificá-lo como considerado.

ii) Definir a recta que passa pelo ponto anteriormente determinado e que tem direcção igual a �1 .

iii) Determinar o próximo ponto na classe C1 ainda não considerado que pertence à linha recta determinada no passo anterior , tendo por base que a distância do ponto à linha terá que ser menor que um determinado limiar pré-definido

iv) Retornar a ii) até ser atingido o último elemento da classe C1.

73

Page 83: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

v) Realizar a regressão linear dos pontos classificados como pertencentes a uma determinada linha, se o número destes for superior a um dado limiar, de modo a eliminar falsas linhas.

vi) determinar uma nova, linha voltando ao ponto i) até não existirem mais elementos na classe C1 ainda não considerados. 6) Determinar as linhas rectas constituídas pelos lados das figuras geométricas na classe C2 do

mesmo modo como foi efectuado para a classe C1 considerando no entanto �2 em vez de �1 . 7) Determinar a intersecção das linhas obtidas para C1 e C2. 8) definir os pontos de intersecção, determinados no passo anterior como os pontos de

calibração pretendidos.

2.3.4 - Software desenvolvido

Nesta parte do relatório serão apresentadas as implementações desenvolvidas no domínio de calibração de câmaras. Estas aplicações foram desenvolvidas em linguagem Microsoft Visual C ++. Assim serão apresentadas as seguintes aplicações:

��Uma implementação para a calibração de todos os parâmetros intrínsecos e extrínsecos de uma câmara, exceptuando a factor de incerteza horizontal : sx.

��Uma implementação para a determinação das coordenadas imagem na memória frame de pontos de calibração utilizados.

��Uma implementação para simulação de uma câmara de geometria interna conhecida. ��Uma implementação para a formatação dos pontos de calibração provenientes da rotina de

detecção dos referidos pontos, para ser possível efectuar a calibração da câmara que efectuou a aquisição da imagem.

O desenvolvimento de uma rotina de simulação de dados de calibração deveu-se ao facto de se

obter resultados simulados de forma a testar convenientemente a implementação da rotina de calibração de todos os parâmetros da câmara. Com esta implementação torna-se possível obter, de forma automática, as coordenadas 3D e as coordenadas na memória frame dos pontos de calibração coplanares, para uma dada geometria interna e posição e orientação da câmara relativamente ao plano de calibração. 2.3.4.1 – Calibração de uma câmara

Neste ponto é apresentada, de uma forma sucinta, uma implementação para calibração de uma dada câmara segundo o método descrito no ponto 2.3.3. Com esta implementação, é possível a calibração de todos os parâmetros de uma câmara excepto o factor de incerteza horizontal sx. A referida implementação é responsável por:

�� Interface utilizador / implementação.

Figura 4.13 – Interface utilizador / implementação onde são especificados todos

parâmetros necessários à realização da rotina de calibração.

��Leitura dos argumentos opcionais:

74

Page 84: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

- nome do ficheiro para escrita dos resultados obtidos, nomeadamente, as condições de realização da calibração.

- O valor da tolerância de erro para as soluções exactas da distância focal efectiva f, da componente tz do vector de translação T e do factor de distorção radial da lente k1, determinadas pela resolução do sistema de equações não lineares respectivo e utilizando o método Levenberg – Marquardt. Por defeito, é igual a 0.0000001.

- Sx, factor de incerteza horizontal. Por defeito, é igual a 0.710935. - Find Image Center, quando esta opção é accionada pelo utilizador, a implementação

determina as coordenadas exactas do centro da imagem na memória frame (Cx, Cy). Por defeito, esta opção encontra-se não accionada.

��Leitura dos argumentos não opcionais:

- dx, distância entre centros dos elementos sensores vizinhos na direcção x. - Dy, distância entre centros dos sensores CCD vizinhos na direcção y. - Cx, coordenada do centro da imagem na memória frame segundo a direcção x. Quando Cx

não é conhecido exactamente, o utilizador deve especificar Cx igual a metade da dimensão da memória frame segundo a direcção x e especificar à implementação que pretende que esta determine a coordenada correcta. Deste modo, o valor especificado para Cx é apenas a solução inicial sendo a implementação responsável pela determinação da solução exacta.

- Cy, coordenada do centro da imagem na memória frame segundo a direcção y. Quando Cy não é conhecido exactamente, o utilizador deve especificar Cy igual a metade da dimensão da memória frame segundo a direcção x e especificar à implementação que pretende que esta determine a coordenada correcta. Deste modo, o valor especificado para Cy é apenas a solução inicial sendo a implementação responsável pela determinação da solução exacta.

- Nome do ficheiro de entrada que contém as coordenadas 3D mundo (xW, yW, zW) e as coordenadas 2D imagem na memória frame (Xf1, Yf1) para todos os pontos de calibração i.

��Determinação das coordenadas do centro da imagem na memória na memória frame (Cx, Cy)

quando pretendido pelo utilizador; para tal, é utilizada outra função. Essa função responsável pela determinação das coordenadas do centro da imagem na memória frame (Cx, Cy), utiliza o método iterativo apresentado. Durante a determinação, todos os parâmetros são também determinados novamente até o módulo atingir uma solução global óptima.

��Calibração de todos os parâmetros restantes da câmara, excepto o factor de incerteza horizontal sx;

para tal, são utilizadas outras funções. A função responsável pela resolução de um sistema sobre determinado de equações lineares, z[m][n] x a[n]=y[m] utiliza o método dos mínimos quadrados, com resolução do respectivo sistema de equações normais. Para tal, utilizamos a decomposição de Cholesky da matriz [z[m][n]Tz[m][n], com posterior substituição para a frente e para trás. Esta decomposição é das mais eficientes em termos de memória consumida; no entanto, a sua utilização só é possível em matrizes [z[m][n]Tz[m][n] definidas positivamente. A função responsável pela resolução de um sistema de equações lineares alfa[NMAX1][NMAX1] x delta[NMAX1]=beta[NMAX1] utiliza a decomposição de Cholesky da matriz alfa[NMAX1][NMAX1], com posterior substituição para a frente e para trás.

��Apresentação dos resultados obtidos.

��Comunicação da existência da existência de erros em argumentos de entrada ou ao longo do

decurso da execução.

Como restrições na utilização deste método têm-se:

��O número de pontos de calibração deve ser maior que cinco; ��O sistema de coordenadas 3D mundo deve ser escolhido de forma que todos os pontos de

calibração tenham a coordenada 3D mundo z igual a zero e a componente ty do vector de translação T não seja exactamente igual a zero.

��O factor de incerteza horizontal sx, deve ser diferente de zero.

75

Page 85: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

��Esta rotina só aceita ficheiros de texto criados pelas rotinas de simulação de uma câmara descrito no ponto 2.3.4.4 ou pela rotina de determinação das coordenadas dos pontos de calibração na memória frame.

2.3.4.2 - Determinação das coordenadas na memória frame dos pontos de calibração

Neste ponto é apresentada, de forma sumária, a implementação do método para determinação das coordenadas imagem na memória frame (Xf, Yf) dos pontos de calibração considerados. O resultado desta aplicação podem ser até cinco imagens, dependendo das opções de visualização seleccionadas, e um ficheiro de texto. Supondo que todas as opções de visualização foram seleccionadas os resultados serão constituídos por:

- Uma imagem contém o resultado da aplicação de uma operação de filtragem de realce ou

suavização da imagem inicial. - Duas imagens contendo o resultado da aplicação do filtro de detecção de orlas de

intensidade, a primeira, contém todos os pixels identificados com amplitude superior a um dado limiar especificado pelo utilizador e direcção aproximadamente igual a uma direcção principal; a segunda, contém todos os pixels identificados com amplitude superior ao mesmo limiar e direcção aproximadamente igual à outra direcção principal.

- Duas imagens que contém as linhas de intersecção segundo as direcções principais. - Uma quinta imagem, onde são identificados os pontos de calibração e assinalados por

intermédio de uma cruz; - Um ficheiro de texto com a escrita dos resultados obtidos, nomeadamente as coordenadas

imagem na memória frame (Xf, Yf) dos pontos de calibração determinados. A referida implementação é responsável pela interface implementação / utilizador.

- Leitura dos parâmetros opcionais: o Tolerância do erro na classificação de um dado pixel quanto à sua direcção. o Diferença mínima entre as duas direcções principais.

Figura 4.14 – Interface utilizador / implementação onde o utilizador especifica todos os parâmetros

de detecção dos pontos de calibração.

o Máxima distância que um pixel a uma dada recta para ser classificado como pertencente a esta.

o Valor mínimo de amplitude que um dado pixel deve apresentar para não ser classificado como ruído.

o Possibilitar o realce ou suavização da imagem de entrada. o Filtro de realce ou suavização da imagem de entrada o Filtro de detecção de orlas de intensidade

76

Page 86: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

o Opções de visualização o Nome do ficheiro de texto onde será feita a escrita dos resultados obtidos,

nomeadamente as coordenadas imagem na memória frame (Xf, Yf) dos pontos de calibração determinados.

- Chamada de outras funções. - Determinação das duas direcções principais presentes na imagem de entrada; - Classificação dos pixels, na segunda imagem de saída, que têm amplitude superior a um

dado limiar e que têm uma direcção próxima de uma das direcções principais; - Classificação dos pixels, na terceira imagem de saída, que têm amplitude superior a um dado

limiar e que têm uma direcção próxima da outra direcção principal; determinação das rectas que existem em cada uma das imagens referenciadas anteriormente; para tal faz a chamada a outra função; durante a execução, a função responsável por essa determinação opta automaticamente pela melhor regressão linear, isto é, para rectas com declives entre –45º e 45º a regressão linear (utilizando a regressão linear pelo método dos mínimos quadrados) é do tipo y=m.x+b e, para os restantes declives, a regressão linear é do tipo x=m’.y+b’. Para determinar se um pixel pertence a uma dada recta, a sua distância a esta é calculada e comparada com a máxima distância admissível especificada pelo utilizador. Para eliminação de falsas linhas, o módulo só considera uma dada recta se o número de pixels que esta contém é maior que um determinado especificado pelo utilizador. Registo das rectas de intersecção nas terceira e quarta imagem, imagens estas que contém apenas uma das direcções das rectas de intersecção.

- Determinação das coordenadas dos pontos de calibração através da intersecção entre várias rectas definidas analiticamente.

- Registo dos pontos de calibração no ficheiro de texto e na última imagem de saída, usando para tal uma função que faz o desenho na imagem de saída respectiva, de uma cruz de dimensões 9x9 centrada num determinado pixel.

- Visualização das imagens seleccionadas pelo utilizador. - Comunicação da existência de erros de argumentos ao longo do decurso da execução.

Como restrições na utilização têm-se:

�� A imagem de entrada deve conter figuras geométricas de quatro lados paralelos dois a dois, perfeitamente iguais e paralelas entre si.

�� A imagem de entrada deve ser do tipo DIB, com a extensão .bmp, sendo uma imagem constituída por níveis de cinzento.

2.3.4.3 – Formatação dos pontos de calibração determinados

Neste ponto é apresentado, de forma sumária, a implementação responsável pela formatação dos pontos de calibração determinados através do método descrito no ponto anterior. Como os pontos de calibração determinados anteriormente são pontos 2D, isto é, são pontos que são descritos relativamente ao plano da memória frame, necessitam de ser formatados de maneira a ser possível utilizar a rotina de cálculo dos parâmetros internos e externos de uma câmara (descrita no ponto 2.3.4.1). Esta rotina exige a par da coordenada 2D na memória frame a coordenada desse mesmo ponto no sistema de coordenadas mundo, isto é, a sua coordenada 3D.

Figura 4.15 – Interface utilizador / implementação onde este especifica o ficheiro de texto proveniente da implementação de detecção dos pontos de calibração

e o nome do ficheiro do resultado da formatação desses pontos.

Assim, com esta implementação obtêm-se:

77

Page 87: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

- Um ficheiro de texto contendo todos os pontos de calibração referidos nas suas coordenadas 2D e 3D.

- Leitura dos argumentos opcionais: o Nome do ficheiro de texto que contém todos os pontos de calibração encontrados

pela rotina descrita no ponto 2.3.4.2. o Nome do ficheiro de texto que irá conter todos os pontos de calibração definidos

através das suas coordenadas 3D e 2D.

- Formatação dos pontos de calibração, através da leitura do ficheiro de texto referido em cima e consecutivamente das coordenadas 2D desses pontos. A formatação permite escolher qual o ponto que se pretende introduzir a sua coordenada 3D, não sendo obrigatório formatar todos os pontos presentes no primeiro ficheiro de texto, possibilitando vários testes ao algoritmo de calibração (por exemplo, qual o resultado da rotina de calibração quando se utiliza apenas ponto colineares). Quando todos os pontos de calibração pretendidos pelo utilizador se encontram formatados, esta informação é guardada no ficheiro de texto indicado pelo utilizador. É também dada a informação de quantos pontos de calibração foram determinados pela rotina anterior.

Figura 4.16 – Interface responsável pela indicação do valor do pixel a formatar

e leitura das coordenadas 3D desse ponto. Restrições a esta implementação:

�� O algoritmo de formatação apenas aceita ficheiros de textos produzidos pela rotina de determinação das coordenadas na memória frame dos pontos de calibração.

2.3.4.4 – Simulador de uma câmara Neste ponto é apresentada uma implementação de um simulador de uma câmara para um dado conjunto de pontos coplanares. A partir dos respectivos parâmetros de entrada, a própria implementação determina automaticamente as coordenadas 3D mundo (xw, yw, zw) e as coordenadas na memória frame (Xf, Yf), para cada ponto de calibração, do seguinte modo:

I) Determinação da projecção inversa, sobre o plano de calibração considerado, dos quatro vértices que definem as dimensões da memória frame. Esta projecção inversa é possível pois conhece-se a geometria interna da câmara, a posição e orientação desta relativamente ao plano de calibração considerado, a coordenada 3D mundo z do plano de calibração e as coordenadas 2D na memória frame dos pontos pretendidos – (1,1), (1, Dimfy), (Dimfx, x) e (Dimfx, Dimfy) onde Dimfx é a dimensão da memória frame segundo a direcção x e Dimfy é a dimensão segundo a direcção y.

II) Considerar este paralelogramo definido pelas projecções sobre o plano de calibração definidas anteriormente. Este paralelogramo tem lados mais ou menos paralelos dois a dois.

III) Definir o conjunto de n – definido como igual à raiz quadrada do número de pontos de calibração pretendidos – linhas rectas distribuídas uniformemente entre dois lados mais ou menos paralelos.

IV) Definir o conjunto de n linhas rectas distribuídas uniformemente entre os restantes dois lados do paralelogramo.

78

Page 88: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

V) Definir os pontos de calibração como situados sobre o plano de calibração e coincidentes com as intersecções, sobre este plano, das linhas rectas definidas em III) com as linhas rectas definidas em IV).

VI) Determinar para cada ponto de calibração, cujas coordenadas 3D foram determinadas anteriormente, as coordenadas respectivas na memória frame.

Figura 4.17 – Interface utilizador / implementação responsável pela caracterização de todos

os parâmetros necessários à simulação de uma câmara de geometria interna conhecida.

Esta implementação é então responsável por:

- Leitura dos argumentos opcionais: o Numero de pontos de calibração pretendidos. o Coordenada 3D mundo z para o plano de calibração. o Coordenada Cx do centro da imagem na memória frame, segundo a direcção x. Por

defeito, é igual a metade da dimensão da referida memória segundo a mesma direcção.

o Coordenada Cy do centro da imagem na memória frame, segundo a direcção y. Por defeito, é igual a metade da dimensão da referida memória segundo a mesma direcção.

o Dimensão da memória frame segundo a direcção x. o Dimensão da memória frame segundo a direcção y. o Valor em graus da rotação segundo o eixo x. o Valor em graus da rotação segundo o eixo y. o Valor em graus da rotação segundo o eixo z. o Componente tx do vector translação, isto é a translação segundo o eixo x. o Componente ty do vector translação, isto é a translação segundo o eixo y. o Componente tz do vector translação, isto é a translação segundo o eixo z. o Distância focal efectiva f. o Distância entre centros dos elementos sensores vizinhos na direcção x, dx. o Distância entre centros dos elementos sensores vizinhos na direcção y, dy. o Factor de incerteza horizontal, sx. o Factor de distorção radial da lente k1. o Nome do ficheiro para escrita dos resultados obtidos, nomeadamente as

coordenadas 3D mundo (xw, yw, zw) e as coordenadas 2D (Xf, Yf) imagem na memória frame determinadas para cada ponto de calibração.

- Apresentação das componentes determinadas da matriz de rotação 3D R do sistema de

coordenadas mundo para o sistema câmara. - Execução da simulação da câmara propriamente dita.

79

Page 89: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

- Escrita no ficheiro de saída das coordenadas 3D mundo (xw, yw, zw) e das coordenadas 2D (Xf, Yf) imagem na memória frame determinadas para todos os pontos de calibração.

- Comunicação da existência de erros em argumentos de entrada ou ao longo do decurso da execução da rotina.

Como restrições a esta rotina temos:

�� O valor especificado para o número de pontos de calibração pretendidos deve ter raíz

quadrada inteira, por exemplo 16. �� Os valores especificados para as rotações segundo os três eixos principais deverão estar

definidos em graus e compreendidos entre –360º e 360º.

2.3.5 – Resultados experimentais

Nesta secção são apresentados alguns resultados experimentais obtidos pelas várias implementações descritas anteriormente. Estes resultados tem apenas um carácter demonstrativo, deixando a maior parte da análise e conclusões de diversos cenários para no Capítulo V. Assim serão apresentados:

a) Resultados experimentais obtidos na utilização da implementação responsável pela determinação das coordenadas na memória frame dos pontos de calibração considerados;

b) Resultados experimentais obtidos na utilização da implementação responsável pela simulação de câmaras de geometria interna conhecida.

c) Resultados experimentais obtidos pela implementação responsável pela calibração de câmaras.

d) Resultados experimentais obtidos pela utilização da implementação responsável pela formatação das coordenadas dos pontos de calibração considerados.

2.3.5.1 – Implementação para a determinação das coordenadas dos pontos de calibração considerados Para realizar o teste da implementação desenvolvida foi capturada uma imagem, em tons de cinzento, formato .bmp, de dimensões 768x586, de 8 bits e contendo 12 quadrados, que está representada na figura 4.18 a). Sendo assim esta imagem contém 48 possíveis pontos de calibração. Na figura 4.18 b) são visíveis os parâmetros de entrada à implementação. Na figura 4.19 podemos observar os resultados do filtro de realce do tipo Gaussiano a) e de detecção de orlas Deriche b) e c) sobre a imagem da figura 4.18 a). As duas imagens resultado da aplicação deste filtro de detecção de orlas foram previamente negadas de maneira a facilitar a sua visualização.

a) b)

Fig. 4.18 – Imagem de teste usada para testar o algoritmo de detecção a) e parâmetros utilizados pela implementação para efectuar essa detecção

80

Page 90: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

Como resultado da implementação obtiveram-se três imagens, que são apresentadas na figura 4.20. Na figura 4.20 a) está representada a imagem que contém todos os pixels que têm um valor de amplitude superior a 50 e direcção aproximadamente igual a uma das direcções principais. Na figura 4.20 b), está representada a imagem que contém todos os pixels que têm uma valor de amplitude superior a 50 e direcção aproximadamente igual à segunda das direcções principais. Na figura 4.20 c), está representada a imagem que contém todas as localizações dos pontos de calibração existentes na imagem de teste, isto é, os vértices dos quadrados localizados. A localização destes pontos na imagem é feita através de uma cruz.

b) c) a)

Figura 4.19 – Resultados das operações de filtragem sobre a imagem original. a) filtro Gaussiano 5x5 b) e c) filtro de detecção de orlas de intensidade Deriche.

De maneira a determinar a qualidade dos resultados obtidos, executou-se a soma lógica da

imagem de teste representada na figura 4.18 a), com a imagem contendo todos os pontos de calibração encontrados, representados na figura 4.21 b). Com o mesmo objectivo procedeu-se também à soma lógica desta última imagem com a imagem obtida pelo detector de orlas de intensidade de Deriche, sendo esta soma representada na figura4.21 a).

c) b) a)

Figura 4.20 – Resultado da detecção de linhas a) numa das direcções principais e b) na segunda direcção principal e c) resultado da intersecção das linhas detectadas, assinaladas por

intermédio de uma cruz.

É possível observar que esta implementação apresenta resultados de boa qualidade, com resolução ao nível do sub pixel. Nas duas imagens da figura 4.22 essa resolução é bem visível através da ampliação de 400 % de dois quadrados escolhidos ao acaso das duas imagens na figura 4.21. De notar, que a imagem original se encontra negada de maneira a facilitar a visualização.

81

Page 91: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

b)a) Figura 4.21 – Soma lógica da imagem contendo os pontos de calibração com a) a primeira imagem de saída do filtro de Deriche e

b) com a imagem original previamente negada.

Figura 4.22 – Ampliação de zonas escolhidas aleatoriamente das imagens

da figura 4.21.

Finalmente, na tabela 1 é ilustrado o conteúdo do ficheiro de texto de saída da implementação, nomeadamente as coordenadas 2D na memória frame (Xf, Yf) de todos os pontos de calibração determinados na imagem de entrada apresentada na figura 4.18 a).

490.26 95.862 494.21 154.46 498.13 212.49 502.05 270.63 505.95 328.35 509.87 386.49 439.34 98.003 443.59 157.42 447.79 216.28 452.01 275.24 456.19 333.79 460.41 392.76

387.91 100.17 392.34 160.41 396.74 220.12 401.13 279.93 405.51 339.34 409.91 399.16 334.8 102.4 339.45 163.51 344.06 224.09 348.68 284.76 353.26 345.06 357.88 405.75

280.28 104.69 285.09 166.69 289.87 228.17 294.65 289.74 299.4 350.95 304.19 412.56 223.27 107.09 228.3 170.01 233.29 232.42 238.29 294.93 243.26 357.1 248.26 419.65

165.37 109.53 170.56 173.38 175.72 236.76 180.88 300.22 186.01 363.36 191.17 426.89 105.63 112.04 110.91 176.87 116.14 241.24 121.39 305.7 126.61 369.87 131.86 434.4

Tabela 1 – Conteúdo do ficheiro de texto de saída de resultados obtidos pela implementação

desenvolvida para a imagem original apresentada na figura 4.18 a).

82

Page 92: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

2.3.5.2 – Implementação da rotina de simulação de câmaras de geometria interna conhecida

Neste ponto serão apresentados alguns resultados de simulações de câmaras de geometria interna conhecida utilizando a implementação apresentada no ponto 2.3.4.4.

Para a executar a simulação de uma calibração de uma câmara de geometria interna conhecida foram usados os seguintes parâmetros de entrada:

Figura 4.23 – Parâmetros de entrada para a implementação de

simulação de calibração.

Como pode não ser muito visível a distância utilizada entre sensores na distância x e y são aqueles que foram apresentados aquando da descrição do material utilizado, que são respectivamente de 0.0098 e 0.0063 cm. O valor de incerteza horizontal sx utilizado foi de 0.710935. Com estes valores foram obtidos os seguintes resultados:

Figura 4.24 – Resultados da implementação de simulação de uma calibração de uma câmara

de geometria interna conhecida.

Estes resultados podem ser comprovados utilizando o ficheiro de texto apresentado na tabela 2, na rotina de calibração de câmaras. Esta verificação faz-se através da comparação dos valores obtidos para a matriz de rotação e de translação, distância focal e distorção radial obtidos pela rotina de calibração com os valores introduzidos como parâmetros iniciais da rotina de simulação de calibração.

83

-88.6867 -121.429 0 438.34 73.503 -99.5096 -121.486 0 364.48 73.3201 -110.333 -121.543 0 290.843 73.2307 -121.156 -121.599 0 217.541 73.2336 -131.979 -121.656 0 144.68 73.3273 -142.802 -121.713 0 72.363 73.5101

-88.6865 -104.239 0 438.574 219.858 -99.5096 -104.25 0 364.619 219.821 -110.333 -104.261 0 290.888 219.804 -121.156 -104.272 0 217.491 219.804 -131.979 -104.283 0 144.537 219.823 -142.802 -104.295 0 72.1277 219.859

-88.6864 -87.0477 0 438.496 366.397 -99.5095 -87.0135 0 364.572 366.508 -110.333 -86.9792 0 290.873 366.562 -121.156 -86.945 0 217.508 366.561 -131.979 -86.9107 0 144.584 366.504 -142.802 -86.8765 0 72.2062 366.393

Page 93: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

-88.6866 -112.834 0 438.496 146.61 -99.5096 -112.868 0 364.572 146.501 -110.333 -112.902 0 290.873 146.447 -121.156 -112.936 0 217.508 146.449 -131.979 -112.97 0 144.584 146.505 -142.802 -113.004 0 72.2062 146.615

-88.6864 -95.6431 0 438.574 293.151 -99.5095 -95.6316 0 364.619 293.189 -110.333 -95.6201 0 290.888 293.207 -121.156 -95.6086 0 217.491 293.206 -131.979 -95.597 0 144.537 293.187 -142.802 -95.5855 0 72.1277 293.15

-88.6863 -78.4523 0 438.34 439.502 -99.5094 -78.3953 0 364.48 439.686 -110.333 -78.3383 0 290.843 439.776 -121.156 -78.2814 0 217.541 439.773 -131.979 -78.2244 0 144.68 439.679 -142.802 -78.1674 0 72.363 439.495

Tabela 2 – Pontos de calibração coplanares obtidos pela rotina de simulação

É possível constatar na tabela 2 que os pontos obtidos pela rotina de simulação são todos

coplanares (coordenada z igual a zero) formando 3 linhas e 3 colunas de quadrados perfeitamente paralelos entre si, perfazendo assim 36 pontos de calibração coplanares. Submetendo estes pontos de calibração à rotina de obtenção dos parâmetros extrínsecos e intrínsecos de uma dada câmaras, os resultados são os seguintes:

Figura 4.25 – Parâmetros intrínsecos e extrínsecos obtidos pela rotina de calibração

de uma dada câmara. Estes resultados também podem ser observados através do ficheiro de texto onde são gravados os resultados da calibração.

Stop for nonlinear equations=1e-008, Find center=0, sx=0.710935, dx=0.0098, dy=0.0063, Cx=256, Cy=256,

Input file: C:\WINNT\Profiles\nscouto\Desktop\simul.txt with 36 calibration points.

Rotation matrix R:

+0.866028 +5.82670e-007 +0.499995

+3.36264e-006 +1.00000 -6.98972e-006 -0.499995 +7.73460e-006 +0.866028

Translation vector T:

+100.000 +100.000 +2000.05

Focal length f:

+110.003

Radial lens distortion k1:

+0.00100597

Tabela 3 – Ficheiro de texto de saída da rotina de calibração onde são referenciados tanto os parâmetros de entrada como os parâmetros de saída da rotina

que são os parâmetros intrínsecos e extrínsecos da câmara

84

Page 94: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

Na observação dos resultados produzidos pela rotina de calibração é possível constatar que estes são idênticos aos parâmetros introduzidos para a rotina de simulação, levando – nos a concluir que a rotina de simulação de calibração retorna uma distribuição de pontos de calibração no plano de calibração sempre regular, dado que, é essa a sua filosofia de implementação; a forma do conjunto dos pontos de calibração depende dos valores utilizados para as rotações nos três eixos principais x, y e z. Sendo assim, concluiu –se que se pode utilizar esta implementação para realizar diversos testes de calibração e analisar os seus resultados sem ter que recorrer a experiências laboratoriais. 2.3.5.3 – Implementação da rotina de formatação de pontos de calibração na memória frame. Esta implementação tem como objectivo executar a formatação dos pontos de calibração obtidos pela implementação de detecção desses mesmos pontos. Esta formatação é necessária dado que, a implementação de calibração dos parâmetros intrínsecos e extrínsecos de uma câmara tem que ter como ficheiro de dados os pontos de calibração coplanares nas suas coordenadas mundo (3D) e na memória frame (2D). Como apenas dispomos das coordenadas na memória frame temos então que introduzir as coordenadas mundo desses pontos. Assim como parâmetro de entrada a esta implementação o ficheiro de dados apresentado na tabela asdasd.

a) b)

Figura 4.26 – a) Parâmetros de entrada à implementação de formatação dos pontos de calibração e b) formatação de um ponto escolhido aleatoriamente.

A formatação, ilustrada na figura 4.26, consiste em introduzir ponto a ponto as respectivas coordenadas 3D mundo. A origem do referencial mundo geralmente é localizada no centro do alvo de calibração. Esta formatação permite-nos escolher quais os pontos de calibração detectados que serão utilizados para a determinação dos parâmetros extrínsecos e intrínsecos da câmara. Desta maneira, é possível realizar vários testes sobre a influência da distribuição dos pontos no plano de calibração nos resultados apresentados pela implementação responsável pela determinação dos parâmetros da câmara. Como resultado desta implementação o ficheiro de dados de saída tem o conteúdo apresentado na tabela 4. De salientar que apenas foram formatados 24 pontos dos 48 detectados pela implementação de detecção dos pontos de calibração na memória frame.

70 -50 0 490.28 95.994 70 -30 0 494.22 154.49 70 -10 0 498.13 212.49 70 10 0 502.06 270.62 70 30 0 505.95 328.34 70 50 0 509.87 386.48 50 -50 0 439.34 98.122 50 -30 0 443.58 157.44

50 -10 0 447.79 216.28 50 10 0 452 275.24 50 30 0 456.18 333.79 50 50 0 460.4 392.76 -50 -50 0 165.38 109.56 -50 -30 0 170.57 173.35 -50 -10 0 175.72 236.77 -50 10 0 180.89 300.23

-50 30 0 186.02 363.35 -50 50 0 191.19 426.89 -70 -50 0 105.64 112.06 -70 -30 0 110.9 176.82 -70 -10 0 116.14 241.25 -70 10 0 121.38 305.72 -70 30 0 126.6 369.86 -70 50 0 131.85 434.42

Tabela 4 – Ficheiro resultante da implementação de formatação onde a informação

2D das coordenadas da memória frame é combinada com a informação 3D das coordenadas mundo.

85

Page 95: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

2.5.3.4 – Implementação de calibração de câmaras Neste ponto serão apresentados os resultados da calibração de uma câmara usando para tal um conjunto de pontos coplanares, previamente detectados e formatados respectivamente pelas implementações de detecção de pontos na memória frame e de formatação de pontos de calibração. Assim este ponto não tentará demonstar o algoritmo, pois essa verificação já foi realizada no ponto 2.5.3.2 deste capítulo. Assim apresentaremos os resultados de uma calibração usando imagens e dados reais capturados através das câmaras usadas no âmbito deste projecto. A análise desses valores, com base também em outras calibrações com outros valores e parâmetros de entrada, será feita nos capítulos seguintes. Assim tendo como ficheiro de dados de entrada o ficheiro apresentado na tabela 4, temos os seguintes resultados:

Figura 4.27 - Resultado da calibração de uma câmara para o alvo de calibração

Ilustrado na figura 4.19 a). É visível na figura 4.27 que quando se efectua uma calibração podemos colocar os resultados dessa calibração como valores por defeito de uma das câmaras, facilitando assim o processo de obtenção de coordenadas 3D, dado que estes valores se encontram em memória, evitando assim que sejam sempre colocados pelo utilizador quando se pretender calcular coordenadas 3D. Os resultados obtidos na verificação desta implementação leva-nos a concluir que se obtém em média bons resultados. No entanto esta qualidade é afectada por algumas características práticas tais como: a translação segundo o principal y não deverá ser nula; o factor de incerteza horizontal deverá ser o mais correcto possível, pois uma pequena variação no seu valor implica grandes variações nos parâmetros determinados; as coordenadas 3D dos pontos deverá ser a mais precisa possível, pois uma pequena variação no seu valor implica grandes variações nos parâmetros determinados e o número de pontos de calibração deverá ser razoável (na ordem de algumas dezenas). 2.4 - Detecção de pontos característicos de um alvo e obtenção de informação 3D dos mesmos 2.4.1 - Introdução

A detecção de pontos característicos de imagens de um alvo colocado sobre um paciente, obtidas

por um sistema stereo de aquisição de imagens e o respectivo emparelhamento para posterior obtenção de informação tridimensional acerca desses mesmos pontos serão discutidos neste capitulo.

A obtenção da informação tridimensional associada a cada par de imagens é a base de todo o processo a apresentar ponto 2.5 para estimação de movimento. Ou seja após possuirmos um sistema stereo de aquisição de imagem posicionado e calibrado, da maneira que foi apresentada no ponto 2.3, podemos obter, fazendo uso do módulo de aquisição de imagem apresentado no ponto 2.3, em sequência temporal, pares de imagem a partir das quais obteremos informação tridimensional. A informação tridimensional obtida irá assim permitir-nos realizar a estimação de movimento desejada.

86

Page 96: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

No método desenvolvido a obtenção de informação tridimensional é conseguida pela resolução do respectivo sistema de projecção stereo após a determinação da localização e emparelhamento de pontos característicos de um alvo num par de imagens adquirido por um sistema stereo calibrado de aquisição de imagem. A determinação da informação tridimensional é obtida fazendo uso de linhas epipolares e fazendo o cálculo da posição do ponto que minimiza os erros associados a disparidades de posição em ambas as linhas epipolares.

Assim admitimos que o processo considerado que parte de um conjunto de pares de imagens, obtido a partir de um sistema de aquisição de imagem stereo calibrado, e que resulta na obtenção de informação tridimensional acerca de pontos característicos que se encontram nesses mesmos pares de imagens, adquiridas em sequência temporal, é um processo que se pode afirmar como sendo constituído por três fases:

��Detecção dos pontos característicos em cada imagem, pontos estes que são os vértices

de sólidos geométricos que se encontram num alvo dimensionado para tal. ��Emparelhamento dos pontos característicos em cada par de imagem por meio de

etiquetagem. ��Obtenção de informação tridimensional a partir da projecção estereo dos pontos

anteriormente emparelhados.

2.4.2 - Detecção de pontos característicos 2.4.2.1 – Dimensionamento do alvo A abordagem seguida para o dimensionamento do alvo foi que os pontos característicos que seriam determinados deveriam ser o resultado da intersecção de linhas pertencentes a figuras geométricas. Assim surgem como possíveis candidatos as seguintes figuras geométricas: triângulos, quadrados, losângulos, rectângulos e cruzes (esta forma pode não ser convencionalmente considerada como uma forma geométrica mas resulta da sobreposição de duas figuras geométricas, que são os rectângulos). A filosofia seguida para o dimensionamento deste alvo foi que deveria ser constituído por um conjunto de formas geométricas o mais diverso possível, de maneira que a eficácia e precisão dessas formas geométricas fosse a mais elevada possível, e assim permitir um emparelhemto dos pontos característicos detectados mais simples e eficaz. O número de figuras geométricas a incluir no alvo deve ser no mínimo 3 figuras, de maneira a produzir pelo menos uma dezena de pontos detectados. Esta quantidade de pontos é necessária para a análise dos resultados dos valores 3D calculados pela rotina responsável, e também para se fazer análise e estimação do movimento sofrido nos diversos instantes de aquisição. Olhando melhor para as figuras geométricas candidatas verificamos desde logo, que algumas delas apresentam características intrínsecas que por si só podem ser vantajosas para a sua detecção. Em seguida é feita uma descrição dessas características internas de cada uma das figuras geométricas candidatas:

- Quadrado: possui duas linhas de direcção que o definem completamente (vertical e horizontal), todos os seus pontos resultantes da intersecção dessas linhas encontram-se nas próprias linhas, forma geométrica simples, entre dois lados consecutivos existe sempre um desfasamento de 90º e têm comprimentos iguais. Estes aspectos são ilustrados na figura 4.28 a).

- Rectângulo: tem todas as características do quadrado, excepto no comprimento igual de todos os lados, que no caso do rectângulo, os lados são iguais em comprimento dois a dois. Da mesma forma podemos caracterizar o losângulo.

- Triângulo: ao contrário das formas geométricas anteriores, o triângulo é constituído por três linhas de direcção diferentes: duas oblíquas e uma horizontal, tal como é ilustrado na figura 4.28 c).

- Cruz: não sendo uma forma geométrica genuína, pode ser construída à custa de dois rectângulos. Desta maneira, também fica completamente definida à custa de duas linhas de direcção, embora todos os pontos resultantes da intersecção dessas duas linhas não pertençam a essa forma geométrica, isto é, a intersecção dessas duas linhas vai originar pontos de intersecção exteriores à forma geométrica, formando assim uma intersecção ‘falsa’, como é ilustrado na figura 4.28 b).

87

Page 97: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

c) b)a)

Figura 4.28 – Intersecção das linhas de direcção que constituem as figuras geométricas. A vermelho são assinaladas as intersecções falsas e a verde as que pertencem à figura geométrica.

a) Quadrado, b) Cruz e c) Triângulo

A partir da observação da figura 4.28 é possível concluir vários aspectos tais como:

- Se juntarmos qualquer uma das figuras geométricas com um / vários triângulos, os pontos de intersecção do triângulo serão resultantes da intersecção das linhas com direcções oblíquas. Desta maneira para sabermos quais são os pontos de intersecção pertencentes ao triângulo, basta saber quais são as rectas com direcção oblíqua e quais os pontos que resultaram da intersecção das duas linhas oblíquas e destas com a linha de direcção horizontal.

- Na cruz, o facto de haver falsas intersecções, pode ser uma vantagem muito grande, dado que, dentro do perímetro formado pelas falsas intersecções, vão-se encontrar todos os pontos de intersecção verdadeiros, pertencentes à cruz. Desta maneira para sabermos quais os pontos de intersecção pertencentes à cruz, faz-se a detecção de falsas intersecções, constrói - se uma caixa imaginária à volta desses pontos, e assim todos os pontos contidos nessa caixa (excepto aqueles que a formam) são considerados pontos pertencentes à cruz.

- Quanto ao quadrado, rectângulo ou losângulo, a única característica que os diferencia em relação às formas geométricas descritas anteriormente é o comprimento entre pontos consecutivos de intersecção ser constante e superior a todos os outros comprimentos detectados nessa direcção. Se o nosso alvo for constituído apenas por triângulos, cruzes e quadrados existe outra forma de detectar estes pontos de intersecção, que consiste basicamente em detectar primariamente os pontos de intersecção dos triângulos e cruzes e só depois classificar os pontos restantes como pontos pertencentes aos quadrados.

Assim o alvo deverá ser constituído principalmente por cruzes e triângulos, dado que, para estes

a classificação dos seus pontos de intersecção faz-se de uma maneira clara e inequívoca. Tendo também em conta que o facto de se incluir uma (ou mais) cruz faz com que os pontos de intersecção sejam muitos mais dado que a existência de mais duas linhas na direcção horizontal vai provocar mais cruzamentos nas outras figuras geométricas tal como é ilustrado na figura 4.29.

Figura 4.29 – Pontos de intersecção resultantes do cruzamento das linhas nas quatro direcções mencionadas na caixa com cor verde. Os pontos assinalados a vermelho são intersecções falsas. A azul é assinalada a caixa

imaginária de classificação dos pontos pertencentes à cruz.

88

Page 98: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

O número de pontos resultantes devido ao facto de haver quatro linhas na direcção horizontal

aumentou significativamente (se em vez da cruz fosse um quadrado haveria menos 16 pontos!), como pode ser observado na figura 4.29. Desta maneira a presença de pelo menos uma cruz pode ser um factor de erro nos cálculos, dado que os pontos resultantes da intersecção das linhas horizontais da cruz, originam pontos que não característicos das outras figuras geométricas. Outro pormenor a ter em conta é a dimensão do alvo. Se este for muito pequeno, é mais sensível à influência do ruído (que tem como uma das consequências a não detecção de certas linhas ou provocar a detecção de linhas inexistentes) e dificultar a análise de pequenos movimentos. Pelo contrário se o alvo for muito grande, além das dificuldades relacionadas com a implementação física, corre-se o risco de não detectar o alvo na sua totalidade e assim perder informação preciosa sobre o movimento efectuado. Assim, tendo em conta as condicionantes referidas, o melhor compromisso será a inclusão de quatro figuras geométricas. Como a filosofia desta implementação requer a maior diversidade possível destas figuras, apenas a quarta figura pode ser uma repetição de uma das outras três. Assim as configurações possíveis seriam:

- Triângulo <> Quadrado <> Cruz <> Triângulo - Quadrado <> Quadrado <> Cruz <> Triângulo - Cruz <> Quadrado <> Cruz <> Triângulo

Tendo em conta as características internas de cada uma destas figuras geométricas concluiu – se

que aquela em a detecção e classificação dos pontos de intersecção é mais eficaz e precisa é o triângulo. Assim a configuração do alvo implementado está representada na figura 4.30.

Embora sejam marcados na figura 4.30 os pontos de intersecção falsos na cruz não usados para o processamento nem são gravados nos ficheiros de texto de saída das implementações.

Figura 4.30 – Alvo dimensionado para detecção, cálculo de coordenadas 3D e estimação de movimento. Na figura são

visíveis a azul os pontos de intersecção do triângulo, a amarelo os do quadrado, a verde os pontos considerados como pertencentes à cruz e a vermelho os pontos de intersecção não pertencentes à cruz

2.4.2.2 – Detecção do alvo Para se efectuar o emparelhamento e posteriormente cálculos das coordenadas 3D é necessário determinar as coordenadas dos pontos de intersecção das figuras características do alvo na memória frame. Todo o processo de cálculo de coordenadas 3D se inicia aqui, sendo que a precisão dos valores tem um peso importante na qualidade dos resultados a obter.

A técnica utilizada para a detecção dos pontos característicos do alvo é baseado no método apresentado no ponto 2.3.3.6, método este que considera um conjunto de quadrados igualmente distribuídos, sendo os vértices dos quadrados os pontos de calibração a considerar. Neste caso, o conjunto de figuras a considerar está ilustrado na figura 4.30, e os pontos a considerar são, além dos vértices, todos os pontos resultantes da intersecção entre as linhas nas quatro direcções principais.

Assim a determinação dos pontos de intersecção das figuras geométricas na memória frame é feita da seguinte forma:

1) Realizar a aquisição da imagem de cinzentos. 2) Sujeitar a imagem de calibração a um detector de orlas de intensidade, para classificar os

pixels da imagem inicial em termos de amplitude e de direcção �.

89

Page 99: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

3) Determinar as quatro direcções principais �1 e �2 que sejam diferentes de pelo menos um valor �d , isto é |�1-�2| � �d, |�1-�3| � �d, |�1-�4| � �d, |�3-�2| � �d, |�4-�2| � �d e |�4-�3| � �d considerando nesta determinação apenas os pixels cujo valor de amplitude Ai seja superior a um determinado valor de modo a desprezar-se pontos de ruído.

4) Classificação dos pixels resultantes da detecção das orlas de intensidade na imagem de calibração em quatro classes C1, C2, C3 e C4, uma vez que temos quatro direcções principais possíveis, tal como é ilustrado na figura asdasd. Uma constituída pelos pixels que apresentam, um valor de amplitude Ai igual ou superior ao limiar e uma direcção �i aproximadamente igual a �1, outra constituída pelos pixels que apresentem um valor de amplitude Ai igual ou superior a um dado limiar e cuja direcção �i seja aproximadamente igual a �2, outra constituída pelos pixels que apresentem um valor de amplitude Ai igual ou superior a um dado limiar e cuja direcção �i seja aproximadamente igual a �3 e outra constituída pelos pixels que apresentem um valor de amplitude Ai igual ou superior a um dado limiar e cuja direcção �i seja aproximadamente igual a �4.

5) Determinar as linhas rectas constituídas pelos lados das figuras geométricas na classe C1 sendo esta determinação efectuada do seguinte modo:

a) Determinar o primeiro elemento da classe C1 não considerado e classificá-lo como considerado.

b) Definir a recta que passa pelo ponto anteriormente determinado e que tem direcção igual a �1 .

c) Determinar o próximo ponto na classe C1 ainda não considerado que pertence à linha recta determinada no passo anterior , tendo por base que a distância do ponto à linha terá que ser menor que um determinado limiar pré-definido

d) Retornar a ii) até ser atingido o último elemento da classe C1. e) Realizar a regressão linear dos pontos classificados como pertencentes a uma

determinada linha, se o número destes for superior a um dado limiar, de modo a eliminar falsas linhas.

f) determinar uma nova, linha voltando ao ponto i) até não existirem mais elementos na classe C1 ainda não considerados.

6) Determinar as linhas rectas constituídas pelos lados das figuras geométricas na classe C2 do mesmo modo como foi efectuado para a classe C1 considerando no entanto �2 em vez de �1 .

7) Determinar as linhas rectas constituídas pelos lados das figuras geométricas na classe C3 do mesmo modo como foi efectuado para a classe C1 considerando no entanto �3 em vez de �1 .

8) Determinar as linhas rectas constituídas pelos lados das figuras geométricas na classe C4 do mesmo modo como foi efectuado para a classe C1 considerando no entanto �4 em vez de �1 .

9) Determinar qual a classes com mais e menos rectas, sendo que a classe com mais linhas rectas corresponde às linhas rectas na vertical e a classe com menos linhas rectas corresponde às linhas rectas oblíquas do triângulo, tal como pode ser constatado na figura dasd. Desta maneira são duas as classes que contêm este valor mínimo. Por exclusão a classe com um valor médio de linhas rectas contém as linhas rectas na direcção horizontal.

10) Determinar a intersecção das linhas obtidas entre as classes que contém os valores mínimos de linhas rectas (esta intersecção irá resultar nos vértices dos triângulos).

11) Definir os pontos de intersecção, determinados no passo anterior como pontos pertencentes a um triângulo (sendo colocados na imagem final a uma intensidade pré – definida exclusiva do triângulo).

12) Determinar a intersecção das linhas obtidas entre as classes que contém os valores mínimos e a classe que contém o valor médio de linhas rectas (esta intersecção irá resultar nas bases dos triângulos).

13) Definir os pontos de intersecção, determinados no passo anterior como pontos pertencentes a um triângulo.

14) Determinar a intersecção das linhas obtidas entre a classe que contém o valor máximo e a classe que contém o valor médio de linhas rectas (esta intersecção irá resultar nos restantes pontos de intersecção).

15) Determinar os pontos que correspondem a falsas intersecções. 16) Definir os pontos de intersecção, contidos num rectângulo imaginário definido pelos pontos

resultante das falsas intersecções, como pontos pertencentes à cruz (sendo colocados na imagem final a uma intensidade pré – definida exclusiva do cruz).

90

Page 100: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

17) Definir os restantes pontos de intersecção, à excepção dos pontos resultante das falsas intersecções, como pontos pertencentes ao quadrado (sendo colocados na imagem final a uma intensidade pré – definida exclusiva do quadrado).

2.4.3 - Emparelhamento de pontos característicos O emparelhamento dos pontos característicos consiste basicamente na classificação unívoca dos pontos de uma imagem, isto é, os pontos pertencentes ao alvo dimensionado no ponto 2.4.2.1 tem que ser classificados sempre da mesma forma, independentemente do tamanho das formas geométricas, translações e rotações a que sejam sujeitos. Assim qualquer imagem, contendo o alvo dimensionado, que seja submetida à implementação de emparelhamento o resultado desta implementação será sempre um vector de pontos devidamente ordenado por figuras geométricas, sendo também feita uma etiquetagem dos pontos, identificando a posição que estes ocupam dentro da figura geométrica. Assim a etiquetagem que é realizada é ilustrada na figura 4.31.

Figura 4.31 – Etiquetagem realizadas no alvo dimensionado para a detecção. A amarelo encontra-se a etiquetagem

realizada no quadrado, a azul nos triângulos e a verde na cruz.

Conforme é visível na figura 4.31 a etiquetagem é realizada por figura geométrica detectada. O processo de etiquetagem é feito da seguinte forma:

1) Procurar todos os pontos identificados como pertencente aos triângulos. 2) Identificar os vértices dos triângulos. 3) Classificar como T1 aquele que se encontrar mais perto da falsa detecção da cruz do canto

superior direito. 4) Classificar T2, T3 e T4 os pontos pertencentes à linha recta que vai desde o vértice T1 até ao

vértice do lado esquerdo da base. 5) Classificar T5, T6 e T7 os pontos pertencentes à linha recta que vai desde o vértice T1 até ao

vértice direito da base. 6) Classificar como T8 o vértice do segundo triângulo 7) Classificar T9, T10 e T11 os pontos pertencentes à linha recta que vai desde o vértice T8 até

ao vértice do lado esquerdo da base. 8) Classificar T12, T13 e T14 os pontos pertencentes à linha recta que vai desde o vértice T8 até

ao vértice do lado esquerdo da base. 9) Procurar todos os pontos identificados como pertencente ao quadrado. 10) Classificar Q1 o ponto que pertence à linha recta de T4 e cuja distância a este é inferior do que

a distância do outro ponto do quadrado pertencente também à linha recta de T4. 11) Classificar Q2 o outro ponto do quadrado pertencente à mesma linha recta de T4. 12) Classificar Q3 e Q4 seguindo a mesma filosofia dos pontos 10 e 11, excepto no facto dos

pontos do quadrado necessitarem de pertencer à linha recta de T3. 13) Classificar Q5 e Q6 seguindo a mesma filosofia dos pontos 10 e 11, excepto no facto dos

pontos do quadrado necessitarem de pertencer à linha recta de T2. 14) Classificar Q7 e Q8 seguindo a mesma filosofia dos pontos 10 e 11, excepto no facto dos

pontos do quadrado necessitarem de pertencer à linha recta de T1. 15) Procurar todos os pontos identificados como pertencente à cruz. 16) Classificar C1 o ponto que pertence à linha recta de T4 e cuja distância a este é inferior do que

a distância do outro ponto da cruz pertencente também à linha recta de T4.

91

Page 101: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

17) Classificar C2 o outro ponto da cruz pertencente à mesma linha de T4. 18) Classificar C3, C4, C5 e C6 seguindo a mesma filosofia dos pontos 10 e 11, excepto no facto

de serem calculadas e analisadas quatro distâncias ao ponto T3 e também é condição os pontos da cruz necessitarem de pertencer à linha recta de T3.

19) Classificar C7, C8, C9 e C10 seguindo a mesma filosofia dos pontos 10 e 11, excepto no facto de serem calculadas e analisadas quatro distâncias ao ponto T2 e também é condição os pontos da cruz necessitarem de pertencer à linha recta de T2.

20) Classificar C11 e C12 seguindo a mesma filosofia dos pontos 10 e 11, excepto no facto dos pontos do quadrado necessitarem de pertencer à linha recta de T1.

2.4.4 Obtenção de informação tridimensional 2.4.4.1 Principio da triangulação estereoscópica

A obtenção de informação tridimensional de uma cena é essencial para a estimação de movimento a que este projecto se propõe. Assim a solução escolhida para o fazer foi o uso de duas câmaras que obtêm imagens distintas de uma cena, conhecendo-se os parâmetros intrínsecos e extrínsecos das câmaras utilizadas para a aquisição de imagem é possível obter informação tridimensional a partir da resolução do sistema de projecção estereo para os pontos característicos previamente detectados e emparelhados (ver 2.4.2 e 2.4.3).

Nesta secção é apresentado o método que foi utilizado para obter a informação tridimensional a partir do conhecimento das coordenadas de pontos característicos previamente detectados e emparelhados.

Quando se pretende obter informação tridimensional de uma cena a partir de imagens distintas da mesma , é necessário o conhecimento prévio do modelo da câmara utilizada. Assim é necessário do modo comos os pontos tridimensionais são transformados em pontos no plano da imagem. O conhecimento destes parâmetros resulta do processo de calibração da câmara. A calibração é norma geral efectuada uma vez e independentemente, devendo ser efectuada de novo apenas se o posicionamento das câmaras ou qualquer outro tipo de factores alterar a conjuntura do sistema. Assim um ponto P no sistema de coordenadas 3D mundo é transformado num ponto 2D no sistema do plano de imagem por uma dada matriz de transformação global determinada através da calibração da câmara,. A equação global que traduz esta transformação global para um ponto P em coordenadas homogéneas, para um dada câmara para a posição e orientação k, é:

����

����

���

���

1

MPPLw

w

w

Lu

Lu

zyx

wwYwX

em que MPPL=

����

����

34333231

24232221

14131211

aaaa

aaaa

aaaa

(wXu

L, wYuL, w) - são as coordenadas homogéneas não distorcidas do ponto P no sistema 2D do

plano imagem da câmara para a posição e orientação L. (xu, yu, zu, 1) - são as coordenadas homogéneas do ponto P no sistema 3D mundo. MPPL - é a matriz não invertível da transformação global da mesma câmara para a posição e

orientação L. Analisando os dados anteriores facilmente se pode verificar que não é possível obtermos as

coordenadas 3D do ponto P no sistema mundo apenas com as coordenadas do mesmo no sistema 2D do plano imagem, pois temos quatro incógnitas - xu, yu, zu, e w - para três equações. Assim necessitamos das coordenadas do mesmo ponto no sistema 2D do plano da imagem para outra posição e orientação. Ou seja com o sistema de equações anterior e o seguinte, obtido com a segunda câmara conseguimos obter as coordenadas 3D do sistema mundo do ponto P pois passamos a ter um sistema de equações sobre determinado.

92

Page 102: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

����

����

���

���

1

MPPRw

w

w

Ru

Ru

zyx

wwYwX

em que MPPR=

����

����

34333231

24232221

14131211

bbbb

bbbb

bbbb

(wXu

R, wYuR, w) - são as coordenadas homogéneas não distorcidas do ponto P no sistema 2D do

plano imagem da câmara para a posição e orientação R. (xu, yu, zu, 1) - são as coordenadas homogéneas do ponto P no sistema 3D mundo. MPPR - é a matriz não invertível da transformação global da mesma câmara para a posição e

orientação R. Fazendo uso das equações obtidas para R e L obtemos então um sistema de equações lineares

sobre determinado (sistema de projecção stereo) :

�����

�����

���

��

������

���

���

���

���

������

2434

1434

2434

1434

332332223121

331332123111

332332223121

331332123111

bYbbXb

aYaaXa

zyx

YbbYbbYbb

XbbXbbXbb

YaaYaaYaa

XaaXaaXaa

Ru

Ru

Lu

Lu

w

w

w

Ru

Ru

Ru

Ru

Ru

Ru

Lu

Lu

Lu

Lu

Lu

Lu

Trata-se de um sistema com quatro equações lineares para três incógnitas onde intervêm apenas

as coordenadas 2D não distorcidas do ponto P no plano imagem e as matrizes de transformação global da câmara para as posições L e R. Este sistema pode ser resolvido em ordem às três incógnitas utilizando por exemplo o método dos mínimos quadrados com decomposição em valor único ou de Cholesky.

De notar que as duas posições e orientações devem fazer entre si uma disparidade estereoscópica aceitável de modo a que a resolução do sistema anterior corresponda a soluções o mais precisas possíveis. 2.4.4.2 Implementação desenvolvida

A extracção de coordenadas 3D de pontos, seguindo o principio da triangulação estereoscopica, cujas coordenadas 2D do frame buffer são conhecidas, foi a funcionalidade. Ou seja a partir dos pontos obtidos e emparelhados por meio de etiquetagem na detecção e emparelhamento dos pontos característicos explicado nos capítulos 2.4.2 e 2.4.3 podemos obter as respectivas coordenadas 3D.

Assim o algoritmo desenvolvido para a obtenção da informação tridimensional efectua dois passos:

��Determinação das coordenadas imagem não distorcidas para cada ponto característico emparelhado, a partir das suas coordenadas na memória frame, para a primeira e segunda posição e orientação da câmara.

��Determinação das coordenadas 3D para o respectivo ponto.

2.4.5 Software desenvolvido 2.4.5.1 Comprovação dos algoritmos desenvolvidos

Nesta secção demonstra-se que os algoritmos desenvolvidos funcionam correctamente, pelo seu

uso em condições onde à partida sabemos a solução verificando se de facto o algoritmo nos fornece a solução esperada. 1) Detecção dos pontos característicos Neste ponto será demonstrada que a detecção do alvo dimensionado no ponto 2.4.3 é unívoca, sendo imune a translações, rotações e tamanhos diferentes dos objectos, diferenciando assim todas as

93

Page 103: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

figuras geométricas, sendo cada classe de figuras representadas com uma cor diferente e exclusiva dessa classe. Desta maneira esta implementação será testada através da detecção destas entidades presentes nas imagens ilustradas na figura 4.32. De notar que as duas imagens apenas têm em comum o facto de possuírem as mesmas figuras geométricas.

a) b)

Figura 4.32 – Imagens de teste criadas para testar o algoritmo de detecção das

entidades presentes em cada imagem.

Aplicando estas imagens à implementação de detecção com os parâmetros indicados na figura 4.18 b), o resultado foi o ilustrado na figura 4.33. De notar que os parâmetros iniciais são submetidos à implementação através do mesmo interface utilizado aquando da detecção dos pontos de calibração na memória frame, dado que, as filosofias de detecção das duas implementações são idênticas. Através da análise da figura 4.33, constata – se que o resultado da implementação de detecção de entidades características presentes numa imagem foi idêntico para as duas imagens ilustradas na figura 4.32. De notar que cada uma das classes de figuras geométricas é representada com um valor diferente de todas as outras classes, facilitando assim o posterior processamento destas imagens assim como uma melhoria em termos de visualização. Desta maneira concluiu – se que a implementação de detecção é bastante robusta e flexível.

b)a)

Figura 4.33 – Resultado da implementação de detecção de entidades características

nas imagens de teste. a) Resultado da imagem de teste da figura 4.32 a) e b) resultado da imagem de teste da figura 4.32 b)

2) Emparelhamento

94

Page 104: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

Neste ponto irá ser feita a demonstração do algoritmo de emparelhamento definido no ponto 2.4.3. Este emparelhamento, como já foi referido, é de extrema importância para o cálculo de coordenadas 3D devido ao facto de que neste cálculos necessitamos de saber para um dado ponto numa imagem aonde é que esse mesmo ponto se encontra na outra imagem. Desta maneira criaram-se duas imagens de teste para ser o par de imagens em que é necessário executar o emparelhamento descrito. De notar que as duas figuras apenas têm em comum as mesmas figuras geométricas, sendo que estas imagens têm orientações diferentes e translações diferentes. Desta maneira será provado a flexibilidade, robustez e eficácia da implementação desenvolvidas. Assim submetendo as imagens de teste ilustradas na figura 4.35 à implementação de emparelhamento obtiveram-se os resultados apresentados na tabela 5.

[b][a]

Figura 4.35 – Imagens de teste criadas para teste do algoritmo de emparelhamento.

[b] [a]

Xf: Yf: Object: 698 148 T1 729 202 T2 761 255 T3 792 310 T4 676 207 T5 655 265 T6 633 324 T7 172 194 T8 203 248 T9 234 301 T10 266 355 T11 150 252 T12 129 311 T13 107 369 T14 541 332 C1 488 336 C2 589 270 C3 536 275 C4 483 280 C5 431 284 C6 584 215 C7 531 219 C8 478 224 C9 426 228 C10 526 163 C11 473 168 C12 396 344 Q1 292 353 Q2 391 288 Q3 287 297 Q4 387 232 Q5 282 241 Q6 382 176 Q7 277 185 Q8

Xf: Yf: Object: 682 149 T1 703 207 T2 725 266 T3 746 325 T4 650 203 T5 619 256 T6 588 311 T7 143 102 T8 164 161 T9 186 219 T10 207 278 T11 111 156 T12 80 210 T13 49 264 T14 509 304 C1 456 299 C2 567 252 C3 514 247 C4 461 243 C5 408 238 C6 572 196 C7 519 191 C8 466 187 C9 413 182 C10 524 136 C11 471 131 C12 338 289 Q1 233 280 Q2 343 232 Q3 238 223 Q4 348 177 Q5 243 167 Q6 352 121 Q7 248 112 Q8

Tabela 5 – Conjunto de pontos classificados a) da imagem de teste da figura 4.35 a) e b) da imagem de

teste da figura 4.35 b).

95

Page 105: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

Através da observação dos valores apresentados na tabela 5, conclui –se queo algoritmo classifica os pontos caractrísticos da cada imagem sempre da mesma maneira, independentemente da direcção, translação e tamanho que as formas geométricas possam apresentar. A classificação destes pontos é idêntica à descrita no ponto 2.4.3. 3) Obtenção das coordenadas 3D Usando como parâmetros de referência: dx= 0.00837766 dy= 0.0080756 Cx= 256 Cy= 256 sx = 0.710935 Para a câmara na posição 1( Left ou L ) usamos a seguinte matriz de transformação

MPPL= e com o ponto a ter as coordenadas de buffer (195, 301)

����

����

6.002.000

15010

55001

Para a câmara na posição 2 ( Right ou R ) usamos a seguinte matriz de transformação

MPPR= e com o ponto a ter as coordenadas de buffer (193, 179)

����

����

202.000

55010

55001

E para ambas as câmaras f = 50 (Distância focal) k = 0.001 (Distorção radial da lente) Obtivemos o seguinte resultado:

(39.94, 30.07, 2103.32)

Sabendo que o ponto tem de coordenadas (40, 30, 2100) podemos comparar o resultado obtido (39.94, 30.07, 2103.32) verificando que os resultados obtidos são bons com uma precisão bastante aceitável.

2.4.5.2 - Implementação do software

Neste capítulo será referida a implementação do módulo que nos permite efectuar as seguintes funções:

��Detecção dos pontos característicos do alvo a colocar sobre o paciente. ��Emparelhamento dos pontos do alvo a colocar sobre o paciente detectados, obtidos a partir de

duas câmaras em locais diferentes (sistema stereo de aquisição) ��Obtenção das coordenadas 3D dos pontos do alvo a partir das suas coordenadas imagem 2D

As três funções referidas anteriormente são todas utilizadas de um modo sequencial permitindo obter

a partir de um conjunto de pares de imagens, previamente adquiridas pelo sistema stereo calibrado, as

96

Page 106: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

coordenadas dos pontos 3D do alvo que se encontra nesses mesmos pares de imagens. Fornecendo assim a informação necessária para a posterior detecção e correcção do movimento efectuado.

Este módulo tem como parâmetros de entrada dados que foram adquiridos e calculados em módulos anteriores do software desenvolvido tais como a calibração e a aquisição.

��As matrizes de transformação de cada câmara. ��A distância focal e distorção radial da lente para cada câmara. ��Os parâmetros dx, dy, cx, cy, sx do sistema. ��Número de pares de imagem a considerar para detecção de alvo.

E posteriormente após introdução dos parâmetros da aquisição as imagens:

��O conjunto de pares de imagem nas quais se pretende fazer a detecção dos pontos característicos de um modo ordenado.

Introdução dos parâmetros da aquisição

Assim quando é iniciado o módulo detecção e cálculo de coordenadas 3D é necessário introduzir os parâmetros de configuração, do sistema que foi utilizado para a aquisição das imagens do alvo a considerar, para a detecção dos pontos característicos do alvo nas imagens de ambas as câmaras utilizadas.

A introdução dos parâmetros pode ser efectuada de 3 modos: i) Manualmente - Os parâmetros são introduzidos pelo utilizador um a um de acordo com os

valores pretendidos pelo mesmo. ii) Usando os valores de default - Os parâmetros são todos automaticamente introduzidos de

acordo com os valores que se encontram configurados como sendo os de pré-definição ou se o processo de calibração tiver sido efectuado anteriormente os parâmetros de pré-definição serão automaticamente actualizados com os valores determinados nesse processo.

iii) Por leitura do ficheiro obtido na calibração do sistema , ficheiro este onde se encontra toda a informação necessária para a câmara em questão.

Os parâmetros introduzidos

são: 1 - A matriz de transformação de cada câmara ( Com a designação genérica de Câmara esquerda/Câmara direita) 2 - Os parâmetros dx- Distância entre centro dos elementos sensores vizinhos na direcção x. dy- distância entre centro dos sensores CD vizinhos na direcção y. cx- Coordenada do centro da imagem na memória frame segundo a direcção x.

Figura 4.36 – Interface utilizador / implementação de aquisição de informação 3D

cy- Coordenada do centro da imagem na memória frame segundo a direcção y. sx- Factor de escala que compensa incertezas no escalamento efectuado pelo frame grabber na linha de scan horizontal.

Todos estes parâmetros são essenciais de modo a referenciar os pontos a um referencial comum tendo em atenção as características das câmaras utilizadas no processo bem como as suas posições relativas. Assim tendo estes dados só nos falta referirmos os pontos cujas coordenadas 3D queremos calcular, em dois referenciais imagem diferentes de modo a calcular as suas coordenadas 3D.

O próximo passo permite-nos organizar as imagens obtidas anteriormente da forma que desejarmos de modo a detectar posteriormente os movimentos efectuados em relação a uma posição inicial, para o número de pares de imagens desejado.

Assim encontrando-se as imagens em processo de visualização na aplicação seleccionando a imagem desejada e posteriormente a referência com a qual a queremos corresponder, iremos activar o

97

Page 107: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

processo de detecção e emparelhamento dos pontos característicos do alvo que se encontram localizados na imagem seleccionada. Utilizando o interface ilustrado na figura 4.17 procede –se à detecção dos

pontos característicos. Tal procedimento deverá ser efectuado para cada imagem de

cada par, indicando qual a câmara utilizada para a sua aquisição e o número associado ao par de imagem. Será dada uma indicação visual de quais os passos efectuados para todos os pares de imagens, possibilitando ao utilizador saber a cada passo o que foi feito e o que se encontra ainda por fazer. Após o processo de detecção e emparelhamento para cada par de imagens deverá ser seleccionada a opção para obtenção de coordenadas 3D. Após ter efectuado o processo de detecção e emparelhamento e o processo de obtenção de coordenadas 3D para cada par de imagens deverá ser seleccionado qual o par de imagens a funcionar de referência para as outras imagens, de modo ao próximo módulo poder referir a estimação de movimento a um par de

imagens referência, a partir do qual o processo de estimação de movimento se desenrola. Após todo este procedimento será pedido ao utilizador o nome e local do ficheiro para gravação em disco, da informação 3D dos pontos característicos para cada par de imagens considerado.

Figura 4.37 – Detecção, Emparelhamento e determinação de

coordenadas 3D

Alguns resultados experimentais

Nesta secção é apresentada uma demonstração processo de detecção, emparelhamento e obtenção de coordenadas 3D.Para tal calibrando o sistema de câmaras para aquisição das imagens do alvo obtivemos as seguintes características:

Câmara 1 (Left)

sx=0.710935 dx=0.0098, dy=0.0063 Cx=384 Cy=288 Rotation matrix R: +0.999861 +0.00199077 -0.0165767 +0.00426899 +0.929377 +0.369107 +0.0161408 -0.369127 +0.929239 Translation vector T: +4.41629 +8.03637 +7651.30 Focal length f: +119.501 Radial lens distortion k1: -0.00376823

Câmara 2 (Right) sx=0.710935 dx=0.0098, dy=0.0063 Cx=384 Cy=288 Rotation matrix R: +0.999308 +0.0371327 +0.00225636 -0.0339079 +0.934115 -0.355358 -0.0153031 +0.355035 +0.934728 Translation vector T: -10.8022 -5.69796 +6696.77 Focal length f: +106.308 Radial lens distortion k1: +0.000896936

Tabela 6 – Resultado da calibração dos parâmetros intrínsecos e

extrínsecos das duas câmaras De seguida foram capturadas as imagens do alvo a partir das duas câmaras, obtendo as seguintes

imagens:

98

Page 108: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

Figura 4.38 – Aquisição simultânea das duas câmaras do alvo a detectar.

Tendo os dados necessários ao processo pudemos iniciá-lo obtendo os seguintes resultados em

termos de detecção e emparelhamento de pontos característicos das imagens alvo:

Figura 4.39 – Detecção e emparelhamento dos alvos detectados na figura 4.38

E assim o resultado obtido em termos de coordenadas 3D é gravado em ficheiro, contendo este

ficheiro a seguinte informação:

Results for the 3D coordinates algorithm. Number of Image Pairs: 1 . 3D Coordinates for Image Pair number: 1 X coord Y coord Z coord TAG 138.351 -50.9643 3.20956 T1 137.561 -34.3583 0.703536 T2 136.685 -16.7062 -2.01538 T3 135.536 -0.737885 -4.91216 T4 139.016 -34.5084 2.27125 T5 139.642 -16.9075 1.28916 T6 140.251 -0.367107 0.158014 T7 -35.6267 -51.2443 1.37772 T8 -35.1206 -33.846 2.6109 T9 -34.8579 -17.7769 1.59176 T10 -34.352 -0.615183 3.22706 T11 -36.577 -33.5109 5.40251 T12 -36.6713 -17.6647 5.57182 T13 -37.8389 0.362267 8.54108 T14 83.1033 -0.47082 0.542053 C1 67.2671 -0.178348 1.36295 C2 …

... 98.9584 -16.9301 0.187258 C3 83.1823 -17.2021 0.92416 C4 67.3396 -17.1955 0.974594 C5 51.4554 -17.1812 1.08141 C6 98.7647 -34.1955 0.57735 C7 83.507 -33.9303 1.2291 C8 67.6676 -33.932 1.2602 C9 51.5209 -33.9391 1.31269 C10 83.563 -51.1969 1.54532 C11 67.7109 -50.9323 0.813521 C12 36.0072 -0.39406 2.34608 Q1 3.83225 -0.344682 4.15349 Q2 36.0801 -17.4369 1.87608 Q3 3.89533 -17.3945 2.23403 Q4 36.1337 -33.9255 1.37334 Q5 3.95507 -33.6268 2.41878 Q6 36.1891 -50.9494 0.842789 Q7 4.02333 -50.9323 1.13632 Q8

Tabela 7 – Coordenadas 3D dos pontos característicos dos alvos da figura 4.38.

99

Page 109: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

A análise e discussão dos resultados obtidos bem como a sua adequação à realidade serão tratados no Capitulo V. 2.5 – Estimação do movimento e correcção das imagens de medicina nuclear 2.5.1 - Introdução A estimação de movimento do paciente durante o exame baseia-se nas coordenadas mundo dos pontos característicos do alvo a colocar sobre o paciente. Partimos do pressuposto de que o paciente efectua apenas movimento simples de translação e rotação no plano paralelo ao plano de calibração. Ignoramos assim a componente de profundidade das coordenadas (z) projectando os pontos no plano que é paralelo ao plano de calibração que por sua vez será colocado paralelamente à mesa sobre a qual se encontra o paciente. A componente de profundidade das coordenadas dos pontos característicos do alvo terá interesse para a aplicação em trabalhos futuros. A correcção das imagens resultantes dos exames SPECT usará a informação obtida pela estimação de movimento para corrigir a posição das imagens de exame efectuando a respectiva translação e rotação calculados para as imagens do alvo colocado sobre o paciente, obtidas pelo sistema estereo de aquisição de imagem. Partimos assim do pressuposto que existe um movimento rígido do órgão que se pretende visualizar e que este movimento é o mesmo que o efectuado pelo alvo colocado sobre o paciente. 2.5.2 - Método O método utilizado faz uso das coordenadas em x e em y dos pontos característicos para calcular o centro geométrico de cada sólido identificado no alvo a colocar sobre o paciente. É ignorada a componente em profundidade uma vez que a projecção dos pontos característicos sobre um plano paralelo ao plano de calibração corresponde simplesmente a ignorar a profundidade, uma vez que o sistema de coordenadas tem o seu plano x-origem-y paralelo ao plano de calibração. Assim são calculadas as coordenadas dos pontos P1, P2, P3, P4 que são os centros geométricos dos sólidos, que teoricamente se encontram sobre a mesma recta no espaço 3D, e consequentemente também no espaço 2D.

P4 P2 P3 P1

Figura 4.40 – Localização dos centros geométricos das figuras.

As coordenadas dos pontos são calculadas da seguinte forma: P1

Fazendo uso das coordenadas dos pontos T8,T9,T10,T11,T12,T13,T14: 1º) Calculamos as coordenadas do ponto médio do segmento de recta definido por T12 e T9 e também as coordenadas do ponto médio do segmento de recta definido por T13 e T10, para de seguida calcular as coordenadas do ponto médio do segmento de recta definido pelos dois pontos

100

Page 110: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

anteriormente calculados. Assim obtemos uma primeira estimativa das coordenadas do ponto central do triângulo.

2º ___

1º ___

2º) Calculamos as coordenadas do ponto médio do segmento de recta definido pelos pontos T14 e T11, calculando de seguida as coordenadas do ponto médio do segmento de recta definido pelos pontos T8 e pelo ponto calculado anteriormente. Assim obtemos uma segunda estimativa das coordenadas do ponto central do triângulo.

3º) Minimiza-se o erro associado ao cálculo das coordenadas do ponto central da figura fazendo a média das coordenadas das duas estimativas calculadas anteriormente, obtendo assim as coordenadas para o ponto P1. Figura 4.41 – Centro

geométrico P1 P2

Fazendo uso das coordenadas dos pontos Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8: 1º) Calculamos as coordenadas do ponto médio do segmento de recta definido por Q6, e Q5, e

também as coordenadas do ponto médio do segmento de recta definido por Q4 e Q3, para de seguida calcular as coordenadas do ponto médio do segmento de recta definido pelos dois pontos anteriormente calculados. Assim obtemos uma primeira estimativa das coordenadas do ponto central do quadrado. 2º ___

1º ___

2º) Calculamos as coordenadas do ponto médio do segmento de recta definido pelos pontos Q8 e Q2, calculando de seguida as coordenadas do ponto médio do segmento de recta definido pelos pontos Q7 e Q1. , para finalmente calcular as coordenadas do ponto médio do segmento de recta definido pelos dois pontos anteriormente calculados. Assim obtemos uma segunda estimativa das coordenadas do ponto central do quadrado. 3º) Minimiza-se o erro associado ao cálculo das coordenadas do ponto central da figura fazendo a média das

coordenadas das duas estimativas calculadas anteriormente, obtendo assim as coordenadas para o ponto P2. É de notar que a direcção dos segmentos de recta utilizados para calcular os pontos médios no 1º e 2º passo são propositadamente diferentes de modo a minimizar erros que possam existir associados a uma das direcções.

Figura 4.42 – Centro geométrico P2

P3 Fazendo uso das coordenadas dos pontos C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12: 1º) Calculamos as coordenadas do ponto médio do segmento de recta definido por C12, e C11, e também as coordenadas do ponto médio do segmento de recta definido por C1 e C2, para de seguida calcular as coordenadas do ponto médio do segmento de recta de finido pelos dois pontos anteriormente calculados. Assim obtemos uma primeira estimativa das coordenadas do ponto central da cruz. 2º) Calculamos as coordenadas do ponto médio do segmento de recta definido pelos pontos C10 e C6, calculando de seguida as coordenadas do ponto médio do segmento de recta definido pelos pontos C7 e C3. , para finalmente calcular as coordenadas do ponto médio do segmento de recta definido pelos dois pontos anteriormente calculados. Assim obtemos uma segunda estimativa das coordenadas do ponto central da cruz. 3º Calculamos as coordenadas do ponto médio do segmento de recta definido pelos pontos C9 e C8, calculando de seguida as coordenadas do ponto médio do segmento de recta definido pelos pontos C5 e C4. , para de seguida calcular as coordenadas do ponto médio do segmento de recta

101

Page 111: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

definido pelos dois pontos anteriormente calculados. Assim obtemos uma terceira estimativa das coordenadas do ponto central da cruz.

3º ___

2º ___

1º ___

4º) Minimiza-se o erro associado ao cálculo das coordenadas do ponto central da figura fazendo a média das coordenadas das três estimativas calculadas anteriormente, obtendo assim as coordenadas para o ponto P3. É de notar que a direcção dos segmentos de recta utilizados para calcular os pontos médios no 1º,2º e 3º passo são propositadamente diferentes de modo a minimizar erros que possam existir associados a uma das direcções. Neste caso a precisão obtida é ainda maior uma vez que este ponto será o ponto que servirá de base para calcular a translação associada ao alvo, tal como explicado a seguir. Figura 4.43 – Centro

geométrico P3

P4

Fazendo uso das coordenadas dos pontos T1,T2,T3,T4,T5,T6,T7 procede-se exactamente da mesma forma que para P1 , fazendo a correspondência entre os pontos característicos do primeiro com o segundo triângulo.

Este processo de cálculo de coordenadas 3D é efectuado para o conjunto de pontos característicos de referência, ou seja o conjunto de pontos característicos da imagem adquirida inicialmente pelo sistema stereo de aquisição, e de seguida é efectuado para o conjunto de pontos característicos associados a outro instante desejado que não o inicial. Ao movimento do alvo é associado um movimento composto de translação e de rotação. Neste algoritmo primeiro é calculado a translação correspondente ao ponto P3 , que é o ponto cujas coordenadas possuem a maior precisão de cálculo, tal como explicado anteriormente. De seguida calculamos a rotação dos restantes pontos (P1, P2 e P4) em torno do eixo perpendicular ao plano e que passa pelo ponto P3. Tal é efectuado do seguinte modo :

��Efectuamos o cálculo das coordenadas dos pontos P1, P2, P3 e P4 (no plano 2D) para os dois conjuntos de pontos.

��È calculado a translação em x e em y da imagem tendo como referência a diferença de coordenadas do ponto P3 em ambos os conjuntos de pontos

��É calculado o declive dos segmentos de recta formados por P3 e P1 , P1 e P4 e P2 e P4 em ambos os conjuntos de pontos. Pretende-se com isto determinar o declive das rectas que passam pelos ponto P1, P2, P3 e P4 nos dois conjuntos de pontos, minimizando em cada um os possíveis erros associados ao cálculo das coordenadas desses mesmos pontos.

��Fazendo uso dos dois declives calculados respectivamente para cada conjunto de pontos, verificamos a diferença angular existente entre ambas, sendo esse o valor da rotação a efectuar.

A correcção das imagens finais é efectuada tendo em atenção os parâmetros que resultam da detecção de movimento. As funções utilizadas para a translação e rotação das imagens são simples funções de translação de imagens seguindo o método do nearest-neighbour para efectuar a interpolação de valores, e preenchendo o background com a cor preta à medida que efectua as operações. A translação segundo o eixo dos x, a translação segundo o eixo dos y e o ângulo de rotação em torno do ponto calculado. As coordenadas do eixo de rotação são introduzidas pelo utilizador uma vez que foi impossível efectuar um exame clínico analisando a correspondência entre o sistema de coordenadas utilizado como referencial mundo e a aquisição dos exames SPECT. Este assunto será debatido nos capitulo posteriores.

102

Page 112: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

2.5.3 Software desenvolvido 2.5.3.1 Comprovação dos algoritmos desenvolvidos Para comprovar a funcionalidade do algoritmo desenvolvido fornecesse dois conjuntos de dados compilados ao algoritmo de modo a comparar o resultado obtido com o esperado. Assim como ponto de partida utilizamos o seguinte esquema, que foi obtido por rotação do alvo de 45º e por translação do mesmo de modo ao vértice do quadrado se localizar na origem do sistema de coordenadas, resultando numa translação de 1.535 cm segundo o eixo dos x e de -6.363 cm segundo o eixo dos. Assim foi feito o cálculo das coordenadas dos pontos característicos, ilustrado na tabela 8.

x y x yT1 7 -2 T1 5.656 -11.312T2 7.5 -1 T2 6.7165 -10.9585T3 8.5 1 T3 8.8375 -10.2515T4 9 2 T4 9.898 -9.898T5 6.5 -1 T5 6.0095 -10.2515T6 5.5 1 T6 6.7165 -8.1305T7 5 2 T7 7.07 -7.07T8 -8 -2 T8 -4.949 -0.707T9 -7.5 -1 T9 -3.8885 -0.3535T10 -6.5 1 T10 -1.7675 0.3535T11 -6 2 T11 -0.707 0.707T12 -8.5 -1 T12 -4.5955 0.3535T13 -9.5 1 T13 -3.8885 2.4745T14 -10 2 T14 -3.535 3.535C1 3 2 C1 5.656 -5.656C2 1 2 C2 4.242 -4.242C3 4 1 C3 5.656 -7.07

x y x yC4 3 1 C4 4.242 -6.363C5 1 1 C5 2.828 -4.949C6 0 1 C6 2.828 -4.242C7 4 -1 C7 4.242 -8.484C8 3 -1 C8 2.828 -7.777C9 1 -1 C9 1.414 -6.363C10 0 -1 C10 1.414 -5.656C11 3 -2 C11 2.828 -8.484C12 1 -2 C12 1.414 -7.07Q1 -1 2 Q1 2.828 -2.828Q2 -5 2 Q2 0 0Q3 -1 1 Q3 2.121 -3.535Q4 -5 1 Q4 -0.707 -0.707Q5 -1 -1 Q5 0.707 -4.949Q6 -5 -1 Q6 -2.121 -2.121Q7 -1 -2 Q7 0 -5.656Q8 -5 -2 Q8 -2.828 -2.828

Tabela 8 – Cálculo das coordenadas dos pontos característicos

Tendo como resultados: Translação segundo o eixo dos x: 1.535 Translação segundo o eixo dos y: -6.363 Rotação em ângulos: 49.9999 º

Os resultados obtidos confirmaram assim o que era esperado, devemos no entanto notar que estes cálculos são exactos como seria de esperar uma vez que foram utilizados coordenadas de pontos característicos exactas.

103

Page 113: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo IV - Sistema Desenvolvido

De seguida apresentamos o resultado utilizando coordenadas para os pontos característicos com alguns erros, na ordem de alguns milímetros aleatoriamente distribuídos:

1º Teste Translação segundo o eixo dos x: 1.447 (5%) Translação segundo o eixo dos y: -6.451 (1%)

Rotação em ângulos: 46.23º (2.7%) 2º Teste - Introduzindo ainda mais erros aleatoriamente Translação segundo o eixo dos x: 1.606 (4,6%) Translação segundo o eixo dos y: -6.452 (1%)

Rotação em ângulos: 46.47º (3%) Verificamos que mesmo assim os erros obtidos são aceitáveis, provando a robustez do algoritmo

e que os erros cancelam-se parcialmente devido à filosofia do método desenvolvido. 2.5.3.2 - Implementação da estimação de movimento e correcção A estimação e correcção surgem no seguimento do processo de detecção e obtenção de informação tridimensional. Os valores obtidos pelo processo de detecção e obtenção de informação tridimensional ficam em memória sendo utilizados pelo processo de estimação e correcção de movimento. Neste processo é possível indicar o número de referência do conjunto de pontos cujo movimento em relação ao conjunto de pontos de referência pretendemos, surgindo a indicação dos valores de translação segundo os eixos dos x e dos y e a rotação em ordem ao eixo, determinado teoricamente como sendo o centro geométrico da cruz que se encontra desenhada no alvo colocado sobre o paciente, de imediato nos campos apropriados.

A correcção do movimento determinado na imagem do exame SPECT pode ser efectuada usando os valores calculados pelo processo de estimação de movimento ou por valores introduzidos pelo utilizador.

É dada ao utilizador uma indicação das imagens médicas que já foram corrigidas de forma que este saiba a cada passo o que foi feito e o que se encontra por fazer.

Uma vez que a associação entre as coordenadas do conjunto de pontos de referência, obtidos no processo de detecção, e as imagens resultantes dos exames médicos não foi estabelecida por motivos discutidos no capítulo VI. É assegurada uma opção ao utilizador para indicação do eixo de rotação na imagem do exame SPECT.

Figura 4.44 – Interface de estimação e correcção

de movimento

104

Page 114: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo V - Análise de Resultados

Capítulo V 1. - Introdução

Neste capítulo será demonstrada a funcionalidade do software , bem como efectuar a análise do

sistema. Esta análise tentará ser uma análise critica sobre todas as condicionantes do sistema, ou seja, tudo o que possa influenciar a precisão das medidas. Para além disso tentaremos caracterizar qual o melhor modo de operação do sistema desenvolvido.

Ao fazermos o setup do sistema devemos efectuar a calibração das câmaras de modo a podermos inferir informação 3D a partir dos pares de imagens stereo obtidos pelo sistema de aquisição.

No entanto antes da calibração é necessário escolher a posição das câmaras. Este posicionamento deve ter em conta os seguintes factores: problema das partes ocultas, resolução e precisão da medida de distância, e o volume de medida pretendido.

O volume de medida depende não só da posição relativa das câmaras mas também do campo de visão de cada câmara que é função da respectiva distância focal. Além disso quando o ângulo formado pelos eixos ópticos das câmaras aumenta, aumenta também a impossibilidade de calcular a distância de certos pontos da cena. Por outro lado a diminuição deste ângulo tem como consequência a diminuição da precisão da medida de distância.

Volume de medida

� - Ângulo de incerteza da linha de visão � �

Figura 5.1 - Volume de medida definido pela intersecção dos ângulos de visão das câmaras

105

Page 115: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo V - Análise de Resultados

O uso de duas câmaras leva a que o seu posicionamento tenha que ser pensado de modo a que a distância entre elas resulte do compromisso entre o agravamento do problema das partes ocultas e a diminuição da precisão da medida. Para um determinado ângulo de incerteza na determinação da linha de visão associada a cada ponto de uma imagem, a incerteza na determinação do ponto do espaço

correspondente aumenta com a aproximação das câmaras.

� �

� - Ângulo de incerteza dalinha de visão

Incerteza de posição

Figura 5.2 - Efeito da aproximação das câmaras na precisão da medida de distância. A incerteza na determinação aumenta à medida que estas se aproximam.

2. - Estimação do ângulo de visão das câmaras

O ângulo de visão das câmaras foi determinado medindo, com a ajuda de uma régua colocada a

Aproximadamente 41,2 cm

Figura 5.3 - Campo de visão das câmaras uma distância bem definida da câmara ( 70 cm ) , a largura de visão, em centimetros, da imagem captada.

Recorrendo à trigonometria podemos determinar o ângulo de visão como sendo de:

41,2 cm

70 cm

� = 2 x arctan (70cm

41,2cm/2) � 32.8 º

Uma vez determinado o ângulo de visão podemos agora

determinar a distância entre câmaras a utilizar de modo a obter a melhor configuração possível, ou seja tendo em atenção o compromisso entre volume de visão e precisão de medição.

Através do ângulo de visão verificamos que, usando cálculos simplificados de modo ao alvo ocupar mais de 50 % da largura de visão da câmara e não ocupar mais de 100 %, obtemos como distância ao alvo um valor que deverá encontrar-se entre 42,5 cm e 85 cm tendo em atenção que a dimensão do alvo em largura é de 25 cm aproximados. Figura 5.4 - Ângulo de visão

106

Page 116: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo V - Análise de Resultados

Atendendo ao ângulo óptimo (� = 60 º) de calibração chegamos aos seguintes valores de

distância ao alvo, e de distância entre câmaras

R (cm) D (cm)50 57.8034755 63.5838260 69.3641665 75.1445170 80.9248675 86.705280 92.4855585 98.265990 104.046295 109.8266100 115.6069105 121.3873110 127.1676115 132.948120 138.7283125 144.5087130 150.289135 156.0694140 161.8497145 167.6301150 173.4104

Direita Esquerda SUPORTE

ALVO

D

R

Figura 5.5 - Relação raio - distância

Uma vez que estes valores não se adaptam às dimensões inicialmente consideradas como aceitáveis para a construção do suporte, de modo a não termos um suporte de elevadas dimensões, não iremos usar um ângulo ( � ) preciso de 60 º. Analisando as dimensões necessárias para realização aproximada dessa condição realizamos vários testes para distâncias variáveis de forma a podermos analisar qual a distância que nos permite visualizar o alvo com as dimensões consideradas adequadas para o algoritmo de calibração e posteriormente para a detecção do alvo, com erros associados baixos.

De seguida apresentamos o resultado de testes efectuados para verificação da executabilidade do modelo e verificação da melhor distância ao alvo, bem como a melhor distância entre câmaras.

3. - Testes efectuados Iniciamos os testes de laboratório para verificar a executibilidade do modelo. O suporte foi posicionado a uma distância de aproximadamente 55 cm do alvo e com um espaçamento entre câmaras de 60 cm o que corresponde a � � 61º, o que não deixa de ser um ângulo bastante aproximado dos 60º pretendidos.

Figura 5.6 - Alvo de calibração

A detecção dos pontos caracteristicos dos alvos foi conseguida de uma forma óptima recorrendo apenas a pequenas alterações nos parâmetros do algoritmo de detecção dos pontos caracteristicos do alvo.

107

Page 117: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo V - Análise de Resultados

��Verificamos que o software implementado consegue assim adaptar-se às condições de aquisição de imagem adaptando-se às caracteristicas especificas de cada câmara e do próprio ambiente, tal como a iluminação e as diferenças que se notam na aquisição efectuada por cada câmara.

Figura 5.7 - Pontos de calibração

De seguida efectuamos a formatação dos pontos associando a cada ponto caracteristico detectado

nas imagens anteriores um par de coordenadas 3D de acordo com o referencial que determinamos como sendo o que se encontra descrito na figura 5.8.

Figura 5.8 - Referencial dos pontos de calibração Assim resultaram os pontos cuja descrição encontramos no tabela 1 para a câmara da posição da

esquerda e 2 para a câmara da posição da direita.

108

Page 118: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo V - Análise de Resultados

105.00000 -75.00000 0.00000 522.76 160.25 105.00000 -45.00000 0.00000 523.24 224.08 105.00000 -15.00000 0.00000 523.73 288.59 105.00000 15.00000 0.00000 524.23 353 105.00000 45.00000 0.00000 524.72 417.75 105.00000 75.00000 0.00000 525.21 482.39 75.00000 -75.00000 0.00000 462.72 164.33 75.00000 -45.00000 0.00000 462.97 226.91 75.00000 -15.00000 0.00000 463.21 290.07 75.00000 15.00000 0.00000 463.45 353 75.00000 45.00000 0.00000 463.7 416.58 75.00000 75.00000 0.00000 463.94 479.74 45.00000 -75.00000 0.00000 405.67 168.2 45.00000 -45.00000 0.00000 405.67 229.6 45.00000 -15.00000 0.00000 405.67 291.48 45.00000 15.00000 0.00000 405.67 353 45.00000 45.00000 0.00000 405.67 415.48 45.00000 75.00000 0.00000 405.67 477.22 15.00000 -75.00000 0.00000 350.57 171.94 15.00000 -45.00000 0.00000 350.57 232.19 15.00000 -15.00000 0.00000 350.57 292.84 15.00000 15.00000 0.00000 350.57 353 15.00000 45.00000 0.00000 350.57 414.43 15.00000 75.00000 0.00000 350.57 474.84 -15.00000 -75.00000 0.00000 297.38 175.55 -15.00000 -45.00000 0.00000 297.62 234.68 -15.00000 -15.00000 0.00000 297.86 294.13 -15.00000 15.00000 0.00000 298.09 353 -15.00000 45.00000 0.00000 298.34 413.43 -15.00000 75.00000 0.00000 298.57 472.59 -45.00000 -75.00000 0.00000 246.51 179.01 -45.00000 -45.00000 0.00000 246.66 237.08 -45.00000 -15.00000 0.00000 246.81 295.38 -45.00000 15.00000 0.00000 246.96 353 -45.00000 45.00000 0.00000 247.11 412.45 -45.00000 75.00000 0.00000 247.26 470.37 -75.00000 -75.00000 0.00000 197.67 182.32 -75.00000 -45.00000 0.00000 197.67 239.38 -75.00000 -15.00000 0.00000 197.67 296.59 -75.00000 15.00000 0.00000 197.66 353 -75.00000 45.00000 0.00000 197.66 411.51 -75.00000 75.00000 0.00000 197.66 468.23 -105.00000 -75.00000 0.00000 150.76 185.51 -105.00000 -45.00000 0.00000 150.76 241.58 -105.00000 -15.00000 0.00000 150.76 297.74 -105.00000 15.00000 0.00000 150.76 353 -105.00000 45.00000 0.00000 150.76 410.62 -105.00000 75.00000 0.00000 150.76 466.2

-105.00000 -75.00000 0.00000 140.96 129.79 -105.00000 -45.00000 0.00000 144.09 198.33 -105.00000 -15.00000 0.00000 147.17 265.79 -105.00000 15.00000 0.00000 150.27 333.66 -105.00000 45.00000 0.00000 153.35 401 -105.00000 75.00000 0.00000 156.41 468.15 -75.00000 -75.00000 0.00000 205.98 130.97 -75.00000 -45.00000 0.00000 208.93 197.93 -75.00000 -15.00000 0.00000 211.84 263.99 -75.00000 15.00000 0.00000 214.77 330.35 -75.00000 45.00000 0.00000 217.67 396.29 -75.00000 75.00000 0.00000 220.57 462.01 -45.00000 -75.00000 0.00000 267.81 132.09 -45.00000 -45.00000 0.00000 270.72 197.55 -45.00000 -15.00000 0.00000 273.6 262.26 -45.00000 15.00000 0.00000 276.49 327.18 -45.00000 45.00000 0.00000 279.36 391.76 -45.00000 75.00000 0.00000 282.23 456.1 -15.00000 -75.00000 0.00000 327.59 133.18 -15.00000 -45.00000 0.00000 330.39 197.19 -15.00000 -15.00000 0.00000 333.17 260.6 -15.00000 15.00000 0.00000 335.96 324.13 -15.00000 45.00000 0.00000 338.73 387.41 -15.00000 75.00000 0.00000 341.49 450.43 15.00000 -75.00000 0.00000 384 134.21 15.00000 -45.00000 0.00000 386.9 196.84 15.00000 -15.00000 0.00000 389.77 259.02 15.00000 15.00000 0.00000 392.65 321.21 15.00000 45.00000 0.00000 395.52 383.25 15.00000 75.00000 0.00000 398.38 444.99 45.00000 -75.00000 0.00000 438.84 135.2 45.00000 -45.00000 0.00000 441.8 196.5 45.00000 -15.00000 0.00000 444.74 257.48 45.00000 15.00000 0.00000 447.68 318.39 45.00000 45.00000 0.00000 450.62 379.21 45.00000 75.00000 0.00000 453.54 439.71 75.00000 -75.00000 0.00000 490.9 136.15 75.00000 -45.00000 0.00000 493.83 196.18 75.00000 -15.00000 0.00000 496.76 256.03 75.00000 15.00000 0.00000 499.67 315.72 75.00000 45.00000 0.00000 502.59 375.4 75.00000 75.00000 0.00000 505.49 434.74 105.00000 -75.00000 0.00000 541.04 137.06 105.00000 -45.00000 0.00000 543.95 195.87 105.00000 -15.00000 0.00000 546.85 254.63 105.00000 15.00000 0.00000 549.74 313.15 105.00000 45.00000 0.00000 552.63 371.73 105.00000 75.00000 0.00000 555.5 429.95

Tabela 1 - Pontos de calibração em coordenadas 3D e 2D.

Fazendo uso deste pontos formatados podemos finalmente calcular os parâmetros de calibração para cada câmara. Para tal configuramos os parâmetros sx, Cx , Cy, dx e dy para cada câmara e obtivemos os resultados indicados na tabela 3 e 4, para a câmara da esquerda e da direita respectivamente.

sx=0.65104, dx=0.0098, dy=0.0063, Cx=210, Cy=323, with 48 calibration points. Rotation matrix R: +0.856558 +0.00174585 +0.516048 -0.0155261 +0.999629 +0.0223890 -0.515817 -0.0271897 +0.856267 Translation vector T: +57.7421 +0.593502 +801.890 Focal length f: +10.0981 Radial lens distortion k1: -0.000571479

sx=0.65104, dx=0.0098, dy=0.0063, Cx=163, Cy=185, with 48 calibration points. Rotation matrix R: +0.966128 +0.0497705 -0.253217 -0.000715475 +0.981739 +0.190234 +0.258061 -0.183609 +0.948521 Translation vector T: +94.8563 +49.7193 +614.194 Focal length f: +8.46767 Radial lens distortion k1: +0.00975270

Tabela 2 - Calibração da câmara da esquerda

Tabela 3 - Calibração da câmara da esquerda

109

Page 119: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo V - Análise de Resultados

��Como podemos verificar as câmaras apresentam valores de distorção radial e de distância focal ligeiramentee diferentes o que levará a erros na estimação das coordenadas 3D devido à não uniformidade destes parâmetros em duas câmaras que à partida se pretendiam semelhantes.

��Foi utilizada a opção de determinação do centro óptico das câmaras ��O valor de sx foi aproximado pela simplificação demonstrada no Capitulo IV em 2.3.3.3

Após o processo de calibração efectuamos o processo de detecção de um alvo para apenas uma posição do alvo de modo a verificarmos a precisão das medidas tridimensionais do mesmo, confirmando -se assim ou não se o processo de calibração efectuado nos permitiu chegar aos valores mais correctos.

Figura 5.9 - Alvo para cálculo de coordenadas 3D

��Verificamos que o processo de detecção dos pontos caracteristicos se apresenta como sendo robusto e adaptável, sendo que facilmente com pequenas alterações dos parâmetros de detecção dos pontos caracteristicos do alvo conseguimos detectar e emparelhar os pontos caracteristicos de uma forma precisa, sem erros.

Figura 5.10 - Detecção dos pontos de intersecção do alvo

Obtivemos do processo de detecção as coordenadas para os pontos detectados e emparelhados

apresentados na tabela 4, associados respectivamente às câmaras da esquerda e da direita.

110

Page 120: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo V - Análise de Resultados

É possível verificar que os pontos foram todos correctamente emparelhados.

Points: Xf: Yf: Object: 515 257 T1 531 289 T2 542 311 T3 557 343 T4 500 289 T5 489 311 T6 474 342 T7 191 264 T8 203 293 T9 211 311 T10 223 340 T11 178 293 T12 171 311 T13 159 339 T14 406 342 C1 388 341 C2 435 311 C3 407 311 C4 388 311 C5 361 311 C6 435 290 C7 407 290 C8 389 290 C9 361 291 C10 408 259 C11 389 259 C12 324 341 Q1 256 340 Q2 325 311 Q3 256 311 Q4 325 291 Q5 257 292 Q6 326 261 Q7 257 262 Q8

Points: Xf: Yf: Object: 540 225 T1 553 254 T2 562 274 T3 575 303 T4 529 255 T5 522 275 T6 511 305 T7 203 225 T8 221 260 T9 231 281 T10 247 313 T11 187 261 T12 178 282 T13 162 315 T14 450 306 C1 432 307 C2 475 276 C3 449 276 C4 431 277 C5 402 277 C6 475 256 C7 448 256 C8 430 257 C9 402 257 C10 446 226 C11 428 226 C12 366 309 Q1 288 312 Q2 365 278 Q3 286 280 Q4 364 258 Q5 286 259 Q6 362 226 Q7 285 226 Q8

Tabela 4 - Classificação dos pontos de intersecção detectados

Figura 5.11 - Método de emparelhamento dos pares de figuras

O processo de cálculo de coordenadas 3D resultou nos valores apresentados na tabela 7, do qual

podemos fazer as seguintes verificações: ��A coordenada em profundidade dos pontos apresenta alguns erros,essencialmente ao

nível da coordenada em Z dos pontos do triângulos verificando-se que para os outros pontos esta coordenada apresenta valores muito satisfatórios.

��Verificando as distâncias medidas dos segmentos de recta definidos por determinados pontos, contabilizando as suas coordenadas verificamos pequenos erros, tal como é ilustrado na tabela 6.

O que nos permite concluir que os resultados obtidos são satisfatórios. No entanto podemos enumerar alguns problemas que podem interferir com a precisão das

coordenadas dos pontos calculados: - O alvo de calibração impresso numa impressora a laser não tem precisão suficiente, notando-se desde logo que o alvo impresso possui os quadrados não completamente alinhados, demonstrando-se esta solução como alvo de calibração uma solução pobre.

111

Page 121: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo V - Análise de Resultados

Seg. Recta Erro Valor medido (mm) Valor esperado (mm)T14 e T8 0.6% 44.71537234 45

T14 e T11 0.1% 39.96804832 40T8 e T11 1.4% 44.38558873 45Q1 e Q2 1.1% 39.57536674 40Q2 e Q8 0.5% 39.79466031 40Q8 e Q7 0.8% 39.66047612 40Q7 e Q1 0.7% 39.70930609 40C1 e C2 1.1% 9.892354365 10

C2 e C12 0.8% 39.66766089 40C12 e C11 1.8% 10.18340339 10C11 e C1 0.7% 39.71641147 40T1 e T4 0.1% 44.96231961 45T4 e T7 1.7% 40.68788063 40T7 e T1 0.5% 44.7842249 45

Tabela 7 - Coordenadas 3D dos pontos detectados e emparelhados

- O suporte não possui estabilidade nem é suficientemente preciso, de modo a podermos alinhar as câmaras, denotando-se que as imagens obtidas, devido ao encaixe das câmaras no suporte, não se encontram alinhadas horizontalmente. - As câmaras têm uma elevada distorção não linear. A distorção é tão elevada que se nota claramente nas próprias imagens adquiridas, sendo o aumento a distorção do centro da imagem para a periferia.

3D Coordinates X coord Y coord Z coord TAG 102.315 -29.4948 -3.20021 T1 109.689 -14.4937 -2.30059 T2 114.795 -4.13703 -1.88616 T3 121.91 10.9543 -1.96876 T4 94.4599 -14.687 -2.20169 T5 89.0088 -4.59058 -2.49656 T6 81.2336 10.003 -2.13947 T7 -78.2201 -32.5149 -1.45711 T8 -70.6646 -16.8247 -1.59232 T9 -66.2103 -7.34219 -0.827526 T10 -59.2111 7.57878 -0.345701 T11 -86.5445 -16.9819 -1.13471 T12 -91.1594 -7.63413 -0.898206 T13 -99.1745 6.9729 -0.412459 T14 45.6982 9.1766 -1.58676 C1 35.8276 8.86312 -1.01086 C2 61.1426 -5.20437 -1.73739 C3

.... 46.2808 -5.64238 -1.47188 C4 36.1105 -5.68239 -1.43658 C5 20.7692 -6.2008 -0.148284 C6 61.5452 -15.1026 -2.50836 C7 46.4221 -15.6036 -1.60963 C8 36.5299 -15.6874 -0.989955 C9 21.1603 -15.8681 -0.823248 C10 46.8199 -30.5208 -1.0852 C11 36.6403 -30.7962 -1.04516 C12 0.292171 8.35522 -0.660441 Q1 -39.2785 7.80425 -0.399517 Q2 0.83038 -6.46212 -0.444182 Q3 -39.3197 -7.00591 -0.223889 Q4 0.937984 -16.1864 -0.502565 Q5 -38.7045 -16.7078 -0.191399 Q6 1.26848 -31.3356 0.0569284 Q7 -38.3805 -31.9795 -0.648156 Q8

Tabela 6 - Erros das distâncias detectadas

- As câmaras apresentam diferenças visiveis entre si o que afecta a aquisição de imagem, denotando-se que uma apresenta uma distorção superior à outra. - As condições de iluminação do local onde se realizaram os testes introduziram pequenos artefactos que dificultam as condições de execuçaõ dos algoritmos de calibração e detecção dos pontos caracteristicos do alvo.

- A distância e posição das câmaras em relação ao alvo poderão ter influência nos resultados obtidos.

De seguida realizamos os seguintes testes para verificação de que o ângulo óptimo de calibração seria de facto aquele que mais se aproxima de � = 60 º.

Para diferentes distâncias entre câmaras, e a uma distância de 55 cm do alvo verificamos a validade da calibração, pela análise da precisão na medição das coordenadas 3D do alvo colocada no plano Z = 0.

112

Page 122: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo V - Análise de Resultados

1º Teste: D = 30 cm ( � � 75º) Seg. Recta Erro Valor medido (mm) Valor esperado (mm)

T14 e T8 3.7% 43.33469605 45T14 e T11 2.6% 38.96045698 40T8 e T11 5.0% 42.77007148 45Q1 e Q2 3.5% 38.61072823 40Q2 e Q8 4.4% 38.2432386 40Q8 e Q7 3.8% 38.47524391 40Q7 e Q1 4.4% 38.24136172 40C1 e C2 3.5% 9.649495558 10

C2 e C12 4.7% 38.1138722 40C12 e C11 3.3% 9.668915514 10C11 e C1 5.6% 37.7730901 40T1 e T4 4.9% 42.81055431 45T4 e T7 2.4% 39.02689787 40T7 e T1 5.4% 42.56906571 45

Tabela 8 - Erros das ditâncias detectadas.

3D Coordinates X coord Y coord Z coord TAG 87.8247 -31.3646 -32.331 T1 95.5259 -16.8541 -30.4716 T2 100.101 -7.07243 -30.4739 T3 107.092 6.79472 -30.0113 T4 80.2712 -17.1383 -29.8447 T5 75.5467 -7.78517 -28.4422 T6 68.3379 5.86087 -25.5006 T7 -86.3103 -33.5902 -26.4033 T8 -79.3599 -19.0772 -25.9541 T9 -74.4849 -9.49677 -25.9069 T10 -67.5424 4.83161 -25.5036 T11 -94.34 -19.4444 -23.8485 T12 -99.1653 -10.1053 -22.8638 T13 -106.483 4.7033 -24.2665 T14 34.0755 5.22629 -24.0493 C1 24.4375 5.24737 -24.5197 C2 ...

.... 48.8421 -8.48822 -25.0451 C3 34.4628 -8.75665 -25.8277 C4 24.6448 -8.85763 -25.2751 C5 10.1497 -9.10261 -24.4482 C6 49.0779 -17.9319 -26.8326 C7 34.5523 -18.1712 -26.1951 C8 24.9852 -18.4077 -24.6627 C9 10.2364 -18.7278 -24.9353 C10 34.794 -32.3656 -27.6742 C11 25.2333 -32.8164 -26.3039 C12 -9.6517 5.13642 -25.149 Q1 -48.2603 4.73438 -25.097 Q2 -9.46191 -9.38994 -24.1467 Q3 -48.1005 -9.4744 -25.2109 Q4 -9.14784 -18.9182 -25.3335 Q5 -47.8709 -19.0178 -24.6966 Q6 -9.12953 -33.0984 -25.6261 Q7 -47.6015 -33.494 -25.935 Q8

Tabela 9 - Erros das distâncias detectadas

Podemos verificar que os erros aumentaram tal como seria de esperar uma vez que o ângulo entre as câmaras se afasta dos 60 º referenciados anteriormente como sendo o ângulo óptimo. As coordenadas em z apresentam valores pouco correctos o que prova que a triangulação esteroscópica apresenta erros elevados devido à falta de precisão na estimação das matrizes de calibração.

2º Teste: D = 40 cm ( � � 70º) Seg. Recta Erro Valor medido (mm) Valor esperado (mm)

T14 e T8 0.0% 44.99494008 45T14 e T11 0.1% 40.02301165 40T8 e T11 1.0% 44.56358326 45Q1 e Q2 0.3% 39.88693402 40Q2 e Q8 0.2% 40.07564728 40Q8 e Q7 0.4% 39.84667475 40Q7 e Q1 0.1% 39.97450997 40C1 e C2 2.1% 10.20762498 10

C2 e C12 0.6% 39.75853547 40C12 e C11 0.1% 10.00798827 10C11 e C1 1.4% 39.45281292 40T1 e T4 0.2% 44.90838664 45T4 e T7 1.5% 40.60222444 40T7 e T1 1.1% 44.51052056 45

Tabela 10 - Erros das distâncias detectadas.

113

Page 123: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo V - Análise de Resultados

A melhoria na estimação das coordenadas é visível tal como seria de esperar uma vez que nos

aproximamos um pouco mais do ângulo óptimo de calibração, o que permite calcular matrizes de calibração mais precisas e consequentemente estimar coordenadas 3D de uma forma mais exacta. Podemos verificar que as coordenadas em z se aproximam bastante do valor devido ( 0 mm ) ao contrário do anterior onde denotamos a existência de coordenadas em z com erros de 3,2 cm

3D X coord Y coord Z coord TAG 100.309 -41.4568 -5.01586 T1 108.446 -26.3123 -5.32037 T2 113.723 -16.6129 -4.87173 T3 121.685 -1.96309 -5.29278 T4 93.1268 -26.2704 -3.42531 T5 88.3387 -16.1749 -2.81114 T6 81.2096 -1.35501 -2.14431 T7 -80.1438 -37.1776 -2.36657 T8 -72.1443 -22.189 -2.02449 T9 -67.0786 -12.2252 -2.51164 T10 -59.359 2.23953 -1.92509 T11 -87.6037 -21.6389 -1.42335 T12 -92.2585 -11.7424 -0.693453 T13 -99.3462 3.483 -0.776578 T14 45.6264 -0.777116 -1.59088 C1 35.4288 -0.382266 -1.3703 C2 ....

... 60.5051 -15.6693 -1.72259 C3 45.6525 -15.406 -1.42177 C4 35.4466 -15.2244 -1.29009 C5 20.4146 -14.8812 -1.6622 C6 60.3581 -25.6111 -2.77478 C7 45.2886 -25.4512 -1.65047 C8 35.0776 -25.2724 -1.48194 C9 20.0318 -24.8575 -0.424805 C10 45.1131 -40.2131 -2.62245 C11 35.1546 -40.139 -1.63118 C12 0.382794 0.574201 -1.52076 Q1 -39.4872 1.72516 -1.68317 Q2 0.125996 -14.2052 -1.99217 Q3 -39.7645 -13.0378 -2.23782 Q4 -0.0365562 -24.2921 -1.5623 Q5 -39.9928 -23.1492 -1.62912 Q6 -0.484947 -39.3907 -1.64389 Q7 -40.3112 -38.3349 -0.928106 Q8

Tabela 11 - Coordenadas 3D dos pontos detectados e emparelhados

3º Teste: D = 50 cm ( � � 66º) Seg. Recta Erro Valor medido (mm) Valor esperado (mm)

T14 e T8 1.0% 44.53994296 45T14 e T11 0.3% 40.10566538 40T8 e T11 0.7% 44.6754495 45Q1 e Q2 0.1% 39.96430236 40Q2 e Q8 0.1% 39.95275878 40Q8 e Q7 0.4% 40.14807382 40Q7 e Q1 0.3% 39.89417869 40C1 e C2 0.1% 9.99487153 10

C2 e C12 0.1% 40.03488767 40C12 e C11 0.0% 9.997670567 10C11 e C1 0.2% 39.93049672 40T1 e T4 0.4% 44.84240859 45T4 e T7 0.3% 40.12367892 40T7 e T1 0.3% 44.86931613 45

Tabela 12 - Coordenadas 3D dos pontos detectados e emparelhados

3D Coordinates X coord Y coord Z coord TAG 103.965 -38.7922 -1.39817 T1 111.972 -23.7058 -1.5184 T2 117.562 -13.9009 -1.58424 T3 125.337 0.629599 -1.4296 T4 96.8717 -23.2896 -1.73664 T5 92.0153 -12.991 -1.59052 T6 85.2366 1.98092 -1.63322 T7 -76.2146 -33.0485 -2.63641 T8 -68.1853 -18.3419 -2.31888 T9 -62.7699 -8.32353 -2.71648 T10 -54.8787 6.1923 -3.55007 T11 -83.3936 -17.9752 -2.11572 T12 -88.1693 -7.50151 -1.87286 T13 -94.9472 7.35902 -2.27788 T14 50.108 2.97163 -2.92752 C1 40.1256 3.25236 -3.34024 C2 ....

... 64.5492 -12.066 -2.73171 C3 49.6971 -11.8702 -3.16517 C4 39.7477 -11.4047 -2.28635 C5 24.6323 -10.966 -3.15265 C6 64.5527 -22.2177 -2.67968 C7 49.462 -21.8247 -2.47327 C8 39.4617 -21.5257 -2.90633 C9 24.3724 -21.1497 -2.48644 C10 49.0567 -36.9445 -2.72282 C11 39.0968 -36.7426 -1.8784 C12 4.88442 4.41981 -3.58639 Q1 -35.0648 5.44927 -3.96783 Q2 4.45802 -10.3996 -3.89286 Q3 -35.5782 -9.14118 - 2.98408 Q4 4.1721 -20.5689 -3.23161 Q5 -35.6221 -19.2792 -2.9494 Q6 3.99596 -35.4584 -2.89033 Q7 -36.1291 -34.4403 -1.98985 Q8

Tabela 13 - Erros das distâncias detectadas

114

Page 124: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo V - Análise de Resultados

Neste teste verificamos que os erros são baixos tal como seria de esperar. De modo a termos uma visão mais ampla da redução de erro de acordo com o aproximar do ângulo ao ângulo óptimo, construimos o gráfico 1 e 2. Podemos verificar pela observação de ambos os gráficos que os erros aumentaram de acordo com o esperado a não ser na posição para a qual esperávamos menores erros. Isto deve-se ao facto de para esta posição tal como pode ser verificado nas imagens adquiridas, devido à posição afastada das câmaras as imagens dos alvos aproximam-se mais da periferia o que leva a que possivelmente exista uma maior distorção na detecção desses pontos e consequentemente maiores erros na estimação de coordenadas 3D. Não é no entanto de eliminar a possibilidade de esses erros terem origem no algoritmo de detecção de pontos caracteristicos, que não se revelou tão robusto como o esperado.

Erro Observado nas Medições 3D

0.00%

1.00%

2.00%

3.00%

4.00%

5.00%

6.00%

60 50 40 30

(cm)

Erro

(%)

T14 a T8T14 a T11T8 a T11Q1 a Q2Q2 a Q8Q8 a Q7Q7 a Q1C1 a C2C12 a C11C11 a C1T1 a T4T4 a T7T7 a T1

Gráfico 1 - Comparação de erros Média dos Erros Observados

0.00%0.50%1.00%1.50%2.00%2.50%3.00%3.50%4.00%4.50%

60 50 40 30

(cm)

Erro

(%)

Média

A análise destes dois gcâmaras devem encontrarem-se u

Gráfico 2 - Comparação de erros em média

ráfico dos erros observados, comprovam que a ângulo ideal a que as ma da outra é 50 cm (para o suporte utilizado). A distância exacta a que

115

Page 125: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo V - Análise de Resultados

as câmaras deveriam estar afastadas uma da outres não foi possível de ser determinada, devido ao facto do suporte não permitir uma maior flexibilidade em termos de distaciamentto entre câmaras.

4. - Influência dos parâmetros de calibração Verificamos que os valores de Cx e Cy apresentaram variações consideráveis para cada um dos testes efectuados o que pode ser parcialmente justificado pela fragilidade apresentada pelas câmaras em termos de capacidade de aquisição de imagens precisas e sem distorção.

Para verficar qual a importância do cálculo correcto dos valores de Cx e Cy nos resultados das medições 3D finais, realizou-se um teste para a posição das câmaras que produz menos erros em média, com valores de Cx e Cy iguais ao centro de uma imagem adquirida na memória frame.

Resultados obtidos na calibração das duas câmaras:

Stop for nonlinear equations=1e-008, Find center=0, sx=0.65104, dx=0.0098, dy=0.0063, Cx=256, Cy=256, Rotation matrix R: +0.975409 +0.0421199 -0.216340 -0.0243283 +0.996147 +0.0842540 +0.219056 -0.0769189 +0.972676 Translation vector T: +56.9042 +15.1657 +516.980 Focal length f: +7.24255 Radial lens distortion k1: +0.00815642

Stop for nonlinear equations=1e-008, Find center=0, sx=0.65104, dx=0.0098, dy=0.0063, Cx=256, Cy=256, Rotation matrix R: +0.900726 -0.00377226 +0.434371 -0.0262306 +0.997665 +0.0630568 -0.433595 -0.0681907 +0.898524 Translation vector T: +40.3242 +32.2108 +738.820 Focal length f: +9.53879 Radial lens distortion k1: +0.00114678

Tabela 14 - Resultados da calibração das duas câmaras, na coluna da esquerda a calibração

referente a câmara da esquerda e na coluna da direita respectivamente a calibração da outra câmara.

Através da análise da tabela 14, verficamos que as matrizes de calibração são diferentes do que aquelas obtidas utilizando um Cx e Cy correcto, sendo ainda de salientar que a distorção com estes valores é cerca de dez vezes superior. Na tabela 15, são ilustradas as coordenadas 3D dos pontos de intersecção característicos.

X coord Y coord Z coord TAG 49.4372 -28.7403 -27.2825 T1 57.4907 -14.0337 -26.7645 T2 63.1788 -4.14289 -26.5515 T3 71.2152 10.3394 -26.3891 T4 41.621 -13.4883 -26.472 T5 36.416 -3.61252 -26.0316 T6 29.1086 11.2199 -25.4681 T7 -112.228 -19.8334 -69.4974 T8 -107.095 -7.99389 -64.9004 T9 -103.559 0.575928 -62.2426 T10 -98.0648 13.1299 -58.9445 T11 -117.43 -7.5214 -72.0406 T12 -120.853 1.14161 -73.7316 T13 -125.899 13.4359 -76.3246 T14 -6.47495 11.3831 -28.8779 C1 -16.2607 11.6363 -30.5241 C2 8.15 -2.81267 -27.7876 C3

... -6.62114 -2.62256 -29.7171 C4 -15.9161 -2.3257 -31.2922 C5 -30.4494 -2.1005 -34.3713 C6 8.39964 -12.7674 -28.3051 C7 -6.3813 -12.097 -30.2123 C8 -16.1623 -11.7838 -31.8799 C9 -30.2076 -11.5074 -34.8667 C10 -6.49506 -26.5326 -31.0103 C11 -15.7843 -26.1772 -32.597 C12 -48.9051 12.3325 -38.4971 Q1 -82.8055 12.5571 -51.3826 Q2 -49.0294 -1.46443 -39.4237 Q3 -82.474 -0.280756 -52.1245 Q4 -48.7868 -10.7978 -39.9181 Q5 -82.2401 -9.23362 -52.604 Q6 -48.4287 -24.1253 -40.5765 Q7 -81.8822 -22.2972 -53.2434 Q8

Tabela 15 - Coordenadas 3D obtidas para as intersecções dos pontos característicos.

Analisando a tabela 15, verificam -se erros de em média 3,5 cm nas coordenadas 3D, em vez dos 1,3 mm obtidos em média quando se utilizam os valores correctos de Cx e Cy, sendo os valores 3D obtidos, altamente imprecisos. Assim se conclui que para se obterem resultados com precisão, é fundamental o cálculo dos valores verdadeiros de Cx e Cy. De forma a determinar a influência do valor do factor de incerteza horizontal sx,, nos resultados das medições 3D finais, realizou-se um teste para a posição das câmaras que produz menos erros em média, com um valores de sx igual a 1, isto é, supondo que não há incerteza horizontal.

116

Page 126: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capitulo V - Análise de Resultados

Rotation matrix R: +0.997662 +0.0441975 -0.0521180 +0.0122071 +0.635147 +0.772295 +0.0672360 -0.771126 +0.633123 Translation vector T: +126.182 +55.0321 +3273.43 Focal length f: +75.3591 Radial lens distortion k1: +0.00583348

Rotation matrix R: +0.976350 -0.00408897 +0.216157 -0.0260375 +0.990320 +0.136341 -0.214622 -0.138745 +0.966792 Translation vector T: +43.7098 +31.9736 +422.149 Focal length f: +85.42266 Radial lens distortion k1: +0.000463852

Tabela 16 - Resultados da calibração das duas câmaras, na coluna da esquerda a calibração

referente a câmara da esquerda e na coluna da direita respectivamente a calibração da outra câmara.

De notar que no resultado das calibrações a distância focal alterou-se bastante relativamente aos valores obtidos quando se utiiza o valor aproximado relativamente às câmaras e frame grabber utilizado.

156.495 -103.252 108.806 T1 144.415 -79.3897 77.196 T2 133.918 -58.8142 56.1849 T3 124.139 -39.5282 36.9941 T4 166.27 -95.3104 131.636 T5 175.485 -83.2981 146.159 T6 184.421 -69.4618 154.129 T7 -4.54997 -79.4234 22.2477 T8 -11.8473 -67.7212 29.6909 T9 -18.8963 -53.9268 31.2223 T10 -26.2977 -42.5962 38.4669 T11 2.4412 -63.6283 17.1158 T12 8.80346 -50.134 19.2958 T13 15.2426 -35.8954 16.0702 T14 94.7337 -32.3678 8.03116 C1 81.1929 -30.6742 0.356269 C2 109.874 -50.7963 26.5209 C3

.... 94.9615 -45.737 7.13351 C4 81.8987 -44.7797 3.60039 C5 68.2467 -45.0953 3.6036 C6 110.19 -63.6035 22.2472 C7 95.8543 -60.5239 10.7718 C8 82.1007 -58.1205 2.49748 C9 68.5585 -57.4127 -0.959401 C10 96.1653 -72.5464 6.43343 C11 82.3148 -71.2791 1.41275 C12 54.7753 -31.9086 3.63526 Q1 28.7599 -34.8657 12.419 Q2 55.4458 -44.6268 1.77374 Q3 28.7951 -47.2818 9.91794 Q4 55.554 -57.8012 0.222014 Q5 29.4369 -60.5736 8.32518 Q6 55.8762 -69.7757 -4.54825 Q7 29.4889 -73.7645 6.14213 Q8

Tabela 17 - Coordenadas 3D obtidas para as intersecções dos pontos característicos.

Como é possível observar através da tabela 17 as coordenadas 3D obtidas para os pontos de intersecção característicos são altamente impresisos, chegando a haver erros na ordem dos 13 centímetros. Assim comprova-se que o cálculo preciso tanto do sx como do Cx e Cy são fundamentais para se obter bons resultados na precisão do cálculo de coordenadas 3D.

117

Page 127: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo VI - Conclusões e Trabalho Futuro

Capítulo VI

Neste capítulo é feita uma discussão em termos de conclusões gerais do que poderá ser feito em termos de desenvolvimento do projecto e trabalho futuro, de modo a possibilitar a evolução do projecto, atingindo melhores resultados (precisões mais elevadas no cálculo das coordenadas 3D dos pontos característicos), e aperfeiçoando técnicas e algoritmos de modo a generalizar a utilização do sistema e a torná-lo mais fiável e robusto. É efectuada uma análise critica do que poderia ser alterado em termos gerais de modo a optimizar o projecto desenvolvido. 1 - Pesquisa de Informação

A obtenção de informação noutros centros de investigação, tal como o que foi efectuada no instituto de engenharia biomédica de Karlsruhe demonstrou ser de extrema importância para definir rumos e estratégias de abordagem ao problema considerado. Essa importância, deveu-se ao facto da experiência de trabalho em áreas similares efectuado nos centros de investigação permitirem a definição de estratégias mais seguras, aprendendo com os trabalhos já efectuados nessa área.

Como trabalho futuro, poderá ser implementada uma plataforma de disponibilização da informação obtida sobre medicina nuclear e seus protocolos de aquisição, através de um portal Internet, que permitisse o acesso a esta informação a qualquer pessoa com interesse nesta área, dando um passo para a concentração de informação acerca deste tema num só local. 2 – Etapas do projecto

O projecto desenvolvido atingiu os objectivos propostos à excepção da realização de exames em ambiente clínico uma vez que tal não foi possível por questões de ordem de disponibilidade e condições de instalações.

A falta de realização de exames clínicos e o recurso a fantomas para efectuar uma análise em termos de funcionamento do sistema projectado em conjunto com a máquina SPECT, levaram a que o projecto não tomasse um carácter tão prático como poderia ter. As imagens resultantes da utilização de fantomas poderiam fornecer informações muito precisas acerca dos métodos e algoritmos a implementar, para correcção da degradação registada das imagens médicas finais. Tal facto condicionou um pouco o projecto, uma vez que a falta de feedback em termos de utilização por parte dos médicos envolvidos no processo de aquisição SPECT levou a uma falta de sensibilidade em termos de aplicação, podendo esta não se encontrar (tal como está desenvolvida), completamente adaptada às necessidades inerentes ao objectivo fundamental do projecto, objectivo esse, a utilização da fusão sensorial para corrigir artefactos introduzidos nos exames médicos.

119

Page 128: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo VI - Conclusões e Trabalho Futuro

Ou seja o uso de informação de diferentes tipos – no caso deste projecto a informação obtida pela máquina SPECT e a informação obtida pelo sistema de aquisição de imagem - pode trazer de facto grandes vantagens em termos de redução de erros no diagnóstico médico bem como trazer vantagens também em outras áreas de actividade em que se poderia desenvolver este tipo de sistema. Assim este projecto enquadra-se numa área que se encontra em desenvolvimento e na qual poderia encontrar muitas outras formas de evoluir quer partindo da base montada neste projecto quer tentando desenvolver outros tipos de sistema com a mesma filosofia de modo a responder à necessidade existente e constante de aperfeiçoamento dos sistemas de aquisição de informação. 3 – Abordagem Seguida

Verificamos que o pressuposto inerente à aquisição simultânea de duas câmaras, em que os instantes de aquisição seriam sequenciais temporalmente, em intervalos bem definidos no tempo, poderá não servir como método directo de medição fiável. Isto acontece pois, pela análise do modo como os exames são efectuados, constatamos que a aquisição da imagem realizada pela máquina SPECT é efectuada por acumulação de contagens e não por aquisição instantânea, nem tão pouco por acumulação em intervalos pequenos de tempo o que poderia ainda assim ser conveniente. No entanto a estimação de movimento poderá ser efectuada se considerarmos a aquisição de várias imagens do paciente por intervalo de tempo, efectuando-se uma medida estatística do movimento a partir desse conjunto de imagens para cada intervalo de tempo. Assim usando modelos estatísticos podemos inferir o movimento efectuado adequando essa estimação ao número de contagens efectuadas por instante de tempo e obtendo assim um modelo mais complexo de estimação de movimento do que o considerado neste projecto. O desenvolvimento do sistema foi direccionado para cumprir objectivos de detecção de um alvo rígido colocado sobre o paciente detectando movimentos simples de rotação e translação no plano paralelo ao da aquisição por parte da máquina SPECT, no entanto esta abordagem poderá ser generalizada de forma a fazer medição de contornos e consequentemente servir melhor os objectivos do projecto criando um modelo tridimensional da anatomia local do paciente que assim por estudo do modelo do corpo humano poderá mais fielmente obter informação do movimento do órgão em estudo. O uso de modelos deformáveis afigura-se como forte oportunidade de servir os nossos propósitos de forma a obtermos um modelo do corpo, podendo mais facilmente inferir a posição de determinados órgãos nesse modelo e consequentemente adaptar de uma forma mais precisa a estimação de movimento ao órgão em questão. 4 – Equipamento Utilizado

��As câmaras adquiridas demonstraram ter uma elevada distorção não linear apresentando

também grandes diferenças entre si.

Como trabalho futuro poderemos fazer uso de câmaras que nos garantam maior precisão e menores distorções e/ou também fazer uso de lentes mais precisas uma vez que poderíamos assim obter uma maior precisão na aquisição de imagem, aumentando assim a precisão dos pontos detectados, quer no alvo de calibração quer no alvo a colocar no o paciente, e consequentemente aumentando também a precisão do cálculo das coordenadas 3D dos pontos característicos do alvo.

��Quando se efectua a aquisição em simultâneo de imagens das duas câmaras verificamos

que existe um tempo morto de cerca de 200 ms, que impossibilita que a aquisição seja perfeitamente simultânea.

Para evitar esta condicionante do sistema, as câmaras deveriam estar sincronizadas de forma a

minimizar os tempos mortos entre aquisições simultâneas ou deveríamos usar um frame grabber que nos possibilitasse fazer a aquisição a partir de dois canais.

��O suporte das câmaras apresenta deficiências ao nível de precisão de posicionamento

entre câmaras, flexibilidade de alteração da posição das câmaras e medição dos ângulos formados entre câmaras. Devido a estes factores os testes realizados para

120

Page 129: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo VI - Conclusões e Trabalho Futuro

dimensionamento, das posições e ângulos das câmaras (factores determinantes nos cálculos de precisão), foram fortemente condicionados.

Como trabalho futuro, o suporte poderá ser redimensionado e estruturado de forma a apresentar-

se como uma solução flexível para realizar testes laboratoriais que nos permitam identificar as fontes de erro de uma forma mais precisa. Assim o suporte deverá permitir a medição dos ângulos entre as câmaras e o eixo que as une, variar as distâncias entre câmaras de uma forma flexível mas precisa e que possua uma base mais estável de modo a não ser tão susceptível de alterações de posição devido a movimentações junto do suporte.

��O frame grabber utilizado introduz fitas negras nas imagens adquiridas, devido à

adaptação das dimensões das imagens e do buffer do frame grabber o que degrada a implementação dos algoritmos de detecção de pontos quer para o alvo de calibração quer para o alvo a colocar sobre o paciente.

O uso de um frame grabber mais evoluído poderá eliminar estas lacuna evitando os tempos

mortos entre mudanças de canais e uma maior despreocupação com factores externos às imagens no desenvolvimento dos algoritmos.

��O alvo de calibração demonstrou ter imperfeições no alinhamento e tamanho dos quadrados impressos, demonstrando que a qualidade de impressão não foi a melhor.

O alvo de calibração deverá ser manufacturado e impresso num material que nos garanta

precisão, de modo a que os resultados da calibração não sejam afectadas à priori por erros do próprio alvo de calibração.

5 - Algoritmos desenvolvidos

��O algoritmo de detecção de pontos do alvo a colocar sobre o paciente para detecção de pontos característicos, apresenta algumas lacunas importantes em termos de precisão. Para além disso existe a necessidade de alterar parâmetros de detecção frequentemente, de acordo com os diferentes datasets de imagem. O algoritmo implementado está limitado à detecção de alvos com um número pré-determinado de figuras geométricas a detectar.

A revisão do algoritmo utilizado ou alteração da abordagem para detecção dos pontos poderia

trazer melhorias na detecção do pontos aumentando assim a precisão com que se efectuam os cálculos das coordenadas 3D desses mesmos pontos. Uma maior automatização do algoritmo traria benefícios para o utilizador.

O algoritmo deverá ser alterado de forma a ser capaz de detectar e emparelhar as figuras geométricas em duas imagens distintas, independentemente da ordem pela qual as figuras geométricas se apresentem nas duas imagens. O algoritmo deveria ser capaz de identificar zonas correspondentes nas duas imagens, e de seguida identificar as figuras geométricas e seus pontos característicos nas duas imagens. Com isto, seria possível fazer-se um dimensionamento de um alvo de detecção que se adapta a toda a superfície lombar do paciente, possibilitando o levantamento 3D de toda essa zona do corpo humano. Este alvo poderia permitir assim que os movimento do paciente fossem caracterizados e corrigidos de uma forma mais eficaz.

��O ambiente em que se localiza o sistema de aquisição stereo apresenta-se como responsável pela presença de pequenos artefactos nas imagens podendo deteriorar a determinação dos parâmetros de calibração e das coordenadas dos pontos tridimensionais do alvo a colocar sobre o paciente.

Poderia ser efectuada uma análise mais profunda da influência de factores externos nos

parâmetros de configuração do sistema de aquisição, de forma a poder aferir se esta influência afecta, e de que forma, a precisão dos cálculos efectuados.

121

Page 130: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Capítulo VI - Conclusões e Trabalho Futuro

��A detecção do sinal de trigger para activação do evento de aquisição de imagens é efectuada através da porta série tendo sido usado um botão de pressão para simulação de evento. Não foi no entanto comprovado a executabilidade deste mecanismo em exame clínico.

A verificação da executabilidade de tal acção torna - se assim indispensável, através do

conhecimento mais detalhado acerca das máquinas utilizadas para efectuar os exames SPECT planar, junto dos fabricantes se possível, de forma a verificar se não seria possível extrair um sinal de trigger da própria máquina SPECT planar.

��A verificação da funcionalidade do módulo de estimação de movimento foi verificada

para o algoritmo com valores simulados e não será validada em ambiente laboratorial uma vez que não existiam condições para a medição com o mínimo de precisão dos valores de translação e de rotação. Também não foi possível a realização da correcção de imagens médicas, devido ao facto de nao se ter realizado nenhuma aquisição de imagens estereoscopicas simultaneamente com um exame do tipo SPECT planar.

Deverá ser feito uso de esquemas de medição das alterações em termos de posição efectuadas

sobre o alvo de forma a possuirmos uma ferramenta que nos permitisse verificar a funcionalidade do módulo de calibração de uma forma prática.

Deverá ser feita uma aquisição simultânea destes dois tipos de sistemas.

122

Page 131: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Bibliografia Publicações [Alves, 1994] - Jorge Silva Aquisição e Processamento de Informação tridimensional Faculdade de Engenharia da Universidade do Porto [Boer, 1997] - Ingo de Boer Dreidimensionale Lokalisation einer Elektrodenanordnung mittels Analyse von Stereofarbaufnahmen Diplomarbeit, IBT - University of Karlsruhe, 1997 [Boer, 2000] - I. H. de Boer, F. B. Sachse, S. Mang, and O. Dössel Methods for determination of electrode positions in tomographic images In CardioModel 2000 - Computer Models of the Heart: Theory and Clinical Application, volume 2-2. International Journal of Bioelectromagnetism, September 2000. ISSN 1456-7865. [Brack, 1996] - Ch. Brack, H. Gotte, F. Gossé, J. Moctezuma, M. Roth, A. Shweikard Towards Accurate X-Ray-Camera Calibration in Computer-Assisted Robotic Surgery Proc. Int. Symp. Computer Assisted Radiology (CAR), Paris, 721-728,1996 [Cao, 2000] - Xinhua Cao, H.K.Huang Current Status and Future Advances of Digital Radiography and PACS IEEE Engineering In Medicine And Biology, Volume 19, N. 5, September/October 2000, 80/88 [Chabat, 2000] - François Chabat, David M. Hansell, Guang-Zhong Yang Computerized Decision Suport in Medical Imaging IEEE Engineering In Medicine And Biology, Volume 19, N. 5, September/October 2000 [Chapra, 1988] - Steven C. Chapra, Raymond P.Canale Numerical Methods for Engineers McGraw-Hill - 1988 [Chiang, 1996] - Ming-Chao Chiang A Public Domain System for Camera Calibration and Distortion Correction April 3, 1996 [Fullton, 1999] - R.R. Fulton, S. Eberl, S.R. Meikle, B. F. Hutton, M. Braun

123

Page 132: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

A Practical 3D Tomographic Method for Correcting patient Head Motion in Clinical SPECT IEEE Transactions on Nuclear Science, Vol. 46, No. 3, June 1999 667/672 [Garcia, 2000] - Ernest V. Garcia, Tracy L. Faber, James R. Galt, C. David Cooke, Russell D. Folks Advances in Nuclear Emission PET and SPECT Imaging IEEE Engineering In Medicine And Biology, Volume 19, N. 5, September/October 2000, 21/33 [Geckle, 1988] - WJ. Geckle, TL Franck, JM. Links, LC. Beck Correction for pacient and organ movement in SPECT: Application to exercise thallium-201 cardiac imaging. Journal of Nuclear Medicine, vol.29, no.4, April 1988, 441/450 [Goldstein, 1997] - Seth R. Goldstein, Maregaret E. Daube-Witherspoon, Michael V. Green, Alec Eidsath A Head Motion Measurement System Suitable for Emission Computed Tomography IEEE Transactions on Medical Imaging, Vol. 16, No. 1, February 1997 [Gonzalez, 1992] - Gonzalez, R., Woods Digital Image Processing Addison-Wesley (1992), Reading; Menlo Park; New York, 1992. [Haacke, 2000] - E. Marck Haacke, Zhi-Pei Liang Challenges of Imaging Structure and Function with MRI IEEE Engineering In Medicine And Biology, Volume 19, N. 5, September/October 2000, 55/62 [Hansell, 2000] - David M- Hansell Imaging the Lungs with Computed Tomography IEEE Engineering In Medicine And Biology, Volume 19, N. 5, September/October 2000, 71/79 [Jahne, 2000] - Bernd Jahne, Horst Haussecker Computer Vision and Applications Academic Press [Jain, 1995] - Ramesh Jain, Rangachar Kasturi, Brian G. Schunk Machine Vision McGraw-Hill, International Editions [Kak, 1999] - Avinash C. Kak, Malcolm Slaney Principles of Computerized Tomographic Imaging IEEE Press [Kruglinski, 1996] - David J. Kruglinski Inside Visual C++ Microsoft Press [Lain, 1991] - Kai H. Lee Computers in Nuclear Medicine: A Practical Approach The Society of Nuclear Medicine, Inc. [Lee, 1998] - KJ Lee, DC Barber Use of Forward projection to correct patient motion during SPECT imaging Physics in Medicine and Biology, Vol. 43, No. 1, Jan. 1998, 171/187 [Lind, 1997] - Jacob Lind, Lasse Riis Ostergaard, Ole Vilhelm Larsen, Henning Nielsen, Niels Jacob Bartholdy, Jens Haase 3D Localisation System for Localisation of Malformations in the Human Brain Virtual Brain Project [Maciel] - Carlos Maciel O Processamento Digital de Imagens Brasil, ,Curso de Ciências de Computação

124

Page 133: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

[Maybank, 1992] - Stephen J. Maybank, Olivier D. Faugeras A Theory of Self-Calibration of a Moving Camera Intern. Journal of Computer Vision, 8:2. 123-151, 1992 [Press, 1992] - WilliamH. Press, Saul A. Teukolsky, William T. Vetterling, Brian P. Flannery Numerical recipes- The Art of Scientific Computing Cambridge University Press - 1992 Second Edition [Richter, 1995] - Jeffrey Richter Advanced Windows Microsoft Press [ Prosise, 1999] - Jeff Prosise Programming Windows with MFC , Second Edition Microsoft Press [Riederer, 2000] - Stephen J. Riederer Current Technical Development of Magnetic Resonance Imaging IEEE Engineering In Medicine And Biology, Volume 19, N. 5, September/October 2000, 34/41 [Robins, 2000] - Peter S. Robins SPECT Versus Planar and Whole Body Bone Imaging Kapiolani Medical Center for Women and Children Section of Nuclear Medicine [Sauve, 1999] - Anne C. Sauve, Alfred O. Hero, W. Leslie Rogers, Scott J. Wilderman, Neal H. Clinthorne 3D Image Reconstruction for a Compton SPECT Camera Model IEEE Transactions on Nuclear Science, Vol. 46, NO. 6, December 1999, 2075/2084 [Slijpen, 1999] - Eddy T.P. Slijpen, Freek J. Beekman Comparison of Post-Filtering and filtering Between Iterations for SPECT Reconstruction IEEE Transactions on Nuclear Science, Vol. 46, NO. 6, December 1999, 2233/2238 [Tavares, 1995] - João Tavares Obtenção de Estrutura Tridimensional a Partir de Movimento de Câmara Faculdade de Engenharia da Universidade do Porto [Tavares2, 1995] - João Tavares Algumas Ferramentas para Visão Tridimensional por Computador Faculdade de Engenharia da Universidade do Porto [Tsai, 1987] - Roger Y. Tsai A Versatile Camera Calibration Technique for High. Accuracy 3D Machine Vision Metrology Using Off-the-Shelf TV Cameras and Lenses IEEE Journal of Robotics and Automation, Vol. RA-3, NO. 4,August 1987, 323/344 [Turner, 2000] - Robert Turner, Roger J. Ordidge Technical Challenges of Functional Magnetic Resonance Imaging IEEE Engineering In Medicine And Biology, Volume 19, N. 5, September/October 2000, 42/54 [Vollmar, 1999] - St. Vollmar, W. Eschner, K. Wienhard, U. Pietrzyk Iterative Reconstruction of Emission Tomography Data with A-Priori-Information IEEE Transactions on Nuclear Science, Vol. 46, NO. 6, December 1999, 1560/1561 [Webb, 1996] - Steve Webb The Physics of Medical Imaging Institute of Physics Publishing, Bristol and Philadelphia [Wells, 2000] - Peter N.T. Wells Current Status and Future Technical Advances of Ultrasonic Imaging

125

Page 134: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

IEEE Engineering In Medicine And Biology, Volume 19, N. 5, September/October 2000, 14/20 [Williams, 2001] - Scott C. Williams Nuclear Medicine Textbook Autminie.com [Zhang, 1998] - Zhengyou Zhang A Flexible New Technique for Camera Calibration Technical Report MSR-TR-98-71, Microsoft Research, Microsoft Corporation Internet Links related to camera calibration http://www.vision.caltech.edu/bouguetj/calib_doc/links.html Carnegie Mellon - School of Computer Science http://www.cs.cmu.edu/afs/cs.cmu.edu/usr/rgw/www/ Medical Image Format Site http://www.dclunie.com/ Digital Imaging and Communications in Medicine (DICOM) section of the Hershey Medical Center Radiology http://www.xray.hmc.psu.edu/dicom/ National Institute of Health - Image Links http://rsb.info.nih.gov/nih-image/links.html University of California, Berkeley - Computer Science Technical Reports http://sunsite.berkeley.edu/NCSTRL/ Elsevier Science - Image and Vision Computing http://www.elsevier.nl/inca/publications/store/5/2/5/4/4/3/ Paul Sharkey's Selected Abstracts http://www.cyber.rdg.ac.uk/people//people/pms/WWW/abstracts.html The Hebrew University - Computer Vision Papers http://www.cs.huji.ac.il/papers/IP/ AAPM Medical Physics Resource Page http://aapm.org/medphys/ Society of Nuclear Medicine: Computer and Instrumentation Council http://gamma.wustl.edu/tf/caic2a.html#anchor4937168 CTSim - The Open Source Computed Tomography Simulator http://www.ctsim.org/ Fessler, Jeffrey A. EECS http://www.eecs.umich.edu/~fessler/ MCO - Radiology - Nuclear Medicine http://www.mco.edu/depts/radiology/nuclearmed.html Mediabook Tracers http://laxmi.nuc.ucla.edu:8000/NM-Mediabook/frame_tracers.html Medical Imaging Related Links

126

Page 135: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

http://www5.bae.ncsu.edu/bae/research/blanchard/www/465/textbook/imaging/links/ Medicina Nuclear en Internet http://members.nbci.com/sano/gamma.htm MEDLINEplus Health Information from the National Library of Medicine http://www.nlm.nih.gov/medlineplus/ National Nuclear Data Center http://www.nndc.bnl.gov/ Nuclear Medicine on the Net http://www.nucmednet.com/frameset.htm Nuclear Medicine Protocols http://www.keston.com/Proto/ Nuclear Medicine http://www5.bae.ncsu.edu/bae/research/blanchard/www/465/textbook/otherprojects/nuclear_97/ Positron Emission TomographyRobyn J. Mullen http://www5.bae.ncsu.edu/bae/research/blanchard/www/465/textbook/imaging/projects/PET/ SPECT - Chris Scarfone - Duke University Medical Center http://www.bae.ncsu.edu/bae/courses/bae590f/1995/scarfone/index.html Society of Nuclear Medicine http://www.snm.org/nuclear/new_whats_nm_1.html SPECT and PET Information http://teach.bhs.mq.edu.au/~tbates/imaging_techniques/PET_&_SPECT/SPECT_&_PET.html SPECT http://www.tbilaw.com/SPECT.html SPECT versus Planar and Whole Body Bone Imaging http://www.lava.net/~peterr/teaching/spondylo.html Nuclear Medicine Service http://www.wramc.amedd.army.mil/departments/nuclear/ Computing and Image Processing http://www.biomed.abdn.ac.uk/Research/Computing/abstracts.html efg's Image Processing http://www.efg2.com/Lab/Library/ImageProcessing/ Image Processing Library 98 http://www.mip.sdu.dk/ipl98/ Medical Imaging/Scientific Visualization resources http://mipgsun.mipg.upenn.edu/~Vnews/usefulwww.html Medical Imaging Resources: Geographic Listing http://www.comp.leeds.ac.uk/comir/resources/links_g.html C++ class library for image manipulation http://www.paintlib.de/paintlib/ The Vision and Modeling Group

127

Page 136: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

http://vismod.www.media.mit.edu/ CodeGuru - Developer site http://codeguru.earthweb.com/ Interfacing the Serial / RS232 Port http://www.beyondlogic.org/serial/serial.htm Code Project http://www.codeproject.com Visual C++ Resources http://www.aul.fiu.edu/tech/visualc.html Institut für Biomedizinische Technik http://www-ibt.etec.uni-karlsruhe.de/ Machine Vision - Proverbs, Opinions And Folklore http://www.eeng.dcu.ie/~whelanp/proverbs/proverbs.html Vision Systems http://www.cm.cf.ac.uk/Dave/Vision_lecture/Vision_lecture_caller.html Collection of Web sites on Image Processing http://www.hal.t.u-tokyo.ac.jp/~pasqual/image.html Image processing and computer vision http://peipa.essex.ac.uk/info/links.html Image Processing Fundamentals http://www.ph.tn.tudelft.nl/Courses/FIP/noframes/fip.html Image Processing http://www.dip.ee.uct.ac.za/imageproc/ The Biomedical Engineering Network http://www.bmenet.org/BMEnet/ Medical Imaging Research Group http://www.physics.ubc.ca/~mirg/

128

Page 137: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Page 138: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

ANEXO

Manual do

Utilizador

Page 139: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

ANEXO

Características das

Câmaras

Page 140: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Caracteristicas Valores Tipo TC-5011 Elemento sensor Sensor CCD de 1/3 de polegada Número de pixels CCIR 500(H) x 582 (V) Tamanho da célula CCIR 9.8 �m(H) x 6.3 �m(V) Sistema de cinsronização Interno Sistema de scan 2:1 entrelaçado Resolução 420 linhas horizontais de TV S/N ratio Mais de 46 dB (AGC off) Caracteristica gama GAMMA = 0.45 Minimo de iluminação 0.2 Lux F1.4 IRIS Electrónico IRIS CCD Saída video 1Vp~p 75 � Tensão de alimentação DC 12 V Corrente 120 mA Dimensões 39 (W) x 43 (H) x 72 (L) mm Peso 150 g

Page 141: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

ANEXO

Características do

Frame Grabber

Page 142: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

MATROX METEOR I Esquema básico:

Entrada Composta

Composto 1 / RComposto 2 / GComposto 3 / B

Composto 4 / Sync

Entrada S-Video ouTrigger

Software:

Matrox imaging library(MIL-Lite) - É uma biblioteca de alto nível em c com comandos para aquisição, transferência e display de imagem. Especificações:

�� Entrada video seleccionável por software.(4 canais) �� Luminosidade, contraste,tonalidade e saturação programáveis. �� Video cor standard ou monocromático: NTSC/PAL/SECAM, RS-170/CCIR, Composto ou Y/C �� Jitter de pixel: � 3ns (tipicamente)

Capacidade de transferência até 45MB/seg dependendo do sistema ou da placa VGA. Requisitos: 9 MB/seg � 640 x 480 x 8 a 30fps RS-170. 11 MB/seg � 768 x 576 x 8 a 25fps CCIR. 35 MB/seg � 640 x 480 x24 a 30fps NTSC ou RGB. 42 MB/seg � 768 x 576 x 24 a 25fps PAL ou RGB. Interface: Interface PCI 32 bit.

Conector de entrada video - DB9 para composto ou RGB. Entrada phono jack para sinal video composto. Entrada Y/C separada (4 pinos mini din).

Page 143: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Conectores:

DB-9 fêmea.

aracteristicas:

Consumo < 7.5 Watts 55 cm x 10.55 cm

sável)

S-VHS. Phono. C

Tamanho da placa: 23.Temperatura de operação de 0º a 55º C Humidade relativa: até 95% (não conden

Page 144: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

ANEXO

Transformações Geométricas em

2D e 3D

Page 145: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Transformações Geométricas em 2D Translação

A translação de pontos que se encontrem no plano (x, y) é efectuada através da soma de quantidades de translação às suas coordenadas.

x' = x + tx , y' = y + ty ou

��

���

''

yx

= + ��

���

yx

��

���

y

x

tt

Rotação A rotação dos pontos de um objecto de um ângulo � consiste em alterar as coordenadas de cada ponto do objecto substituindo-as por uma função pesada das coordenadas anteriores, em que o peso depende de �. x' = x*cos� - y*sen�, y' = x*sen � + y*cos�

ou

��

���

''

yx

= * ��

����

θsenθsenθθ

coscos

��

���

yx

Nota: Ângulos de rotação positivos são medidos segundo o sentido contrário dos ponteiros do relógio, para ângulos negativos o sentido é o dos ponteiros do relógio.

A rotação é efectuada em torno da origem do referencial podendo no entanto ser efectuada em torno de um ponto arbitrário.

Escalonamento

O escalonamento de pontos consiste em multiplicar as coordenadas do ponto do objecto a escalonar pelo factor de escalonamento, sx e sy, pelas coordenadas x e y respectivamente.

x' = x * sx , y' = y * sy ou

��

���

''

yx

= * ��

���

y

x

ss0

0��

���

yx

Nota:

Se sx e sy forem diferentes obteremos um objecto com proporções alteradas. O escalonamento é feito em relação à origem do referencial, fazendo com que o ponto se afaste

ou aproxime do referencial, podendo no entanto ser efectuado em relação a um ponto arbitrário.

Distorção

Page 146: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

A distorção consiste na alteração das coordenadas de cada ponto do objecto substituindo-as por uma função pesada das coordenadas anteriores.

x' = x*d1 + y*d2 , y' = x*d3 + y*d4 ou

��

���

''

yx

= * ��

���

43

21

dddd

��

���

yx

Nota:

Pode-se transladar, escalonar, rodar ou efectuar outras operações a um objecto efectuando a operação nos pontos extremos de cada segmento de recta que o compõe de forma a não ter que efectuar a operação no objecto ponto por ponto, minimizando o tempo de processamento. Equações homogéneas Uma vez que a translação envolve a operação adição enquanto as restantes envolvem a operação multiplicação torna-se impossível representar um conjunto de operações numa só matriz. Assim de modo a podermos representar todas as transformações pelo mesmo tipo de operação representamos os pontos nas suas coordenadas homogéneas. Assim em coordenadas homogéneas acrescentamos uma coordenada ao ponto. Assim cada ponto deixa de possuir um par de coordenadas para passar a ter 3 coordenadas.

(x, y) � (x, y, w)

�� Dois conjuntos de pontos em coordenadas homogéneas representam o mesmo ponto se umas são múltiplas das outras, ou seja cada ponto tem em coordenadas homogéneas várias representações possíveis.

�� Pelo menos uma das coordenadas homogéneas do ponto tem de ser diferente de zero. �� Dividindo as coordenadas x e y pela terceira coordenada homogénea obtemos as

coordenadas cartesianas do ponto homogéneo. �� Os pontos que possuam w = 0 são apelidados de pontos no infinito. �� Todas as representações de um ponto homogéneo formam uma recta no espaço 3D que

passa na origem , para cada w=c ,�c encontramos um plano de definição do espaço 2D

As operações anteriormente demonstradas passam a ser representadas em coordenadas homogéneas do seguinte modo:

____________________________________________________________________ Translação

���

���

1''

yx

= *

���

���

1001001

y

x

tt

���

���

1yx

Nota:

A translação tem a propriedade aditiva, isto é:

Se = * e = *

���

���

1''

yx

���

���

1001001

y

x

tt

���

���

1yx

���

���

1''''

yx

���

���

100'10'01

y

x

tt

���

���

1''

yx

então

Page 147: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

���

���

1''''

yx

= * � = *

���

���

100'10'01

y

x

tt

���

���

1001001

y

x

tt

���

���

1yx

���

���

1''

yx

���

���

100'10'01

yy

xx

tttt

���

���

1yx

____________________________________________________________________ Rotação

���

���

1''

yx

= *

���

��

���

1000cos0cos

θsenθsenθθ

���

���

1yx

A rotação tem a propriedade aditiva, isto é:

Se = * e = *

���

���

1''

yx

���

��

���

1000cos0cos

θsenθsenθθ

���

���

1yx

���

���

1''''

yx

���

��

���

1000cos0cos

φsenφsenφφ

���

���

1''

yx

então

���

���

1''''

yx

= * �

= *

���

��

���

1000cos0cos

φsenφsenφφ

���

���

1''

yx

���

0

cosφ)sen(θφ)(θ

���

��

���

1000cos0cos

θsenθsenθθ

���

��

100cos0

φ)(θφ)sen(θ

���

���

1yx

���

���

1yx

____________________________________________________________________ Escalonamento

���

���

1''

yx

= *

���

���

1000000

y

x

ss

���

���

1yx

Nota:

O escalonamento tem a propriedade multiplicativa, isto é:

Se = * e = *

���

���

1''

yx

���

���

1000000

y

x

ss

���

���

1yx

���

���

1''''

yx

���

���

1000'000'

y

x

ss

���

���

1''

yx

Então

���

���

1''''

yx

= * � = *

���

���

1000'000'

y

x

ss

���

���

1000000

y

x

ss

���

���

1yx

���

���

1''

yx

���

���

1000.'000.'

yy

xx

ssss

���

���

1yx

____________________________________________________________________

Distorção

Page 148: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

���

���

1''

yx

= *

���

���

10000

43

21

dddd

���

���

1yx

Composição de transformações geométricas

A combinação das matrizes representativas das transformações fundamentais pode ser efectuada

aumentando assim a eficiência pela aplicação de uma transformação composta a um ponto, em vez da aplicação de uma série de transformações uma após a outra.

Exemplo: Rotação de um objecto em torno de um ponto arbitrário.

1) Translação de modo que o ponto arbitrário se localize na origem. 2) Rotação. 3) Translação de modo que o ponto arbitrário retorne à sua posição original.

Sendo P(x1, y1)

���

���

1''

yx

= * �

= *

���

���

1001001

1

1

yx

���

���

1''

yx

���

0

cossenθ

θ

���

��

���

1000cos0cos

θsenθsenθθ

��

10)cos1.(cos)cos1.(

1

1

θyθθxsenθ

���

���

1001001

1

1

yx

���

.

.

1

1

senθxsenθy

���

���

1yx

���

���

1yx

Nota:

Para o escalonamento é possível fazê-lo em relação a um ponto arbitrário seguindo o mesmo procedimento adaptado ao escalonamento.

No geral a multiplicação de matrizes de transformações geométricas não é comutativa.

Transformações geométricas em 3D

Em coordenadas homogéneas tal como em 2D podemos representar as transformações por uma matriz de 3x3 em 3D podemos representálas numa matriz de 4x4. Os pontos são representados por um quádruplo em vez de um triplo.

(x, y, z) � (x, y, z, w)

�� Dois conjuntos de pontos em coordenadas homogéneas representam o mesmo ponto se umas são múltiplas das outras, ou seja cada ponto tem em coordenadas homogéneas várias representações possíveis.

�� Pelo menos uma das coordenadas homogéneas do ponto tem de ser diferente de zero. �� Dividindo as coordenadas x, y ez pela quarta coordenada homogénea obtemos as

coordenadas cartesianas do ponto homogéneo. �� Os pontos que possuam w = 0 são apelidados de pontos no infinito. �� Todas as representações de um ponto homogéneo formam uma recta no espaço 4D que

passa na origem , para cada w =c ,�c encontramos um subespaço de definição do espaço 3D.

Page 149: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Utilizamos o sistema de coordenadas da mão direita. Podemos verificar o sentido positivo das rotações pela figura

z

y

x

A transformação de coordenadas é efectuada assim da seguinte forma:

���

���

'''

zyx

= M.

���

���

zyx

Em que M é a matriz representativa das transformações básicas em 3D , que são:

Translação

����

����

1000100010001

z

y

x

ttt

Rotação

Em torno do eixo dos z

����

��

����

1000010000cos00cos

θsenθsenθθ

Em torno do eixo dos y

����

�����

10000cos0001000cos

θsenθ

senθθ

Page 150: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Em torno do eixo dos x

����

����

10000cos00cos00001

θsenθsenθθ

Escalonamento

����

����

1000000000000

z

y

x

ss

s

Distorção

����

����

1000000

987

654

321

ddddddddd

O resultado da multiplicação destes 3 tipos de matrizes terá a forma:

����

����

1000333231

232221

131211

z

y

x

trrrtrrrtrrr

De modo a aumentar a eficiência computacional podemos fazer os cálculos usando a seguinte

notação:

���

���

'''

zyx

= R* + T , onde R = e T =

���

���

zyx

���

���

333231

232221

131211

rrrrrrrrr

���

���

z

y

x

t

tt

Nota: A composição de transformações em 3D segue a mesma perspectiva que em 2D, ou seja divide-se o

problema original em sub - problemas nos quais se utilizam as transformações primitivas .

Outras transformações geométricas em 3D Transformação projecção

Page 151: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Tudo se passa como se o observador projectasse a cena ou o objecto segundo uma direcção paralela à direcção de projecção sobre um plano que é perpendicular à respectiva direcção de projecção. Neste caso o centro de projecção localiza-se no infinito. Projecção segundo direcção x

����

����

1000010000100000

Projecção segundo direcção y

����

����

1000010000000001

P (x, y, z)

P (x, y, z)

Projecção segundo direcção z

����

����

1000000000100001

Transformação projecção perspectiva

P (x, y, z)

No caso de transformação perspectiva o centro de projecção não se localiza no infinito mas sim a

uma distância d do plano de projecção. Uma vez que este tipo de projecção não tem interesse directo para o projecto limitamo-nos a referir a sua existência.

Page 152: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

ANEXO

Exemplo de um Exame

SPECT Planar

Page 153: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Exemplo de imagens obtidas por exame SPECT Planar ( Rins) Imagens numeradas em sequência

Page 154: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Page 155: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Page 156: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Page 157: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Page 158: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

ANEXO

Radionuclidos

Page 159: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

1 - Radionuclidos

A qualidade de controlo dos rádiofarmacos é feita através da análise destes quatro itens: esterilidade, pureza química, pureza do radionuclido e pureza radioquimica. 1.1- Esterilidade

O gerador e o kit do produto são testados para esterilidade e pirogénios pelo fabricante durante a produção.

Os pirogénios são endotoxinas bacteriais que produzem um estado febril. O teste de limulus é utilizado para detectar a presença de pirogénios. Os testes usam um agente derivado do sangue dos cravos de ferradura (limulus polyphemus). O limulus extraído forma um gel quando misturado com endotoxinas. 1.2- Pureza quimica

O alumínio (Al+3) é um contaminante químico que pode ser encontrado na solução de Technetium, mas isso muito raramente é um problema nos geradores actuais. O alumínio pode interferir com algumas reacções etiquetáveis. A USP (United States Pharmacopeia) limita a quantidade de alumínio que pode ser detectada a menos de 10 micro/ml. 1.3- Pureza do radionuclido

O Mobylednum é o mais importante radionuclido contaminante. De cada vez que um gerador é solvido deve ser avaliado para passagens de Mo-99.

Quando administrado intravenosamente o mobylednum é fagocitado pelo sistema reticuloendotelial. O seu tempo de vida longo e as suas emissões beta resultam numa dose muito elevada de radiação apesar de proveniente de uma pequena quantidade de actividade. No entanto outras contaminantes radionuclidos tais como I-131 , Ru-103,Sr-89 e Sr-90 podem ser detectados.

Outros contaminantes mais raros que são de menos importância clínica incluem Nb-92 , Nb-95 e Zr-95. No Mo-99 produzido por irradiação de neutrões, sendo que as impurezas mais comuns são Cs-134,Co-60, Rb-86 e Sb-124. 1.4-Pureza radioquimica

As impurezas radioquímicas são os compostos de Tc-99m que não os desejados para uso radiofarmacêutico. Existem sempre alguns não etiquetados Tc-pertechnate bem como technetium colloids não solúveis. 1.5 - Tabela com radioisótopos e aplicações correntes

Rádioisotopo Meia-Vida (Half-Life)

Aplicações

Ac-225 10.0d Acessório monoclonal do anticorpo usado para o tratamento do cancro (RIT), também parente de Bi-213.

Ac-227 21.8a Parente de Ra-223 (Acessório monoclonal do anticorpo usado para o tratamento do cancro (RIT) ).

Am-241 432a Detecção de osteoporose, visionamento do coração

Page 160: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

As-72 26.0h Visualização planar, SPECT ou PET.

As-74 17.8d Isótopo emissor de positrões com aplicações biomédicas.

At-211 7.21h Acessório monoclonal do anticorpo (emissor alfa) usado para o tratamento do (RIT), usado com F-18 para estudos in vivo.

Au-198 2.69d Tratamento do cancro usando mini-gun (B), tratamento de cancro dos ovários, prostata, ecérebro.

B-11 Estável Tratamento de melanoma e tumor de cérebro.

Be-7 53.2d Usado no estudo da berylliosis.

Bi-212 1.10h Acessório monoclonal do anticorpo (emissor alfa) usado para o tratamento do (RIT), estudo de dosimetria celular.

Bi-213 45.6m Acessório monoclonal do anticorpo (emissor alfa) usado para o tratamento do (RIT),

Br-75 98m Visualização planar , SPECT ou PET (C).

Br-77 57h Etiqueta radiosentizers para a quantização de Te da hypoxia em tumores, e etiquetagem monoclonal do anticorpo.

C-11 20.3m Radioisótopo em PET para estudar funções cerebrais normais ou anormais.

C-14 5730y Etiquetagem isotópica para detecção de tumores (breast, et al.).

Ca-48 Estável

Cd-109 462d Detecção de cancro, visualização pediátrica

Ce-139 138d Calibra detectores de germânio de elevada.

Ce-141 32.5d Diagnóstico de tracto gastrointestinal, medição de fluxo sanguineo do miocárdio.

Cf-252 2.64a Tratamento de cancro cervical, melanoma e cérebro .

Co-55 17.5h Visualização planar SPECT ou PET. Usado em PET para visualização de tecidos cerebrais danificados após .

Co-57 272d Calibração de câmara gama, deve ser dada alta prioridade,

Page 161: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

para raio-X .

Co-60 5.27a Teleterapia(destrói células cancerosas), desinfecção de equipamento cirurgico e médico, terapia externa por raiação para o cancro .

Cr-51 27.7d Médica, dosimetria, etiquetagem de células

Cs-130 29.2m Agente localizador miocárdico

Cs-131 9.69d Implantes intercavitais para radioterapia.

Cs-137 30.2a Irradiadores de sangue, visualização PET, tratamento de tumores.

Cu-61 3.35h Visualização planar, SPECT ou PET

Cu-62 4.7m Radionuclido emissor de positrão, usado como radioisótopo em conjunção com Cu 64 em fluxo sanguineo do miocárdio e cérebro

Cu-64 12.7h Visualização PET, visualização planar, visualização SPECT, estudos de dosimetria, fluxo sanguíneo de cérebro e miocárdio, usado com Cu 62 tratamento de cancro colorectal.

Cu-67 61.9h Tratamento/diagnóstico de cancro, monoclonal de anticorpos, radioimunoterapia, visualização planar, SPECT ou PET.

Dy-165 2.33h Sinovectomia de radiação, tratamento de artrite reumatoidal.

Eu-152 13.4a Médica.

Eu-155 4.73a Detecção de osteoporose.

F-18 110m Radioisótopo para o cérebro, estudos PET.

Fe-55 2.73a Fonte de aquecimento.

Fe-59 44.5d Médica.

Ga-64 2.63m Tratamento de doenças pulmonares (fibrose dos pulmões).

Ga-67 78.3h Visualização de infecções abdominais, detecção de linfoma de Hodgkins, usado com In-111 para infecç~oes de tecidos moles e detecção de osteomelite, avaliação de doenças granulosas tais como a sarcoidiodis e outros, particularmente pulmões e mediastiusim .

Page 162: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Ga-68 68.1m Estudo de tromboses e artereoesclerose, visualização PET, detecção de cancro pancreático correcção de atenuação.

Gd-153 242d Fonte dual de fotões, detecção de osteoporose, visualização SPECT.

Ge-68 271d Visualização PET.

H-3 12.3a Visualização PET, etiquetagem.

I-122 3.6m Estudo de fluxo sanguíneo cerebral

I-123 13.1h Visualização de cérebro, tiróide, rim e miocárdio, fluxo sanguíneo cerebral, doenças neurológicas.

I-124 4.17d Radioisótopo usado para criar imagens da tiróide humana, visualização PET.

I-125 59.9d Detecção da osteoporose, visualização diagnóstica, localizador para drogas, anticorpos monoclonais, tratamento de cancro cerebral(substituto de I-131),visualização SPECT,etiquetagem com radiação, visualização de tumores, mapeamento de receptores cerebrais, terapia de radiação intersticial para tratamento do cancro da próstata.

I-131 8.04d Tratamento de tumor /hipertiroidismo de tecidos linfáticos, etiquetagem de anticorpos, bioquimica cerebral em doenças mentais, agente renal, problemas da tiróide, alternativa ao Tl-201 para radioimunoterapia , visualização, dosimetria celular, cintilografia, , tratamento da doença de Graves, tratamento de goiters, visualização SPECT, tratamento do cancro da próstata, tratamento de melanoma, localização de infecções de osteomyelitis, etiquetagem radioactiva, localização de tumores para remoção, tratemnto de tumores espinais, localizaçao de lesões metastáticas , terapia de radiação interna, trataemnto do carcinoma da tiróide.

I-132 2.28h Mapeamento preciso de região do tumor cerebral antes de operação.

In-111 2.81d Detecção de rejeição de transplante do coração, visualização de infecções abdominais, etiquetagem de anticorpos, , imunologia celular, usado com Ga-67 para detecção de infecções de tecidos moles e ostemyelitis , concentração no figado, rins,alta actividade especifica, visualização de células brancas sanguineas, dosimetria celular, visualização do miocárdio, tratamento da leucemia, visualização de tumores

In-115m 4.49h Etiquetagem de elementos sanguineos para avaliação da doença inflamatória de Bowel.

Page 163: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Ir-191m 6s Angiografia cardiovascular.

Ir-192 73.8d Implante de sementes para o tratamento do cancro da próstata, cérebro, mama, e ginecológico.

Kr-81m 13.3s Visualização pulmonar.

Lu-177 6.68d Tratamento de doença do coração, terapia de cancro.

Mn-51 46.2m Agente localizador do miocárdio.

Mn-52 5.59d Visualização PET

Mo-99 65.9h Parente de gerador Tc-99m usado para cérebro, pulmões, fígado e visualização do coração.

N-13 9.97m Visualização PET, perfusão do miocárdio.

Nb-95 35d Estudos do efeito de radioactividade em grávidas e fetos, localizador do miocárdio, visualização PET.

O-15 122s Água usada para medições tomográficas do fluxo sanguíneo cerebral, visualização PET e SPECT.

Os-191 15.4d Parente do gerador Ir-191m para angiografia cardiovascular.

Os-194 6.00a Acessório monoclonal do anticorpo (emissor alfa) usado para o tratamento do (RIT

P-32 14.3d Polycythaemia Rubra Vera (doença de células sanguíneas) e leucemia, tratamento / diagnóstico de doenças dos ossos, visualização SPECT de tumores, tratamento do cancro do pâncreas etiquetagem radioactiva.

P-33 25d Etiquetagem

Pb-203 2.16d Visualização planar, SPECT ou PET (usado com Bi-212), imunoterapia de anticorpos monoclonais, dosimetria celular.

Pb-212 10.6h Etiquetagem radioactiva para terapia usando anticorpos, dosimetria celular.

Pd-103 17d Tratamento do cancro da próstata.

Pd-109 13.4h Agente radioterapeutico potencial.

Page 164: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Pu-238 2.3a Pacemaker (sem contaminantes Pu-236).

Ra-223 11.4d Acessório monoclonal do anticorpo (emissor alfa) usado para o tratamento do (RIT), estudo de dosimetria celular.

Ra-226 1.60e3a Isótopo alvo para fazer Ac-227, Th-228, Th-229 (Parentes deemissores alfa usado para o RIT).

Rb-82 1.27m Agente de visualização do miocárdio, detecção precoce de doenças da artéria coronária , visualização PET, localizadores de fluxo sanguineo.

Re-186 3.9d Tratamento/ diagnóstico de cancro, anticorpos monoclonais, alivio de dor de cancro dos ossos, tratamento de artrite reumatoidal, tratamento do cancro da próstata, tratamento da dor de ossos.

Re-188 17h Tratamento de cancro , anticorpos monoclonais.

Rh-105 35.4h Aplicações terapeuticas potenciais: etiquetagem de moléculas e anticorpos monoclonais.

Ru-97 2.89d Etiquetaghem de anticorpos monoclonais, visualização planar, SPECT ou PET, visualização por câmara gama.

Ru-103 39d Fluxo sanguíneo do miocárdio, etiquetagem radioactiva de microesferas, visualização PET.

S-35 87.2d Etiquetagem de ácidos nucleicos,substituoto de P-32, dosimetria celular.

Sc-46 84d Estudos de fluxo sanguíneos locais, visualização PET.

Sc-47 3.34d Tratamento / diagnóstico do cancro, anticorpos monoclonais, radioimunoterapia.

Se-72 8.4d Visualização do cérebro, sistema gerador com As-72, anticorpo monoclonal.

Se-75 120d Localizador radioactivo usado em estudos cerebrais, visualização por cintilografia.

Si-28 Estável Terapia por radiação do cancro.

Sm-145 340d Tratamento do cancro do cérebro usando I-127 (D).

Sm-153 2.00d

Page 165: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

alivio de dor de cancro dos ossos, tratamento de leucemia.

Sn-117m 13.6d Alivio de dor do cancro dos ossos.

Sr-85 65.0d Visualização cerebral, detecção de lesões cerebrais focais.

Sr-89 50d Paliação da dor do cancro dos ossos, dosimetria celular, myeloma ,tratamento do cancro da próstata,, tratamento de myeloma multipla, terapia osteoblastica , agente potencial para tratamento de metástases do cancro da próstata e mamas.

Sr-90 29.1a Sistema gerador com Y-90 , imunoterapia com anticorpos monoclonais.

Ta-178 9.3m Radionuclido injectado nos pacientes para permitir a visualização das veias e do coração.

Ta-179 1.8a Fonte fluorescente de raio-X.

Ta-182 115d Tratamento do cancro da bexiga, implantes internos.

Tb-149 4.13h Acessório monoclonal do anticorpo usado para o tratamento do cancro (RIT), também parente de Bi-213.

Tc-96 4.3d Estudos em animais com Tc-99m.

Tc-99m 6.01h Visualização do cérebro, coração, fígado, pulmões, ossos, tiróide, e rins, fluxo sanguíneo cerebral local, anticorpos, células sanguíneas vermelhas, substituto de Tl-201.

Th-228 720d Tratamento do cancro, anticorpos monoclonais, parente de Bi-212.

Th-229 7300a Parente para emissor alfa (Bi-213) usado para tyratamento de cancro (RIT), parente de Ac-225.

Tl-201 73.1h Radiologia clínica, visualização do coração, caracteristicas nucleares menos desejáveis que Tc-99m opara SPECT e SPECT planar, perfusão do miocárdio, dosimetria celular.

Tm-170 129d Irradiações sanguíneas portáveis para leucemia, tratamento de linfoma, fonte de potência.

Tm-171 1.9a Médica.

W-188 69.4d Tratamento de cancro, anticorpos monoclonais, parente para gerador de Re-188.

Page 166: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Xe-127 36.4d Visualização neuronal para alterações cerebrais, investigação para alterações neuropsiquiatricas, especialmente esquizofrenia e demência, resoluções SPECT superiores com menores doses para o paciente, visualização de pulmões.

Xe-133 5.25d Visualização de pulmões, fluxo sanguíneo cerebral local ,visualização de fígado, visualização SPECT do cérebro, visualização dos pulmões, detecção de lesões.

Y-88 107d Substituto para Y-90 no desenvolvimento de terapia para tumores cancerígenos.

Y-90 64h Terapia radioactiva interna de cancro do fígado, anticorpos monoclonais, doença de Hodgkins e hepatoma, dosimetria celular, tratamento de artrite reumatoidal,, tratamento de cancro da mama, tratamento de adenocarcinomas gastrointestinal .

Y-91 58.5d Tratamento do cancro (RIT), dosimetria celular..

Yb-169 32d Diagnóstico do trato gastro intestinal

Zn-62 9.22h Parente de Cu-62, um emissor de positrões, usado para o estudo de fluxo sanguineo cerebral e miocardial.

Zn-65 244d Médica.

Zr-95 64.0d Médica.

Page 167: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

��Anexo A – Manual do Utilizador ��Anexo B - Características da câmara ��Anexo C - Características do frame grabber ��Anexo D - Transformações geométricas em 2D e 3D ��Anexo E - Exemplo de imagens obtidas por exame

SPECT planar ��Anexo F - Radionuclidos ��Anexo G - Código implementado

Page 168: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

ANEXO

VPA - Vision Processing Application

Page 169: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Introdução

Este manual destina-se a servir como base de suporte à utilização da aplicação desenvolvida no âmbito do projecto final de curso - PD77 Alinhamento de imagens de medicina nuclear do curso de Engenharia Electrotécnica e de Computadores da Faculdade de Engenharia da Universidade do Porto.

Este manual não fornece as bases teóricas adjacentes às funcionalidades implementadas, tentando apenas fornecer uma visão dos módulos existentes e das capacidades de cada módulo no que concerne a resolver o tipo de situações que estão na origem da sua criação.

Assim se restarem dúvidas acerca do modo de funcionamento de algum módulo será necessário consultar o relatório final do projecto PD 77.

Page 170: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Índice Módulo I - Aquisição

1.1 - Opções de aquisição 1.2 - Grab 1.3 - Aquisição 1.4 - Progresso 1.5 - Informação

Módulo II - Calibração 2.1 - Simulação de uma Câmara de Geometria Interna Conhecida 2.2 - Detecção de Pontos de Calibração na Memória frame. 2.3 - Formatação dos Pontos de Calibração Considerados 2.4 - Calibração de uma Câmara Módulo III - Detecção de Entidades e cálculo de coordenadas 3D

3.1 - Inicialização 3.2 - Detecção de Pontos Característicos e Emparelhamento 3.3 - Obtenção de Informação Tridimensional

Módulo IV - Estimação e correcção de movimento

4.1 - Estimação e Correcção

Page 171: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Módulo I - Aquisição 1.1 - Opções de aquisição

A aquisição a partir de uma câmara ligada ao frame grabber envolve uma quantidade de parâmetros de configuração consideráveis. Parâmetros estes que podem ser configurados na aplicação antes de se realizar a aquisição, de modo a que esta tenha as características adaptadas ao sistema usado.

1) Número de câmaras 2) Canal associado a cada câmara 3) Tipo de sinal vídeo a captar 4) Tipo de imagem a captar 5) Modo de display 6)Escala a utilizar na aquisição 7) Comentários a anexar aos ficheiros do tipo “.BMP” 8) Formato de gravação de sequência de imagens 9) Taxa de compressão de sequência de imagens, em formato AVI-M10) Form

PEG ato de gravação das

) Número de câmaras

Define o número de câmaras a utilizar quando for efectuada a aquisição.

ção usando uma câmara.

2) Cana ssociado a cada câmara

imagens

1

Opções: 1 - Aquisi2 - Aquisição usando duas câmaras.

l a

Define o canal da placa de aquisição a utilizar para ca da câmara utilizada.

nal 1 da placa de aquisição.

3) Tipo de sinal vídeo a captar

Define o tipo de sinal vídeo a captar pela câmara ou câmaras escolhidas. Quando é seleccionada aquisiç

diferen

B

Opções: CH1 - CaCH2 - Canal 2 da placa de aquisição. CH3 - Canal 3 da placa de aquisição. CH4 - Canal 4 da placa de aquisição.

ão com duas câmaras – em 1) - ambas as câmaras terão que ter o mesmo tipo de sinal vídeo. O tipo de sinal vídeo depende da escolha em 4) se esta for RGB teremos tipos de sinal vídeo tes dos que encontramos com a opção GRAY.

Opções: Se 4) em RGNTSC PAL

Page 172: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

SECAM RAY

4) Tipo imagem a captar

Define o tipo de imagem a captar, o que por sua vez depende também do tipo de câmara utilizada, a cores

uisição de imagem a cores. omática.

5) M do de display

Se 4) em GCCIR RS-170

de

ou monocromática. Opções: RGB - AqGRAY - Aquisição de imagem monocr

o

Define o tipo de display a utilizar, variando com o tipo de display a velocidade de refrescamento da ima

ste modo não há otimização de velocidade em imagens a cores, o que pode resultar numa perf

- este modo faz uso de um algoritmo que permite aumentar a velocidade de visualiz

faz uso de dithering melhorando particularmente o display de imagens a

) Escala a utilizar na aquisição

Define a escala da imagem a adquirir.

- imagem adquirida em formato 768 x 576 pixels.

ls .

7) Comen os a anexar aos ficheiros do tipo “.BMP”

Define comentário a anexar às imagens adquiridas, de modo a referenciar as mesmas. Esta opção só se e

) Formato de gravação de sequência de imagens

gem e a qualidade da mesma para aquisição a cores. Opções: BASIC - eormance mais lenta. BASIC OPTIMIZEDação em imagens a cores. ENHANCED - este modo

cores.

6

Opções: NORMALHALF - imagem adquirida em formato 384 x 288 pixels . QUARTER - imagem adquirida em formato 192 x 144 pixe tári

ncontra activa para aquisição de imagem em formato “.BMP”.

8

Define o formato da imagem adquirida para gravação da mesma em disco.

- formato de sequência de imagens “.avi” não comprimido.

) Taxa de compressão de sequência de imagens, em formato AVI-MPEG

Define a taxa de compressão , que pode variar entre 1 e 99, utilizada na gravação da sequência de imagen

Opções: AVI-DIB AVI-MJPG - formato de sequência de imagens “.avi” comprimido.

9

s do tipo “.avi” comprimido encontrando-se activo apenas no caso da opção AVI-MJPG se encontrar seleccionada em 8).

Page 173: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

10) Formato de gravação das imagens

Define o formato da imagem adquirida para gravação da mesma em disco.

mato

.2 - Grab

Este módulo permite alterar as referências da placa de aquisição no que concerne ao brilho, contras

1) Zoom in

e imagem

res de propriedades de image

) Zoom in

C ez que é pressionado efectua um zoom à imagem duplicando o seu tamanho.

) Zoom out

C ez que é pressionado efectua um zoom à imagem diminuindo o seu tamanho para metade do tamanh

) Aquisição de imagem

a aquisição da imagem que se encontrar activa na janela de aquisição gravando de imedia ódulo

uirir.

) Visualização

opção se encontrar activa, após a gravação para disco, o ficheiro será aberto e visualizado. Esta op

Opções: BMP - forTIFF - formato MIL - formato

1

te, saturação e tonalidade das imagens adquiridas. E adquirir e visualizar imagens em qualquer dos canais do fram grabber.

2) Zoom out 3) Aquisição d4) Visualização 5) Canal 6) Selecto

m

1

ada v

2

ada v

o actual. 3

Efectuato a imagem para um ficheiro em disco com o formato de imagem seleccionado em 9) do M

de aquisição- Opções de aquisição. As dimensões da imagem adquirida são as da imagem que se encontrar em visualização. As opções de zoom não interferem com as dimensões da imagem a adq 4

Se esta ção só se encontrará activa se o formato de imagem seleccionado em 9) do Módulo de aquisição-

Opções de aquisição for o formato BMP .

Page 174: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

5) Canal

ermite alterar o canal da placa de aquisição seleccionado (canal este que fornece o sinal vídeo) a partir d

) Selectores de propriedades de imagem

alterar os valores de luminosidade, contraste, tonalidade e saturação que a placa de aquisiç ela de

.3 - Aquisição

Foram implementados vários esquemas de aquisição que no

1) Tipo de aquisição ultiple shot

odo Multiple shot /

entre aquisições em modo Multiple shot / Temp

o de trigger a utilizar gravação das

imageo

quisições em modo Sequence

sequênocalização, em disco, da gravação da

sequênuisição

) Tipo de aquisição

uisição pode ser feita em dois modos.

- É adquirida uma sequência de n imagens, com n definido em 10), a uma cadência de uma im

odendo os instantes de aquisição

2) Tipo de aquisição Multiple shot

Po qual se está a visualizar as imagens de modo a podermos captar imagens 3) ou alterar os valores

dos selectores de imagem 6) tendo a possibilidade de visualizar imagens de todas as câmaras ligadas ao sistema. 6

Permiteão usa para efectuar a aquisição de imagem verificando os seus efeitos imediatamente na jan

aquisição. 1

s permitem adquirir imagens de um modo sequencial de acordo com vários parâmetros ajustáveis.

2) Tipo de aquisição M3) Número de imagens a adquirir 4) Tempo inicial de aquisição em m

Temporal 5) Tempooral 6) Tip7) Localização, em disco, da

ns adquiridas 8) Visualizaçã9) Tempo entre a10) Número de imagens a adquirir para a cia 11) Lcia adquirida 12) Opções de aq

1

A aq

Opções: Sequênciaagem por cada intervalo especificado em 9) para o path indicado em 11) com as caracteristicas

de ficheiro definidas em 7) e 8) do Módulo de aquisição - Opções de aquisição Multiple Shot - Permite adquirir as imagens de um modo sequencial, pserem activados de dois modos distintos.

Page 175: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Aquisição em modo sequencial de n imagens, com n definido em 3) .

- São adquiridas n imagens em intervalos de tempo definidos em 5) após um período de espera

idas n imagens a uma cadência dependente dos instantes de trigger. Trigger es

3) Número de im gens a adquirir

de imagens a adquirir em modo Multiple Shot , após o qual se dá por terminado o proces

) Tempo inicial de aquisição em modo Multiple shot-Temporal

inicial a partir do qual é iniciado o processo de captura em modo Multiple Shot / Temporal. Pode s

) Tempo entre aquisições em modo Multiple shot-Temporal

empo entre aquisições de imagem em modo Multipler Shot / Temporal . Pode ser especificado em minu

) Tipo de trigger a utilizar

Tipo de Trigger que despoleta a aquisição de imagem para o modo Multiple Shot / Trigger. Podem ser sel

vento de trigger a partir do teclado, com o pressionar das teclas “C” e “SPACE” a servirem d

ento de trigger a partir da porta série efectuado por pressão do botão de porta série

) Localização, em disco, da gravação das imagens adquiridas

ção em disco da gravação das imagens adquiridas em modo Multiple Shot. O nome do ficheir s

) Visualização

e visualização das imagens adquiridas em modo Multiple Shot se adquiridas com a opção “.BMP

) Tempo entre aquisições em modo Sequence

T po entre aquisições de imagem em modo Sequence . Pode ser especificado em minutos ou segund

0) Número de imagens a adquirir para a sequência

Opções: Temporal inicial definido em 4) Trigger - São adquirte que é do tipo definido em 6).

a

Númeroso de captura de imagem.

4

Tempo er especificado em minutos ou segundos.

5

Ttos ou segundos.

6

eccionados ambos ou apenas um dos dois, actuando o que primeiro for despoletado. Opções: Tecla - Ee eventos de trigger. Trigger Externo - Ev fornecido.

7

Localizao escolhido será a base de formação dos nomes de todas as imagens adquiridas, sendo adicionado

ao nome o índice de imagem e um índice da câmara utilizada se a aquisição for feita com duas câmaras , escolhidas em 1) do Módulo de aquisição - Opções de aquisição. 8

Opção d” em 9) do Módulo de aquisição- Opções de aquisição.

9

em

os. 1

Page 176: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

N mero de imagens a adquirir em modo Sequence , após o qual se dá por terminado o processo de captur

11) Loca zação, em disco, da gravação da sequência adquirida

L m disco da gravação das imagens adquiridas em modo Sequence. O nome do ficheiro escolh

12) Opções de aquisição

ao Módulo de aquisição - Opções de aquisição, para configurar todos os elementos de config

.4 - Progresso

Permite-nos iniciar e obter informação acerca do progresso do processo em qualquer um dos modos

1) Informação

) Informação

tado do processo de aquisição é actualizada de modo a dar um certo feedba

) Start

Dá inicio ao processo de aquisição de imagens.

) Close

No fim do processo de aquisição torna-se activo de modo a poder fechar a caixa com a informação acerca

úa de imagem.

li ocalização e

ido será a base de formação do nome das sequências de imagens adquiridas, se a aquisição for feita com duas câmaras (escolhidas em 1) do Módulo de aquisição - Opções de aquisição) sendo adicionados ao nome o indice da câmara utilizada.

Acesso

uração do processo de aquisição. 1

de aquisição utilizado em em 1) do Módulo de aquisição - Grab.

2) Start 3) Close

1

Informação acerca do esck ao utilizador.

2

3

do processo de aquisição de imagens.

Page 177: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

1.5 - Informação

a toda a informação acerca dos ficheiros de imagem adquiridos em formato .BMP

Permite-nos aceder

“ ” em 9) do Módulo de aquisição - Opções de aquisição . Este módulo já se encontrava implementado pelo que nos limitamos a fazer uma breve referência. Fazendo uso desta funcionalidade podemos visualizar a informação anexada a cada ficheiro de imagem em 10) do Módulo de aquisição - Opções de aquisição

Page 178: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Capítulo II - Calibração 2.1 - Simulação de uma Câmara de Geometria Interna Conhecida

Esta parte da aplicação consiste na execução de simulações de câmaras de geometria interna conhec

res.

1) Parâmetros globais os - rotação

o

metros de visualização dos

) Parâmetros globais

troduz os valores globais que serão utilizados no cálculo dos parâmetros de alibração e na formulação do conjunto de pontos coplanares.

calibração pretendidos. Por defeito, é igual a 16. - Coordenada 3D mundo z para o plano de calibração. Por defeito, é igual a 0.0.

hos na direcção x, dx. hos na direcção y, dy.

) Parâmetros extrínsecos – rotação

alores dos graus de rotação segundo os eixos x, y e z, spectivamente. Por defeito, os valores são de –30º, -30º e –30º respectivamente.

) Parâmetros extrínsecos – translação

utilizador as componentes do vector de translação segundo os ixos x, y e z, respectivamente. Por defeito, os valores são de 100, 100 e 2000 respectivamente.

4) Par etros intrínsecos

ida, de maneira a serem analisados os efeitos de certos parâmetros nos resultados finais de calibração sem recorrer a testes laboratoriais. São também gerados um conjunto de pontos coplanaAssim na interface utilizador / implementação o utilizador tem as seguintes opções:

2) Parâmetros extrínsec 3) Parâmetros extrínsecos - translaçã 4) Parâmetros intrínsecos 5) Parâresultados 6) Efectuar a simulação de uma câmara

1

Aqui o utilizador inc

Os parâmetros que podem ser optimizados pelo utilizador são respectivamente (seguindo uma ordenação de cima para baixo):

- Número de pontos de

- Dimensão da memória frame segundo a direcção x. - Dimensão da memória frame segundo a direcção y. - Distância entre centros dos elementos sensores vizin- Distância entre centros dos elementos sensores vizin

2

Aqui o utilizador especifica os vre

3

Nesta secção são especificadas peloe

âm

Page 179: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

e especificar os parâmetros intrínsecos que a câmara a simular tenha, tais

omo:

- Distância focal efectiva f. - F istorção da lente, k1.

tal, sx. gem na memória frame, segundo a direcção x. Por defeito, é

igual a me egundo a mesma direcção.

) Parâmetros de visualização dos resultados

es de visualização dos resultados da simulação e mbém pode guardar o conjunto de pontos de calibração coplanares gerados pela simulação num ficheiro

de text

implementação da simulação de uma câmara de geometria

terna conhecida introduzidos por defeito ou pelo utilizador na interface ilustrada.

Aqui o utilizador podc

actor de d- Factor de incerteza horizon- Coordenada Cx do centro da imatade da dimensão da referida memória s- Coordenada Cy do centro da imagem na memória frame, segundo a direcção y. Por defeito, é

igual a metade da dimensão da referida memória segundo a mesma direcção.

5

O utilizador pode inibir / desinibir as opçõta

o, sendo possível especificar o nome e a localização da gravação deste ficheiro.

6) Efectuar a simulação de uma câmara

Este botão tem como função iniciar ain

.2 - Detecção de Pontos de Calibração na Memória frame.

ria frame de uma agem contendo o alvo de calibração previamente dimensionado para o efeito. Assim na interface

tilizad

) Inibir / desinibir a avização da imagem

e

de orlas de

iciais.

s

) Inibir /desinibir a suavização da imagem através da aplicação de filtros

iltros que actuarão sob imagem de entrada contendo os pontos de calibração a detectar. O resultado será a suavização da

2 Esta parte da aplicação consiste em determinar os pontos de calibração na memóimu or / implementação o utilizador tem as seguintes opções:

1suatravés da aplicação dfiltros. 2) Escolher o filtro de detecçãointensidade. 3) Alterar os parâmetrosde detecção in4) Escolher as opções de visualização dos resultados e destino dos resultado. 5) Efectuar a detecção dopontos.

1

Quando seleccionada esta opção de suavização, o utilizador pode escolher fa

Page 180: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

imagem

) Escolher o filtro de detecção de orlas de intensidade.

etecção de orlas de intensidade mais convin nte a aplicar sob a imagem contendo os pontos de calibração. Aqui serão encontrados filtros como o

) Parâmetros de detecção iniciais

alores que melhor se adaptam à imagem a detectar. Os parâmetros que podem ser optimizados pelo utilizador são respectivamente (seguindo uma

ordena

plitude que um dado pixel deverá apresentar para não ser classificado como ruído. Por defeito, é igual a 50.

- Máxima distância de um dado pixel a uma determinada recta para ser classificado como pertencent

tal.

) Opções de visualização dos resultados:

ir por ordem descente:

- A visualização do resultado do filtro de detecção de orlas de intensidade. uas direcções principais.

m nos pontos de calibraçã

opção de gravação dos resultados da detecção num ficheiro e texto, sendo também possível especificar o nome a localização de gravação do ficheiro de texto.

entação de detecção dos pontos de calibração com os arâmetros introduzidos por defeito ou pelo utilizador na interface ilustrada.

.3 - Formatação dos Pontos de Calibração Co

a formatação, isto é, é necessário incluir no conjunto de pontos detercoordenadas 3D de cada ponto determinado.

A primeira interface tem como objectivo:

se forem escolhidos os filtros Gaussianos ou a extracção de ruído se forem seleccionados os filtros de mediana ou média. 2

Nesta caixa o utilizador pode seleccionar o filtro de die de Deriche, Canny, Spacek e Shen and Castan.

3

Aqui o utilizador introduz os v

ção de cima para baixo): - Valor mínimo de am

- Tolerância de erro na classificação de uma dado pixel quanto à sua direcção. Por defeito é igual a 2.

- Diferença mínima entre duas direcções principais. Por defeito , é igual a 32.

e a esta . Por defeito é igual a 10. - Mínimo número de pontos que deve ser constituída uma linha para ser considerada como

Por defeito é igual a 15.

4

Aqui o utilizador pode inibir / desinib

- A visualização do resultado da suavização da imagem.

- A visualização do resultado da detecção das linhas nas d- A visualização do resultado da intersecção das linhas detectadas, que resulta

o considerados na memória frame.

O utilizador também pode accionar a d

5) Efectuar a detecção dos pontos de calibração

Este botão tem como função iniciar a implemp

2 nsiderados

é necessário fazer a minados as correspondentes

Após a determinação dos pontos de calibração coplanares na memória frame

su

Page 181: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

e texto com os pontos formatados, sendo também ossível especificar o nome e a localização do ficheiro.

A

2) Apresentação de valores 3) Inserção de coordenadas 3D 4) Formatação dos pontos 5) Limpa ponto já formatado

) Número total de pontos

Indicação do número total de pontos a formatar.

total de pontos de calibração detectados na

memória fram , assim como os valores de cada ponto nas suas coordenadas 3D.

) Inserção de coordenadas 3D

corres ndentes.

) Formatação dos pontos

onto formatado é possível inseri-lo no ficheiro de s desse mesmo ficheiro. Desta maneira os pontos que irão form

alibração da câmara, serão apenas aqueles que o utilizador form

como função concluir o processo de formatação.

1) Especificação da localização do ficheiro de texto com o conjunto de pontos coplanares namemória frame.

2) Especificação do nome do ficheiro dp

segunda interface tem como objectivo:

1) Número total de pontos

1

2) Apresentação de valores

Nesta parte da interface é disponibilizado o númeroe

3

Para cada ponto de calibração detectado é possível inserir as suas coordenadas 3D

aída da implementação ou removê-ar o conjunto de pontos para o cálculo da atar, permitindo assim uma série de

po 4

Para cada ploctestes de calibração.

5) Conclusão da formatação

Este botão tem

.4 -

A calibração de uma câmara consiste na determinação dos seus parâmetros intrínsecos e extrínsecos. Para executar a

2 Calibração de uma Câmara

Page 182: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

calibração de uma câmara o utilizador têm à sua disposição as seguintes opções:

plementação 2) Especificação do ficheiro contendo o conjunto de pontos de calibração coplanares.

) Especificação dos valores gerais da implementação

necessários ao cálculo dos parâmetros Estes são:

s sensores vizinhos na direcção x, dx. Por defeito é igual

a 0.009- Coordenada C do centro da imagem na memória frame, segundo a direcção x. Por defeito é

- Distância entre centros dos elementos sensores vizinhos na direcção y, dy. Por defeito é igual a 0.006

a frame, segundo a direcção y. Por defeito é

icação do ficheiro contendo o conjunto de pontos de calibração coplanares.

or aqui necessita de especificar a localização do ficheiro contendo o conjunto de pontos

coplanares

3) Optimização dos valores por defeito.

ão de alibração pode optimizar os seguintes parâmetros:

A tolerância do erro no cálculo das soluções exactas da distância focal efectiva f, da omponente tz do vector de translação T e do factor de distorção k1, determinadas pela resolução do stema de equações não linear respectivo e utilizando o método Levenberg – Marquardt. Por defeito, é

- Inibir / desinibir a determinação exacta das coordenadas do centro da imagem (C ,C ) na memór

4) Opções

do

Este botão tem como função efectuar a calibração de uma câmara com os parâmetros especificados

1) Especificação dos valores gerais da im

3) Optimização dos valores por defeito. 4) Opções de saída da implementação. 5) Efectuar a calibração.

1

Aqui o utilizador pode especificar vários parâmetros globaisintrínsecos e extrínsecos da câmara.

- Distância entre centros dos elemento8.

xigual 256.

3. - Coordenada Cy do centro da imagem na memóri

igual 256.

2) Especif

O utilizad detectados ou simulados pelas rotinas, respectivamente pelas implementações de detecção e

simulação.

O utilizador ao inibir a optimização total dos parâmetros de entrada na implementaçc

- O factor de incerteza horizontal, sx, por defeito é igual a 0.710935. -

csiigual a 0.0000001.

x yia frame.

de saída da implementação.

O utilizador pode inibir /desinibir a salva guarda dos resultados para um ficheiro de texto, sentambém possível especificar o nome e a localização do ficheiro a gravar.

5) Efectuar a calibração

pelo utilizador na interface.

Page 183: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Módulo III - Detecção de Entidades e cálculo de coordenadas 3D 3.1 - Inic lização

rísticos e posterior triangulação estereoscópica para obtenção de coordenadas 3D.

1) Matrizes de transformação l e distorção radial da câmara calibração : dx, dy, Cx, Cy, sx

4) Número de pares de imagens

) Uso de valores pré-definidos para definir matriz de transformação, distância focal e distor

1) M

2) Di

Permite a introdução dos valores de distância focal f e de distorção radial k.

3) Par de calibração : dx, dy, Cx, Cy, sx

Permite a introdução dos seguintes parâmetros: dx- Distância entre centro dos elementos sensores vizinhos na direcção x.

vizinhos na direcção y. cx- Coordenada do centro da imagem na memória frame segundo a direcção x.

ção y. sx- Factor de escala que compensa incertezas no escalamento efectuado pelo framegrabber na

nha de scan horizontal.

ia

Permite-nos introduzir os parâmetros de calibração de um sistema stereo ou monocular obtido em 2.4 . Para posterior obtenção de informação tridimensional por detecção e emparelhamento de pontos caracte

2) Distância Foca 3) Parâmetros de

5) Uso de valores pré-definidos de calibração 6) Uso de valores guardados em ficheiro para definir matriz de transformação, distância

focal e distorção radial 7

ção radial 8) Tipo de sistema

atrizes de transformação Permite a introdução dos valores da matriz de transformação da respectiva câmara calibrada.

stância Focal e distorção radial da câmara

âmetros

dy- distância entre centro dos sensores CD

cy- Coordenada do centro da imagem na memória frame segundo a direc

li

Page 184: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

4) Númer

Per obtenção de informaçã

5) Uso de alores pré-definidos de calibração

Permite fazer uso de valores pré-definidos de calibração ( dx, dy, Cx, Cy, sx ) , no caso da atamente antes deste passo, os valores de calibração obtidos

anteriorm nte constituem os valortes pré-definidos.

6) Uso d ores guardados em ficheiro para definir matriz de transformação, distância focal e distorção radial

fazer uso de valores contidos em ficheiro para determinar os valores da matriz de transfo

res pré-definidos para definir matriz de transformação, distância focal e distorção adial

er uso de valores pré-definidos de calibração (matriz de transformação, distância focal e distorção radial ) , no caso da calibração ter sido efectuada imediatamente antes deste passo, os valores de cal

) Tipo de sistema

efine o tipo de sistema. Sistema que usa duas câmaras para obtenção de informação tridimensional.

uir-se-à o módulo Detecção e D -

s Característicos e Emparelhamento A d

interface q e o ponto 2.2 - Detecção de Pontos de Calibração na Memória frame, uma vez ue a f

o de pares de imagens

mite introduzir o número de pares de imagens a utilizar na detecção e posterior o tridimensional.

v

calibração ter sido efectuada imedie

e val

Permite rmação 1) .

7) Uso de valor

Permite faz

ibração obtidos anteriormente constituem os valortes pré-definidos. 8

DStereo -Mono - Sistema que usa uma câmara para obtenção de informação bidimensional.

Ao aceitar todos os parâmetros introduzidos, premindo em OK, seg3 3.2 - Detecção de Ponto

etecção dos pontos característicos e emparelhamento utiliza o mesmo interface utilizador / u

q ilisiofia da detecção dos pontos característicos é idêntica à da detecção dos pontos de calibração.

.3 - Obtenção de Informação Tridimensional

módulo é activado imediatamente após o módulo Detecção e 3D- Inicialização e permite organi do

3

Estezar as imagens obtidas em sequência temporal associando-as a um número de par 1) possibilitan

a detecção e obtenção de informação 3D para cada par de imagens. Fazendo uso de imagens determina ascoordenadas 3D de pontos característicos de um alvo típico.

Page 185: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

1) Número do par de imagem

2) Detecção dos pontos característicos de cada imagem pertencente ao par 3) Obtenção das coordenadas tridimensionais dos pontos aracterísticos

4) Marcação de pares de imagens como sendo a referência

e imagem

do índice associado ao par de imagens do qual queremosontos

) Detecção dos pontos característicos de cada imagem pertencente ao par Permite a detecção e emparelhamento dos pontos característicos da imagem correspondente à

2 ) do sistema stereo de aquisição de imagem. Ao activar automa ente executa módulo Detecção e 3D - Detecção de pontos característicos e Empar

) Obtenção das coordenadas tridimensionais dos pontos característicos

o cálculo de coordenadas 3D dos pontos característicos, emparelhados, identificados em

res de imagens como sendo a referência

Estabelece qual dos pares de imagem será a referência em termos de estimação de movimento.

que falta fazer para terminar o processo. Estes indicadores permitem ao tilizador organizar do modo que lhe entender todo o processo.

detectar e emparelhar os

c

1) Número do par d

Indicação

p característicos. 2 posição esquerda ou direita (1 ou

ticamelhamento.

3 Permite2) colocando-as em memória. 4) Marcação de pa A detecção e obtenção de coordenadas 3D têm uma indicação que permite ao utilizador saber a cada passo o que já foi feito e ou

Page 186: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Módulo IV - Estimação e correcção de movimento 4.1 - E timação e Correcção

s

3) Indicação dos valores estimados de movimento 4) Coordenadas do centro de rotação 5) Estimação de movimento

1) Nú ero do conjunto de pontos Dá-nos a indicação do número de conjuntos de pontos detectadosde inform mensional, bem como a indicação de ter sido efectuado oumovimen o para esse conjunto de pontos em comparação com o conjunt 2) Correcção do movimento

Permite efectuar a correcção de uma imagem após o cálculo da translação segundo o eixo dos x e os y e

) Indicação dos valores estimados de movimento

alores estimados da translação segundo o eixo dos x e dos y e da rotação e pontos escolhido em 1) em ordem ao conjunto de pontos referência. Este campos são

automa

) Estimação de movimento

vimento é efectuado pressionando este botão o que irá desencadear o processo de estimação de movimento e respectivo preenchimento dos campos contidos em 3) .

obtidos no processo de obtenção não a estimação de

o de pontos de referência.

s

1) Número do conjunto de ponto2) Correcção do movimento

m

ação tridit

d da rotação pelo botão de estimação de movimento 5). 3 Aqui encontram-se os vpara o conjunto d

ticamente preenchidos pelo processo de estimação de movimento 5) podendo no entanto ser alteradas pelo utilizador. 4) Coordenadas do centro de rotação

As coordenadas do centro de rotação devem ser indicadas de forma a ser efectuada a rotação emtorno do eixo de rotação certo. 5

O processo de estimação de mo

Page 187: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Calpoints.h typedef struct{ double x; /* point's coordinate x */ double y; /* point's coordinate y */ } point; typedef struct{ double m; /* line's equation y=m*x+b */ double b; } line; int lregression(point *linepoint,int nline,int n,line *calline); int mark(LPBITMAPINFOHEADER lp_in, int y, int x, int color); int findlines (HDIB bin1, double m, double maxdist,line *calline, int v, int goodline); int findpoints(HDIB bin1, HDIB bin2, HDIB bout1, HDIB bout2, HDIB bout3, int error, int dang, double maxdist, int t, BOOL save, int goodline); int cal_point(HDIB hNewDIB); Calpoints.cpp /************************************************************************* ******************** INCLUDES ************************ *************************************************************************/ #include "stdafx.h" #include "MainFrm.h" #include "Dialogs.h" #include <math.h> #include "stdlib.h" #include "Edges_de.h" #include "cal_points.h" #include "Thres.h" #include "Logi_ope.h" #include "Dib_func.h" #include "Gauss_Log.h"

#include "Max_min_med.h" #include "DCalibration.h" /************************************************************************* ******************** DEFINES ************************ *************************************************************************/ #define WHITE 255 /* white's value */ #define BLACK 0 /* black's value */ #define SEEN 156 /* tag used for indication that some pixel was seen already */ #define NLINES 30 /* maximum number of lines to be considered */ #define NPOINTLINE 1500 /* maximum number of points that any line could have */ //#define GOODLINE 20 /* minimum number of line's points for a line could be considered */ #define MPI 3.141592654 /* pi's value */ FILE *fpt; /* output file for calibration points */ /*******************************************************************/ /*F:lregression* ________________________________________________________________ lregression ________________________________________________________________ Name: lregression - make the linear regression by least-squares fit of a straight line Syntax: | int lregression(point *linepoint,int nline,int n,line *calline) Description: 'n' is the number of points to be considered. 'nline' is the tag of the line to be considered. 'linepoint' is a typedef struct{ double x; double y;} point; where x, y are the point's coordinate. 'calline' is a typedef struct{ double m; double b;} line; where m and b are coefficients representing the slope and the intercept, respectively. Return value: | 0 => Ok. | 1 => Can't make the linear regression.

Page 188: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Restrictions: (n*sum(x^2)-(sum(x))^2) must be different of zero. Author: Sergio Barros; Nuno Sá Couto; Joao Tavares Based On: Code By João Tavares version: 1.0 1/05/2001 Visual C++ Implementation ________________________________________________________________ */ int lregression(point *linepoint,int nline,int n,line *calline) { register int j; double sumx, sumy, sumxy, sumx2, xmean, ymean, aux; sumx = sumy = sumxy = sumx2 = 0.0; for (j = 0; j < n; ++j) { sumx += linepoint[j].x; sumy += linepoint[j].y; sumxy += linepoint[j].x*linepoint[j].y; sumx2 += linepoint[j].x*linepoint[j].x; } xmean = sumx/n; ymean = sumy/n; aux = n*sumx2-sumx*sumx; if (aux == 0.0) return(1); /* save m and b of this line */ calline[nline].m = (n*sumxy-sumx*sumy)/aux; calline[nline].b = ymean-calline[nline].m*xmean; return(0); }

/*******************************************************************/ /*F:mark* ________________________________________________________________ mark ________________________________________________________________ Name: mark - mark one cross Syntax: | int mark(LPBITMAPINFOHEADER lp_in, int y, int x, int color) Description: 'lp_in' is the input DIB LPBITMAPINFOHEADER. 'x' and 'y' are the coordinate of the cross's center. 'color' is the value for all the cross's pixels. Return value: | 0 => Ok. Restrictions: None. Author: Nuno Sa Couto; Sergio Barros; Joao Tavares Based On: Code By João Tavares Id: 1.1 1/05/2001 Visual C++ Implementation ________________________________________________________________ */ int mark(LPBITMAPINFOHEADER lp_in, int y, int x, int color) { int aux1, aux2; register int i; int xsize = lp_in -> biWidth; int ysize = lp_in -> biHeight; for (i = -4; i <= 4 ; ++i) { aux1 = y-(i); aux2 = x-(i);

Page 189: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

if (aux1 < 1 || aux1 > ysize) continue; if (aux2 < 1 || aux2 > xsize) continue; /* make all pixel's in cross at y, x as color */ wDp(lp_in,aux1,x,DWORD(color)); wDp(lp_in,y,aux2,DWORD(color)); } return(0); } /*________________________________________________________________ F: FINDLINES __________________________________________________________________ Name: findlines - find all the parallel lines in an input DIB Syntax: | int findlines (HDIB bin1, double m, double maxdist,line *calline, int v) Description: 'bin1' is the input DIB with all the pixels which have more or less the same direction. 'm' is the slope of the median direction in the input DIB. The maximum distance to a point belongs to some line is 'maxdist'. 'calline' is a typedef struct{ double m; double b;} line; where m and b are coefficients If the median direction in the input band is vertical then 'v' is 1. Return value: | The number of lines. Restrictions: None. Author: Nuno Sa Couto; Sergio Barros; Joao Tavares Based On: Code By João Tavares

Id: 1.1 1/05/2001 Visual C++ Implementation and Optimization ________________________________________________________________ */ int findlines (HDIB bin1, double m, double maxdist,line *calline, int v, int goodline) { point linepoint[NPOINTLINE]; double mperp, b1, b2, xint, yint, dist, aux1, aux2; int n, nline; int i, j, l, k; DWORD dummy1, dummy2; nline = 0; if (v != 1) mperp= -(1.0/m); LPBITMAPINFOHEADER lp_in = (LPBITMAPINFOHEADER) GlobalLock((HGLOBAL) bin1); int xsize = lp_in -> biWidth; int ysize = lp_in -> biHeight; /**********/ xsize =xsize -10; LPSTR lpDIB1; BYTE *lpB1; lpDIB1 = FindDIBBits ((LPSTR) lp_in); // find the first point of an line // for (j = 10; j < ysize; j++) { for (i = 0; i < xsize; i++) { lpB1 = DIBGotoPoint ((BYTE *)lpDIB1, *lp_in, (LONG) i, (LONG) j); dummy1= DIBGetPoint(lpB1, lp_in ->biBitCount, (LONG) i);

Page 190: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

if (dummy1 == (DWORD) BLACK) { DIBChangePoint(lpB1, lp_in->biBitCount, (LONG) i, (DWORD) SEEN); b1 = j-m*i; n = 0; if (m >= -1 && m <= 1 && v != 1) { linepoint[n].x = i; linepoint[n].y = j; } else { linepoint[n].x = j; linepoint[n].y = i; } // find all the points of the line // for (k = 10; k < ysize; k++) { for (l =0 ; l < xsize; l++) { lpB1 = DIBGotoPoint ((BYTE *)lpDIB1, *lp_in, (LONG) l, (LONG) k); dummy2= DIBGetPoint(lpB1, lp_in ->biBitCount, (LONG) l); if (dummy2 == (DWORD) BLACK) { if (v == 1) dist = abs(l-i); else { b2 = (double)k-mperp*(double)l; xint = (b2-b1)/(m-mperp); yint = mperp*xint+b2; aux1 = xint-(double)l; aux1 *= aux1; aux2 = yint-(double)k; aux2 *= aux2; dist = sqrt(aux1+aux2);

} if (dist < maxdist) { // this point belong to the line // DIBChangePoint(lpB1, lp_in->biBitCount, (LONG) l, (DWORD) SEEN); n += 1; b1 = k-m*l; if (m >= -1 && m <= 1 && v != 1) { linepoint[n].x = l; linepoint[n].y = k; } else { linepoint[n].x = k; linepoint[n].y = l; } } } } } n += 1; if (n > goodline) { if (lregression(linepoint, nline, n, calline)!=0) { MessageBox(NULL,"Can't make linear regression","Calline routine error", MB_ICONERROR ); return 0; } nline += 1; } } }

Page 191: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

} ::GlobalUnlock((HGLOBAL) bin1); return(nline); } /*******************************************************************/ /*F:findpoints* ________________________________________________________________ findpoints ________________________________________________________________ Name: findpoints - find the corners's points of parallel squares or rectangles with same dimension Syntax: | int findpoints(HDIB bin1, HDIB bin2, HDIB bout1, HDIB bout2, HDIB bout3, int error, int dang, double maxdist, int t, BOOL save) Description: The DIB 'bin1' have the amplitude and the DIB 'bin2' have the directions [0-PI] of the output results of any edges detector, for example Deriche. The error tolerance for the direction threshold is 'error'. The minimum difference between the two levels of direction threshold is 'dang'. The maximum distance to a point belongs to some line is 'maxdist'. The amplitude threshold level is 't'. The output DIB 'bout1' have all the points which belongs to lines with one direction. The output DIB 'bout2' have all the points which belongs to lines with the other direction. The output DIB 'bout3' have all the corners found mark with one cross. The flag save enables the writing of the calibration points in a output file Return value: | The number of points found.

Restrictions: None. Author: Sergio Barros; Nuno Sa Couto; Joao Tavares Based On: Code By João Tavares Id: 1.1 1/05/2001 VC++ Implementation and Optimization ___________________________________________________________________ */ int findpoints(HDIB bin1, HDIB bin2, HDIB bout1, HDIB bout2, HDIB bout3, int error, int dang, double maxdist, int t, BOOL save, int goodline) { int n1, n2, i, j; UINT ang[256], xint, yint, max1, max2, npoint, v1, v2; DWORD aux , aux2,aux3,aux4, m1, m2; double m11,m22; double xintreal, yintreal; line calline1[NLINES], calline2[NLINES]; // Pointers to the input DIB's // LPSTR lpDIB1, lpDIB2, lpout1, lpout2; BYTE *lpB1, *lpB2, *out1, *out2; LPBITMAPINFOHEADER lp_in1 = (LPBITMAPINFOHEADER) GlobalLock((HGLOBAL) bin1); LPBITMAPINFOHEADER lp_in2 = (LPBITMAPINFOHEADER) GlobalLock((HGLOBAL) bin2); LPBITMAPINFOHEADER lp_out1 = (LPBITMAPINFOHEADER) GlobalLock((HGLOBAL) bout1); LPBITMAPINFOHEADER lp_out2 = (LPBITMAPINFOHEADER) GlobalLock((HGLOBAL) bout2); int xsize = lp_in1 -> biWidth; int ysize = lp_in1 -> biHeight;

Page 192: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

//************// xsize= xsize -10; lpDIB1 = FindDIBBits ((LPSTR) lp_in1); lpDIB2 = FindDIBBits ((LPSTR) lp_in2); lpout1 = FindDIBBits ((LPSTR) lp_out1); lpout2 = FindDIBBits ((LPSTR) lp_out2); // Make the counter of the output angle threshold // for ( i=0 ; i<= 255; i++) ang[i] = 0; /**********/ for(j=10; j < ysize; j++){ for (i=0; i < xsize ; i++){ lpB1 = DIBGotoPoint ((BYTE *)lpDIB1, *lp_in1, (LONG) i, (LONG) j); aux2= DIBGetPoint(lpB1, lp_in1->biBitCount, (LONG) i); if (aux2>=(DWORD)t){ lpB2 = DIBGotoPoint ((BYTE *)lpDIB2, *lp_in2, (LONG) i, (LONG) j); aux= DIBGetPoint(lpB2, lp_in2->biBitCount, (LONG) i); ang[(UINT) aux] += 1; } } } /* angle threshold */ aux = ang[0]; max1 = 0; for (i = 1; i <= 255; ++i) { if ((UINT)aux<ang[i]) { aux = ang[i]; max1 = i; } }

m1 = 0; n1=0; for(j=10; j< ysize; j++){ for (i=0; i<xsize; i++){ lpB1 = DIBGotoPoint ((BYTE *)lpDIB1, *lp_in1, (LONG) i, (LONG) j); aux2= DIBGetPoint(lpB1, lp_in1->biBitCount, (LONG) i); // find the points superiors to the threshold level // if (aux2 >= (DWORD) t){ lpB2 = DIBGotoPoint ((BYTE *)lpDIB2, *lp_in2, (LONG) i, j); aux3= DIBGetPoint(lpB2, lp_in2->biBitCount, (LONG) i); if(aux3 <= ((DWORD) (max1+error)) && aux3 >= ((DWORD) (max1-error))){ // make the pixel in bout1 as BLACK and compute the average direction // out1 = DIBGotoPoint ((BYTE *)lpout1, *lp_out1, (LONG) i, (LONG) j); DIBChangePoint(out1, lp_out1->biBitCount, (LONG) i, (DWORD) BLACK); m1 += aux3; n1 += 1; } else if ( aux3 > ((DWORD) (max1+dang)) || aux3 < ((DWORD) (max1-dang))){ aux = aux3; ang[(UINT) aux] += 1; } } } } for (i = -4; i <= 4 ; ++i) { if (aux = max1-(i) > 0) {

Page 193: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

aux = max1-(i); ang[aux]=0; } } if ( n1 == 0 ){ MessageBox(NULL,"Image without parallel squares or rectangles","Calline routine error", MB_ICONERROR ); return 0; } m1 /= n1; aux = ang[0]; max2 = 0; for (i = 0; i <= 255; ++i) { if ( (UINT)aux< ang[i]) { aux = ang[i]; max2 = i; } } m2 = 0; n2 = 0; aux4 = 0; for(j=10; j < ysize; j++){ for (i=0; i < xsize ; i++){ lpB1 = DIBGotoPoint ((BYTE *)lpDIB1, *lp_in1, (LONG) i, (LONG) j); aux2= DIBGetPoint(lpB1, lp_in1->biBitCount, (LONG) i); out1 = DIBGotoPoint ((BYTE *)lpout1, *lp_out1, (LONG) i, (LONG) j); aux3= DIBGetPoint(out1, lp_out1->biBitCount, (LONG) i); if(aux2 >= ((DWORD) t) && aux3 != ((DWORD) BLACK)){

lpB2 = DIBGotoPoint ((BYTE *)lpDIB2, *lp_in2, (LONG) i, (LONG) j); aux4= DIBGetPoint(lpB2, lp_in2->biBitCount, (LONG) i); if ( aux4 <= ((DWORD) (max2+error)) && aux4 >= ((DWORD) (max2-error))){ // make the pixel im bout2 as BLACK and compute the average direction // out2 = DIBGotoPoint ((BYTE *)lpout2, *lp_out2, (LONG) i, (LONG) j); DIBChangePoint(out2, lp_out2->biBitCount, (LONG) i, (DWORD) BLACK); m2 += aux4; n2 += 1; } else if ( aux4 > ((DWORD) (max2+dang)) || aux4 < ((DWORD) (max2-dang))){ aux = aux4; ang[(UINT) aux] += 1; } } } } if ( n2 == 0 ){ MessageBox(NULL,"Image without parallel squares or rectangles","Calline routine error", MB_ICONERROR ); return 0; } m2 /= n2; ::GlobalUnlock((HGLOBAL) bin1); ::GlobalUnlock((HGLOBAL) bin2); ::GlobalUnlock((HGLOBAL) bout1); ::GlobalUnlock((HGLOBAL) bout2); // compute the two angles of lines // v1 = v2 = 0;

Page 194: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

if (m1 == 64){ v1 = 1; m11=(double)m1; } else m11 = tan(MPI*(double)m1/128.0); if (m2 == 64){ v2 = 1; m22=(double)m2; } else m22 = tan(MPI*(double)m2/128.0); // find lines in bout1 // n1 = findlines(bout1, m11, maxdist, calline1, v1, goodline); // find lines in bout2 // n2 = findlines(bout2, m22, maxdist, calline2, v2, goodline); // find the intersection points // LPBITMAPINFOHEADER lp_out3 = (LPBITMAPINFOHEADER) GlobalLock((HGLOBAL) bout3); if ( n1 == 0 || n2 == 0) return 0; for (i = 0; i < n1; ++i) { for (j = 0; j < n2; ++j) { npoint += 1; if (m11 >= -1.0 && m11 <= 1.0 && v1 != 1) { if (m22 >= -1.0 && m22 <= 1.0 && v2 != 1) { xintreal = ((calline1[i].b-calline2[j].b)/(calline2[j].m-calline1[i].m)); yintreal = (calline1[i].m*xintreal+calline1[i].b); } else {

yintreal = ((calline1[i].m*calline2[j].b+calline1[i].b)/(1.0-calline1[i].m*calline2[j].m)); xintreal = (calline2[j].m*yintreal+calline2[j].b); } } else { if(m22 >= -1.0 && m22 <= 1.0 && v2 != 1) { yintreal = ((calline2[j].m*calline1[i].b+calline2[j].b)/(1.0-calline1[i].m*calline2[j].m)); xintreal = (calline1[i].m*yintreal+calline1[i].b); } else { yintreal = ((calline1[i].b-calline2[j].b)/(calline2[j].m-calline1[i].m)); xintreal = (calline1[i].m*yintreal+calline1[i].b); } } // make an cross in bout3 at yint, xint with color BLACK // xint =(int (xintreal+0.5)); yint =(int (yintreal+0.5)); mark(lp_out3, yint, xint, BLACK); // write in output file the intersection point // if (save) fprintf(fpt, "%.5g %.5g\n", xintreal, yintreal); } } ::GlobalUnlock((HGLOBAL) bout3); return(npoint);

Page 195: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

} /*******************************************************************/ /*P:cal_point* ________________________________________________________________ cal_point ________________________________________________________________ Name: cal_point - find the corners of parallel squares or rectangles with same dimension in an image Syntax: | int cal_point(HDIB hDIB) Description: 'cal_point' find the corners of parallel squares or rectangles with same dimension in an input DIB hDIB. This image will be submitted to an enhancement filter selected by the user in the dialog IDD_CALIB_POINTS and afterwards to an edge detector selected by the user in the same dialog. The output of the edge detector are two images. the first with the amplitude and the second with the directions of the output results. The calibration points will be calculated based on these two images and the dialog IDD_CALIB_POINTS parameters. Finnaly the routine makes the output of the different images. Return value: | 0 => OK. Restrictions: Acepts only UNS_BYTE pixels. Author: Nuno Sa Couto; Sergio Barros; Id: 1.0 1/05/2001 - Original Implementation ________________________________________________________________ */ int cal_point(HDIB hDIB)

{ LPTSTR name; CDCalib_get_points list; HDIB in1DIB=NULL, in2DIB=NULL, out1DIB=NULL, out2DIB=NULL, out3DIB=NULL; int t, error, dang, npoint; double maxdist; // read arguments // if (list.DoModal()==IDOK) { error = list.m_error; dang = list.m_dang; maxdist = list.m_maxdist; t = list.m_t; // read input image // in1DIB = (HDIB) CopyHandle(hDIB); // make output images // SetDIBBits(in1DIB, (BYTE) 255); in2DIB = (HDIB) CopyHandle(in1DIB); ::GlobalUnlock(hDIB); out1DIB = (HDIB) CopyHandle(in1DIB); out2DIB = (HDIB) CopyHandle(out1DIB); out3DIB = (HDIB) CopyHandle(out1DIB); // Make Image Enhancement HDIB gaussDIB = NULL; LPBITMAPINFOHEADER lp1 = (LPBITMAPINFOHEADER) GlobalLock((HGLOBAL) hDIB); gaussDIB = (HDIB) CopyHandle(hDIB); SetDIBBits(gaussDIB, (BYTE) 255); LPBITMAPINFOHEADER gauss = (LPBITMAPINFOHEADER) GlobalLock((HGLOBAL) gaussDIB);

Page 196: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

if (list.m_enable_enhan){ if (list.m_smooth == "Gaussian_5x5") make_gauss(lp1, gauss, 4); else if (list.m_smooth == "Gaussian_9x9") npoint = make_gauss(lp1, gauss, 5); else if (list.m_smooth == "Gaussian_4_2_1") make_gauss(lp1, gauss, 1); else if (list.m_smooth == "Gaussian_2_1_1") make_gauss(lp1, gauss, 2); else if (list.m_smooth == "Gaussian_1_1_1") make_gauss(lp1, gauss, 3); else if (list.m_smooth == "Mean"){ CDdx_dy diag1; if (diag1.DoModal() == 1) mean(lp1, gauss, diag1.m_dx, diag1.m_dy); } else if (list.m_smooth == "Median"){ CDdx_dy diag2; diag2.m_dx = 2; diag2.m_dy = 2; if (diag2.DoModal() == 1) median(lp1, gauss, diag2.m_dx, diag2.m_dy); } if (list.m_show_enhancement){ CMainFrame* pAppFrame6 = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame6->IsKindOf(RUNTIME_CLASS( CMainFrame ))); CString titulo6 = "Image Enhancement"; pAppFrame6->OpenNewDocument( gaussDIB , TRUE, (const char*) titulo6); } } else ::GlobalFree((HGLOBAL) gaussDIB); // Make Edge Detector LPBITMAPINFOHEADER lp_in1 = (LPBITMAPINFOHEADER) GlobalLock((HGLOBAL) in1DIB); LPBITMAPINFOHEADER lp_in2 = (LPBITMAPINFOHEADER) GlobalLock((HGLOBAL) in2DIB); double alpha=1.0, omega=0.0001; int angles=1, width = 8;

if (list.m_edge == "Deriche"){ CDialOpDer pDiag; pDiag.m_Alfa = alpha; pDiag.m_Omega = omega; pDiag.m_Angles = angles; if (pDiag.DoModal() == 1) { alpha = pDiag.m_Alfa; omega = pDiag.m_Omega; angles = pDiag.m_Angles; } if(list.m_enable_enhan){ npoint= deriche (gauss, lp_in1, lp_in2, alpha, omega, angles); ::GlobalUnlock((HGLOBAL) gaussDIB); } else npoint= deriche (lp1, lp_in1, lp_in2, alpha, omega, angles); } else if (list.m_edge == "Canny"){ CDoptCanny pdiag1; pdiag1.m_Angles = angles; pdiag1.m_Width = width; if (pdiag1.DoModal() == 1) { angles = pdiag1.m_Angles; width = pdiag1.m_Width; } if(list.m_enable_enhan){ npoint = canny (gauss, lp_in1, lp_in2, width, angles); ::GlobalUnlock((HGLOBAL) gaussDIB); } else npoint = canny (lp1, lp_in1, lp_in2, width, angles); } else if (list.m_edge == "Shen_and_Castan"){ CDoptShen pdiag2; pdiag2.m_Alfa = alpha; pdiag2.m_Angles = angles; if (pdiag2.DoModal() == 1) { angles = pdiag2.m_Angles;

Page 197: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

alpha = pdiag2.m_Alfa; } if(list.m_enable_enhan){ npoint = shencas (gauss, lp_in1, lp_in2, alpha, angles); ::GlobalUnlock((HGLOBAL) gaussDIB); } else npoint = shencas (lp1, lp_in1, lp_in2, alpha, angles); } else if (list.m_edge == "Spacek"){ CDoptSpacek pdiag3; pdiag3.m_Angles = angles; pdiag3.m_Width = width; if (pdiag3.DoModal() == 1) { angles = pdiag3.m_Angles; width = pdiag3.m_Width; } if(list.m_enable_enhan){ npoint = spacek (gauss, lp_in1, lp_in2, width, angles); ::GlobalUnlock((HGLOBAL) gaussDIB); } else npoint = spacek (lp1, lp_in1, lp_in2, width, angles); } ::GlobalUnlock(hDIB); ::GlobalUnlock(in1DIB); ::GlobalUnlock(in2DIB); // Open Output file char arg[100]; if(list.m_save){ name= (list.m_Outputfile).GetBuffer(30); fpt = fopen(name, "w"); if (fpt == NULL) { MessageBox(0,"Can not open input file", "Calibration Error", MB_ICONERROR ); return 0; }

sprintf(arg, "Warning_A_This_file_contains_calibration_data_for_the_input_routine!!\n"); //sprintf(arg, "1\n"); fprintf(fpt, arg); } // call function findpoints // npoint = findpoints(in1DIB, in2DIB, out1DIB, out2DIB, out3DIB, error, dang, maxdist, t, list.m_save, list.m_goodline); if (npoint == 0){ MessageBox(0,"Can not find calibration points", "Calibration Error", MB_ICONERROR ); return 0; } // close output file // if (fpt != NULL) fclose(fpt); // Visualization of results // if (list.m_show_orlas) { CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); CString titulo = "Edges Detector - Amplitude"; pAppFrame->OpenNewDocument( in1DIB , TRUE, (const char*) titulo); CMainFrame* pAppFrame2 = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame2->IsKindOf(RUNTIME_CLASS( CMainFrame ))); CString titulo2 = "Edges Detector - Direction"; pAppFrame2->OpenNewDocument( in2DIB , TRUE, (const char*) titulo2); } if (list.m_show_lines) { CMainFrame* pAppFrame3 = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame3->IsKindOf(RUNTIME_CLASS( CMainFrame ))); CString titulo3 = "Calibration Lines"; pAppFrame3->OpenNewDocument( out1DIB , TRUE, (const char*) titulo3); CMainFrame* pAppFrame4 = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame4->IsKindOf(RUNTIME_CLASS( CMainFrame ))); CString titulo4 = "Calibration Lines"; pAppFrame4->OpenNewDocument( out2DIB , TRUE, (const char*) titulo4);

Page 198: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

} if (list.m_show_points){ CMainFrame* pAppFrame5 = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame5->IsKindOf(RUNTIME_CLASS( CMainFrame ))); CString titulo5 = "Calibration Points"; pAppFrame5->OpenNewDocument( out3DIB , TRUE, (const char*) titulo5); } } return(1); } calcamera.h #define NMAX 5 /* number of variables in the model for the least-squares */ #define NMAX1 3 /* dimension square matrix of coefficients to be solved by solve function */ #define STOP1 0.000001 /* control variable used in the non linear search of the buffer's center */ #define STOP2 0.000001 /* control variable used in the non linear search of the buffer's center */ typedef struct { float xw; /* point's 3D world coordinate x */ float yw; /* point's 3D world coordinate y */ float xf; /* point's 2D frame buffer coordinate x */ float yf; /* point's 2D frame buffer coordinate y */ double xd; /* point's 2D distorced image coordinate x */ double yd; /* point's 2D distorced image coordinate y */ } calpoint; int calibrate(BOOL grava, double sx, BOOL find, double cx, double cy, double dx, double dy, double nlstop, CString inputfile , CString outputfile ); int linleastsquar(int m, int n, double z[][NMAX],double a[], double y[]);

int solve(double alfa[][NMAX1], double delta[], double beta[]); int findcenter(UINT n,calpoint point[], double dxl,double dy, double *cx, double *cy); calcamera.cpp //#include "stdio.h" #include "stdafx.h" #include "mainfrm.h" #include <math.h> #include "stdlib.h" #include "calcamera.h" #include "DCalibration.h" /*******************************************************************/ /* DEFINES */ #define NPOINT 300 /* maximum number of points to be considered */ #define NMAX 5 /* number of variables in the model for the least-squares */ #define NMAX1 3 /* dimension square matrix of coefficients to be solved by solve function */ #define STOP1 0.000001 /* control variable used in the non linear search of the buffer's center */ #define STOP2 0.000001 /* control variable used in the non linear search of the buffer's center */ /*******************************************************************/ /*******************************************************************/ /*F:linleastsquar* ________________________________________________________________ linleastsquar ________________________________________________________________ Name: linleastsquar - make the linear least-squares regression by Cholesky's method Syntax: |int linleastsquar(int m, int n, double z[][NMAX],

Page 199: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

double a[], double y[]) Description: 'z[][]' is the matrix of the observed values for the independent variable. 'n' is the number of variables in the model and 'm' is the number of data points, 'NMAX' is the maximum number of variables in the model. The vector 'y[]' contains the observed values of the dependent variable. The vector 'a[]' contains the unknown coefficients. Return value: | 0 => Ok. Restrictions: The matrix [(z[[][]transposed)*z[][]] must be positive definite. Author: Sergio Barros; Nuno Sa Couto; Joao Tavares Based On: Code By João Tavares Id: 1.1 1/05/2001 VC++ Implementation ________________________________________________________________ */ int linleastsquar(int m, int n, double z[][NMAX],double a[], double y[]) { int i, j, k; double aux1[NMAX][NMAX], aux2[NMAX], aux3[NMAX], sum= 0.0, teste; /* make aux1[][]=(z[][]transposed)*z[][] */ for (i = 0; i < n; ++i) { for (j = 0; j < n; ++j) { aux1[i][j] = 0.0; for (k = 0; k < m; ++k) aux1[i][j] += z[k][i]*z[k][j]; }

} /* make aux2[][]=(z[][]transposed)*y[][] */ for (i = 0; i < n; ++i) { aux2[i] = 0.0; for (j = 0; j < m; ++j) aux2[i] += z[j][i]*y[j]; } /* cholesky decomposition - aux1[][]=l[][]*(l[][]transposed) */ for (k = 0; k < n; ++k) { for (i = 0; i < k; ++i) { sum = 0.0; for (j = 0; j < i; ++j) sum += aux1[i][j]*aux1[k][j]; if (aux1[i][i] == 0.0){ MessageBox(0,"Cannot make CHOLESKY decomposition!","Calibration error", MB_ICONERROR | MB_OK); return(1); } aux1[k][i] = (aux1[k][i]-sum)/aux1[i][i]; } sum = 0.0; for (j = 0; j < k; ++j) sum += aux1[k][j]*aux1[k][j]; if (aux1[k][k] < sum) MessageBox(0,"Can't make CHOLESKY decomposition!", "Calibration Error", MB_ICONERROR | MB_OK); teste = aux1[k][k]-sum; aux1[k][k] = sqrt(teste); } /* forward substitution */ aux3[0] = aux2[0]/aux1[0][0]; for (i = 1; i < n; ++i) { sum = 0.0; for (j = 0; j < i; ++j) sum += aux1[i][j]*aux3[j]; aux3[i] = (aux2[i]-sum)/aux1[i][i];

Page 200: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

} /* backward substitution */ a[n-1] = aux3[n-1]/aux1[n-1][n-1]; for (i = n-2; i >= 0 ; --i) { sum = 0.0; for (j = i+1; j < n; ++j) sum += aux1[j][i]*a[j]; a[i] = (aux3[i]-sum)/aux1[i][i]; } return(0); } /*******************************************************************/ /*F:solve* ________________________________________________________________ solve ________________________________________________________________ Name: solve - solve a system of linear algebraic equations by Cholesky's decomposition Syntax: | int solve(double alfa[][NMAX1], double delta[] , double beta[]) Description: 'alfa[][]' is the 'NMAX1'-by-'NMAX1' square matrix of coefficient. 'delta[]' is the vector of unknowns. 'beta[]' is the vector of constants. Return value: | 0 => Ok. Restrictions: The matrix 'alfa[][]' must be positive definite. Author: Sergio Barros; Nuno Sa Couto; Joao Tavares

Based On: Code By João Tavares Id: 1.1 1/05/2001 VC++ Implementation ________________________________________________________________ */ int solve(double alfa[][NMAX1], double delta[], double beta[]) { register int i, j, k; double aux[NMAX1], sum; /* cholesky decomposition - alfa[][]=l[][]*(l[][]transposed) */ for (k = 0; k < NMAX1; ++k) { for (i = 0; i < k; ++i) { sum = 0.0; for (j = 0; j < i; ++j) sum += alfa[i][j]*alfa[k][j]; if (alfa[i][i] == 0.0) { MessageBox(0,"Can't make CHOLESKY decomposition.", "Calibration Error", MB_ICONERROR | MB_OK); return(1); } alfa[k][i] = (alfa[k][i]-sum)/alfa[i][i]; } sum = 0.0; for (j = 0; j < k; ++j) sum += alfa[k][j]*alfa[k][j]; if (alfa[k][k] < sum) { MessageBox(0,"Can't make CHOLESKY decomposition.", "Calibration Error", MB_ICONERROR | MB_OK); return(2); } alfa[k][k] = sqrt(alfa[k][k]-sum); } /* forward substitution */ aux[0] = beta[0]/alfa[0][0]; for (i = 1; i < NMAX1; ++i) { sum = 0.0;

Page 201: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

for (j = 0; j < i; ++j) sum += alfa[i][j]*aux[j]; aux[i] = (beta[i]-sum)/alfa[i][i]; } /* backward substitution */ delta[NMAX1-1] = aux[NMAX1-1]/alfa[NMAX1-1][NMAX1-1]; for (i = NMAX1-2; i >= 0 ; --i) { sum = 0.0; for (j = i+1; j < NMAX1; ++j) sum += alfa[j][i]*delta[j]; delta[i] = (aux[i]-sum)/alfa[i][i]; } return(0); } /*******************************************************************/ /*F:findcenter* ________________________________________________________________ findcenter ________________________________________________________________ Name: findcenter - compute the image center in the frame buffer using the radial alignment constraint Syntax: | findcenter(UINT n,calpoint point[], double dxl Description: 'n' is the number of calibration points. 'point' is typedef struct { float xw; float yw; float xf; float yf; double xd; double yd; } calpoint. Where xw, yw are the world 3D coordinate; xd, yd are the distorted image coordinate and xf, yf are the computer image coordinate in frame buffer. 'dxl' is sx*dx where dx is the distance between adjacent sensor elements in x (scan line) direction and sx is the horizontal scale factor.

'dy' is the center to center distance between adjacent CCD sensor in the y direction. 'cx' and 'cy' are the row and column numbers of the center of frame buffer, the input values are half of image's size. Return value: | 0 => Ok. Restrictions: The set of calibration points must be coplanar with the world 3D coordinate system being chosen so that z=0 for all points. The number of calibration points must be larger than five. Author: Sergio Barros; Nuno Sa Couto; Joao Tavares Based On: Code By João Tavares Id: 1.1 1/05/2001 VC++ Implementation ________________________________________________________________ */ int findcenter(UINT n,calpoint point[], double dxl,double dy, double *cx, double *cy) { int auxin, pass; double tx, ty, tz, f, r[9], z[NPOINT][NMAX], a[NMAX], y[NPOINT], aux, aux1, aux2, aux3, aux4, aux5, beta[2], alfa[2][2], delta[2], quiold, quinew, lambda, dcx, dcy, cxold, cyold; //double k1; UINT i; pass = 0; do { /* define xd, yd for all calibration points */ for (i = 0; i < n; ++i) { point[i].xd = dxl*(point[i].xf-*cx); point[i].yd = dy*(point[i].yf-*cy); }

Page 202: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

/* define z[NPOINT][NMAX], y[NPOINT] of linear equations */ for (i = 0; i < n; ++i) { z[i][0] = point[i].yd*point[i].xw; z[i][1] = point[i].yd*point[i].yw; z[i][2] = point[i].yd; z[i][3] = -(point[i].xd*point[i].xw); z[i][4] = -(point[i].xd*point[i].yw); y[i] = point[i].xd; } /* solve the linear regression by linear last squares */ linleastsquar(n, 5, z, a, y); /* define r[], tx, ty */ aux = a[0]*a[0]+a[1]*a[1]+a[3]*a[3]+a[4]*a[4]; aux1 = a[0]*a[4]-(a[3]*a[1]); if (aux1 != 0.0) ty = sqrt((aux-sqrt(aux*aux-(4*aux1*aux1)))/(2*aux1*aux1)); else ty = sqrt(1.0/aux); /* define ty sign */ aux1 = point[0].xf-*cx; aux1 *= aux1; aux2 = point[0].yf-*cy; aux2 *= aux2; aux = sqrt(aux1+aux2); auxin = 0; /* find the point more distant of *cx, *cy */ for (i = 1; i < n; ++i) { aux1 = point[i].xf-*cx; aux1 *= aux1; aux2 = point[i].yf-*cy; aux2 *= aux2; aux3 = sqrt(aux1+aux2); if (aux3 < aux) {

aux = aux3; auxin = i; } } r[0] = a[0]*ty; r[1] = a[1]*ty; r[3] = a[3]*ty; r[4] = a[4]*ty; tx = a[2]*ty; aux = r[0]*point[auxin].xw+r[1]*point[auxin].yw+tx; aux1 = r[3]*point[auxin].xw+r[4]*point[auxin].yw+ty; aux3 = point[auxin].xd/aux; aux4 = point[auxin].yd/aux1; if (aux3 < 0.0 || aux4 < 0.0) { /* ty sign is wrong */ r[0] = -(r[0]); r[1] = -(r[1]); r[3] = -(r[3]); r[4] = -(r[4]); tx = -(tx); ty = -(ty); } /* define R */ r[2] = sqrt(1.0-(r[0]*r[0])-(r[1]*r[1])); r[5] = sqrt(1.0-(r[3]*r[3])-(r[4]*r[4])); aux = r[0]*r[3]+r[1]*r[4]; aux /= fabs(aux); aux = -(aux); r[5] *= aux; r[6] = r[1]*r[5]-r[2]*r[4]; r[7] = r[2]*r[3]-r[0]*r[5]; r[8] = r[0]*r[4]-r[1]*r[3]; /* compute an approximation of f and tz by ignoring lens distorcion */ for (i = 0; i < n; ++i) {

Page 203: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

aux1 = r[3]*point[i].xw+r[4]*point[i].yw+ty; aux2 = r[6]*point[i].xw+r[7]*point[i].yw; z[i][0] = aux1; z[i][1] = -(point[i].yd); y[i] = aux2*point[i].yd; } /* solve the linear regression by linear least squares */ linleastsquar(n, 2, z, a, y); f = a[0]; tz = a[1]; if (f < 0.0) { r[2] = -(r[2]); r[5] = -(r[5]); r[6] = -(r[6]); r[7] = -(r[7]); f = -(f); tz = -(tz); } /* compute the *cx, *cy by Levenberg-Marquardt method */ dcx = dcy = 0.0; cxold = *cx; cyold = *cy; lambda = 0.001; quiold = 0.0; /* compute merit function for the first solution */ for (i = 0; i < n; ++i) { aux = -(point[i].yd*(point[i].xw*r[0]+point[i].yw*r[1]+tx))+point[i].xd*(point[i].xw*r[3]+point[i].yw*r[4]+ty); quiold += aux*aux; }

do { beta[0] = beta[1] = alfa[0][0] = alfa[0][1] = alfa[1][1] = 0.0; /* compute beta[] and alfa[][] */ for (i = 0; i < n; ++i) { aux = point[i].xw*r[6]+point[i].yw*r[7]+tz; aux1 = -point[i].xw*r[3]-point[i].yw*r[4]-ty; aux2 = point[i].xw*r[0]+point[i].yw*r[1]+tx; aux3 = -(point[i].yd*aux2)+point[i].xd*(-(aux1)); aux4 = (point[i].yd/f)*aux+aux1; aux5 = -(point[i].xd/f)*aux+aux2; aux3 -= dcx*aux4+dcy*aux5; beta[0] += aux3*aux4; beta[1] += aux3*aux5; alfa[0][0] += aux4*aux4; alfa[0][1] += aux4*aux5; alfa[1][1] += aux5*aux5; } alfa[1][0] = alfa[0][1]; alfa[0][0] *= (1.0+lambda); alfa[1][1] *= (1.0+lambda); /* solve the linear equations */ delta[0] = (beta[0]*alfa[1][1]-alfa[0][1]*beta[1])/(alfa[0][0]*alfa[1][1]-alfa[0][1]*alfa[1][0]); delta[1] = (beta[1]-alfa[1][0]*delta[0])/alfa[1][1]; /* compute merit function for the new solution */ quinew = 0.0; for (i = 0; i < n; ++i) { aux = point[i].xw*r[6]+point[i].yw*r[7]+tz; aux1 = -point[i].xw*r[3]-point[i].yw*r[4]-ty; aux2 = point[i].xw*r[0]+point[i].yw*r[1]+tx; aux3 = -(point[i].yd*aux2)+point[i].xd*(-(aux1)); aux4 = (point[i].yd/f)*aux+aux1; aux5 = -(point[i].xd/f)*aux+aux2; aux3 -= (dcx+delta[0])*aux4+(dcy+delta[1])*aux5; quinew += aux3*aux3;

Page 204: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

} if (quinew >= quiold) { lambda *= 10.0; quiold = quinew; } else { lambda *= 0.1; dcx += delta[0]; dcy += delta[1]; *cx -= dcx; *cy -= dcy; if (quiold-quinew < STOP1) { aux = (*cx-cxold); aux *= aux; aux1 = (*cy-cyold); aux1 *= aux1; aux += aux1; if (aux < STOP2) pass = 1; break; } quiold = quinew; } } while(1); } while(!pass); *cx = floor(*cx+0.5); *cy = floor(*cy+0.5); return 0; } /*******************************************************************/ /*P:calibrate*

________________________________________________________________ calibrate ________________________________________________________________ Name: calcamera - performs a camera calibration in the context of 3D machine vision using a coplanar set of calibration points Syntax: | void calibrate(BOOL grava, double sx, BOOL find, double cx, double cy, double dx, double dy, double nlstop, CString inputfile , CString outputfile ) Description: Determining the internal camera geometric and optical characteristics (the intrinsic parameters : the effective focal lenght f and the lens radial distortion coefficient k1), and the 3D position and orientation of the camera relative to a certain world coordinate system (extrinsic parameters: the rotation matrix R and the translation vector T). The output results can be writting in the file 'outfilename' if the BOOL flag 'grava' is on, by default this flag is off. The error tolerance for the exact solution of f, tz and k1, by Levenberg-Marquardt method can be indicated through flaf 'nlstop', by default 'nlstop' is 0.0000001. The horizontal scale factor 'sx' can be indicated through flag '-sx', and by default 'sx' is 0.710935. If through the BOOL flag 'find' is indicated that 'findcenter' is 1 then the image center in the frame buffer is computed, by default isn't compute. 'dx' is the distance between adjacent sensor elements in x (scan line) direction. 'dy' is the center to center distance between adjacent CCD sensor in the y direction. 'Cx' and 'Cy' are the row and column numbers of the image center in the frame buffer. If the correct values are unknown, then the input values are half of image's size. 'inputfile' is the name of input file which have the world and frame buffer coordinate of all the

Page 205: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

calibration points. Return value: | 0 => OK Restrictions: The set of calibration points must be coplanar with the world 3D coordinate system being chosen so that z=0 for all points. The number of calibration points must be larger than five. The horizontal scale factor 'sx' must be different of zero. Author: Sergio Barros; Nuno Sa Couto; Joao Tavares Based On: Code By João Tavares 1.0 93/12/18 Joao Tavares Original Implementation 1.1 1/05/2001 SVB & NSC VC++ Implementation ________________________________________________________________ */ int calibrate(BOOL grava, double sx, BOOL find, double cx, double cy, double dx, double dy, double nlstop, CString inputfile , CString outputfile ) { int n,auxin; double dxl, tx, ty, tz, f, r[9], z[NPOINT][NMAX], a[NMAX], y[NPOINT], aux, aux1, aux2, aux3, aux4, aux5, beta[3], alfa[3][3], delta[3], quiold, quinew, lambda; double k1; float auxf; char arg[200], arg1[200], arg2[80], arg3[40], arg4[60], arg5[200]; register int i; FILE *infpt, *outfpt; calpoint point[NPOINT]; LPTSTR name1, name2; char valid[500], *pdest; int ch = 'B',result=0; // Opens the input data file // name1= inputfile.GetBuffer(100); infpt = fopen(name1, "r");

if (infpt == NULL){ MessageBox(0,"Can not open input file", "Calibration Error", MB_ICONERROR | MB_OK); } // Get data points // fscanf (infpt,"%s", valid); pdest = strchr( valid, ch ); result = pdest - valid + 1; if( result != 8 ){ MessageBox(0,"Invalid data file!! Input proper calibration data!!", "Calibration error", MB_ICONERROR | MB_OK); return(0); } n = 0; fscanf(infpt, "%g %g %g %g %g", &point[n].xw, &point[n].yw, &auxf, &point[n].xf, &point[n].yf); while (!feof(infpt)) { if (auxf != 0.0) { MessageBox(0,"Some Point(s) don't have the world coordinate z zero", "Calibration Error", MB_ICONERROR | MB_OK); } n += 1; fscanf(infpt, "%g %g %g %g %g", &point[n].xw, &point[n].yw, &auxf, &point[n].xf, &point[n].yf); } // Close input data file // fclose(infpt); if (n < 5){ MessageBox(0,"The number of calibrating points must be superior to five", "Calibration Error", MB_ICONERROR | MB_OK); return 0; } /* define dxl */ if (sx == 0.0) { MessageBox(0,"The horizontal scale factor (sx) must be different of zero!", "Calibration Error", MB_ICONERROR | MB_OK);

Page 206: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

return 0; } dxl = dx*sx; /* if was desire find the image center in the frame buffer */ if (find){ int teste; teste = findcenter (n, point, dxl, dy, &cx, &cy); if (teste != 0){ MessageBox(0,"Can not find image center!", "Calibration Error", MB_ICONERROR | MB_OK); return 0; } } /* define xd, yd for all calibration points */ for (i = 0; i < n; ++i) { point[i].xd = dxl*(point[i].xf-cx); point[i].yd = dy*(point[i].yf-cy); } /* define z[NPOINT][NMAX], y[NPOINT] of linear equations */ for (i = 0; i < n; ++i) { z[i][0] = point[i].yd*point[i].xw; z[i][1] = point[i].yd*point[i].yw; z[i][2] = point[i].yd; z[i][3] = -(point[i].xd*point[i].xw); z[i][4] = -(point[i].xd*point[i].yw); y[i] = point[i].xd; } /* solve the linear regression by linear last squares */ if ( linleastsquar(n, 5, z, a, y) !=0){

MessageBox(0,"Can not make linear least mean squares!!", "Calibration Error", MB_ICONERROR | MB_OK); return 0 ; } /* define r[], tx, ty */ aux = a[0]*a[0]+a[1]*a[1]+a[3]*a[3]+a[4]*a[4]; aux1 = a[0]*a[4]-(a[3]*a[1]); if (aux1 != 0.0) ty = sqrt((aux-sqrt(aux*aux-(4*aux1*aux1)))/(2*aux1*aux1)); else ty = sqrt(1.0/aux); /* define ty sign */ aux1 = point[0].xf-cx; aux1 *= aux1; aux2 = point[0].yf-cy; aux2 *= aux2; aux = sqrt(aux1+aux2); auxin = 0; /* find the point more distant of cx, cy */ for (i = 1; i < n; ++i) { aux1 = point[i].xf-cx; aux1 *= aux1; aux2 = point[i].yf-cy; aux2 *= aux2; aux3 = sqrt(aux1+aux2); if (aux3 < aux) { aux = aux3; auxin = i; } } r[0] = a[0]*ty; r[1] = a[1]*ty; r[3] = a[3]*ty; r[4] = a[4]*ty; tx = a[2]*ty;

Page 207: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

aux = r[0]*point[auxin].xw+r[1]*point[auxin].yw+tx; aux1 = r[3]*point[auxin].xw+r[4]*point[auxin].yw+ty; aux3 = point[auxin].xd/aux; aux4 = point[auxin].yd/aux1; if (aux3 < 0.0 || aux4 < 0.0) { /* ty sign is wrong */ r[0] = -(r[0]); r[1] = -(r[1]); r[3] = -(r[3]); r[4] = -(r[4]); tx = -(tx); ty = -(ty); } /* define R */ r[2] = sqrt(1.0-(r[0]*r[0])-(r[1]*r[1])); r[5] = sqrt(1.0-(r[3]*r[3])-(r[4]*r[4])); aux = r[0]*r[3]+r[1]*r[4]; aux /= fabs(aux); aux = -(aux); r[5] *= aux; r[6] = r[1]*r[5]-r[2]*r[4]; r[7] = r[2]*r[3]-r[0]*r[5]; r[8] = r[0]*r[4]-r[1]*r[3]; /* compute an approximation of f and tz by ignoring lens distorcion */ for (i = 0; i < n; ++i) { aux1 = r[3]*point[i].xw+r[4]*point[i].yw+ty; aux2 = r[6]*point[i].xw+r[7]*point[i].yw; z[i][0] = aux1; z[i][1] = -(point[i].yd); y[i] = aux2*point[i].yd; } /* solve the linear regression by linear least squares */

if ( linleastsquar(n, 2, z, a, y) !=0){ MessageBox(0,"Can not make linear least mean squares!!", "Calibration Error", MB_ICONERROR | MB_OK); return 0 ; } f = a[0]; tz = a[1]; if (f < 0.0) { r[2] = -(r[2]); r[5] = -(r[5]); r[6] = -(r[6]); r[7] = -(r[7]); f = -(f); tz = -(tz); } /* compute the exact solution for f, tz and k1, by Levenberg-Marquardt method */ k1 = 0.0; lambda = 0.001; quiold = 0.0; /* compute merit function for the first solution */ for (i = 0; i < n; ++i) { aux = r[3]*point[i].xw+r[4]*point[i].yw+ty; aux1 = r[6]*point[i].xw+r[7]*point[i].yw+tz; aux3 = point[i].yd-f*aux/aux1; quiold += aux3*aux3; } do { beta[0] = beta[1] = beta[2] = 0.0; alfa[0][0] = alfa[0][1] = alfa[0][2] = 0.0; alfa[1][0] = alfa[1][1] = alfa[1][2]=0.0; alfa[2][0] = alfa[2][1] = alfa[2][2]=0.0; /* compute beta[] and alfa[][] */

Page 208: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

for (i = 0; i < n; ++i) { aux = r[3]*point[i].xw+r[4]*point[i].yw+ty; aux1 = r[6]*point[i].xw+r[7]*point[i].yw; aux2 = point[i].yd*(point[i].yd*point[i].yd+point[i].xd*point[i].xd); aux3 = aux1+tz; aux4 = aux/aux3; aux3 = -f*aux/(aux3*aux3); aux5 = point[i].yd-f*aux4+k1*aux2; beta[0] += aux5*aux4; beta[1] += aux5*aux3; beta[2] += aux5*(-aux2); alfa[0][0] += aux4*aux4; alfa[0][1] += aux4*aux3; alfa[0][2] += aux4*(-aux2); alfa[1][1] += aux3*aux3; alfa[1][2] += (-aux2)*aux3; alfa[2][2] += aux2*aux2; } alfa[1][0] = alfa[0][1]; alfa[2][0] = alfa[0][2]; alfa[2][1] = alfa[1][2]; alfa[0][0] *= (1.0+lambda); alfa[1][1] *= (1.0+lambda); alfa[2][2] *= (1.0+lambda); /* solve the linear equations */ if ( solve(alfa, delta, beta) !=0){ MessageBox(0,"Can not make solve equation!!", "Calibration Error", MB_ICONERROR | MB_OK); return 0 ; } /* compute merit function for the new solution */ quinew = 0.0; for (i = 0; i < n; ++i) { aux = r[3]*point[i].xw+r[4]*point[i].yw+ty; aux1 = r[6]*point[i].xw+r[7]*point[i].yw+(tz+delta[1]); aux2 = point[i].yd*(k1+delta[2])*(point[i].yd*point[i].yd+point[i].xd*point[i].xd); aux3 = (f+delta[0])*aux/aux1;

aux4 = point[i].yd-aux3+aux2; quinew += aux4*aux4; } if (quinew >= quiold) { lambda *= 10.0; quiold = quinew; } else { lambda *= 0.1; f += delta[0]; tz += delta[1]; k1 += delta[2]; if (quiold-quinew < nlstop) break; quiold = quinew; } } while(1); /* output results */ CDCalibration_res* list; list = (CDCalibration_res*) new CDCalibration_res; list->m_r1=r[0]; list->m_r2=r[1]; list->m_r3=r[2]; list->m_r4=r[3]; list->m_r5=r[4]; list->m_r6=r[5]; list->m_r7=r[6]; list->m_r8=r[7]; list->m_r9=r[8]; list->m_tx=tx; list->m_ty=ty; list->m_tz=tz; list->m_f=f; list->m_k1=k1; list->m_npoint=n;

Page 209: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

list->Create(IDD_CALIB_PARAMS_RES,NULL); list->CenterWindow(); list->ShowWindow(SW_SHOWNORMAL); CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); pAppFrame->m_VarCalib.sx=sx; pAppFrame->m_VarCalib.dx=dx; pAppFrame->m_VarCalib.dy=dy; pAppFrame->m_VarCalib.cx=(int)cx; pAppFrame->m_VarCalib.cy=(int)cy; if (grava) { // Opens the output data file // name2= outputfile.GetBuffer(30); outfpt = fopen(name2, "w"); if (outfpt == NULL) { MessageBox(0,"Can not open output data file", "Calibration Error", MB_ICONERROR | MB_OK); return 0; } double k11; k11=k1; sprintf(arg5, "Notice_C_!_This_file_contains_default_calibration_data"); sprintf(arg, "Results for the calibration algorithm with:\n\nStop for nonlinear equations=%g, Find center=%d, sx=%g, dx=%g,\ndy=%g, Cx=%g, Cy=%g, \nInput file: %s \n\twith %i calibration points.\n",nlstop, find, sx, dx, dy, cx, cy, name1, n); sprintf(arg1, "\nRotation matrix R:\n\n%+#g %+#g %+#g\n%+#g %+#g %+#g\n%+#g %+#g %+#g\n", r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8]); sprintf(arg2, "\nTranslation vector T:\n\n%+#g %+#g %+#g\n", tx, ty, tz); sprintf(arg3, "\nFocal length f:\n\n%+#g\n", f); sprintf(arg4, "\nRadial lens distortion k1:\n\n%+#g\n\n", k11); fprintf(outfpt, arg5); fprintf(outfpt, arg); fprintf(outfpt, arg1); fprintf(outfpt, arg2); fprintf(outfpt, arg3); fprintf(outfpt, arg4);

fclose(outfpt); outputfile.ReleaseBuffer(); inputfile.ReleaseBuffer(); } return(1); } /*******************************************************************/ calib_sim.h #define MPI 3.141592654 #define NLINES 10 /*******************************************************************/ typedef struct{ double m; double b; int v; } line2; /*******************************************************************/ int simcam3(double npoint, double zw, double tx, double ty, double tz, double rotx, double roty, double rotz, double f, double dx, double dy, double sx, double k1, double nx, double ny, double cx, double cy, CString outfilename, BOOL save, BOOL show); calib_sim.cpp #include "stdafx.h" #include "mainfrm.h" #include <math.h> #include "stdlib.h" #include "calib_sim3.h" #include "DCalibration.h"

Page 210: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

#include "ProjectDoc.h" #include "Dialogs.h" /* DEFINES */ #define MPI 3.141592654 #define NLINES 10 /*F:simcamera* ________________________________________________________________ simcamera ________________________________________________________________ Name: simcamera - simulation of a camera using the TSAIïs model and a coplanar set of points. Syntax: | int simcam3(double npoint, double zw, double tx, double ty, double tz, double rotx, double roty, double rotz, double f, double dx, double dy, double sx, double k1, double nx, double ny, double cx, double cy, CString outfilename, BOOL save, BOOL show) Description: 'simcamera' performs the simulation of a camera using the TSAI's model. The world 3D coordinates and frame buffer 2D coordinates of all the points are automatically generated. The number of points to be considered is indicate through flag '-npoint', by default the number of points to be considered is 36. The world 3D coordinate z of all the points is indicate through flag '-zw', by default 'zwplane' is zero. The image center in the frame buffer for direction x is indicate through flag '-cx', by default 'xcenterbuf' is (xsizebuf/2). The image center in the frame buffer for direction y is indicate through flag '-cy', by default 'ycenterbuf' is

(ysizebuf/2). 'rotx', 'roty' and 'rotz', are the angles (in degree) of rotation from object world coordinate system to the camera 3D system about the x, y and z, axis. 'tx', 'ty' and 'tz', are the translations from object world coordinate system to the 3D camera system by the x, y and z, axis. 'f' is the effective focal length. 'dx' is the center to center distance between adjacent sensor elements in x (scan line) direction. 'dy' is the center to center distance between adjacent CCD sensor in the y direction. 'sx' is the horizontal scale factor. 'k1' is the lens's radial distortion. 'outfilename' is the file's name to write the output results; the world 3D coordinates and the frame buffer 2D coordinates of all the points. Return value: | 0 => OK. Restrictions: The sqrt of <npoint> must be integer. The values for <rotx>, <roty> and <rotz> must be smaller than 360 and greater than -360 degree. Author: Sergio Barros; Nuno Sá Couto; Joao Tavares Based On: Code By João Tavares 1.0 93/12/30 Joao Tavares 1.1 1/05/2001 NSC & SVB VC++ Implementation ________________________________________________________________ */ int simcam3(double npoint, double zw, double tx, double ty, double tz, double rotx, double roty, double rotz, double f, double dx, double dy, double sx, double k1, double nx, double ny, double cx, double cy, CString outfilename, BOOL save, BOOL show)

Page 211: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

{ FILE *fpt; register int i, j; double xw,n, yw, dxl, r1, r2, r3, r4, r5, r6, r7, r8, r9, incx1, incy1, incx2, incy2, x, y, z, xu, yu, xd, yd, xf, yf, xw1, xw2, xw3, xw4, yw1, yw2, yw3, yw4, aux1, aux2, aux3, aux4, aux5, aux6, aux7; int lixo; line2 line1[NLINES], line2[NLINES]; LPTSTR name1; CDCalib_simul_res* list; list = (CDCalib_simul_res*) new CDCalib_simul_res; /* if cx and cy arenït given then compute cx and cy by the size of the frame buffer */ if (cx == 0) cx = nx/2; if (cy == 0) cy = ny/2; /* npoint is correct ? */ aux1 = sqrt(npoint); n = aux1; if (aux1 != n) { MessageBox(0,"Wrong Value of number point, the sqrt(npoint) must be integer!", "Simulation of Calibration error", MB_ICONERROR | MB_OK); } /* rotx, roty and rotz, are correct ? */ if (rotx > 360.0 || rotx < -360.0) { MessageBox(0,"Wrong Value of number point, the sqrt(npoint) must be integer!", "Simulation of Calibration error", MB_ICONERROR | MB_OK); } if (roty > 360.0 || roty < -360.0) { MessageBox(0,"Wrong Value of number point, the sqrt(npoint) must be integer!", "Simulation of Calibration error", MB_ICONERROR | MB_OK); } if (rotz > 360.0 || rotz < -360.0) { MessageBox(0,"Wrong Value of number point, the sqrt(npoint) must be integer!",

"Simulation of Calibration error", MB_ICONERROR | MB_OK); } aux1 = MPI/180.0; rotx = rotx*aux1; roty = roty*aux1; rotz = rotz*aux1; char arg[200]; // Opens the output data file // if (save){ name1= outfilename.GetBuffer(30); fpt=fopen(name1, "w"); if (fpt==NULL){ MessageBox(0,"Unable to open file!", "Simulation of Calibration error", MB_ICONERROR | MB_OK); return 0; } else { sprintf(arg, "Notice_B_This_file_contains_calibration_data_for_the_parameters_routine!!\n"); fprintf(fpt, arg); } } dxl = sx*dx; /* compute matrix R */ aux1 = cos(rotx); aux2 = sin(rotx); aux3 = cos(roty); aux4 = sin(roty); aux5 = cos(rotz); aux6 = sin(rotz); r1 = aux3*aux5; r2 = aux3*aux6; r3 = -aux4; r4 = aux5*aux2*aux4-aux1*aux6; r5 = aux6*aux2*aux4+aux1*aux5; r6 = aux2*aux3; r7 = aux5*aux4*aux1+aux2*aux6; r8 = -aux2*aux5+aux6*aux4*aux1;

Page 212: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

r9 = aux3*aux1; // If the user wants to the the results // if (show){ CString name1 (" xW yW zW"), name2(" xF yF"); list->m_r1=r1; list->m_r2=r2; list->m_r3=r3; list->m_r4=r4; list->m_r5=r5; list->m_r6=r6; list->m_r7=r7; list->m_r8=r8; list->m_r9=r9; list->m_npoint=npoint; list->Create(IDD_CALIB_SIMUL_RES,NULL); LV_COLUMN lvc, lvc2; lvc.mask = LVCF_TEXT; lvc.fmt = LVCFMT_RIGHT; lvc.pszText = (LPTSTR) name1.GetBuffer(20); lvc.cx = list->m_table.GetStringWidth(lvc.pszText) + 10; if(lvc.mask & LVCF_SUBITEM){ lvc.iSubItem = 0; } list->m_table.InsertColumn(0,&lvc); list->m_table.SetColumnWidth (0, 100); lvc2.mask = LVCF_TEXT; lvc2.fmt = LVCFMT_RIGHT; lvc2.pszText = (LPTSTR) name2.GetBuffer(10); lvc2.cx = list->m_table2.GetStringWidth(lvc2.pszText) + 10; if(lvc2.mask & LVCF_SUBITEM){ lvc2.iSubItem = 0; } list->m_table2.InsertColumn(0,&lvc2); list->m_table2.SetColumnWidth (0, 85); } /* compute xw1, yw1, xw2, yw2, xw3, yw3, xw4, yw4 */ lixo= 1-2; xd = dxl*(1- cx); yd = dy*(1-cy); aux1 = xd*xd+yd*yd; aux1 = 1.0+k1*aux1; xu = xd*aux1; yu = yd*aux1;

aux1 = xu*r7-f*r1; aux2 = f*r2-r8*xu; aux3 = zw*(f*r3-xu*r9)-xu*tz+f*tx; aux4 = yu*r8-f*r5; aux5 = -yu*r7+f*r4; aux6 = -yu*(r9*zw+tz)+f*r6*zw+ty*f; yw1 = (aux6*aux1+aux3*aux5)/(aux1*aux4-aux5*aux2); xw1 = (yw1*aux2+aux3)/aux1; xd = dxl*(1-cx); yd = dy*(ny-cy); aux1 = xd*xd+yd*yd; aux1 = 1.0+k1*aux1; xu = xd*aux1; yu = yd*aux1; aux1 = xu*r7-f*r1; aux2 = f*r2-r8*xu; aux3 = zw*(f*r3-xu*r9)-xu*tz+f*tx; aux4 = yu*r8-f*r5; aux5 = -yu*r7+f*r4; aux6 = -yu*(r9*zw+tz)+f*r6*zw+ty*f; yw2 = (aux6*aux1+aux3*aux5)/(aux1*aux4-aux5*aux2); xw2 = (yw2*aux2+aux3)/aux1; xd = dxl*(nx-cx); yd = dy*(1-cy); aux1 = xd*xd+yd*yd; aux1 = 1.0+k1*aux1; xu = xd*aux1; yu = yd*aux1; aux1 = xu*r7-f*r1; aux2 = f*r2-r8*xu; aux3 = zw*(f*r3-xu*r9)-xu*tz+f*tx; aux4 = yu*r8-f*r5; aux5 = -yu*r7+f*r4; aux6 = -yu*(r9*zw+tz)+f*r6*zw+ty*f; yw3 = (aux6*aux1+aux3*aux5)/(aux1*aux4-aux5*aux2); xw3 = (yw3*aux2+aux3)/aux1; xd = dxl*(nx-cx); yd = dy*(ny-cy); aux1 = xd*xd+yd*yd; aux1 = 1.0+k1*aux1; xu = xd*aux1; yu = yd*aux1; aux1 = xu*r7-f*r1;

Page 213: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

aux2 = f*r2-r8*xu; aux3 = zw*(f*r3-xu*r9)-xu*tz+f*tx; aux4 = yu*r8-f*r5; aux5 = -yu*r7+f*r4; aux6 = -yu*(r9*zw+tz)+f*r6*zw+ty*f; yw4 = (aux6*aux1+aux3*aux5)/(aux1*aux4-aux5*aux2); xw4 = (yw4*aux2+aux3)/aux1; /* compute the xw, yw, xf, yf, for all points */ aux1 = xw2-xw1; aux2 = yw2-yw1; incx1 = aux1/(n+1); incy1 = aux2/(n+1); aux1 = xw4-xw3; aux2 = yw4-yw3; incx2 = aux1/(n+1); incy2 = aux2/(n+1); aux1 = xw1; aux2 = yw1; aux3 = xw3; aux4 = yw3; /* define line1[] */ for (i=0; i<n; ++i) { aux1 += incx1; aux2 += incy1; aux3 += incx2; aux4 += incy2; aux5 = aux4-aux2; aux6 = aux3-aux1; if (aux6 != 0.0) { aux7 = aux5/aux6; if (aux7 <= 1.0 && aux7 >= -1.0) { line1[i].m = aux7; line1[i].b = aux2-line1[i].m*aux1; line1[i].v = 0; continue; }

} aux7 = aux6/aux5; line1[i].m = aux7; line1[i].b = aux1-line1[i].m*aux2; line1[i].v = 1; } aux1 = xw1-xw3; aux2 = yw1-yw3; incx1 = aux1/(n+1); incy1 = aux2/(n+1); aux1 = xw2-xw4; aux2 = yw2-yw4; incx2 = aux1/(n+1); incy2 = aux2/(n+1); aux1 = xw3; aux2 = yw3; aux3 = xw4; aux4 = yw4; /* define line2[] */ for (i=0; i<n; ++i) { aux1 += incx1; aux2 += incy1; aux3 += incx2; aux4 += incy2; aux5 = aux4-aux2; aux6 = aux3-aux1; if (aux6 != 0.0) { aux7 = aux5/aux6; if (aux7 <= 1.0 && aux7 >= -1.0) { line2[i].m = aux7; line2[i].b = aux2-line2[i].m*aux1; line2[i].v = 0; continue; } } aux7 = aux6/aux5;

Page 214: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

line2[i].m = aux7; line2[i].b = aux1-line2[i].m*aux2; line2[i].v = 1; } for (i=0; i<n; ++i) { for (j=0; j<n; ++j) { if (line1[i].v == 1 && line2[i].v == 1) { yw=(line1[i].b-line2[j].b)/(line2[j].m-line1[i].m); xw=line1[i].m*yw+line1[i].b; } else { if (line1[i].v == 1) { yw = (line2[j].m*line1[i].b+line2[j].b)/(1.0-line2[j].m*line1[i].m); xw = line1[i].m*yw+line1[i].b; } else { if (line2[j].v == 1) { yw = (line1[i].m*line2[j].b+line1[i].b)/(1.0-line1[i].m*line2[j].m); xw = line2[j].m*yw+line2[j].b; } else { xw = (line1[i].b-line2[j].b)/(line2[j].m-line1[i].m); yw = line1[i].m*xw+line1[i].b; } } } x = r1*xw+r2*yw+r3*zw+tx; y = r4*xw+r5*yw+r6*zw+ty; z = r7*xw+r8*yw+r9*zw+tz; xu = f*(x/z);

yu = f*(y/z); aux3 = xu*xu+yu*yu; aux3 = 1.0+k1*aux3; xd = xu/aux3; yd = yu/aux3; xf = xd/dxl+cx; yf = yd/dy+cy; // Print to file the output points // if (save) fprintf(fpt, " %g %g %g %g %g\n", xw, yw, zw, xf, yf); // User want to see the resuls // if (show){ CString buffer1, buffer2; buffer1.Format (" %.5g %.5g %.5g ", xw, yw, zw); buffer2.Format (" %.5g %.5g ", xf, yf); LV_ITEM lvItem; lvItem.mask = LVIF_TEXT; lvItem.iItem = (UINT) n; lvItem.iSubItem = 0; lvItem.pszText = (LPTSTR) buffer1.GetBuffer(20); if(lvItem.iSubItem == 0) { lvItem.mask |= LVIF_PARAM | LVIF_STATE; lvItem.lParam = NULL; lvItem.stateMask=LVIS_STATEIMAGEMASK; lvItem.state=INDEXTOSTATEIMAGEMASK(1); list->m_table.InsertItem(&lvItem); } list->m_table.SetItem(&lvItem); LV_ITEM lvItem2; lvItem2.mask = LVIF_TEXT; lvItem2.iItem = (UINT) n; lvItem2.iSubItem = 0; lvItem2.pszText = (LPTSTR) buffer2.GetBuffer(20); if(lvItem2.iSubItem == 0) { lvItem2.mask |= LVIF_PARAM | LVIF_STATE; lvItem2.lParam = NULL; lvItem2.stateMask=LVIS_STATEIMAGEMASK; lvItem2.state=INDEXTOSTATEIMAGEMASK(1); list->m_table2.InsertItem(&lvItem2); } list->m_table2.SetItem(&lvItem2);

Page 215: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

list->CenterWindow(); list->ShowWindow(SW_SHOWNORMAL); } } } /* close file */ if (save) fclose(fpt); return(0); } /*******************************************************************/ input.h int format(CString inputfile, CString outputfile); input.cpp #include "stdafx.h" #include <stdio.h> #include "input.h" #include "DCalibration.h" #include "my_memory.h" #include "mainfrm.h" #include "string.h" /*******************************************************************/ /*P:input* ________________________________________________________________ input ________________________________________________________________ Name: input - join the world 3D and the frame buffer coordinate for all the calibration

points Syntax: | input <inputfile> <outputfile> Description: 'input' read in input file 'inputfile' the frame buffer coordinate, ask to the user the world 3D coordinate and write in the output file 'outputfile' the world 3D and the frame buffer coordinates. Return value: | 0 => OK. Restrictions: None. Author: Sergio Barros; Nuno Sá Couto; Joao Tavares Based On: Code By João Tavares 1.0 93/12/18 Joao Tavares 1.1 1/05/2001 NSC & SVB VC++ Implementation ________________________________________________________________ */ int format(CString inputfile, CString outputfile) { int n; float xf, yf; FILE *infpt, *outfpt; char valid[500], *pdest; int ch = 'A',result=0; LPTSTR name1,name2; CDCalib_input_frm list; CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); /* open input file */

Page 216: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

name1= inputfile.GetBuffer(30); infpt=fopen(name1, "r"); if (infpt==NULL){ MessageBox(0,"Unable to open input file!", "Formating input calibration errors", MB_ICONERROR | MB_OK); return 0; } fscanf (infpt,"%s", valid); pdest = strchr( valid, ch ); result = pdest - valid + 1; if( result != 9 ){ MessageBox(0,"Invalid data file!! Input only calibration data!", "Formating calibration error", MB_ICONERROR | MB_OK); return(0); } /* read in input file the frame buffer 2D coordinates, input to the user the world 3D coordinates, and write in the output file */ n = 0; fscanf(infpt,"%f %f", &xf, &yf); pAppFrame->m_VarCalib.array[n][0]=xf; pAppFrame->m_VarCalib.array[n][1]=yf; while(!feof(infpt)) { n += 1; fscanf(infpt,"%f %f", &xf, &yf); pAppFrame->m_VarCalib.array[n][0]=xf; pAppFrame->m_VarCalib.array[n][1]=yf; } list.size= n; if( list.DoModal() != IDOK) { fclose(infpt); return 0; }

char arg[200]; /* open ouput file */ name2= outputfile.GetBuffer(30); outfpt=fopen(name2, "w"); if (outfpt==NULL){ MessageBox(0,"Unable to open output file!", "Formating input calibration errors", MB_ICONERROR | MB_OK); return 0; } else { sprintf(arg, "Notice_B_This_file_contains_calibration_data_for_the_parameters_routine!!\n"); //sprintf(arg, "1\n"); fprintf(outfpt, arg); } int i; for (i=0 ;i<list.size;i++) { if (!( (pAppFrame->m_VarCalib.out_array[i][0]==0.0) && (pAppFrame->m_VarCalib.out_array[i][1]==0.0) && (pAppFrame->m_VarCalib.out_array[i][2]==0.0) )) fprintf(outfpt, "%.5f %.5f %.5f %.5f %.5f\n", pAppFrame->m_VarCalib.out_array[i][0] , pAppFrame->m_VarCalib.out_array[i][1], pAppFrame->m_VarCalib.out_array[i][2] , pAppFrame->m_VarCalib.array[i][0], pAppFrame->m_VarCalib.array[i][1]); } fclose(infpt); fclose(outfpt); return(1); } /*******************************************************************/

Page 217: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

Dcalibration.h #include <resource.h> ///////////////////////////////////////////////////////////////////////////// // CDCalib_get_points dialog class CDCalib_get_points : public CDialog { // Construction public: CDCalib_get_points(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CDCalib_get_points) enum { IDD = IDD_CALIB_POINTS }; BOOL m_save; int m_t; int m_error; int m_dang; double m_maxdist; CString m_Outputfile; BOOL m_show_points; BOOL m_show_lines; BOOL m_show_orlas; BOOL m_show_enhancement; BOOL m_enable_enhan; CString m_edge; CString m_smooth; int m_goodline; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDCalib_get_points) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CDCalib_get_points)

afx_msg void OnBrowse(); virtual BOOL OnInitDialog(); afx_msg void OnSave_Points(); afx_msg void OnEnable(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////// // CDCalib_input dialog class CDCalib_input : public CDialog { // Construction public: CDCalib_input(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CDCalib_input) enum { IDD = IDD_CALIB_INPUT }; CString m_strInputfile; CString m_strOutputfile; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDCalib_input) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CDCalib_input) virtual BOOL OnInitDialog(); afx_msg void OnBrowse(); afx_msg void OnBrowse2(); virtual void OnOK(); //}}AFX_MSG DECLARE_MESSAGE_MAP() };

Page 218: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

///////////////////////////////////////////////////////////////////////////// // CDCalib_input_frm dialog class CDCalib_input_frm : public CDialog { // Construction public: CDCalib_input_frm(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CDCalib_input_frm) enum { IDD = IDD_CALIB_INPUT_FORMT }; int m_point; int size; int m_npoints; float m_xf; float m_yf; float m_xw; float m_yw; float m_zw; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDCalib_input_frm) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CDCalib_input_frm) afx_msg void OnDeltaposSpin2(NMHDR* pNMHDR, LRESULT* pResult); virtual BOOL OnInitDialog(); afx_msg void OnButton1(); afx_msg void OnButton2(); afx_msg void OnUpdateEdit7(); virtual void OnCancel(); //}}AFX_MSG DECLARE_MESSAGE_MAP() };

///////////////////////////////////////////////////////////////////////////// // CDCalib_simul dialog class CDCalib_simul : public CDialog { // Construction public: CDCalib_simul(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CDCalib_simul) enum { IDD = IDD_CALIB_SIMUL }; double m_drotx; double m_droty; double m_drotz; double m_dtx; double m_dty; double m_dtz; double m_df; CString m_strOutputfile; double m_dk1; BOOL m_cksave; double m_dsx; double m_ddx; double m_ddy; double m_iCX; double m_iCY; double m_inpoint; double m_inx; double m_iny; double m_izw; BOOL m_ckshow; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDCalib_simul) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected:

Page 219: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

// Generated message map functions //{{AFX_MSG(CDCalib_simul) virtual BOOL OnInitDialog(); afx_msg void OnSave(); afx_msg void OnBrowse(); afx_msg void OnSimulate(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////// // CDCalib_simul_res dialog class CDCalib_simul_res : public CDialog { // Construction public: CDCalib_simul_res(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CDCalib_simul_res) enum { IDD = IDD_CALIB_SIMUL_RES }; CListCtrl m_table2; CListCtrl m_table; double m_r1; double m_r2; double m_r3; double m_r4; double m_r5; double m_r6; double m_r7; double m_r8; double m_r9; double m_npoint; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDCalib_simul_res) public: virtual void OnFinalRelease(); protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL

// Implementation protected: // Generated message map functions //{{AFX_MSG(CDCalib_simul_res) // NOTE: the ClassWizard will add member functions here //}}AFX_MSG DECLARE_MESSAGE_MAP() // Generated OLE dispatch map functions //{{AFX_DISPATCH(CDCalib_simul_res) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_DISPATCH DECLARE_DISPATCH_MAP() DECLARE_INTERFACE_MAP() }; ///////////////////////////////////////////////////////////////////////////// // CDCalibration dialog class CDCalibration : public CDialog { // Construction public: CDCalibration(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CDCalibration) enum { IDD = IDD_CALIB_PARAMS }; BOOL m_cksave; BOOL m_ckfulloptm; CString m_strOutputFile; BOOL m_ckFindCenter; double m_isx; double m_idy; double m_idx; double m_icy; double m_icx; double m_itolerance; CString m_strInputFile; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDCalibration) protected:

Page 220: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CDCalibration) virtual BOOL OnInitDialog(); afx_msg void OnFullOptm(); afx_msg void OnChkSave(); afx_msg void OnBrowse(); virtual void OnOK(); afx_msg void OnBrowse2(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////// // CDCalibration_res dialog class CDCalibration_res : public CDialog { // Construction public: CDCalibration_res(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CDCalibration_res) enum { IDD = IDD_CALIB_PARAMS_RES }; double m_npoint; double m_r1; double m_r2; double m_r3; double m_r4; double m_r5; double m_r6; double m_r7; double m_r8; double m_r9; double m_tx; double m_ty; double m_f; double m_k1; double m_tz;

int m_default; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDCalibration_res) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CDCalibration_res) afx_msg void OnDefault(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; Dcalibration.cpp #include "stdafx.h" #include "Project.h" #include "DCalibration.h" #include "input.h" #include "calib_sim3.h" #include "calcamera.h" #include "resource.h" #include "mainfrm.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CDCalib_get_points dialog

Page 221: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

CDCalib_get_points::CDCalib_get_points(CWnd* pParent /*=NULL*/) : CDialog(CDCalib_get_points::IDD, pParent) { //{{AFX_DATA_INIT(CDCalib_get_points) m_save = FALSE; m_t = 0; m_error = 0; m_dang = 0; m_maxdist = 0.0; m_Outputfile = _T(""); m_show_points = FALSE; m_show_lines = FALSE; m_show_orlas = FALSE; m_show_enhancement = FALSE; m_enable_enhan = FALSE; m_edge = _T(""); m_smooth = _T(""); m_goodline = 0; //}}AFX_DATA_INIT } void CDCalib_get_points::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDCalib_get_points) DDX_Check(pDX, IDC_CHECK1, m_save); DDX_Text(pDX, IDC_EDIT1, m_t); DDX_Text(pDX, IDC_EDIT2, m_error); DDX_Text(pDX, IDC_EDIT3, m_dang); DDX_Text(pDX, IDC_EDIT4, m_maxdist); DDX_Text(pDX, IDC_EFILE, m_Outputfile); DDX_Check(pDX, IDC_CHECK5, m_show_points); DDX_Check(pDX, IDC_CHECK4, m_show_lines); DDX_Check(pDX, IDC_CHECK3, m_show_orlas); DDX_Check(pDX, IDC_CHECK6, m_show_enhancement); DDX_Check(pDX, IDC_CHECK2, m_enable_enhan); DDX_CBString(pDX, IDC_COMBO2, m_edge); DDV_MaxChars(pDX, m_edge, 120); DDX_CBString(pDX, IDC_SMOOTH, m_smooth); DDV_MaxChars(pDX, m_smooth, 120); DDX_Text(pDX, IDC_EDIT5, m_goodline); DDV_MinMaxInt(pDX, m_goodline, 2, 500); //}}AFX_DATA_MAP }

BEGIN_MESSAGE_MAP(CDCalib_get_points, CDialog) //{{AFX_MSG_MAP(CDCalib_get_points) ON_BN_CLICKED(IDC_BROWSE, OnBrowse) ON_BN_CLICKED(IDC_CHECK1, OnSave_Points) ON_BN_CLICKED(IDC_CHECK2, OnEnable) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDCalib_get_points message handlers void CDCalib_get_points::OnBrowse() { // TODO: Add your control notification handler code here UpdateData(TRUE); BOOL bOpen = FALSE; // File Open Dialog LPCSTR lpszDefExt = "txt"; // Default Extension DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; // default LPCSTR lpszFilter = "Project File Types (*.txt) | *.txt;;|All files (*.*) | *.*; ||"; CFileDialog dlg( bOpen, lpszDefExt,NULL, dwFlags, lpszFilter ); if (dlg.DoModal() == IDOK) { m_Outputfile = dlg.GetPathName(); UpdateData(FALSE); } } BOOL CDCalib_get_points::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here m_t=50; m_error=2; m_maxdist=10.0; m_dang=32; m_goodline=15; m_Outputfile = "get_points.txt";

Page 222: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

m_edge = "Deriche"; m_save = TRUE; m_enable_enhan = TRUE; m_show_orlas = TRUE; m_show_lines = TRUE; m_show_enhancement = FALSE; m_show_points = TRUE; m_smooth = "Gaussian_9x9"; UpdateData(FALSE); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CDCalib_get_points::OnSave_Points() { // TODO: Add your control notification handler code here UpdateData(TRUE); if (m_save == TRUE) { GetDlgItem(IDC_EFILE)->EnableWindow(TRUE); GetDlgItem(IDC_BROWSE)->EnableWindow(TRUE); } else { GetDlgItem(IDC_EFILE)->EnableWindow(FALSE); GetDlgItem(IDC_BROWSE)->EnableWindow(FALSE); } } void CDCalib_get_points::OnEnable() { // TODO: Add your control notification handler code here UpdateData(TRUE); if (m_enable_enhan == TRUE) { GetDlgItem(IDC_CHECK6)->EnableWindow(TRUE); GetDlgItem(IDC_SMOOTH)->EnableWindow(TRUE); GetDlgItem(IDC_STC_SMOOTH)->EnableWindow(TRUE); } else {

m_show_enhancement = FALSE; GetDlgItem(IDC_CHECK6)->EnableWindow(FALSE); GetDlgItem(IDC_SMOOTH)->EnableWindow(FALSE); GetDlgItem(IDC_STC_SMOOTH)->EnableWindow(FALSE); } UpdateData(FALSE); } ///////////////////////////////////////////////////////////////////////////// // CDCalib_input dialog CDCalib_input::CDCalib_input(CWnd* pParent /*=NULL*/) : CDialog(CDCalib_input::IDD, pParent) { //{{AFX_DATA_INIT(CDCalib_input) m_strInputfile = _T(""); m_strOutputfile = _T(""); //}}AFX_DATA_INIT } void CDCalib_input::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDCalib_input) DDX_Text(pDX, IDC_EFILE, m_strInputfile); DDV_MaxChars(pDX, m_strInputfile, 120); DDX_Text(pDX, IDC_EFILE2, m_strOutputfile); DDV_MaxChars(pDX, m_strOutputfile, 120); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDCalib_input, CDialog) //{{AFX_MSG_MAP(CDCalib_input) ON_BN_CLICKED(IDC_BROWSE, OnBrowse) ON_BN_CLICKED(IDC_BROWSE2, OnBrowse2) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDCalib_input message handlers BOOL CDCalib_input::OnInitDialog()

Page 223: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

{ CDialog::OnInitDialog(); m_strInputfile = "input.txt"; m_strOutputfile = "output.txt"; UpdateData(FALSE); // TODO: Add extra initialization here return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CDCalib_input::OnBrowse() { // TODO: Add your control notification handler code here BOOL bOpen = TRUE; // File Open Dialog LPCSTR lpszDefExt = "txt"; // Default Extension DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; // default UpdateData(TRUE); LPCSTR lpszFilter = "Project File Types (*.txt) | *.txt;;|All files (*.*) | *.*; ||"; CFileDialog dlg( bOpen, lpszDefExt,NULL, dwFlags, lpszFilter ); if (dlg.DoModal() == IDOK) m_strInputfile = dlg.GetPathName(); UpdateData(FALSE); } void CDCalib_input::OnBrowse2() { // TODO: Add your control notification handler code here BOOL bOpen = FALSE; // File Open Dialog LPCSTR lpszDefExt = "txt"; // Default Extension DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; // default UpdateData(TRUE); LPCSTR lpszFilter = "Project File Types (*.txt) | *.txt;;|All files (*.*) | *.*; ||"; CFileDialog dlg( bOpen, lpszDefExt,NULL, dwFlags, lpszFilter ); if (dlg.DoModal() == IDOK) m_strOutputfile = dlg.GetPathName();

UpdateData(FALSE); } void CDCalib_input::OnOK() { // TODO: Add extra validation here CDialog::OnOK(); } ///////////////////////////////////////////////////////////////////////////// // CDCalib_input_frm dialog CDCalib_input_frm::CDCalib_input_frm(CWnd* pParent /*=NULL*/) : CDialog(CDCalib_input_frm::IDD, pParent) { //{{AFX_DATA_INIT(CDCalib_input_frm) m_point = 0; m_npoints = 0; m_xf = 0.0f; m_yf = 0.0f; m_xw = 0.0f; m_yw = 0.0f; m_zw = 0.0f; //}}AFX_DATA_INIT } void CDCalib_input_frm::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDCalib_input_frm) DDX_Text(pDX, IDC_EDIT1, m_point); DDX_Text(pDX, IDC_EDIT7, m_npoints); DDV_MinMaxInt(pDX, m_npoints, 0, 200); DDX_Text(pDX, IDC_EDIT2, m_xf); DDX_Text(pDX, IDC_EDIT3, m_yf); DDX_Text(pDX, IDC_EDIT4, m_xw); DDX_Text(pDX, IDC_EDIT5, m_yw); DDX_Text(pDX, IDC_EDIT6, m_zw); //}}AFX_DATA_MAP }

Page 224: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

BEGIN_MESSAGE_MAP(CDCalib_input_frm, CDialog) //{{AFX_MSG_MAP(CDCalib_input_frm) ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN2, OnDeltaposSpin2) ON_BN_CLICKED(IDC_BUTTON1, OnButton1) ON_BN_CLICKED(IDC_BUTTON2, OnButton2) ON_EN_UPDATE(IDC_EDIT7, OnUpdateEdit7) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDCalib_input_frm message handlers void CDCalib_input_frm::OnDeltaposSpin2(NMHDR* pNMHDR, LRESULT* pResult) { NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR; // TODO: Add your control notification handler code here UpdateData(TRUE); if (pNMUpDown->iDelta == -1 && m_npoints>0 ) m_npoints -= 1; else if(pNMUpDown->iDelta == +1 && m_npoints <= size ) m_npoints += 1; if (m_npoints == 0 ) m_npoints=1; if (m_npoints > size ) m_npoints = size; CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); m_xf=pAppFrame->m_VarCalib.array[m_npoints-1][0]; m_yf=pAppFrame->m_VarCalib.array[m_npoints-1][1]; m_xw=pAppFrame->m_VarCalib.out_array[m_npoints-1][0]; m_yw=pAppFrame->m_VarCalib.out_array[m_npoints-1][1]; m_zw=pAppFrame->m_VarCalib.out_array[m_npoints-1][2]; UpdateData(FALSE); *pResult = 0; }

BOOL CDCalib_input_frm::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); m_point = size ; m_xf=pAppFrame->m_VarCalib.array[0][0]; m_yf=pAppFrame->m_VarCalib.array[0][1]; m_npoints=1; CSpinButtonCtrl* control; control= (CSpinButtonCtrl*) GetDlgItem(IDC_SPIN2); control->SetRange( 0, size +1 ); UpdateData(FALSE); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CDCalib_input_frm::OnButton1() { // TODO: Add your control notification handler code here CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); UpdateData(TRUE); pAppFrame->m_VarCalib.out_array[m_npoints-1][0]=m_xw; pAppFrame->m_VarCalib.out_array[m_npoints-1][1]=m_yw; pAppFrame->m_VarCalib.out_array[m_npoints-1][2]=m_zw;

Page 225: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

UpdateData(FALSE); } void CDCalib_input_frm::OnButton2() { // TODO: Add your control notification handler code here CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); UpdateData(TRUE); pAppFrame->m_VarCalib.out_array[m_npoints-1][0]=0.0; pAppFrame->m_VarCalib.out_array[m_npoints-1][1]=0.0; pAppFrame->m_VarCalib.out_array[m_npoints-1][2]=0.0; m_xw=pAppFrame->m_VarCalib.out_array[m_npoints-1][0]; m_yw=pAppFrame->m_VarCalib.out_array[m_npoints-1][1]; m_zw=pAppFrame->m_VarCalib.out_array[m_npoints-1][2]; UpdateData(FALSE); } void CDCalib_input_frm::OnUpdateEdit7() { // TODO: If this is a RICHEDIT control, the control will not // send this notification unless you override the CDialog::OnInitDialog() // function to send the EM_SETEVENTMASK message to the control // with the ENM_UPDATE flag ORed into the lParam mask. // TODO: Add your control notification handler code here UpdateData(TRUE); if (m_npoints > (size +1)) m_npoints = size +1; UpdateData(FALSE); }

void CDCalib_input_frm::OnCancel() { // TODO: Add extra cleanup here CDialog::OnCancel(); } ///////////////////////////////////////////////////////////////////////////// // CDCalib_simul dialog CDCalib_simul::CDCalib_simul(CWnd* pParent /*=NULL*/) : CDialog(CDCalib_simul::IDD, pParent) { //{{AFX_DATA_INIT(CDCalib_simul) m_drotx = 0.0; m_droty = 0.0; m_drotz = 0.0; m_dtx = 0.0; m_dty = 0.0; m_dtz = 0.0; m_df = 0.0; m_strOutputfile = _T(""); m_dk1 = 0.0; m_cksave = FALSE; m_dsx = 0.0; m_ddx = 0.0; m_ddy = 0.0; m_iCX = 0.0; m_iCY = 0.0; m_inpoint = 0.0; m_inx = 0.0; m_iny = 0.0; m_izw = 0.0; m_ckshow = FALSE; //}}AFX_DATA_INIT } void CDCalib_simul::DoDataExchange(CDataExchange* pDX)

Page 226: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

{ CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDCalib_simul) DDX_Text(pDX, IDC_ERX, m_drotx); DDV_MinMaxDouble(pDX, m_drotx, -360., 360.); DDX_Text(pDX, IDC_ERY, m_droty); DDV_MinMaxDouble(pDX, m_droty, -360., 360.); DDX_Text(pDX, IDC_ERZ, m_drotz); DDV_MinMaxDouble(pDX, m_drotz, -360., 360.); DDX_Text(pDX, IDC_ETX, m_dtx); DDX_Text(pDX, IDC_ETY, m_dty); DDX_Text(pDX, IDC_ETZ, m_dtz); DDX_Text(pDX, IDC_EF, m_df); DDX_Text(pDX, IDC_EFILE, m_strOutputfile); DDV_MaxChars(pDX, m_strOutputfile, 100); DDX_Text(pDX, IDC_EK1, m_dk1); DDX_Check(pDX, IDC_CKSAVE, m_cksave); DDX_Text(pDX, IDC_ESX, m_dsx); DDX_Text(pDX, IDC_EDX, m_ddx); DDX_Text(pDX, IDC_EDY, m_ddy); DDX_Text(pDX, IDC_ECX, m_iCX); DDX_Text(pDX, IDC_ECY, m_iCY); DDX_Text(pDX, IDC_ENPTS, m_inpoint); DDX_Text(pDX, IDC_ENX, m_inx); DDX_Text(pDX, IDC_ENY, m_iny); DDX_Text(pDX, IDC_EZW, m_izw); DDX_Check(pDX, IDC_TABLE1, m_ckshow); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDCalib_simul, CDialog) //{{AFX_MSG_MAP(CDCalib_simul) ON_BN_CLICKED(IDC_CKSAVE, OnSave) ON_BN_CLICKED(IDC_BROWSE, OnBrowse) ON_BN_CLICKED(IDSIMULATE, OnSimulate) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDCalib_simul message handlers BOOL CDCalib_simul::OnInitDialog() { CDialog::OnInitDialog();

// TODO: Add extra initialization here m_inpoint = 16; m_izw = 0; m_inx = 512; m_iny = 512; m_iCX = 256; m_iCY = 256; m_drotx = -30.0; m_droty = -30.0; m_drotz = -30.0; m_dtx = 100.0; m_dty = 100.0; m_dtz = 2000.0; m_df = 50; m_ddx = 8.37765957e-3; m_ddy = 8.075601357e-3; m_dsx = 0.710935; m_dk1 = 0.001; m_strOutputfile = "res_sim.txt"; m_cksave = FALSE ; GetDlgItem(IDC_EFILE)->EnableWindow(FALSE); GetDlgItem(IDC_BROWSE)->EnableWindow(FALSE); m_ckshow = TRUE ; UpdateData(FALSE); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CDCalib_simul::OnSave() { // TODO: Add your control notification handler code here UpdateData(TRUE); if (m_cksave == TRUE) { GetDlgItem(IDC_EFILE)->EnableWindow(TRUE); GetDlgItem(IDC_BROWSE)->EnableWindow(TRUE); }

Page 227: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

else { GetDlgItem(IDC_EFILE)->EnableWindow(FALSE); GetDlgItem(IDC_BROWSE)->EnableWindow(FALSE); } } void CDCalib_simul::OnBrowse() { // TODO: Add your control notification handler code here BOOL bOpen = FALSE; // File Open Dialog LPCSTR lpszDefExt = "txt"; // Default Extension DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; // default LPCSTR lpszFilter = "Project File Types (*.txt) | *.txt;;|All files (*.*) | *.*; ||"; CFileDialog dlg( bOpen, lpszDefExt,NULL, dwFlags, lpszFilter ); if (dlg.DoModal() == IDOK) { m_strOutputfile = dlg.GetPathName(); UpdateData(FALSE); } } void CDCalib_simul::OnSimulate() { // TODO: Add your control notification handler code here OnOK(); } ///////////////////////////////////////////////////////////////////////////// // CDCalib_simul_res dialog CDCalib_simul_res::CDCalib_simul_res(CWnd* pParent /*=NULL*/) : CDialog(CDCalib_simul_res::IDD, pParent) { EnableAutomation();

//{{AFX_DATA_INIT(CDCalib_simul_res) m_r1 = 0.0; m_r2 = 0.0; m_r3 = 0.0; m_r4 = 0.0; m_r5 = 0.0; m_r6 = 0.0; m_r7 = 0.0; m_r8 = 0.0; m_r9 = 0.0; m_npoint = 0.0; //}}AFX_DATA_INIT } void CDCalib_simul_res::OnFinalRelease() { // When the last reference for an automation object is released // OnFinalRelease is called. The base class will automatically // deletes the object. Add additional cleanup required for your // object before calling the base class. CDialog::OnFinalRelease(); } void CDCalib_simul_res::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDCalib_simul_res) DDX_Control(pDX, IDC_LIST4, m_table2); DDX_Control(pDX, IDC_LIST3, m_table); DDX_Text(pDX, IDC_EDIT1, m_r1); DDX_Text(pDX, IDC_EDIT2, m_r2); DDX_Text(pDX, IDC_EDIT3, m_r3); DDX_Text(pDX, IDC_EDIT4, m_r4); DDX_Text(pDX, IDC_EDIT5, m_r5); DDX_Text(pDX, IDC_EDIT6, m_r6); DDX_Text(pDX, IDC_EDIT7, m_r7); DDX_Text(pDX, IDC_EDIT8, m_r8); DDX_Text(pDX, IDC_EDIT9, m_r9); DDX_Text(pDX, IDC_EDIT10, m_npoint); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDCalib_simul_res, CDialog)

Page 228: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

//{{AFX_MSG_MAP(CDCalib_simul_res) // NOTE: the ClassWizard will add message map macros here //}}AFX_MSG_MAP END_MESSAGE_MAP() BEGIN_DISPATCH_MAP(CDCalib_simul_res, CDialog) //{{AFX_DISPATCH_MAP(CDCalib_simul_res) // NOTE - the ClassWizard will add and remove mapping macros here. //}}AFX_DISPATCH_MAP END_DISPATCH_MAP() // Note: we add support for IID_IDCalib_simul_res to support typesafe binding // from VBA. This IID must match the GUID that is attached to the // dispinterface in the .ODL file. // {5FC48095-2F4F-11D5-9592-0080AD1CB143} static const IID IID_IDCalib_simul_res = { 0x5fc48095, 0x2f4f, 0x11d5, { 0x95, 0x92, 0x0, 0x80, 0xad, 0x1c, 0xb1, 0x43 } }; BEGIN_INTERFACE_MAP(CDCalib_simul_res, CDialog) INTERFACE_PART(CDCalib_simul_res, IID_IDCalib_simul_res, Dispatch) END_INTERFACE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDCalib_simul_res message handlers ///////////////////////////////////////////////////////////////////////////// // CDCalibration dialog CDCalibration::CDCalibration(CWnd* pParent /*=NULL*/) : CDialog(CDCalibration::IDD, pParent) { //{{AFX_DATA_INIT(CDCalibration) m_cksave = FALSE; m_ckfulloptm = FALSE; m_strOutputFile = _T(""); m_ckFindCenter = FALSE; m_isx = 0.0; m_idy = 0.0; m_idx = 0.0; m_icy = 0.0; m_icx = 0.0; m_itolerance = 0.0;

m_strInputFile = _T(""); //}}AFX_DATA_INIT } void CDCalibration::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDCalibration) DDX_Check(pDX, IDC_CHK_SAVE, m_cksave); DDX_Check(pDX, IDC_FULL_OPTM, m_ckfulloptm); DDX_Text(pDX, IDC_OUTPUT_FILE, m_strOutputFile); DDV_MaxChars(pDX, m_strOutputFile, 100); DDX_Check(pDX, IDC_FIND_CENTER, m_ckFindCenter); DDX_Text(pDX, IDC_ESX, m_isx); DDV_MinMaxDouble(pDX, m_isx, 0., 1.); DDX_Text(pDX, IDC_EDY, m_idy); DDV_MinMaxDouble(pDX, m_idy, 0., 1.); DDX_Text(pDX, IDC_EDX, m_idx); DDV_MinMaxDouble(pDX, m_idx, 0., 1.); DDX_Text(pDX, IDC_ECY, m_icy); DDV_MinMaxDouble(pDX, m_icy, 0., 10000.); DDX_Text(pDX, IDC_ECX, m_icx); DDV_MinMaxDouble(pDX, m_icx, 0., 10000.); DDX_Text(pDX, IDC_ETOLERANCE, m_itolerance); DDV_MinMaxDouble(pDX, m_itolerance, 0., 1.); DDX_Text(pDX, IDC_INPUT_FILE, m_strInputFile); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDCalibration, CDialog) //{{AFX_MSG_MAP(CDCalibration) ON_BN_CLICKED(IDC_FULL_OPTM, OnFullOptm) ON_BN_CLICKED(IDC_CHK_SAVE, OnChkSave) ON_BN_CLICKED(IDC_BROWSE, OnBrowse) ON_BN_CLICKED(IDC_BROWSE2, OnBrowse2) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDCalibration message handlers BOOL CDCalibration::OnInitDialog() { CDialog::OnInitDialog();

Page 229: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

// TODO: Add extra initialization here m_cksave = TRUE; m_icx = 256; m_icy = 256; m_idx = 0.0098; m_idy = 0.0063; m_isx = 0.710935; m_itolerance = 0.00000001; m_strOutputFile= "results.txt"; m_strInputFile= "points.txt"; GetDlgItem(IDC_SX)->EnableWindow(FALSE); GetDlgItem(IDC_TOLERANCE)->EnableWindow(FALSE); GetDlgItem(IDC_ESX)->EnableWindow(FALSE); GetDlgItem(IDC_ETOLERANCE)->EnableWindow(FALSE); GetDlgItem(IDC_FIND_CENTER)->EnableWindow(FALSE); UpdateData(FALSE); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CDCalibration::OnFullOptm() { // TODO: Add your control notification handler code here UpdateData(TRUE); if (m_ckfulloptm == TRUE) { GetDlgItem(IDC_SX)->EnableWindow(TRUE); GetDlgItem(IDC_TOLERANCE)->EnableWindow(TRUE); GetDlgItem(IDC_ESX)->EnableWindow(TRUE); GetDlgItem(IDC_ETOLERANCE)->EnableWindow(TRUE); GetDlgItem(IDC_FIND_CENTER)->EnableWindow(TRUE); } else {

GetDlgItem(IDC_SX)->EnableWindow(FALSE); GetDlgItem(IDC_TOLERANCE)->EnableWindow(FALSE); GetDlgItem(IDC_ESX)->EnableWindow(FALSE); GetDlgItem(IDC_ETOLERANCE)->EnableWindow(FALSE); GetDlgItem(IDC_FIND_CENTER)->EnableWindow(FALSE); } } void CDCalibration::OnChkSave() { // TODO: Add your control notification handler code here UpdateData(TRUE); if (m_cksave == TRUE) { GetDlgItem(IDC_OUTPUT_FILE)->EnableWindow(TRUE); GetDlgItem(IDC_BROWSE2)->EnableWindow(TRUE); } else { GetDlgItem(IDC_OUTPUT_FILE)->EnableWindow(FALSE); GetDlgItem(IDC_BROWSE2)->EnableWindow(FALSE); } } void CDCalibration::OnBrowse() { // TODO: Add your control notification handler code here BOOL bOpen = TRUE; // File Open Dialog LPCSTR lpszDefExt = "txt"; // Default Extension DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; // default LPCSTR lpszFilter = "Project File Types (*.txt) | *.txt;;|All files (*.*) | *.*; ||"; CFileDialog dlg( bOpen, lpszDefExt,NULL, dwFlags, lpszFilter ); if (dlg.DoModal() == IDOK) { m_strInputFile = dlg.GetPathName(); UpdateData(FALSE); } } void CDCalibration::OnOK() {

Page 230: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

// TODO: Add extra validation here CDialog::OnOK(); } void CDCalibration::OnBrowse2() { // TODO: Add your control notification handler code here UpdateData(TRUE); BOOL bOpen = FALSE; // File Open Dialog LPCSTR lpszDefExt = "txt"; // Default Extension DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; // default LPCSTR lpszFilter = "Project File Types (*.txt) | *.txt;;|All files (*.*) | *.*; ||"; CFileDialog dlg( bOpen, lpszDefExt,NULL, dwFlags, lpszFilter ); if (dlg.DoModal() == IDOK) { m_strOutputFile = dlg.GetPathName(); UpdateData(FALSE); } UpdateData(FALSE); } ///////////////////////////////////////////////////////////////////////////// // CDCalibration_res dialog CDCalibration_res::CDCalibration_res(CWnd* pParent /*=NULL*/) : CDialog(CDCalibration_res::IDD, pParent) { //{{AFX_DATA_INIT(CDCalibration_res) m_npoint = 0.0; m_r1 = 0.0; m_r2 = 0.0; m_r3 = 0.0; m_r4 = 0.0; m_r5 = 0.0; m_r6 = 0.0; m_r7 = 0.0; m_r8 = 0.0;

m_r9 = 0.0; m_tx = 0.0; m_ty = 0.0; m_f = 0.0; m_k1 = 0.0; m_tz = 0.0; m_default = -1; //}}AFX_DATA_INIT } void CDCalibration_res::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDCalibration_res) DDX_Text(pDX, IDC_EPOINTS, m_npoint); DDX_Text(pDX, IDC_EPOINTS2, m_r1); DDX_Text(pDX, IDC_EPOINTS3, m_r2); DDX_Text(pDX, IDC_EPOINTS4, m_r3); DDX_Text(pDX, IDC_EPOINTS5, m_r4); DDX_Text(pDX, IDC_EPOINTS6, m_r5); DDX_Text(pDX, IDC_EPOINTS7, m_r6); DDX_Text(pDX, IDC_EPOINTS8, m_r7); DDX_Text(pDX, IDC_EPOINTS9, m_r8); DDX_Text(pDX, IDC_EPOINTS10, m_r9); DDX_Text(pDX, IDC_EPOINTS11, m_tx); DDX_Text(pDX, IDC_EPOINTS12, m_ty); DDX_Text(pDX, IDC_EPOINTS14, m_f); DDX_Text(pDX, IDC_EPOINTS15, m_k1); DDX_Text(pDX, IDC_EPOINTS13, m_tz); DDX_Radio(pDX, IDC_RADIO1, m_default); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDCalibration_res, CDialog) //{{AFX_MSG_MAP(CDCalibration_res) ON_BN_CLICKED(IDC_BUTTON1, OnDefault) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDCalibration_res message handlers

Page 231: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

void CDCalibration_res::OnDefault() { // TODO: Add your control notification handler code here UpdateData(TRUE); CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); if ( m_default == 0 ){ pAppFrame->m_VarCalib.mpp1[0][0]=m_r1; pAppFrame->m_VarCalib.mpp1[0][1]=m_r2; pAppFrame->m_VarCalib.mpp1[0][2]=m_r3; pAppFrame->m_VarCalib.mpp1[0][3]=m_tx; pAppFrame->m_VarCalib.mpp1[1][0]=m_r4; pAppFrame->m_VarCalib.mpp1[1][1]=m_r5; pAppFrame->m_VarCalib.mpp1[1][2]=m_r6; pAppFrame->m_VarCalib.mpp1[1][3]=m_ty; pAppFrame->m_VarCalib.mpp1[2][0]=m_r7/m_f; pAppFrame->m_VarCalib.mpp1[2][1]=m_r8/m_f; pAppFrame->m_VarCalib.mpp1[2][2]=m_r9/m_f; pAppFrame->m_VarCalib.mpp1[2][3]=m_tz/m_f; pAppFrame->m_VarCalib.f1=m_f; pAppFrame->m_VarCalib.k1=m_k1; pAppFrame->m_VarCalib.matrix1_exist=TRUE; } else { pAppFrame->m_VarCalib.mpp2[0][0]=m_r1; pAppFrame->m_VarCalib.mpp2[0][1]=m_r2; pAppFrame->m_VarCalib.mpp2[0][2]=m_r3; pAppFrame->m_VarCalib.mpp2[0][3]=m_tx; pAppFrame->m_VarCalib.mpp2[1][0]=m_r4; pAppFrame->m_VarCalib.mpp2[1][1]=m_r5; pAppFrame->m_VarCalib.mpp2[1][2]=m_r6; pAppFrame->m_VarCalib.mpp2[1][3]=m_ty; pAppFrame->m_VarCalib.mpp2[2][0]=m_r7/m_f; pAppFrame->m_VarCalib.mpp2[2][1]=m_r8/m_f; pAppFrame->m_VarCalib.mpp2[2][2]=m_r9/m_f; pAppFrame->m_VarCalib.mpp2[2][3]=m_tz/m_f; pAppFrame->m_VarCalib.f2=m_f; pAppFrame->m_VarCalib.k2=m_k1; pAppFrame->m_VarCalib.matrix2_exist=TRUE; } }

acquire.h #include "mil.h" #include "dacquire.h" /* ________________________________________________________________ acquire.h @(#)acquire.h 09/04/2001, Copyright 2001 Instituto de Engenharia Biomédica (INEB) Faculdade de Engenharia da Universidade do Porto (FEUP) Autor: Sergio Barros & Nuno Sa Couto ________________________________________________________________ */ UINT MilApplication(LPVOID pParam); void one_camera(); void Two_camera(); UINT SequenciaNuclear(LPVOID pParam); UINT ShotTemp(LPVOID pParam); UINT ShotTrigger(LPVOID pParam); void StopThreadNuclear (); void StartThreadNuclear (); void bmpsave(CString filename,CString text); //Serial// BOOL PortInitialize (LPTSTR lpszPortName); void PortWrite (BYTE Byte); DWORD WINAPI PortReadThread (LPVOID lpvoid); BOOL PortClose (HANDLE hCommPort); // void writetext(char* text,UINT size,UINT color,bool position,bool save,MIL_ID buffer); //////////////////////////////////////////////////////////////////////// // Classe CVariaveisNuclear class CVariaveisNuclear{

Page 232: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

public: CVariaveisNuclear(); bool m_bTriggerMode,m_bSequencia,m_bPixelTypeRGB ,m_CameraNum1,m_CameraNum2,m_bCompressed ,m_bvideo,m_bTecla,m_bTriggerExterno ,m_bDataTypeRGB,m_bSignature,first ,m_bTimeBetween,ExitSerial,m_bVisualize; HWND m_hWndNuclear,m_hWndNuclear2; MIL_ID MilApplication,MilSystem,MilDisplay[2] ,MilDigitizer,MilImage[2],MilOverlayImage ,m_MILSequenceType,m_MILImageType; CString m_csTecla,m_csTriggerExterno,m_csFileName ,m_csSinal,m_csData,m_csCh1,m_csCh2 ,m_csScale,m_csDisplay,m_csSequence ,m_csImage,m_cstext,aux; UINT m_iNbFrames,m_iDuration ,m_iTimeBetween,m_iInitialTime ,m_iBetweenTime,m_iCamera,Q_FACTOR; double m_dTimeBetweenUnit,m_dInitialTimeUnit, m_dBetweenTimeUnit,m_dImageScale,Time; long m_lChannel1,m_lChannel2,m_lDispMode ,BufSizeX,BufSizeY,BufSizeBand,ErrorPtr; char* m_pcDataFormat; int m_iBrightness,m_iContrast,m_iHue,m_iSaturation; HANDLE Semaphore,SerialSem,hReadThread; CDComents* dlg; HANDLE hPort; DWORD id; };

acquire.cpp /* ________________________________________________________________ acquire.cpp @(#)acquire.cpp 10/09/2000, Copyright 2000 Instituto de Engenharia Biomédica (INEB) Faculdade de Engenharia da Universidade do Porto (FEUP) Autor: Sergio Barros & Nuno Sa Couto ________________________________________________________________ */ #include "stdafx.h" #include "dib_func.h" // functions for DIBs #include "MainFrm.h" #include <afxmt.h> // permite sincronização por eventos CEvent #include "ChildFrm.h" // para definir CChildFrame para conseguir aceder ao Doc #include <stdio.h> #include <string.h> #include <malloc.h> #include <windows.h> #include "mil.h" #include "mwinmil.h" #include "wingdi.h" #include <afxwin.h> #include <conio.h> #include <ctype.h> #include "math.h" #include "Dacquire.h" #include "project.h" #include "dib_func.h" #define DIB_HEADER_MARKER ((WORD) ('M' << 8) | 'B') #define MAKEP(sel,off) ((VOID *)MAKELONG(off,sel)) #ifdef _MAC #define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))

Page 233: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x))) void ByteSwapHeader(BITMAPFILEHEADER* bmiHeader); void ByteSwapInfo(LPSTR lpHeader, BOOL fWin30Header); #endif CEvent EventoThreadNuclear(FALSE, TRUE); /*---------------------------------------------------------------- Function: UINT MilApplication(LPVOID pParam) Purpose: Choose between 1 or 2 cameras and visualizes it -----------------------------------------------------------------*/ UINT MilApplication(LPVOID pParam) { BOOL AcabaThread = FALSE; CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); /* Grab in the user window if supported by the system. */ if (pAppFrame->m_VarNuclear.MilDigitizer) { MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.m_lChannel1 ); MdigGrabContinuous(pAppFrame->m_VarNuclear.MilDigitizer, pAppFrame->m_VarNuclear.MilImage[0]); int status = ::WaitForSingleObject(EventoThreadNuclear.m_hObject, INFINITE); /* Stop continuous grab. */ MdigHalt(pAppFrame->m_VarNuclear.MilDigitizer); } return 0; }

/*---------------------------------------------------------------- Function: void StopThreadNuclear () Purpose: Prepares end of thread -----------------------------------------------------------------*/ void StopThreadNuclear () { EventoThreadNuclear.SetEvent(); } /*---------------------------------------------------------------- Function: void StartThreadNuclear () Purpose: Prepares start of thread -----------------------------------------------------------------*/ void StartThreadNuclear () { EventoThreadNuclear.ResetEvent(); } /*---------------------------------------------------------------- Function: void SequenciaNuclear() Purpose: Records sequence of images in a sequence type AVI or AVI-MJPG , from 1 or 2 cameras -----------------------------------------------------------------*/ UINT SequenciaNuclear(LPVOID pParam) { CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); //Variables// long lExtendedAttrib=0; UINT n = 0; double Time=0.0; CString aux; ///////////// // Grab continuous on display //

Page 234: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.m_lChannel1 ); MdigGrabContinuous(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.MilImage[0]); //Comments// CEdit* edit=(CEdit*) pAppFrame->m_VarNuclear.dlg->GetDlgItem(IDC_EDIT1); CButton* button=(CButton*) pAppFrame->m_VarNuclear.dlg->GetDlgItem(IDC_BUTTON1); CButton* button2=(CButton*) pAppFrame->m_VarNuclear.dlg->GetDlgItem(IDC_BUTTON2); pAppFrame->m_VarNuclear.Semaphore= CreateSemaphore(NULL, 0, 2,NULL ); WaitForSingleObject(pAppFrame->m_VarNuclear.Semaphore,INFINITE); button2->EnableWindow(FALSE); ///////////// //Compression/////// if ( pAppFrame->m_VarNuclear.m_bCompressed == TRUE ) if ( MsysInquire(pAppFrame->m_VarNuclear.MilSystem, M_COMPRESSION_SUPPORTED, M_NULL) ) { lExtendedAttrib = M_COMPRESS | M_JPEG_LOSSY; if ( MsysInquire(pAppFrame->m_VarNuclear.MilSystem, M_BOARD_TYPE, M_NULL) & M_MJPEG_MODULE ) if ( MdigInquire(pAppFrame-> m_VarNuclear.MilDigitizer, M_SCAN_MODE, M_NULL ) == M_INTERLACE ) lExtendedAttrib = M_COMPRESS | M_JPEG_LOSSY_INTERLACED; } ////////////////////

//1 or 2 cameras// if (pAppFrame->m_VarNuclear.m_CameraNum1 && pAppFrame->m_VarNuclear.m_CameraNum2 ) { //Memory allocation for the buffers// MIL_ID* MilImageSeq; MilImageSeq = (MIL_ID*) ::GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,(pAppFrame->m_VarNuclear.m_iNbFrames)*sizeof(MIL_ID)); MIL_ID* MilImageSeq2; MilImageSeq2 = (MIL_ID*) ::GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,(pAppFrame->m_VarNuclear.m_iNbFrames)*sizeof(MIL_ID)); ///////////////////////////////////// MappControl(M_ERROR, M_PRINT_DISABLE); // Allocate grab buffers to hold the sequence// for (n=0; n<pAppFrame->m_VarNuclear.m_iNbFrames; n++) { if (pAppFrame->m_VarNuclear.m_bDataTypeRGB == FALSE) { MbufAlloc2d(pAppFrame->m_VarNuclear.MilSystem ,(long)(pAppFrame->m_VarNuclear.BufSizeX*pAppFrame->m_VarNuclear.m_dImageScale) ,(long)(pAppFrame->m_VarNuclear.BufSizeY*pAppFrame->m_VarNuclear.m_dImageScale) ,8 + M_UNSIGNED , M_IMAGE+M_GRAB + lExtendedAttrib ,&MilImageSeq[n]); MbufAlloc2d(pAppFrame->m_VarNuclear.MilSystem ,(long)(pAppFrame->m_VarNuclear.BufSizeX*pAppFrame->m_VarNuclear.m_dImageScale) ,(long)(pAppFrame->m_VarNuclear.BufSizeY*pAppFrame->m_VarNuclear.m_dImageScale) ,8 + M_UNSIGNED , M_IMAGE + M_GRAB + lExtendedAttrib ,&MilImageSeq2[n]); }

Page 235: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

else if (pAppFrame->m_VarNuclear.m_bDataTypeRGB == TRUE) { MbufAllocColor(pAppFrame->m_VarNuclear.MilSystem, pAppFrame->m_VarNuclear.BufSizeBand ,(long)(pAppFrame->m_VarNuclear.BufSizeX*pAppFrame->m_VarNuclear.m_dImageScale) ,(long)(pAppFrame->m_VarNuclear.BufSizeY*pAppFrame->m_VarNuclear.m_dImageScale) ,8+M_UNSIGNED,M_IMAGE + M_GRAB + lExtendedAttrib ,&MilImageSeq[n]); MbufAllocColor(pAppFrame->m_VarNuclear.MilSystem, pAppFrame->m_VarNuclear.BufSizeBand ,(long)(pAppFrame->m_VarNuclear.BufSizeX*pAppFrame->m_VarNuclear.m_dImageScale) ,(long)(pAppFrame->m_VarNuclear.BufSizeY*pAppFrame->m_VarNuclear.m_dImageScale) ,8+M_UNSIGNED,M_IMAGE + M_GRAB + lExtendedAttrib ,&MilImageSeq2[n]); } MbufClear(MilImageSeq[n],0); MbufClear(MilImageSeq2[n],0); if (pAppFrame->m_VarNuclear.m_bCompressed == TRUE ) { MbufControl( MilImageSeq[n], M_Q_FACTOR, pAppFrame->m_VarNuclear.Q_FACTOR ); MbufControl( MilImageSeq2[n], M_Q_FACTOR, pAppFrame->m_VarNuclear.Q_FACTOR ); } } ////////////////////////////////////////////////////// /*/ERROR////////////////////////////////////// MappGetError(M_CURRENT,& pAppFrame->m_VarNuclear.ErrorPtr); if ( pAppFrame->m_VarNuclear.ErrorPtr != M_NULL) { MessageBox(0,"Some kind of invalide parameter","Error Reporting",MB_OK);

//CWnd* destrwnd; //destrwnd->Attach(m_VarNuclear.m_hWndNuclear); //MDIActivate(destrwnd); CMDIFrameWnd* frame = (CMDIFrameWnd*) MDIGetActive(); CProjectDoc* documento = (CProjectDoc*) frame->GetActiveDocument(); documento->OnCloseDocument(); return; } /*//////////////////////////////////////////// MdigControl(pAppFrame->m_VarNuclear.MilDigitizer,M_GRAB_MODE,M_ASYNCHRONOUS); //Start Grabbing // MdigHalt(pAppFrame->m_VarNuclear.MilDigitizer); aux="Recording "; edit->ReplaceSel(aux,FALSE ); //MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.m_lChannel1 ); //Sleep(200); //MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer, pAppFrame->m_VarNuclear.MilImage[0]); MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer,MilImageSeq[0]); MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.m_lChannel2 ); Sleep(200); MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer, pAppFrame->m_VarNuclear.MilImage[1]); MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer,MilImageSeq2[0]); MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.m_lChannel1 ); Sleep(200); MappTimer(M_TIMER_RESET, M_NULL);

Page 236: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

pAppFrame->m_VarNuclear.Time=(pAppFrame->m_VarNuclear.m_iTimeBetween * pAppFrame->m_VarNuclear.m_dTimeBetweenUnit); // Grab the sequence. // for (n=1; n<pAppFrame->m_VarNuclear.m_iNbFrames; n++) { /* Grab one buffer at a time. */ MdigGrabContinuous(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.MilImage[0]); if (pAppFrame->m_VarNuclear.m_bTimeBetween) MappTimer(M_TIMER_WAIT, &pAppFrame->m_VarNuclear.Time); MdigHalt(pAppFrame->m_VarNuclear.MilDigitizer); //MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer, pAppFrame->m_VarNuclear.MilImage[0]); MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer, MilImageSeq[n]); MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.m_lChannel2 ); Sleep(200); MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer, pAppFrame->m_VarNuclear.MilImage[1]); MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer, MilImageSeq2[n]); MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.m_lChannel1 ); Sleep(200); } /* Wait last grab end. */ MdigGrabWait(pAppFrame->m_VarNuclear.MilDigitizer, M_GRAB_END); MappTimer(M_TIMER_READ,&Time); if (pAppFrame->m_VarNuclear.m_bTimeBetween) Time= Time - (pAppFrame->m_VarNuclear.m_iNbFrames-1)*pAppFrame->m_VarNuclear.Time; int decimal, sign; double y, r; y = modf( Time , &r); /* and integer parts */

aux="Time Ellapsed "; aux+= _fcvt( r, 0, &decimal, &sign ); aux+="."; aux+=_fcvt( y*1000, 0, &decimal, &sign ); aux+=" "; edit->ReplaceSel(aux,FALSE ); /*/ERROR////////////////////////////////////// MappGetError(M_CURRENT,& pAppFrame->m_VarNuclear.ErrorPtr); if ( pAppFrame->m_VarNuclear.ErrorPtr != M_NULL) { MessageBox(0,"Some kind of invalide parameter","Error Reporting",MB_OK); //CWnd* destrwnd; //destrwnd->Attach(m_VarNuclear.m_hWndNuclear); //MDIActivate(destrwnd); CMDIFrameWnd* frame = (CMDIFrameWnd*) MDIGetActive(); CProjectDoc* documento = (CProjectDoc*) frame->GetActiveDocument(); documento->OnCloseDocument(); return; } /*//////////////////////////////////////////// MdigControl(pAppFrame->m_VarNuclear.MilDigitizer,M_GRAB_MODE,M_SYNCHRONOUS); StartThreadNuclear(); AfxBeginThread (MilApplication,(LPVOID) NULL , THREAD_PRIORITY_NORMAL); pAppFrame->m_VarNuclear.m_csFileName.MakeLower(); int len =pAppFrame->m_VarNuclear.m_csFileName.GetLength(); int t=len-1; while((pAppFrame->m_VarNuclear.m_csFileName[t] != '.') && (t!=0) ) t--; if (t<3) t=len-1;

Page 237: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

CString filenameout =pAppFrame->m_VarNuclear.m_csFileName.Left(t); CString filenameout2 = filenameout; filenameout+="_cam1.avi"; filenameout2+="_cam2.avi"; /* Save the sequence into a file */ //printf( "Saving the sequence into an AVI file...\n" ); MbufExportSequence( filenameout.GetBuffer(256), pAppFrame->m_VarNuclear.m_MILSequenceType, MilImageSeq, pAppFrame->m_VarNuclear.m_iNbFrames, (long)(pAppFrame->m_VarNuclear.m_iNbFrames/Time), M_DEFAULT ); MbufExportSequence( filenameout2.GetBuffer(256), pAppFrame->m_VarNuclear.m_MILSequenceType, MilImageSeq2, pAppFrame->m_VarNuclear.m_iNbFrames, (long)(pAppFrame->m_VarNuclear.m_iNbFrames/Time), M_DEFAULT ); /* Free all the buffers of the sequence. */ for (n=0; n<pAppFrame->m_VarNuclear.m_iNbFrames; n++) { MbufFree(MilImageSeq[n]); MbufFree(MilImageSeq2[n]); } ::GlobalFree((HGLOBAL) MilImageSeq); ::GlobalFree((HGLOBAL) MilImageSeq2); aux="Finished Sequence"; edit->ReplaceSel(aux,FALSE ); button->EnableWindow(TRUE); } else if (pAppFrame->m_VarNuclear.m_CameraNum1 && (!pAppFrame->m_VarNuclear.m_CameraNum2))

{ MIL_ID* MilImageSeq; //Memory Allocation// MilImageSeq = (MIL_ID*) ::GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT ,(pAppFrame->m_VarNuclear.m_iNbFrames)*sizeof(MIL_ID)); ///////////////////// MappControl(M_ERROR, M_PRINT_DISABLE); // Allocate grab buffers to hold the sequence. // for (n=0; n<pAppFrame->m_VarNuclear.m_iNbFrames; n++) { if (pAppFrame->m_VarNuclear.m_bDataTypeRGB == FALSE) { MbufAlloc2d(pAppFrame->m_VarNuclear.MilSystem ,(long)(pAppFrame->m_VarNuclear.BufSizeX*pAppFrame->m_VarNuclear.m_dImageScale ) ,(long)(pAppFrame->m_VarNuclear.BufSizeY*pAppFrame->m_VarNuclear.m_dImageScale) ,8 + M_UNSIGNED , M_IMAGE+M_GRAB + lExtendedAttrib ,&MilImageSeq[n]); } else if (pAppFrame->m_VarNuclear.m_bDataTypeRGB == TRUE) { MbufAllocColor(pAppFrame->m_VarNuclear.MilSystem, pAppFrame->m_VarNuclear.BufSizeBand ,(long)(pAppFrame->m_VarNuclear.BufSizeX*pAppFrame->m_VarNuclear.m_dImageScale) ,(long)(pAppFrame->m_VarNuclear.BufSizeY*pAppFrame->m_VarNuclear.m_dImageScale) ,8+M_UNSIGNED,M_IMAGE + M_GRAB + lExtendedAttrib ,&MilImageSeq[n]); } MbufClear(MilImageSeq[n],0);

Page 238: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

if (pAppFrame->m_VarNuclear.m_bCompressed == TRUE ) MbufControl( MilImageSeq[n], M_Q_FACTOR, pAppFrame->m_VarNuclear.Q_FACTOR ); } ////////////////////////////////////////////////////// /*/ERROR////////////////////////////////////// MappGetError(M_CURRENT,& pAppFrame->m_VarNuclear.ErrorPtr); if ( pAppFrame->m_VarNuclear.ErrorPtr != M_NULL) { MessageBox(0,"Some kind of invalide parameter","Error Reporting",MB_OK); //CWnd* destrwnd; //destrwnd->Attach(m_VarNuclear.m_hWndNuclear); //MDIActivate(destrwnd); CMDIFrameWnd* frame = (CMDIFrameWnd*) MDIGetActive(); CProjectDoc* documento = (CProjectDoc*) frame->GetActiveDocument(); documento->OnCloseDocument(); return; } /*//////////////////////////////////////////// //Begin grabbing// MdigHalt(pAppFrame->m_VarNuclear.MilDigitizer); aux="Recording "; edit->ReplaceSel(aux,FALSE ); MdigControl(pAppFrame->m_VarNuclear.MilDigitizer,M_GRAB_MODE,M_ASYNCHRONOUS); //MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.m_lChannel1); // Grab continuous on display // //MdigGrabContinuous(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.MilImage[0]); // Halt continuous grab // //MdigHalt(pAppFrame->m_VarNuclear.MilDigitizer);

//MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.MilImage[0]); MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer,MilImageSeq[0]); MappTimer(M_TIMER_RESET, M_NULL); pAppFrame->m_VarNuclear.Time=(pAppFrame->m_VarNuclear.m_iTimeBetween * pAppFrame->m_VarNuclear.m_dTimeBetweenUnit); // Grab the sequence. // for (n=1; n<pAppFrame->m_VarNuclear.m_iNbFrames; n++) { // Grab one buffer at a time. // MdigGrabContinuous(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.MilImage[0]); if (pAppFrame->m_VarNuclear.m_bTimeBetween) MappTimer(M_TIMER_WAIT, &pAppFrame->m_VarNuclear.Time); MdigHalt(pAppFrame->m_VarNuclear.MilDigitizer); //MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer, pAppFrame->m_VarNuclear.MilImage[0]); MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer, MilImageSeq[n]); } // Wait last grab end. // MdigGrabWait(pAppFrame->m_VarNuclear.MilDigitizer, M_GRAB_END); MappTimer(M_TIMER_READ, &Time); if (pAppFrame->m_VarNuclear.m_bTimeBetween) Time= Time - (pAppFrame->m_VarNuclear.m_iNbFrames-1)*pAppFrame->m_VarNuclear.Time; int decimal, sign; double y, r; y = modf( Time , &r); /* and integer parts */ aux="Time Ellapsed "; aux+= _fcvt( r, 0, &decimal, &sign ); aux+="."; aux+=_fcvt( y*1000, 0, &decimal, &sign ); aux+=" "; edit->ReplaceSel(aux,FALSE );

Page 239: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

/* Print statistics. */ //printf("%ld frames grabbed, at a frame rate of %.2f frames/sec (%.2f ms/frame).\n", // NbFrames, NbFrames/Time, 1000.0*Time/NbFrames); /*/ERROR////////////////////////////////////// MappGetError(M_CURRENT,& pAppFrame->m_VarNuclear.ErrorPtr); if ( pAppFrame->m_VarNuclear.ErrorPtr != M_NULL) { MessageBox(0,"Some kind of invalide parameter","Error Reporting",MB_OK); //CWnd* destrwnd; //destrwnd->Attach(m_VarNuclear.m_hWndNuclear); //MDIActivate(destrwnd); CMDIFrameWnd* frame = (CMDIFrameWnd*) MDIGetActive(); CProjectDoc* documento = (CProjectDoc*) frame->GetActiveDocument(); documento->OnCloseDocument(); return; } //*/////////////////////////////////////////// MdigControl(pAppFrame->m_VarNuclear.MilDigitizer,M_GRAB_MODE,M_SYNCHRONOUS); StartThreadNuclear(); AfxBeginThread (MilApplication,(LPVOID) NULL , THREAD_PRIORITY_NORMAL); /* Save the sequence into a file */ //printf( "Saving the sequence into an AVI file...\n" ); pAppFrame->m_VarNuclear.m_csFileName.MakeLower(); int len =pAppFrame->m_VarNuclear.m_csFileName.GetLength(); int t=len-1; while((pAppFrame->m_VarNuclear.m_csFileName[t] != '.') && (t!=0) )

t--; if (t<3) t=len-1; CString filenameout =pAppFrame->m_VarNuclear.m_csFileName.Left(t); filenameout+=".avi"; MbufExportSequence(filenameout.GetBuffer(256), pAppFrame->m_VarNuclear.m_MILSequenceType, MilImageSeq, pAppFrame->m_VarNuclear.m_iNbFrames, (long)(pAppFrame->m_VarNuclear.m_iNbFrames/Time), M_DEFAULT ); /* Free all the buffers of the sequence. */ for (n=0; n<pAppFrame->m_VarNuclear.m_iNbFrames; n++) MbufFree(MilImageSeq[n]); ::GlobalFree((HGLOBAL) MilImageSeq); aux="Finished Sequence"; edit->ReplaceSel(aux,FALSE ); button->EnableWindow(TRUE); } CloseHandle (pAppFrame->m_VarNuclear.Semaphore); return 0; } /*---------------------------------------------------------------- Function: void ShotTemp() Purpose: Gets shots from frame grabber with time conditions -----------------------------------------------------------------*/ UINT ShotTemp(LPVOID id) {

Page 240: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); UINT n = 0; CString aux; char numero[4]; MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.m_lChannel1); MdigGrabContinuous(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.MilImage[0]); //Comments// CEdit* edit=(CEdit*) pAppFrame->m_VarNuclear.dlg->GetDlgItem(IDC_EDIT1); CButton* button=(CButton*) pAppFrame->m_VarNuclear.dlg->GetDlgItem(IDC_BUTTON1); CButton* button2=(CButton*) pAppFrame->m_VarNuclear.dlg->GetDlgItem(IDC_BUTTON2); pAppFrame->m_VarNuclear.Semaphore= CreateSemaphore(NULL, 0, 2,NULL ); WaitForSingleObject(pAppFrame->m_VarNuclear.Semaphore,INFINITE); button2->EnableWindow(FALSE); ///////////// //Choose from 1 or 2 cameras if (pAppFrame->m_VarNuclear.m_CameraNum1 && (!pAppFrame->m_VarNuclear.m_CameraNum2)) { MIL_ID* MilImageSeq; //Memory Allocation// MilImageSeq = (MIL_ID*) ::GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT ,(pAppFrame->m_VarNuclear.m_iNbFrames)*sizeof(MIL_ID)); /////////////////////

MappControl(M_ERROR, M_PRINT_DISABLE); // Allocate grab buffers to hold the sequence. // for (n=0; n<pAppFrame->m_VarNuclear.m_iNbFrames; n++) { if (pAppFrame->m_VarNuclear.m_bDataTypeRGB == FALSE) { MbufAlloc2d(pAppFrame->m_VarNuclear.MilSystem ,(long)(pAppFrame->m_VarNuclear.BufSizeX*pAppFrame->m_VarNuclear.m_dImageScale) ,(long)(pAppFrame->m_VarNuclear.BufSizeY*pAppFrame->m_VarNuclear.m_dImageScale) ,8 + M_UNSIGNED , M_IMAGE+M_GRAB ,&MilImageSeq[n]); } else if (pAppFrame->m_VarNuclear.m_bDataTypeRGB == TRUE) { MbufAllocColor(pAppFrame->m_VarNuclear.MilSystem, pAppFrame->m_VarNuclear.BufSizeBand ,(long)(pAppFrame->m_VarNuclear.BufSizeX*pAppFrame->m_VarNuclear.m_dImageScale) ,(long)(pAppFrame->m_VarNuclear.BufSizeY*pAppFrame->m_VarNuclear.m_dImageScale) ,8+M_UNSIGNED,M_IMAGE + M_GRAB ,&MilImageSeq[n]); } MbufClear(MilImageSeq[n],0); } ///////////////////////////////////////////////////////// //Begin grab// //MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.m_lChannel1);

Page 241: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

// Grab continuous on display // //MdigGrabContinuous(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.MilImage[0]); MappTimer(M_TIMER_RESET, M_NULL); pAppFrame->m_VarNuclear.Time=(pAppFrame->m_VarNuclear.m_iInitialTime * pAppFrame->m_VarNuclear.m_dInitialTimeUnit); MappTimer(M_TIMER_WAIT, &pAppFrame->m_VarNuclear.Time); // Halt continuous grab and put digitizer in asynchronous mode. // MdigHalt(pAppFrame->m_VarNuclear.MilDigitizer); //MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.MilImage[0]); MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer,MilImageSeq[0]); aux="Grabbed shot"; aux+=(_itoa( 1, numero, 10 )); aux+=" "; edit->ReplaceSel(aux,FALSE ); // Grab the sequence. // pAppFrame->m_VarNuclear.Time=(pAppFrame->m_VarNuclear.m_iBetweenTime * pAppFrame->m_VarNuclear.m_dBetweenTimeUnit); for (n=1; n<pAppFrame->m_VarNuclear.m_iNbFrames; n++) { /* Grab one buffer at a time. */ MdigGrabContinuous(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.MilImage[0]); MappTimer(M_TIMER_WAIT, &pAppFrame->m_VarNuclear.Time); MdigHalt(pAppFrame->m_VarNuclear.MilDigitizer); //MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer, pAppFrame->m_VarNuclear.MilImage[0]); MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer, MilImageSeq[n]); aux="Grabbed shot"; aux+=(_itoa( n+1, numero, 10 )); aux+=" "; edit->ReplaceSel(aux,FALSE ); }

for (n=0; n<pAppFrame->m_VarNuclear.m_iNbFrames; n++) { char numero[4]; pAppFrame->m_VarNuclear.m_csFileName.MakeLower(); int len =pAppFrame->m_VarNuclear.m_csFileName.GetLength(); int t=len-1; while((pAppFrame->m_VarNuclear.m_csFileName[t] != '.') && (t!=0) ) t--; if (t<3) t=len-1; CString filenameout =pAppFrame->m_VarNuclear.m_csFileName.Left(t); if(pAppFrame->m_VarNuclear.m_iNbFrames > 1) filenameout+=(_itoa( n+1, numero, 10 )); filenameout+="."+pAppFrame->m_VarNuclear.m_csImage; MbufExport(filenameout.GetBuffer(256),pAppFrame->m_VarNuclear.m_MILImageType,MilImageSeq[n]); if (pAppFrame->m_VarNuclear.m_csImage == "bmp") if (pAppFrame->m_VarNuclear.m_bSignature) bmpsave(filenameout,pAppFrame->m_VarNuclear.m_cstext); Sleep(500); pAppFrame->m_VarNuclear.aux=filenameout; //Visualize all results obtained if (pAppFrame->m_VarNuclear.m_bVisualize ) { PostThreadMessage((DWORD) id, WM_NUCLEAR, 0 ,0); } } for (n=0; n<pAppFrame->m_VarNuclear.m_iNbFrames; n++)

Page 242: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

MbufFree(MilImageSeq[n]); ::GlobalFree((HGLOBAL) MilImageSeq); aux="Finished Shooting"; edit->ReplaceSel(aux,FALSE ); button->EnableWindow(TRUE); StartThreadNuclear(); AfxBeginThread (MilApplication,(LPVOID) NULL , THREAD_PRIORITY_NORMAL); } else if (pAppFrame->m_VarNuclear.m_CameraNum1 && pAppFrame->m_VarNuclear.m_CameraNum2) { MIL_ID* MilImageSeq; MIL_ID* MilImageSeq2; //Memory Allocation// MilImageSeq = (MIL_ID*) ::GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT ,(pAppFrame->m_VarNuclear.m_iNbFrames)*sizeof(MIL_ID)); MilImageSeq2 = (MIL_ID*) ::GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT ,(pAppFrame->m_VarNuclear.m_iNbFrames)*sizeof(MIL_ID)); ////////////////////// MappControl(M_ERROR, M_PRINT_DISABLE); // Allocate grab buffers to hold the sequence. // for (n=0; n<pAppFrame->m_VarNuclear.m_iNbFrames; n++) { if (pAppFrame->m_VarNuclear.m_bDataTypeRGB == FALSE) { MbufAlloc2d(pAppFrame->m_VarNuclear.MilSystem ,(long)(pAppFrame->m_VarNuclear.BufSizeX*pAppFrame->m_VarNuclear.m_dImageScale )

,(long)(pAppFrame->m_VarNuclear.BufSizeY*pAppFrame->m_VarNuclear.m_dImageScale) ,8 + M_UNSIGNED , M_IMAGE+M_GRAB ,&MilImageSeq[n]); MbufAlloc2d(pAppFrame->m_VarNuclear.MilSystem ,(long)(pAppFrame->m_VarNuclear.BufSizeX*pAppFrame->m_VarNuclear.m_dImageScale ) ,(long)(pAppFrame->m_VarNuclear.BufSizeY*pAppFrame->m_VarNuclear.m_dImageScale) ,8 + M_UNSIGNED , M_IMAGE+M_GRAB ,&MilImageSeq2[n]); } else if (pAppFrame->m_VarNuclear.m_bDataTypeRGB == TRUE) { MbufAllocColor(pAppFrame->m_VarNuclear.MilSystem, pAppFrame->m_VarNuclear.BufSizeBand ,(long)(pAppFrame->m_VarNuclear.BufSizeX*pAppFrame->m_VarNuclear.m_dImageScale) ,(long)(pAppFrame->m_VarNuclear.BufSizeY*pAppFrame->m_VarNuclear.m_dImageScale) ,8+M_UNSIGNED,M_IMAGE + M_GRAB ,&MilImageSeq[n]); MbufAllocColor(pAppFrame->m_VarNuclear.MilSystem, pAppFrame->m_VarNuclear.BufSizeBand ,(long)(pAppFrame->m_VarNuclear.BufSizeX*pAppFrame->m_VarNuclear.m_dImageScale) ,(long)(pAppFrame->m_VarNuclear.BufSizeY*pAppFrame->m_VarNuclear.m_dImageScale) ,8+M_UNSIGNED,M_IMAGE + M_GRAB ,&MilImageSeq2[n]); } MbufClear(MilImageSeq[n],0); MbufClear(MilImageSeq2[n],0); } ///////////////////////////////////////////////////////////////

Page 243: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

//Begin grab// //MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.m_lChannel1); // Grab continuous on display // //MdigGrabContinuous(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.MilImage[0]); MappTimer(M_TIMER_RESET, M_NULL); pAppFrame->m_VarNuclear.Time=(pAppFrame->m_VarNuclear.m_iInitialTime * pAppFrame->m_VarNuclear.m_dInitialTimeUnit); MappTimer(M_TIMER_WAIT, &pAppFrame->m_VarNuclear.Time); // Halt continuous grab // MdigHalt(pAppFrame->m_VarNuclear.MilDigitizer); //MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.MilImage[0]); MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer,MilImageSeq[0]); MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.m_lChannel2); Sleep(200); MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.MilImage[1]); MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer,MilImageSeq2[0]); aux="Grabbed shot"; aux+=(_itoa( 1, numero, 10 )); aux+=" "; edit->ReplaceSel(aux,FALSE ); // Grab the sequence. // pAppFrame->m_VarNuclear.Time=(pAppFrame->m_VarNuclear.m_iBetweenTime * pAppFrame->m_VarNuclear.m_dBetweenTimeUnit); for (n=1; n<pAppFrame->m_VarNuclear.m_iNbFrames; n++) { /* Grab one buffer at a time. */ MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.m_lChannel1);

Sleep(200); MdigGrabContinuous(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.MilImage[0]); MappTimer(M_TIMER_WAIT, &pAppFrame->m_VarNuclear.Time); MdigHalt(pAppFrame->m_VarNuclear.MilDigitizer); //MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer, pAppFrame->m_VarNuclear.MilImage[0]); MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer, MilImageSeq[n]); MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.m_lChannel2); Sleep(200); MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.MilImage[1]); MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer,MilImageSeq2[n]); aux="Grabbed shot"; aux+=(_itoa( n+1, numero, 10 )); aux+=" "; edit->ReplaceSel(aux,FALSE ); } for (n=0; n<pAppFrame->m_VarNuclear.m_iNbFrames; n++) { char numero[4]; pAppFrame->m_VarNuclear.m_csFileName.MakeLower(); int len =pAppFrame->m_VarNuclear.m_csFileName.GetLength(); int t=len-1; while((pAppFrame->m_VarNuclear.m_csFileName[t] != '.') && (t!=0) ) t--; if (t<3) t=len-1; CString filenameout =pAppFrame->m_VarNuclear.m_csFileName.Left(t); if(pAppFrame->m_VarNuclear.m_iNbFrames> 1) filenameout+=(_itoa( n+1, numero, 10 ));

Page 244: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

CString filenameout2 = filenameout; filenameout+="_cam1."+pAppFrame->m_VarNuclear.m_csImage; filenameout2+="_cam2."+pAppFrame->m_VarNuclear.m_csImage; MbufExport(filenameout.GetBuffer(256),pAppFrame->m_VarNuclear.m_MILImageType,MilImageSeq[n]); MbufExport(filenameout2.GetBuffer(256),pAppFrame->m_VarNuclear.m_MILImageType,MilImageSeq2[n]); if (pAppFrame->m_VarNuclear.m_csImage == "bmp") if (pAppFrame->m_VarNuclear.m_bSignature) { bmpsave(filenameout,pAppFrame->m_VarNuclear.m_cstext); bmpsave(filenameout2,pAppFrame->m_VarNuclear.m_cstext); } //Visualize all results obtained Sleep(500); pAppFrame->m_VarNuclear.aux=filenameout; //Visualize all results obtained if (pAppFrame->m_VarNuclear.m_bVisualize ) { PostThreadMessage((DWORD) id, WM_NUCLEAR, 0 ,0); Sleep(500); pAppFrame->m_VarNuclear.aux=filenameout2; PostThreadMessage((DWORD) id, WM_NUCLEAR, 0 ,0); } } for (n=0; n<pAppFrame->m_VarNuclear.m_iNbFrames; n++) { MbufFree(MilImageSeq[n]); MbufFree(MilImageSeq2[n]); }

::GlobalFree((HGLOBAL) MilImageSeq); ::GlobalFree((HGLOBAL) MilImageSeq2); aux="Finished Shooting"; edit->ReplaceSel(aux,FALSE ); button->EnableWindow(TRUE); StartThreadNuclear(); AfxBeginThread (MilApplication,(LPVOID) NULL , THREAD_PRIORITY_NORMAL); } CloseHandle (pAppFrame->m_VarNuclear.Semaphore); return 0; } /*---------------------------------------------------------------- Function: UINT ShotTrigger(LPVOID pParam) Purpose: Gets shots from frame grabber with trigger conditions -----------------------------------------------------------------*/ UINT ShotTrigger(LPVOID id) { CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); //Variables// UINT n = 0; CString aux; char numero[4]; MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.m_lChannel1); MdigGrabContinuous(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.MilImage[0]); //Port initialization///////// if (pAppFrame->m_VarNuclear.m_bTriggerExterno)

Page 245: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

PortInitialize ("COM1"); pAppFrame->m_VarNuclear.SerialSem= CreateSemaphore(NULL, 0, 1,NULL ); ////////////////////////////// //Comments// CEdit* edit=(CEdit*) pAppFrame->m_VarNuclear.dlg->GetDlgItem(IDC_EDIT1); CButton* button=(CButton*) pAppFrame->m_VarNuclear.dlg->GetDlgItem(IDC_BUTTON1); CButton* button2=(CButton*) pAppFrame->m_VarNuclear.dlg->GetDlgItem(IDC_BUTTON2); pAppFrame->m_VarNuclear.Semaphore= CreateSemaphore(NULL, 0, 2,NULL ); WaitForSingleObject(pAppFrame->m_VarNuclear.Semaphore,INFINITE); button2->EnableWindow(FALSE); ///////////// //Choose from 1 or 2 cameras if (pAppFrame->m_VarNuclear.m_CameraNum1 && (!pAppFrame->m_VarNuclear.m_CameraNum2)) { MIL_ID* MilImageSeq; //Memory Allocation// MilImageSeq = (MIL_ID*) ::GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT ,(pAppFrame->m_VarNuclear.m_iNbFrames)*sizeof(MIL_ID)); ///////////////////// MappControl(M_ERROR, M_PRINT_DISABLE);

// Allocate grab buffers to hold the sequence. // for (n=0; n<pAppFrame->m_VarNuclear.m_iNbFrames; n++) { if (pAppFrame->m_VarNuclear.m_bDataTypeRGB == FALSE) { MbufAlloc2d(pAppFrame->m_VarNuclear.MilSystem ,(long)(pAppFrame->m_VarNuclear.BufSizeX*pAppFrame->m_VarNuclear.m_dImageScale ) ,(long)(pAppFrame->m_VarNuclear.BufSizeY*pAppFrame->m_VarNuclear.m_dImageScale) ,8 + M_UNSIGNED , M_IMAGE+M_GRAB ,&MilImageSeq[n]); } else if (pAppFrame->m_VarNuclear.m_bDataTypeRGB == TRUE) { MbufAllocColor(pAppFrame->m_VarNuclear.MilSystem, pAppFrame->m_VarNuclear.BufSizeBand ,(long)(pAppFrame->m_VarNuclear.BufSizeX*pAppFrame->m_VarNuclear.m_dImageScale) ,(long)(pAppFrame->m_VarNuclear.BufSizeY*pAppFrame->m_VarNuclear.m_dImageScale) ,8+M_UNSIGNED,M_IMAGE + M_GRAB ,&MilImageSeq[n]); } MbufClear(MilImageSeq[n],0); } ///////////////////////////////////////////////////////// //Begin grab// //MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.m_lChannel1); MdigHalt(pAppFrame->m_VarNuclear.MilDigitizer); // Grab the sequence. // for (n=0; n<pAppFrame->m_VarNuclear.m_iNbFrames; n++) {

Page 246: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

/* Grab one buffer at a time. */ MdigGrabContinuous(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.MilImage[0]); //Wait for signal WaitForSingleObject(pAppFrame->m_VarNuclear.SerialSem,INFINITE); MdigHalt(pAppFrame->m_VarNuclear.MilDigitizer); //MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer, pAppFrame->m_VarNuclear.MilImage[0]); MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer, MilImageSeq[n]); aux="Grabbed shot"; aux+=(_itoa( n+1, numero, 10 )); aux+=" "; edit->ReplaceSel(aux,FALSE ); } pAppFrame->m_VarNuclear.ExitSerial=TRUE; SetCommMask (pAppFrame->m_VarNuclear.hPort,EV_DSR); for (n=0; n<pAppFrame->m_VarNuclear.m_iNbFrames; n++) { char numero[4]; pAppFrame->m_VarNuclear.m_csFileName.MakeLower(); int len =pAppFrame->m_VarNuclear.m_csFileName.GetLength(); int t=len-1; while((pAppFrame->m_VarNuclear.m_csFileName[t] != '.') && (t!=0) ) t--; if (t<3) t=len-1; CString filenameout =pAppFrame->m_VarNuclear.m_csFileName.Left(t); if(pAppFrame->m_VarNuclear.m_iNbFrames > 1) filenameout+=(_itoa( n+1, numero, 10 )); filenameout+="."+pAppFrame->m_VarNuclear.m_csImage;

MbufExport(filenameout.GetBuffer(256),pAppFrame->m_VarNuclear.m_MILImageType,MilImageSeq[n]); if (pAppFrame->m_VarNuclear.m_csImage == "bmp") if (pAppFrame->m_VarNuclear.m_bSignature) bmpsave(filenameout,pAppFrame->m_VarNuclear.m_cstext); Sleep(500); pAppFrame->m_VarNuclear.aux=filenameout; //Visualize all results obtained if (pAppFrame->m_VarNuclear.m_bVisualize ) { PostThreadMessage((DWORD) id, WM_NUCLEAR, 0 ,0); } } for (n=0; n<pAppFrame->m_VarNuclear.m_iNbFrames; n++) MbufFree(MilImageSeq[n]); ::GlobalFree((HGLOBAL) MilImageSeq); aux="Finished Shooting"; edit->ReplaceSel(aux,FALSE ); button->EnableWindow(TRUE); StartThreadNuclear(); AfxBeginThread (MilApplication,(LPVOID) NULL , THREAD_PRIORITY_NORMAL); } else if (pAppFrame->m_VarNuclear.m_CameraNum1 && pAppFrame->m_VarNuclear.m_CameraNum2) { MIL_ID* MilImageSeq; MIL_ID* MilImageSeq2; //Memory Allocation// MilImageSeq = (MIL_ID*) ::GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT

Page 247: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

,(pAppFrame->m_VarNuclear.m_iNbFrames)*sizeof(MIL_ID)); MilImageSeq2 = (MIL_ID*) ::GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT ,(pAppFrame->m_VarNuclear.m_iNbFrames)*sizeof(MIL_ID)); ////////////////////// MappControl(M_ERROR, M_PRINT_DISABLE); // Allocate grab buffers to hold the sequence. // for (n=0; n<pAppFrame->m_VarNuclear.m_iNbFrames; n++) { if (pAppFrame->m_VarNuclear.m_bDataTypeRGB == FALSE) { MbufAlloc2d(pAppFrame->m_VarNuclear.MilSystem ,(long)(pAppFrame->m_VarNuclear.BufSizeX*pAppFrame->m_VarNuclear.m_dImageScale ) ,(long)(pAppFrame->m_VarNuclear.BufSizeY*pAppFrame->m_VarNuclear.m_dImageScale) ,8 + M_UNSIGNED , M_IMAGE+M_GRAB ,&MilImageSeq[n]); MbufAlloc2d(pAppFrame->m_VarNuclear.MilSystem ,(long)(pAppFrame->m_VarNuclear.BufSizeX*pAppFrame->m_VarNuclear.m_dImageScale ) ,(long)(pAppFrame->m_VarNuclear.BufSizeY*pAppFrame->m_VarNuclear.m_dImageScale) ,8 + M_UNSIGNED , M_IMAGE+M_GRAB ,&MilImageSeq2[n]); } else if (pAppFrame->m_VarNuclear.m_bDataTypeRGB == TRUE) { MbufAllocColor(pAppFrame->m_VarNuclear.MilSystem, pAppFrame->m_VarNuclear.BufSizeBand ,(long)(pAppFrame->m_VarNuclear.BufSizeX*pAppFrame->m_VarNuclear.m_dImageScale) ,(long)(pAppFrame->m_VarNuclear.BufSizeY*pAppFrame->m_VarNuclear.m_dImageScale) ,8+M_UNSIGNED,M_IMAGE + M_GRAB

,&MilImageSeq[n]); MbufAllocColor(pAppFrame->m_VarNuclear.MilSystem, pAppFrame->m_VarNuclear.BufSizeBand ,(long)(pAppFrame->m_VarNuclear.BufSizeX*pAppFrame->m_VarNuclear.m_dImageScale) ,(long)(pAppFrame->m_VarNuclear.BufSizeY*pAppFrame->m_VarNuclear.m_dImageScale) ,8+M_UNSIGNED,M_IMAGE + M_GRAB ,&MilImageSeq2[n]); } MbufClear(MilImageSeq[n],0); MbufClear(MilImageSeq2[n],0); } /////////////////////////////////////////////////////////////// //Begin grab// // Grab the sequence. // MdigHalt(pAppFrame->m_VarNuclear.MilDigitizer); for (n=0; n<pAppFrame->m_VarNuclear.m_iNbFrames; n++) { /* Grab one buffer at a time. */ MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.m_lChannel1); Sleep(200); MdigGrabContinuous(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.MilImage[0]); //Wait for signal WaitForSingleObject(pAppFrame->m_VarNuclear.SerialSem,INFINITE); MdigHalt(pAppFrame->m_VarNuclear.MilDigitizer); //MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer, pAppFrame->m_VarNuclear.MilImage[0]); MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer, MilImageSeq[n]);

Page 248: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.m_lChannel2); Sleep(200); MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame->m_VarNuclear.MilImage[1]); MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer,MilImageSeq2[n]); aux="Grabbed shot"; aux+=(_itoa( n+1, numero, 10 )); aux+=" "; edit->ReplaceSel(aux,FALSE ); } pAppFrame->m_VarNuclear.ExitSerial=TRUE; SetCommMask (pAppFrame->m_VarNuclear.hPort,EV_DSR); for (n=0; n<pAppFrame->m_VarNuclear.m_iNbFrames; n++) { char numero[4]; pAppFrame->m_VarNuclear.m_csFileName.MakeLower(); int len =pAppFrame->m_VarNuclear.m_csFileName.GetLength(); int t=len-1; while((pAppFrame->m_VarNuclear.m_csFileName[t] != '.') && (t!=0) ) t--; if (t<3) t=len-1; CString filenameout =pAppFrame->m_VarNuclear.m_csFileName.Left(t); if(pAppFrame->m_VarNuclear.m_iNbFrames> 1) filenameout+=(_itoa( n+1, numero, 10 )); CString filenameout2 = filenameout; filenameout+="_cam1."+pAppFrame->m_VarNuclear.m_csImage;

filenameout2+="_cam2."+pAppFrame->m_VarNuclear.m_csImage; MbufExport(filenameout.GetBuffer(256),pAppFrame->m_VarNuclear.m_MILImageType,MilImageSeq[n]); MbufExport(filenameout2.GetBuffer(256),pAppFrame->m_VarNuclear.m_MILImageType,MilImageSeq2[n]); if (pAppFrame->m_VarNuclear.m_csImage == "bmp") if (pAppFrame->m_VarNuclear.m_bSignature) { bmpsave(filenameout,pAppFrame->m_VarNuclear.m_cstext); bmpsave(filenameout2,pAppFrame->m_VarNuclear.m_cstext); } Sleep(500); pAppFrame->m_VarNuclear.aux=filenameout; //Visualize all results obtained if (pAppFrame->m_VarNuclear.m_bVisualize ) { PostThreadMessage((DWORD) id, WM_NUCLEAR, 0 ,0); Sleep(500); pAppFrame->m_VarNuclear.aux=filenameout2; PostThreadMessage((DWORD) id, WM_NUCLEAR, 0 ,0); } } for (n=0; n<pAppFrame->m_VarNuclear.m_iNbFrames; n++) { MbufFree(MilImageSeq[n]); MbufFree(MilImageSeq2[n]); } ::GlobalFree((HGLOBAL) MilImageSeq); ::GlobalFree((HGLOBAL) MilImageSeq2); aux="Finished Shooting";

Page 249: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

edit->ReplaceSel(aux,FALSE ); button->EnableWindow(TRUE); StartThreadNuclear(); AfxBeginThread (MilApplication,(LPVOID) NULL , THREAD_PRIORITY_NORMAL); } CloseHandle (pAppFrame->m_VarNuclear.SerialSem); CloseHandle (pAppFrame->m_VarNuclear.Semaphore); return 0; } //////////////////////////////////////////////////////////////////////////////////// //Serial port /*---------------------------------------------------------------- Function: PortInitialize (LPTSTR lpszPortName) Purpose: initializes port -----------------------------------------------------------------*/ BOOL PortInitialize (LPTSTR lpszPortName) { DWORD dwError, dwThreadID; DCB PortDCB; COMMTIMEOUTS CommTimeouts; CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); // Open the serial port. pAppFrame->m_VarNuclear.hPort = CreateFile (lpszPortName, // Pointer to the name of the port GENERIC_READ | GENERIC_WRITE ,// Access (read/write) mode 0, // Share mode NULL, // Pointer to the security attribute OPEN_EXISTING,// How to open the serial port FILE_FLAG_OVERLAPPED, // Port attributes

NULL); // Handle to port with attribute // to copy // If it fails to open the port, return FALSE. if ( pAppFrame->m_VarNuclear.hPort == INVALID_HANDLE_VALUE ) { // Could not open the port. MessageBox (0,"Unable to open the port","ERROR", MB_OK); dwError = GetLastError (); return FALSE; } PortDCB.DCBlength = sizeof (DCB); // Get the default port setting information. GetCommState (pAppFrame->m_VarNuclear.hPort, &PortDCB); // Change the DCB structure settings. PortDCB.BaudRate = 9600; // Current baud PortDCB.fBinary = TRUE; // Binary mode; no EOF check PortDCB.fParity = TRUE; // Enable parity checking. PortDCB.fOutxCtsFlow = FALSE; // No CTS output flow control PortDCB.fOutxDsrFlow = FALSE; // No DSR output flow control PortDCB.fDtrControl = DTR_CONTROL_ENABLE; // DTR flow control type PortDCB.fDsrSensitivity = FALSE; // DSR sensitivity PortDCB.fTXContinueOnXoff = TRUE; // XOFF continues Tx PortDCB.fOutX = FALSE; // No XON/XOFF out flow control PortDCB.fInX = FALSE; // No XON/XOFF in flow control PortDCB.fErrorChar = FALSE; // Disable error replacement. PortDCB.fNull = FALSE; // Disable null stripping. PortDCB.fRtsControl = RTS_CONTROL_DISABLE; // RTS flow control PortDCB.fAbortOnError = FALSE; // Do not abort reads/writes on // error. PortDCB.ByteSize = 8; // Number of bits/bytes, 4-8 PortDCB.Parity = NOPARITY; // 0-4=no,odd,even,mark,space PortDCB.StopBits = ONESTOPBIT; // 0,1,2 = 1, 1.5, 2 // Configure the port according to the specifications of the DCB // structure. if (!SetCommState (pAppFrame->m_VarNuclear.hPort, &PortDCB)) { // Could not configure the serial port. MessageBox (0,"Unable to configure the serial port","Error", MB_OK); dwError = GetLastError ();

Page 250: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

return FALSE; } // Retrieve the time-out parameters for all read and write operations // on the port. GetCommTimeouts (pAppFrame->m_VarNuclear.hPort, &CommTimeouts); // Change the COMMTIMEOUTS structure settings. CommTimeouts.ReadIntervalTimeout = MAXDWORD; CommTimeouts.ReadTotalTimeoutMultiplier = 0; CommTimeouts.ReadTotalTimeoutConstant = 0; // Set the time-out parameters for all read and write operations // on the port. if (!SetCommTimeouts (pAppFrame->m_VarNuclear.hPort, &CommTimeouts)) { // Could not set the time-out parameters. MessageBox (0, "Unable to set the time-out parameters","Error", MB_OK); dwError = GetLastError (); return FALSE; } // Create a read thread for reading data from the communication port. if (pAppFrame->m_VarNuclear.hReadThread = CreateThread (NULL, 0, PortReadThread, 0, 0, &dwThreadID)) { CloseHandle (pAppFrame->m_VarNuclear.hReadThread); } else { // Could not create the read thread. MessageBox (0, "Unable to create the read thread","Error", MB_OK); dwError = GetLastError (); return FALSE; } return TRUE; } /*---------------------------------------------------------------- Function: PortWrite (BYTE Byte) Purpose: writes on port -----------------------------------------------------------------*/ void PortWrite (BYTE Byte)

{ DWORD dwError, dwNumBytesWritten; CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); if (!WriteFile (pAppFrame->m_VarNuclear.hPort, // Port handle &Byte, // Pointer to the data to write 1, // Number of bytes to write &dwNumBytesWritten, // Pointer to the number of bytes // written NULL)) // Must be NULL for Windows CE { // WriteFile failed. Report error. dwError = GetLastError (); } } /*---------------------------------------------------------------- Function: PortReadThread (LPVOID lpvoid) Purpose: waits for port events -----------------------------------------------------------------*/ DWORD WINAPI PortReadThread (LPVOID lpvoid) { DWORD dwCommModemStatus; DWORD dwRes; OVERLAPPED osStatus = {0}; CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); // Create the overlapped event. Must be closed before exiting // to avoid a handle leak. osStatus.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (osStatus.hEvent == NULL) // Error creating overlapped event; abort. return 0;

Page 251: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

// Specify a set of events to be monitored for the port. SetCommMask (pAppFrame->m_VarNuclear.hPort, EV_CTS); while (pAppFrame->m_VarNuclear.hPort != INVALID_HANDLE_VALUE) { // Wait for an event to occur for the port. WaitCommEvent (pAppFrame->m_VarNuclear.hPort, &dwCommModemStatus, &osStatus); dwRes = WaitForSingleObject(osStatus.hEvent, INFINITE); if (dwCommModemStatus == EV_CTS) ReleaseSemaphore(pAppFrame->m_VarNuclear.SerialSem, 1, NULL); if (pAppFrame->m_VarNuclear.ExitSerial==TRUE) break; } CloseHandle(osStatus.hEvent); //pAppFrame->m_VarNuclear.ExitSerial=FALSE; PortClose(pAppFrame->m_VarNuclear.hPort); return 0; } /*---------------------------------------------------------------- Function: PortClose (HANDLE hCommPort) Purpose: Close port -----------------------------------------------------------------*/ BOOL PortClose (HANDLE hCommPort) { DWORD dwError; CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); if (hCommPort != INVALID_HANDLE_VALUE) { // Close the communication port. if (!CloseHandle (hCommPort))

{ dwError = GetLastError (); return FALSE; } else { pAppFrame->m_VarNuclear.hPort = INVALID_HANDLE_VALUE; return TRUE; } } return FALSE; } /*---------------------------------------------------------------- Function: void bmpsave(CString filename,CString text) Purpose: Adds info on files -----------------------------------------------------------------*/ void bmpsave(CString filename,CString text) { CFile file; CFileException fe; if (!file.Open(filename,CFile::modeReadWrite | CFile::shareExclusive, &fe)) { CString strMsg; strMsg="Erro de abertura do ficheiro"; MessageBox(NULL, strMsg, NULL, MB_ICONEXCLAMATION | MB_OK); return ; } TRY { file.SeekToEnd( ); int size = text.GetLength(); // size of the comments text if (size != 0) file.Write(text, size); file.Close(); } CATCH (CException, eSave) { CString strMsg; strMsg="Erro de escrita no ficheiro";

Page 252: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

MessageBox(NULL, strMsg, NULL, MB_ICONEXCLAMATION | MB_OK); file.Abort(); // will not throw an exception return ; } END_CATCH return ; } /*---------------------------------------------------------------- Function: void writetext() Purpose: Writes text in images -----------------------------------------------------------------*/ /* void writetext(char* text,UINT size,UINT color,bool position,bool save,MIL_ID buffer) { CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); //Writing text // long TransparentColor; if (save) { // Draw MIL monochrome overlay annotation // // Set graphic text to transparent background. // MgraControl(M_DEFAULT, M_BACKGROUND_MODE, M_TRANSPARENT); if (pAppFrame->m_VarNuclear.m_bDataTypeRGB) { if (color==0)

MgraColor(M_DEFAULT, M_RGB888(0, 0, 255)); else if (color==1) MgraColor(M_DEFAULT, M_RGB888(255, 0, 0)); else if (color==2) MgraColor(M_DEFAULT, M_RGB888(0, 255, 0)); } else { MgraColor(M_DEFAULT,255); } if (position) MgraText(M_DEFAULT, buffer, 4, 4, text ); else if (!position) MgraText(M_DEFAULT, buffer, 4, (pAppFrame->m_VarNuclear.BufSizeY-30)*pAppFrame->m_VarNuclear.m_dImageScale, text); } else { //Disable overlay display while preparing the data. MdispControl(pAppFrame->m_VarNuclear.MilDisplay[0], M_WINDOW_OVR_SHOW, M_DISABLE); // Enable writing Overlay graphics on top of display buffer. // MdispControl(pAppFrame->m_VarNuclear.MilDisplay[0], M_WINDOW_OVR_WRITE, M_ENABLE); // Inquire the Overlay buffer associated with the displayed buffer. // MdispInquire(pAppFrame->m_VarNuclear.MilDisplay[0], M_WINDOW_OVR_BUF_ID, &pAppFrame->m_VarNuclear.MilOverlayImage); // Inquire the current keying color. // MdispInquire(pAppFrame->m_VarNuclear.MilDisplay[0], M_KEY_COLOR, &TransparentColor); // Clear the overlay buffer with the keying color. // MbufClear(pAppFrame->m_VarNuclear.MilOverlayImage, TransparentColor); // Enable the overlay display. // MdispControl(pAppFrame->m_VarNuclear.MilDisplay[0], M_WINDOW_OVR_SHOW, M_ENABLE);

Page 253: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

HDC hCustomDC; HGDIOBJ hpen, hpenOld; char* chText;//[80]; // Create a device context to draw in the overlay buffer with GDI. // MbufControl(pAppFrame->m_VarNuclear.MilOverlayImage, M_WINDOW_DC_ALLOC, M_DEFAULT); // Inquire the device context. // hCustomDC = ((HDC)MbufInquire(pAppFrame->m_VarNuclear.MilOverlayImage, M_WINDOW_DC, M_NULL)); if (hCustomDC) { // Create a pen. // if (pAppFrame->m_VarNuclear.m_bDataTypeRGB) { if (color==0) hpen=CreatePen(PS_SOLID, 1, RGB(0, 0, 255)); else if (color==1) hpen=CreatePen(PS_SOLID, 1, RGB(255, 0, 0)); else if (color==2) hpen=CreatePen(PS_SOLID, 1, RGB(0, 255, 0)); } else { hpen=CreatePen(PS_SOLID, 1,255); } hpenOld = SelectObject(hCustomDC,hpen); // Write text in the overlay buffer. // chText= text; if (pAppFrame->m_VarNuclear.m_bDataTypeRGB) { if (color==0) SetTextColor(hCustomDC, RGB(0, 0, 255)); else if (color==1) SetTextColor(hCustomDC,RGB(255, 0, 0)); else if (color==2) SetTextColor(hCustomDC,RGB(0, 255, 0)); } else { SetTextColor(hCustomDC,255);

} if (position) TextOut(hCustomDC,0,0, chText, size); else if (!position) TextOut(hCustomDC,0,(pAppFrame->m_VarNuclear.BufSizeY-30)*pAppFrame->m_VarNuclear.m_dImageScale , chText, size); // Deselect and destroy the blue pen. // SelectObject(hCustomDC,hpenOld); DeleteObject(hpen); } // Delete created device context. // MbufControl(pAppFrame->m_VarNuclear.MilOverlayImage, M_WINDOW_DC_FREE, M_DEFAULT); // Signal MIL that the overlay buffer was modified. // MbufControl(pAppFrame->m_VarNuclear.MilOverlayImage, M_MODIFIED, M_DEFAULT); MgraControl(M_DEFAULT, M_BACKGROUND_MODE, M_TRANSPARENT); if (pAppFrame->m_VarNuclear.m_bDataTypeRGB) { if (color==0) MgraColor(M_DEFAULT, M_RGB888(0, 0, 255)); else if (color==1) MgraColor(M_DEFAULT, M_RGB888(255, 0, 0)); else if (color==2) MgraColor(M_DEFAULT, M_RGB888(0, 255, 0)); } else { MgraColor(M_DEFAULT,255); } if (position) MgraText(M_DEFAULT, buffer, 4, 4, text ); else if (!position)

Page 254: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

MgraText(M_DEFAULT, buffer, 4, (pAppFrame->m_VarNuclear.BufSizeY-30)*pAppFrame->m_VarNuclear.m_dImageScale, text); } }*/ //////////////////////////////////////////////////////////////////////// // Implementação da classe CVariaveisNuclear // valores por defeito CVariaveisNuclear::CVariaveisNuclear() { //Compressão// /* Quantization factor to use during the compression */ /* Permissible values from 1 to 99 both inclusively */ /* Used only if the compression is available */ Q_FACTOR = 50; m_bCompressed = FALSE; m_csSequence = "avi"; //AUX m_MILSequenceType=M_AVI_DIB; m_csImage = "bmp"; //AUX m_MILImageType=M_BMP; //////////////////// //Selecção// m_bSequencia = FALSE; // Grab em sequencia(FALSE)/shot(TRUE) m_bTriggerMode = FALSE; // Grab por Modo trigger ou temporal //////////// ///////////////////////////////////// //Sequence// m_iTimeBetween = 5;

m_dTimeBetweenUnit = 1; m_csFileName = ""; /////////// //Shot///// m_iInitialTime = 0; m_dInitialTimeUnit = 1; m_iBetweenTime = 0; m_dBetweenTimeUnit = 1; m_csTecla = ""; m_bTecla = FALSE; m_csTriggerExterno = ""; m_bTriggerExterno = FALSE; //Geral// m_iNbFrames = 0; m_iCamera = 1; m_dImageScale = 0.5; m_csScale = "Half"; //AUX m_lChannel1 = M_CH0; m_csCh1 = "CH1"; //AUX m_lChannel2 = M_CH1; m_csCh2 = "CH2"; //AUX m_pcDataFormat="M_CCIR"; m_csSinal = "CCIR"; //AUX m_bDataTypeRGB = FALSE; m_csData = "GRAY"; //AUX m_lDispMode = M_WINDOWED+M_DISPLAY_24_BASIC+M_DISPLAY_8_BASIC;

ess=M_DEFAULT; m_iContrast=M_DEFAULT;

m_csDisplay = "Basic"; //AUX m_bSignature = FALSE; m_cstext = "NSB Production"; //AUX m_iBrightn

Page 255: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

m_iHue=M_DEFAULT; m_iSaturation=M_DEFAULT; ///////////////////////////////////// //Sistema// double Time = 0.0; MilApplication = NULL; MilSystem = NULL; MilDisplay[0] = NULL; MilDisplay[1] = NULL; MilDigitizer = NULL; MilImage[0]=NULL; MilImage[1]=NULL; /////////// m_hWndNuclear = NULL; // Handle da janela da camara m_hWndNuclear2 = NULL; // Handle da janela da camara m_bvideo = FALSE; //Sinal de modo aquisicao via matrox //Cameras Activas// m_CameraNum1 = FALSE; // camera 1 activa m_CameraNum2 = FALSE; // camera 2 activa /////////////////// BufSizeBand=1; BufSizeX= 640; BufSizeY= 480; m_bTimeBetween=FALSE; first=FALSE; Semaphore= NULL; SerialSem=NULL; ExitSerial=FALSE; hReadThread=NULL; hPort=NULL;

m_bVisualize=FALSE; id=NULL; } Dacquire.h #include "resource.h" ///////////////////////////////////////////////////////////////////////////// // CDAcquire dialog class CDAcquire : public CDialog { // Construction public: CDAcquire(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CDAcquire) enum { IDD = IDD_ACQUIRE }; BOOL m_bcheck1; BOOL m_bcheck2; CString m_cscombo10; CString m_cscombo5; CString m_cscombo6; CString m_cscombo7; CString m_cscombo8; CString m_csedit3; CString m_csedit4; int m_iradio1; int m_iradio3; UINT m_iedit1; UINT m_iedit2; UINT m_iedit5; UINT m_iedit7; UINT m_iedit8; BOOL m_bcheck5; BOOL m_bcheck3; //}}AFX_DATA // Overrides

Page 256: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

// ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDAcquire) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions

/

1;

/

//{

//{{AFX_MSG(CDAcquire) virtual BOOL OnInitDialog(); afx_msg void OnRadio1(); afx_msg void OnRadio2(); afx_msg void OnRadio3(); afx_msg void OnRadio4(); afx_msg void OnButton2(); afx_msg void OnButton1(); afx_msg void OnButton3(); afx_msg void OnCheck1(); afx_msg void OnCheck2(); afx_msg void OnCheck5();

/}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////// // CDAcquireOptions dialog class CDAcquireOptions : public CDialog { // Construction public: CDAcquireOptions(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CDAcquireOptions) enum { IDD = IDD_ACQUIRE_OPTIONS }; CString m_cscombo2; CString m_cscombo3; CString m_cscombo4; CString m_cscombo5; CString m_cscombo6; CString m_cscombo7; CString m_cscombo8;

CString m_csedit1; CString m_cscombo1; int m_iradio int m_level; // threshold level int m_max; // maximum threshold level int m_min; BOOL m_bcheck2; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDAcquireOptions) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

/}}AFX_VIRTUAL // Implementation protected: // Generated message map functions

{AFX_MSG(CDAcquireOptions) virtual BOOL OnInitDialog(); afx_msg void OnRadio1(); afx_msg void OnRadio2(); afx_msg void OnSelchangeCombo1(); afx_msg void OnSelchangeCombo3(); afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); afx_msg void OnCheck2(); afx_msg void OnSelchangeCombo7(); afx_msg void OnSelchangeCombo8(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////// // CDImage dialog class CDImage : public CDialog { // Construction public: CDImage(CWnd* pParent = NULL); // standard constructor // Dialog Data

Page 257: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

//{{AFX_DATA(CDImage) enum { IDD = IDD_IMAGE }; int m_level; // threshold level int m_max; // maximum threshold level int m_min; int m_zoomlevel; CBitmapButton m_zoom_out; CBitmapButton m_zoom_in; CBitmapButton m_shot; CString m_cscombo1; BOOL m_bcheck1; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

t additional declarations immediately before the previous line.

Dacquire.cpp

//{{AFX_VIRTUAL(CDImage) protected:

//}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CDImage) virtual BOOL OnInitDialog(); afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); virtual void OnCancel(); afx_msg void OnZoomIn(); afx_msg void OnZoomOut(); afx_msg void OnShot(); afx_msg void OnSelchangeCombo1(); virtual void OnOK(); afx_msg void OnCheck1(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////// // CDComents dialog class CDComents : public CDialog

{ // Construction public: CDComents(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CDComents) enum { IDD = IDD_COMMENT }; CString m_csedit1; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDComents) public: virtual BOOL PreTranslateMessage(MSG* pMsg); protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CDComents) afx_msg void OnButton1(); afx_msg void OnButton2(); afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will inser

#endif // !defined(AFX_DACQUIRE_H__131459F0_3577_11D5_954D_0080AD1CB308__INCLUDED_)

// DAcquire.cpp : implementation file

Page 258: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

// #include "stdafx.h" #include "Project.h" #include "DAcquire.h" #include "MainFrm.h" #include <direct.h> #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CDAcquire dialog -parameters for acquisition in different modes CDAcquire::CDAcquire(CWnd* pParent /*=NULL*/) : CDialog(CDAcquire::IDD, pParent) { //{{AFX_DATA_INIT(CDAcquire) m_bcheck1 = FALSE; m_bcheck2 = FALSE; m_cscombo10 = _T(""); m_cscombo5 = _T(""); m_cscombo6 = _T(""); m_cscombo7 = _T(""); m_cscombo8 = _T(""); m_csedit3 = _T(""); m_csedit4 = _T(""); m_iradio1 = -1; m_iradio3 = -1; m_iedit1 = 0; m_iedit2 = 0; m_iedit5 = 0; m_iedit7 = 0; m_iedit8 = 0; m_bcheck5 = FALSE; m_bcheck3 = FALSE; //}}AFX_DATA_INIT }

void CDAcquire::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDAcquire) DDX_Check(pDX, IDC_CHECK1, m_bcheck1); DDX_Check(pDX, IDC_CHECK2, m_bcheck2); DDX_CBString(pDX, IDC_COMBO10, m_cscombo10); DDX_CBString(pDX, IDC_COMBO5, m_cscombo5); DDX_CBString(pDX, IDC_COMBO6, m_cscombo6); DDX_CBString(pDX, IDC_COMBO7, m_cscombo7); DDX_CBString(pDX, IDC_COMBO8, m_cscombo8); DDX_Text(pDX, IDC_EDIT3, m_csedit3); DDX_Text(pDX, IDC_EDIT4, m_csedit4); DDX_Radio(pDX, IDC_RADIO1, m_iradio1); DDX_Radio(pDX, IDC_RADIO3, m_iradio3);

DX_Text(pDX, IDC_EDIT1, m_iedit1); D

D ck5);

DDV_MinMaxUInt(pDX, m_iedit1, 0, 30); DDX_Text(pDX, IDC_EDIT2, m_iedit2); DDV_MinMaxUInt(pDX, m_iedit2, 0, 30); DDX_Text(pDX, IDC_EDIT5, m_iedit5); DDV_MinMaxUInt(pDX, m_iedit5, 1, 50); DDX_Text(pDX, IDC_EDIT7, m_iedit7); DDV_MinMaxUInt(pDX, m_iedit7, 0, 30); DDX_Text(pDX, IDC_EDIT8, m_iedit8); DDV_MinMaxUInt(pDX, m_iedit8, 1, 100);

DX_Check(pDX, IDC_CHECK5, m_bche DDX_Check(pDX, IDC_CHECK3, m_bcheck3); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDAcquire, CDialog) //{{AFX_MSG_MAP(CDAcquire) ON_BN_CLICKED(IDC_RADIO1, OnRadio1) ON_BN_CLICKED(IDC_RADIO2, OnRadio2) ON_BN_CLICKED(IDC_RADIO3, OnRadio3) ON_BN_CLICKED(IDC_RADIO4, OnRadio4) ON_BN_CLICKED(IDC_BUTTON2, OnButton2) ON_BN_CLICKED(IDC_BUTTON1, OnButton1) ON_BN_CLICKED(IDC_BUTTON3, OnButton3) ON_BN_CLICKED(IDC_CHECK1, OnCheck1) ON_BN_CLICKED(IDC_CHECK2, OnCheck2) ON_BN_CLICKED(IDC_CHECK5, OnCheck5) //}}AFX_MSG_MAP END_MESSAGE_MAP()

Page 259: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

///////////////////////////////////////////////////////////////////////////// // CDAcquire message handlers BOOL CDAcquire::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); m_bcheck1 = FALSE;

m_bcheck2 = TRUE; m_bcheck5 = FALSE; //m_bcheck3 = pAppFrame->m_VarNuclear.m_bVisualize; m_iedit1 = 5; m_iedit2 = 5; m_iedit5 =5; m_iedit7 =5; m_iedit8 =5; m_iradio1 = 1; m_iradio3 = 0; m_cscombo10 ="seg"; m_cscombo5 = "seg"; m_cscombo6 ="seg"; m_cscombo7 ="C"; m_cscombo8 ="SERIAL"; char buffer[256]; _getcwd( buffer,256 ); m_csedit3 =buffer; m_csedit3+="\\imagem"; m_csedit3+="."+pAppFrame->m_VarNuclear.m_csImage; m_csedit4 =buffer; m_csedit4+="\\sequence.avi";

UpdateData(false); UpdateData(TRUE); //LEFT// GetDlgItem(IDC_CHECK1)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK2)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO7)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO8)->EnableWindow(FALSE); GetDlgItem(IDC_RADIO3)->EnableWindow(TRUE); GetDlgItem(IDC_RADIO4)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT1)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT2)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT3)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT8)->EnableWindow(TRUE); GetDlgItem(IDC_COMBO5)->EnableWindow(TRUE); GetDlgItem(IDC_COMBO6)->EnableWindow(TRUE); GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE); //RIGHT// GetDlgItem(IDC_CHECK5)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT4)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT5)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT7)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO10)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE }

Page 260: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

void CDAcquire::OnRadio1() { // TODO: Add your control notification handler code here UpdateData(TRUE); if (m_iradio1 == 1) { //LEFT// GetDlgItem(IDC_RADIO3)->EnableWindow(TRUE);

indow(FALSE);

GetDlgItem(IDC_RADIO4)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT8)->EnableWindow(TRUE); GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT3)->EnableWindow(TRUE); GetDlgItem(IDC_CHECK3)->EnableWindow(TRUE); GetDlgItem(IDC_CHECK5)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT4)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT5)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT7)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO10)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE); if (m_iradio3==0) { GetDlgItem(IDC_EDIT1)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT2)->EnableWindow(TRUE); GetDlgItem(IDC_COMBO5)->EnableWindow(TRUE); GetDlgItem(IDC_COMBO6)->EnableWindow(TRUE); GetDlgItem(IDC_CHECK1)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK2)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO7)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO8)->EnableWindow(FALSE); } else if (m_iradio3==1) { GetDlgItem(IDC_EDIT1)->EnableWindow(FALSE);

GetDlgItem(IDC_EDIT2)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO5)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO6)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK1)->EnableWindow(TRUE); GetDlgItem(IDC_CHECK2)->EnableWindow(TRUE); if (m_bcheck1 == TRUE) GetDlgItem(IDC_COMBO7)->EnableWindow(TRUE); else GetDlgItem(IDC_COMBO7)->EnableWindow(FALSE); if (m_bcheck2 == TRUE) GetDlgItem(IDC_COMBO8)->EnableWindow(TRUE); else GetDlgItem(IDC_COMBO8)->EnableWindow(FALSE); } //RIGHT// GetDlgItem(IDC_CHECK5)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT4)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT5)->EnableW GetDlgItem(IDC_EDIT7)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO10)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE); } else { //LEFT// GetDlgItem(IDC_CHECK1)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK2)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK3)->EnableWindow(FALSE); GetDlgItem(IDC_RADIO3)->EnableWindow(FALSE); GetDlgItem(IDC_RADIO4)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT1)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT2)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT3)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT8)->EnableWindow(FALSE);

Page 261: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

GetDlgItem(IDC_COMBO5)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO6)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO7)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO8)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE); //RIGHT// GetDlgItem(IDC_CHECK5)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT5)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT4)->EnableWindow(TRUE); GetDlgItem(IDC_BUTTON2)->EnableWindow(TRUE); if (m_bcheck5==TRUE) { GetDlgItem(IDC_EDIT7)->EnableWindow(TRUE); GetDlgItem(IDC_COMBO10)->EnableWindow(TRUE); } else { GetDlgItem(IDC_EDIT7)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO10)->EnableWindow(FALSE); } } } void CDAcquire::OnRadio2() { // TODO: Add your control notification handler code here UpdateData(TRUE); if (m_iradio1 == 1) {

Window(TRUE); GetDlgItem(IDC_RADIO3)->EnableWindow(TRUE); GetDlgItem(IDC_RADIO4)->Enable GetDlgItem(IDC_EDIT8)->EnableWindow(TRUE); GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT3)->EnableWindow(TRUE); GetDlgItem(IDC_CHECK3)->EnableWindow(TRUE); GetDlgItem(IDC_CHECK5)->EnableWindow(FALSE);

GetDlgItem(IDC_EDIT4)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT5)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT7)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO10)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE); if (m_iradio3==0) { GetDlgItem(IDC_EDIT1)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT2)->EnableWindow(TRUE); GetDlgItem(IDC_COMBO5)->EnableWindow(TRUE); GetDlgItem(IDC_COMBO6)->EnableWindow(TRUE); GetDlgItem(IDC_CHECK1)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK2)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO7)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO8)->EnableWindow(FALSE); } else if (m_iradio3==1) { GetDlgItem(IDC_EDIT1)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT2)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO5)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO6)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK1)->EnableWindow(TRUE); GetDlgItem(IDC_CHECK2)->EnableWindow(TRUE); if (m_bcheck1 == TRUE) GetDlgItem(IDC_COMBO7)->EnableWindow(TRUE); else GetDlgItem(IDC_COMBO7)->EnableWindow(FALSE); if (m_bcheck2 == TRUE) GetDlgItem(IDC_COMBO8)->EnableWindow(TRUE); else GetDlgItem(IDC_COMBO8)->EnableWindow(FALSE); }

Page 262: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

} else { //LEFT// GetDlgItem(IDC_CHECK1)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK2)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK3)->EnableWindow(FALSE); GetDlgItem(IDC_RADIO3)->EnableWindow(FALSE); GetDlgItem(IDC_RADIO4)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT1)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT2)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT3)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT8)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO5)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO6)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO7)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO8)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE); //RIGHT// GetDlgItem(IDC_CHECK5)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT5)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT4)->EnableWindow(TRUE); GetDlgItem(IDC_BUTTON2)->EnableWindow(TRUE); if (m_bcheck5==TRUE) { GetDlgItem(IDC_EDIT7)->EnableWindow(TRUE); GetDlgItem(IDC_COMBO10)->EnableWindow(TRUE); } else { GetDlgItem(IDC_EDIT7)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO10)->EnableWindow(FALSE); } } } void CDAcquire::OnRadio3() { // TODO: Add your control notification handler code here

UpdateData(TRUE); if (m_iradio3 == 0) { GetDlgItem(IDC_EDIT1)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT2)->EnableWindow(TRUE); GetDlgItem(IDC_COMBO5)->EnableWindow(TRUE); GetDlgItem(IDC_COMBO6)->EnableWindow(TRUE); GetDlgItem(IDC_CHECK1)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK2)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO7)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO8)->EnableWindow(FALSE); } else { GetDlgItem(IDC_EDIT1)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT2)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO5)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO6)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK1)->EnableWindow(TRUE); GetDlgItem(IDC_CHECK2)->EnableWindow(TRUE); if (m_bcheck1 == TRUE) GetDlgItem(IDC_COMBO7)->EnableWindow(TRUE); else GetDlgItem(IDC_COMBO7)->EnableWindow(FALSE); if (m_bcheck2 == TRUE) GetDlgItem(IDC_COMBO8)->EnableWindow(TRUE); else GetDlgItem(IDC_COMBO8)->EnableWindow(FALSE); } } void CDAcquire::OnRadio4() { // TODO: Add your control notification handler code here UpdateData(TRUE);

Page 263: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

if (m_iradio3 == 1) { GetDlgItem(IDC_EDIT1)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT2)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO5)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO6)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK1)->EnableWindow(TRUE); GetDlgItem(IDC_CHECK2)->EnableWindow(TRUE); if (m_bcheck1 == TRUE) GetDlgItem(IDC_COMBO7)->EnableWindow(TRUE); else GetDlgItem(IDC_COMBO7)->EnableWindow(FALSE); if (m_bcheck2 == TRUE) GetDlgItem(IDC_COMBO8)->EnableWindow(TRUE); else GetDlgItem(IDC_COMBO8)->EnableWindow(FALSE); } else{ GetDlgItem(IDC_EDIT1)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT2)->EnableWindow(TRUE); GetDlgItem(IDC_COMBO5)->EnableWindow(TRUE); GetDlgItem(IDC_COMBO6)->EnableWindow(TRUE); GetDlgItem(IDC_CHECK1)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK2)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO7)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO8)->EnableWindow(FALSE); } } void CDAcquire::OnButton2() { // TODO: Add your control notification handler code here

UpdateData(TRUE); CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); CString aux; LPCSTR lpszDefExt; BOOL bOpen = FALSE; // File Open Dialog DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; // default // file filters lpszDefExt = "avi"; aux="Project File Types (*.AVI) | *.avi;;|All files (*.*) | *.*; ||"; LPCSTR lpszFilter =(LPCSTR) (aux); // Create a File Open CFileDialog CFileDialog dlg( bOpen, lpszDefExt, NULL, dwFlags, lpszFilter ); if( dlg.DoModal() != IDOK ) return; // Open the File Dialog CString fileName = dlg.GetPathName(); // Get file name m_csedit4=fileName ; UpdateData(FALSE); } void CDAcquire::OnButton1() { // TODO: Add your control notification handler code here UpdateData(TRUE); CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); CString aux; LPCSTR lpszDefExt; BOOL bOpen = FALSE; // File Open Dialog

Page 264: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; // default // file filters lpszDefExt = LPCSTR (pAppFrame->m_VarNuclear.m_csImage); aux="Project File Types (*."+(pAppFrame->m_VarNuclear.m_csImage)+") | *."+(pAppFrame->m_VarNuclear.m_csImage)+";;|All files (*.*) | *.*; ||"; LPCSTR lpszFilter =(LPCSTR) (aux); // Create a File Open CFileDialog CFileDialog dlg( bOpen, lpszDefExt, NULL, dwFlags, lpszFilter ); if( dlg.DoModal() != IDOK ) return; // Open the File Dialog CString fileName = dlg.GetPathName(); // Get file name m_csedit3=fileName ; UpdateData(FALSE); } void CDAcquire::OnButton3() { // TODO: Add your control notification handler code here UpdateData(TRUE); CDAcquireOptions dlg; CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); if (dlg.DoModal()==IDOK) { UpdateData(TRUE); pAppFrame->m_VarNuclear.m_csSinal=dlg.m_cscombo4; pAppFrame->m_VarNuclear.m_csData=dlg.m_cscombo3; pAppFrame->m_VarNuclear.m_csCh1=dlg.m_cscombo1; pAppFrame->m_VarNuclear.m_csCh2=dlg.m_cscombo2; pAppFrame->m_VarNuclear.m_csScale=dlg.m_cscombo5;

pAppFrame->m_VarNuclear.m_csDisplay=dlg.m_cscombo6; if (dlg.m_iradio1==0) { pAppFrame->m_VarNuclear.m_iCamera=1; if (dlg.m_cscombo1=="CH1") pAppFrame->m_VarNuclear.m_lChannel1=M_CH0; else if (dlg.m_cscombo1=="CH2") pAppFrame->m_VarNuclear.m_lChannel1=M_CH1; else if (dlg.m_cscombo1=="CH3") pAppFrame->m_VarNuclear.m_lChannel1=M_CH2; else if (dlg.m_cscombo1=="CH4") pAppFrame->m_VarNuclear.m_lChannel1=M_CH3; } else { pAppFrame->m_VarNuclear.m_iCamera=2; if (dlg.m_cscombo1=="CH1") pAppFrame->m_VarNuclear.m_lChannel1=M_CH0; else if (dlg.m_cscombo1=="CH2") pAppFrame->m_VarNuclear.m_lChannel1=M_CH1; else if (dlg.m_cscombo1=="CH3") pAppFrame->m_VarNuclear.m_lChannel1=M_CH2; else if (dlg.m_cscombo1=="CH4") pAppFrame->m_VarNuclear.m_lChannel1=M_CH3; if (dlg.m_cscombo2=="CH1") pAppFrame->m_VarNuclear.m_lChannel2=M_CH0; else if (dlg.m_cscombo2=="CH2") pAppFrame->m_VarNuclear.m_lChannel2=M_CH1; else if (dlg.m_cscombo2=="CH3") pAppFrame->m_VarNuclear.m_lChannel2=M_CH2; else if (dlg.m_cscombo2=="CH4") pAppFrame->m_VarNuclear.m_lChannel2=M_CH3; } if (dlg.m_cscombo4=="RS-170") pAppFrame->m_VarNuclear.m_pcDataFormat="M_RS170"; if (dlg.m_cscombo4=="CCIR") pAppFrame->m_VarNuclear.m_pcDataFormat="M_CCIR"; if (dlg.m_cscombo4=="PAL I") pAppFrame->m_VarNuclear.m_pcDataFormat="M_PAL";

Page 265: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

if (dlg.m_cscombo4=="SECAM") pAppFrame->m_VarNuclear.m_pcDataFormat="M_SECAM";

scombo6=="Enhanced")

ppFrame->m_VarNuclear.m_MILSequenceType=M_AVI_DIB;

check2)

if (dlg.m_cscombo4=="NTSC") pAppFrame->m_VarNuclear.m_pcDataFormat="M_NTSC"; if (dlg.m_cscombo3=="RGB") { pAppFrame->m_VarNuclear.m_bDataTypeRGB=TRUE; pAppFrame->m_VarNuclear.BufSizeBand=3; } else { pAppFrame->m_VarNuclear.m_bDataTypeRGB=FALSE; pAppFrame->m_VarNuclear.BufSizeBand=1; } if (dlg.m_cscombo5=="Normal") pAppFrame->m_VarNuclear.m_dImageScale=1; else if (dlg.m_cscombo5=="Half") pAppFrame->m_VarNuclear.m_dImageScale=0.5; else if (dlg.m_cscombo5=="Quarter") pAppFrame->m_VarNuclear.m_dImageScale=0.25; if (dlg.m_c pAppFrame->m_VarNuclear.m_lDispMode=M_WINDOWED+M_DISPLAY_24_ENHANCED+M_DISPLAY_8_ENHANCED; else if (dlg.m_cscombo6=="Basic") pAppFrame->m_VarNuclear.m_lDispMode=M_WINDOWED+M_DISPLAY_24_BASIC+M_DISPLAY_8_BASIC; else if (dlg.m_cscombo6=="Basic Optimized") pAppFrame->m_VarNuclear.m_lDispMode=M_WINDOWED+M_DISPLAY_24_WINDOWS+M_DISPLAY_8_BASIC; pAppFrame->m_VarNuclear.m_csSequence=dlg.m_cscombo7; pAppFrame->m_VarNuclear.m_csImage=dlg.m_cscombo8; pAppFrame->m_VarNuclear.m_csImage.MakeLower(); pAppFrame->m_VarNuclear.Q_FACTOR=dlg.m_level; if (dlg.m_cscombo7=="AVI-MJPG") { pAppFrame->m_VarNuclear.m_bCompressed=TRUE;

pAppFrame->m_VarNuclear.m_MILSequenceType=M_AVI_MJPG; } else if (dlg.m_cscombo7=="AVI-DIB") { pA

pAppFrame->m_VarNuclear.m_bCompressed=FALSE; } if (dlg.m_cscombo8=="BMP") { pAppFrame->m_VarNuclear.m_MILImageType=M_BMP; GetDlgItem(IDC_CHECK3)->EnableWindow(TRUE); } else { GetDlgItem(IDC_CHECK3)->EnableWindow(FALSE); if (dlg.m_cscombo8=="MIL") pAppFrame->m_VarNuclear.m_MILImageType=M_MIL; else if (dlg.m_cscombo8=="RAW") pAppFrame->m_VarNuclear.m_MILImageType=M_RAW; else if (dlg.m_cscombo8=="TIFF") pAppFrame->m_VarNuclear.m_MILImageType=M_TIFF; } m_csedit3.MakeLower(); int len =m_csedit3.GetLength(); int t=len-1; while((m_csedit3[t] != '.') && (t!=0) ) t--; if (t<3) t=len-1; m_csedit3 =m_csedit3.Left(t); dlg.m_cscombo8.MakeLower(); m_csedit3+="."+dlg.m_cscombo8; dlg.m_cscombo8.MakeUpper(); if (dlg.m_b pAppFrame->m_VarNuclear.m_bSignature=TRUE;

Page 266: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

else pAppFrame->m_VarNuclear.m_bSignature=FALSE; pAppFrame->m_VarNuclear.m_cstext=dlg.m_csedit1; } UpdateData(FALSE); } void CDAcquire::OnCheck1() { // TODO: Add your control notification handler code here UpdateData(TRUE); if (m_bcheck1 == FALSE) m_bcheck2 = TRUE; GetDlgItem(IDC_COMBO8)->EnableWindow(TRUE); UpdateData(FALSE); UpdateData(TRUE); if (m_bcheck1 == TRUE) GetDlgItem(IDC_COMBO7)->EnableWindow(TRUE);

oid CDAcquire::OnCheck2()

if (m_bcheck2 == TRUE)

else if (m_bcheck1 == FALSE) GetDlgItem(IDC_COMBO7)->EnableWindow(FALSE); } v{ // TODO: Add your control notification handler code here UpdateData(TRUE); if (m_bcheck2 == FALSE) m_bcheck1 = TRUE; GetDlgItem(IDC_COMBO7)->EnableWindow(TRUE); UpdateData(FALSE); UpdateData(TRUE);

GetDlgItem(IDC_COMBO8)->EnableWindow(TRUE); else if (m_bcheck2 == FALSE) GetDlgItem(IDC_COMBO8)->EnableWindow(FALSE); } void CDAcquire::OnCheck5() { // TODO: Add your control notification handler code here UpdateData(TRUE); if (m_bcheck5 == TRUE) { GetDlgItem(IDC_EDIT7)->EnableWindow(TRUE); GetDlgItem(IDC_COMBO10)->EnableWindow(TRUE); } else if (m_bcheck5 == FALSE) { GetDlgItem(IDC_EDIT7)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO10)->EnableWindow(FALSE); } } ///////////////////////////////////////////////////////////////////////////// // CDAcquireOptions dialog options to acquire from the cameras CDAcquireOptions::CDAcquireOptions(CWnd* pParent /*=NULL*/) : CDialog(CDAcquireOptions::IDD, pParent) { //{{AFX_DATA_INIT(CDAcquireOptions) m_cscombo2 = _T(""); m_cscombo3 = _T(""); m_cscombo4 = _T(""); m_cscombo5 = _T(""); m_cscombo6 = _T(""); m_cscombo7 = _T(""); m_cscombo8 = _T(""); m_csedit1 = _T(""); m_cscombo1 = _T(""); m_iradio1 = -1; m_level = 50; m_max = 99; // maximum level m_min = 1;

Page 267: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

m_bcheck2 = FALSE; //}}AFX_DATA_INIT } void CDAcquireOptions::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDAcquireOptions) DDX_CBString(pDX, IDC_COMBO2, m_cscombo2); DDX_CBString(pDX, IDC_COMBO3, m_cscombo3); DDX_CBString(pDX, IDC_COMBO4, m_cscombo4); DDX_CBString(pDX, IDC_COMBO5, m_cscombo5); DDX_CBString(pDX, IDC_COMBO6, m_cscombo6); DDX_CBString(pDX, IDC_COMBO7, m_cscombo7); DDX_CBString(pDX, IDC_COMBO8, m_cscombo8); DDX_Text(pDX, IDC_EDIT1, m_csedit1); DDV_MaxChars(pDX, m_csedit1, 300); DDX_CBString(pDX, IDC_COMBO1, m_cscombo1); DDX_Radio(pDX, IDC_RADIO1, m_iradio1); DDX_Check(pDX, IDC_CHECK2, m_bcheck2); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDAcquireOptions, CDialog) //{{AFX_MSG_MAP(CDAcquireOptions) ON_BN_CLICKED(IDC_RADIO1, OnRadio1) ON_BN_CLICKED(IDC_RADIO2, OnRadio2) ON_CBN_SELCHANGE(IDC_COMBO1, OnSelchangeCombo1) ON_CBN_SELCHANGE(IDC_COMBO3, OnSelchangeCombo3) ON_WM_HSCROLL() ON_BN_CLICKED(IDC_CHECK2, OnCheck2) ON_CBN_SELCHANGE(IDC_COMBO7, OnSelchangeCombo7) ON_CBN_SELCHANGE(IDC_COMBO8, OnSelchangeCombo8) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDAcquireOptions message handlers BOOL CDAcquireOptions::OnInitDialog() { CDialog::OnInitDialog();

CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); CScrollBar* psb= (CScrollBar*) GetDlgItem(IDC_SCROLLBAR1); psb->SetScrollRange(m_min,m_max); psb->SetScrollPos(pAppFrame->m_VarNuclear.Q_FACTOR); m_iradio1=pAppFrame->m_VarNuclear.m_iCamera; m_cscombo4=pAppFrame->m_VarNuclear.m_csSinal; m_cscombo3=pAppFrame->m_VarNuclear.m_csData; m_cscombo1=pAppFrame->m_VarNuclear.m_csCh1; m_cscombo2=pAppFrame->m_VarNuclear.m_csCh2; CComboBox* combo=(CComboBox*) GetDlgItem(IDC_COMBO2); CComboBox* combo1=(CComboBox*) GetDlgItem(IDC_COMBO1); if (combo->FindString(-1, "CH1") == CB_ERR)

f (combo->FindString(-1, "CH4")== CB_ERR)

combo->InsertString(0,"CH1"); if (combo->FindString(-1, "CH2") == CB_ERR) combo->InsertString(1,"CH2"); if (combo->FindString(-1, "CH3")== CB_ERR) combo->InsertString(2,"CH3"); i combo->InsertString(3,"CH4"); if (m_cscombo2=="CH1") combo->SetCurSel(1); else if (m_cscombo2=="CH2") combo->SetCurSel(0); else if (m_cscombo2=="CH3") combo->SetCurSel(0); else if (m_cscombo2=="CH4") combo->SetCurSel(0); if (m_cscombo1=="CH1") combo->DeleteString(0); else if (m_cscombo1=="CH2") combo->DeleteString(1); else if (m_cscombo1=="CH3")

Page 268: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

combo->DeleteString(2); else if (m_cscombo1=="CH4") combo->DeleteString(3); m_cscombo5=pAppFrame->m_VarNuclear.m_csScale; m_cscombo6=pAppFrame->m_VarNuclear.m_csDisplay; m_cscombo7=pAppFrame->m_VarNuclear.m_csSequence; pAppFrame->m_VarNuclear.m_csImage.MakeUpper(); m_cscombo8=pAppFrame->m_VarNuclear.m_csImage; pAppFrame->m_VarNuclear.m_csImage.MakeLower(); m_csedit1=pAppFrame->m_VarNuclear.m_cstext; m_level=pAppFrame->m_VarNuclear.Q_FACTOR; if (pAppFrame->m_VarNuclear.m_csImage=="bmp") { GetDlgItem(IDC_EDIT1)->EnableWindow(TRUE); GetDlgItem(IDC_CHECK2)->EnableWindow(TRUE); } else { GetDlgItem(IDC_EDIT1)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK2)->EnableWindow(FALSE); } GetDlgItem(IDC_SCROLLBAR1)->EnableWindow(FALSE); GetDlgItem(IDC_VALUE)->EnableWindow(FALSE); CString strtext; strtext.Format("%d",m_level); SetDlgItemText(IDC_VALUE,strtext); if (pAppFrame->m_VarNuclear.m_iCamera==1)

{ m_iradio1 = 0; GetDlgItem(IDC_COMBO2)->EnableWindow(FALSE); } else m_iradio1 = 1;

if (! (pAppFrame->m_VarNuclear.m_bSignature)) { m_bcheck2 = FALSE; GetDlgItem(IDC_EDIT1)->EnableWindow(FALSE); } else m_bcheck2 = TRUE; CComboBox* combo4=(CComboBox*) GetDlgItem(IDC_COMBO4); if (pAppFrame->m_VarNuclear.m_bDataTypeRGB)//RGB { combo4->ResetContent( ); combo4->InsertString(0,"NTSC"); combo4->InsertString(0,"SECAM"); combo4->InsertString(0,"PAL I"); } else if (!pAppFrame->m_VarNuclear.m_bDataTypeRGB)//GRAY { combo4->ResetContent( ); combo4->InsertString(0,"RS-170"); combo4->InsertString(0,"CCIR"); } combo4->SetCurSel(0);

UpdateData(FALSE); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CDAcquireOptions::OnRadio1() { // TODO: Add your control notification handler code here UpdateData(TRUE); if (m_iradio1== 0) GetDlgItem(IDC_COMBO2)->EnableWindow(FALSE); }

Page 269: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

void CDAcquireOptions::OnRadio2() { // TODO: Add your control notification handler code here UpdateData(TRUE); if (m_iradio1== 1) GetDlgItem(IDC_COMBO2)->EnableWindow(TRUE); } void CDAcquireOptions::OnCheck2() { // TODO: Add your control notification handler code here UpdateData(TRUE); if (m_bcheck2 == TRUE) GetDlgItem(IDC_EDIT1)->EnableWindow(TRUE); else if (m_bcheck2 == FALSE) GetDlgItem(IDC_EDIT1)->EnableWindow(FALSE); } void CDAcquireOptions::OnSelchangeCombo1() { // TODO: Add your control notification handler code here CComboBox* combo=(CComboBox*) GetDlgItem(IDC_COMBO2); CComboBox* combo1=(CComboBox*) GetDlgItem(IDC_COMBO1); UpdateData(TRUE); if (combo->FindString(-1, "CH1") == CB_ERR) combo->InsertString(0,"CH1"); if (combo->FindString(-1, "CH2") == CB_ERR) combo->InsertString(1,"CH2"); if (combo->FindString(-1, "CH3")== CB_ERR) combo->InsertString(2,"CH3"); if (combo->FindString(-1, "CH4")== CB_ERR) combo->InsertString(3,"CH4"); int pos = combo1->GetCurSel();

if (m_cscombo2=="CH1" && pos ==0) combo->SetCurSel(1); else if (m_cscombo2=="CH2" && pos ==1) combo->SetCurSel(0); else if (m_cscombo2=="CH3" && pos ==2) combo->SetCurSel(0); else if (m_cscombo2=="CH4" && pos ==3) combo->SetCurSel(0); combo->DeleteString(pos); } void CDAcquireOptions::OnSelchangeCombo3() { // TODO: Add your control notification handler code here CComboBox* combo=(CComboBox*) GetDlgItem(IDC_COMBO3); CComboBox* combo1=(CComboBox*) GetDlgItem(IDC_COMBO4); CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); UpdateData(TRUE); if (combo->GetCurSel() == 1)//RGB { combo1->ResetContent( ); combo1->InsertString(0,"NTSC"); combo1->InsertString(0,"SECAM"); combo1->InsertString(0,"PAL I"); } else if (combo->GetCurSel() == 0)//GRAY { combo1->ResetContent( ); combo1->InsertString(0,"RS-170"); combo1->InsertString(0,"CCIR"); } combo1->SetCurSel(0); } void CDAcquireOptions::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: Add your message handler code here and/or call default

Page 270: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

int nTemp1; CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); UpdateData(TRUE); nTemp1 = pScrollBar->GetScrollPos(); switch(nSBCode) { case SB_LINELEFT: // Scroll left. nTemp1--; break; case SB_LINERIGHT: // Scroll right. nTemp1++; break; case SB_PAGELEFT: // Scroll one page left. nTemp1 -= (m_max-m_min+1)/10; break; case SB_PAGERIGHT: // Scroll one page right. nTemp1 += (m_max-m_min+1)/10; break; case SB_THUMBTRACK: // Drag scroll box to specified position. nTemp1 = nPos; break; case SB_LEFT: // Scroll to far left.. nTemp1 = m_min; break; case SB_RIGHT: // Scroll to far right. nTemp1 = m_max; break; } if (nTemp1 < m_min) nTemp1 = m_min; else if (nTemp1 > m_max) nTemp1 = m_max; if (m_level != nTemp1) { pScrollBar->SetScrollPos(nTemp1); m_level = nTemp1; }

pAppFrame->m_VarNuclear.Q_FACTOR=m_level; CString strtext; strtext.Format("%d",m_level); SetDlgItemText(IDC_VALUE,strtext); UpdateData(FALSE); CDialog::OnHScroll(nSBCode, nPos, pScrollBar); } void CDAcquireOptions::OnSelchangeCombo7() { // TODO: Add your control notification handler code here CComboBox* combo=(CComboBox*) GetDlgItem(IDC_COMBO7); UpdateData(TRUE); if (combo->GetCurSel() == 1) { GetDlgItem(IDC_SCROLLBAR1)->EnableWindow(TRUE); GetDlgItem(IDC_VALUE)->EnableWindow(TRUE); } else { GetDlgItem(IDC_SCROLLBAR1)->EnableWindow(FALSE); GetDlgItem(IDC_VALUE)->EnableWindow(FALSE); } } void CDAcquireOptions::OnSelchangeCombo8() { // TODO: Add your control notification handler code here UpdateData(TRUE); if (m_cscombo8=="BMP") {

Page 271: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

if (m_bcheck2==TRUE) GetDlgItem(IDC_EDIT1)->EnableWindow(TRUE); GetDlgItem(IDC_CHECK2)->EnableWindow(TRUE); } else { GetDlgItem(IDC_EDIT1)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK2)->EnableWindow(FALSE); } } ///////////////////////////////////////////////////////////////////////////// // CDImage dialog - Zoom , shot and image settings in acquisition CDImage::CDImage(CWnd* pParent /*=NULL*/) : CDialog(CDImage::IDD, pParent) { //{{AFX_DATA_INIT(CDImage) m_level = 128; m_max = 255; // maximum level m_min = 0; m_zoomlevel=1; m_cscombo1 = _T(""); m_bcheck1 = FALSE; //}}AFX_DATA_INIT } void CDImage::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDImage) DDX_CBString(pDX, IDC_COMBO1, m_cscombo1);

DX_Check(pDX, IDC_CHECK1, m_bcheck1); D //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDImage, CDialog) //{{AFX_MSG_MAP(CDImage)

ON_WM_HSCROLL() ON_BN_CLICKED(IDC_ZOOM_IN, OnZoomIn) ON_BN_CLICKED(IDC_ZOOM_OUT, OnZoomOut) ON_BN_CLICKED(IDC_SHOT, OnShot) ON_CBN_SELCHANGE(IDC_COMBO1, OnSelchangeCombo1) ON_BN_CLICKED(IDC_CHECK1, OnCheck1) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDImage message handlers BOOL CDImage::OnInitDialog() { CDialog::OnInitDialog(); CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); pAppFrame->m_VarNuclear.first=TRUE; //Initiate dialog CenterWindow(); m_cscombo1=pAppFrame->m_VarNuclear.m_csCh1; VERIFY(m_zoom_out.AutoLoad(IDC_ZOOM_OUT,this)); VERIFY(m_zoom_in.AutoLoad(IDC_ZOOM_IN,this)); VERIFY(m_shot.AutoLoad(IDC_SHOT,this)); CScrollBar* psb= (CScrollBar*) GetDlgItem(IDC_SCROLLBAR1); psb->SetScrollRange(m_min,m_max); psb->SetScrollPos(pAppFrame->m_VarNuclear.m_iBrightness); psb= (CScrollBar*) GetDlgItem(IDC_SCROLLBAR2); psb->SetScrollRange(m_min,m_max); psb->SetScrollPos(pAppFrame->m_VarNuclear.m_iContrast); psb= (CScrollBar*) GetDlgItem(IDC_SCROLLBAR3); psb->SetScrollRange(m_min,m_max); psb->SetScrollPos(pAppFrame->m_VarNuclear.m_iHue); psb= (CScrollBar*) GetDlgItem(IDC_SCROLLBAR4);

Page 272: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

psb->SetScrollRange(m_min,m_max); psb->SetScrollPos(pAppFrame->m_VarNuclear.m_iSaturation); MdigControl(pAppFrame->m_VarNuclear.MilDigitizer,M_BRIGHTNESS_REF,pAppFrame->m_VarNuclear.m_iBrightness); MdigControl(pAppFrame->m_VarNuclear.MilDigitizer,M_CONTRAST_REF,pAppFrame->m_VarNuclear.m_iContrast); MdigControl(pAppFrame->m_VarNuclear.MilDigitizer,M_HUE_REF,pAppFrame->m_VarNuclear.m_iHue); MdigControl(pAppFrame->m_VarNuclear.MilDigitizer,M_SATURATION_REF,pAppFrame->m_VarNuclear.m_iSaturation); if ( pAppFrame->m_VarNuclear.m_csImage != "bmp") { GetDlgItem(IDC_CHECK1)->EnableWindow(FALSE); pAppFrame->m_VarNuclear.m_bVisualize=FALSE; } else { GetDlgItem(IDC_CHECK1)->EnableWindow(TRUE); } UpdateData(FALSE); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CDImage::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: Add your message handler code here and/or call default int nTemp1; CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); UpdateData(TRUE); if (pAppFrame->m_VarNuclear.m_CameraNum1==FALSE) return;

nTemp1 = pScrollBar->GetScrollPos(); switch(nSBCode) { case SB_LINELEFT: // Scroll left. nTemp1--; break; case SB_LINERIGHT: // Scroll right. nTemp1++; break; case SB_PAGELEFT: // Scroll one page left. nTemp1 -= (m_max-m_min+1)/10; break; case SB_PAGERIGHT: // Scroll one page right. nTemp1 += (m_max-m_min+1)/10; break; case SB_THUMBTRACK: // Drag scroll box to specified position. nTemp1 = nPos; break; case SB_LEFT: // Scroll to far left.. nTemp1 = m_min; break; case SB_RIGHT: // Scroll to far right. nTemp1 = m_max; break; } if (nTemp1 < m_min) nTemp1 = m_min; else if (nTemp1 > m_max) nTemp1 = m_max; if (m_level != nTemp1) { pScrollBar->SetScrollPos(nTemp1); m_level = nTemp1; if (pScrollBar->GetDlgCtrlID() == IDC_SCROLLBAR1) { MdigReference(pAppFrame->m_VarNuclear.MilDigitizer,M_BRIGHTNESS_REF,m_level); pAppFrame->m_VarNuclear.m_iBrightness=m_level; } else if (pScrollBar->GetDlgCtrlID() == IDC_SCROLLBAR2) {

Page 273: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

MdigReference(pAppFrame->m_VarNuclear.MilDigitizer,M_CONTRAST_REF,m_level); pAppFrame->m_VarNuclear.m_iContrast=m_level; } else if (pScrollBar->GetDlgCtrlID() == IDC_SCROLLBAR3) { MdigReference(pAppFrame->m_VarNuclear.MilDigitizer,M_HUE_REF,m_level);

AppFrame->m_VarNuclear.MilDigitizer);

pAppFrame->m_VarNuclear.m_iHue=m_level; } else if (pScrollBar->GetDlgCtrlID() == IDC_SCROLLBAR4) { MdigReference(pAppFrame->m_VarNuclear.MilDigitizer,M_SATURATION_REF,m_level); pAppFrame->m_VarNuclear.m_iSaturation=m_level; } } UpdateData(FALSE); CDialog::OnHScroll(nSBCode, nPos, pScrollBar); } void CDImage::OnZoomIn() { // TODO: Add your control notification handler code here CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); if (pAppFrame->m_VarNuclear.m_CameraNum1==FALSE) return; if (m_zoomlevel==1) m_zoomlevel=-1; m_zoomlevel=m_zoomlevel-1; MdispZoom(pAppFrame->m_VarNuclear.MilDisplay[0],m_zoomlevel,m_zoomlevel); }

void CDImage::OnZoomOut() { // TODO: Add your control notification handler code here CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); if (pAppFrame->m_VarNuclear.m_CameraNum1==FALSE) return; if (m_zoomlevel==-1) m_zoomlevel=1; m_zoomlevel=m_zoomlevel+1; MdispZoom(pAppFrame->m_VarNuclear.MilDisplay[0],m_zoomlevel,m_zoomlevel); } void CDImage::OnShot() { // TODO: Add your control notification handler code here CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); UpdateData(TRUE); if (pAppFrame->m_VarNuclear.m_CameraNum1==FALSE) return; MdigHalt(p MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer, pAppFrame->m_VarNuclear.MilImage[0]); CString aux; LPCSTR lpszDefExt; BOOL bOpen = FALSE; // File Open Dialog DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; // default

Page 274: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

// file filters lpszDefExt = LPCSTR (pAppFrame->m_VarNuclear.m_csImage); aux="Project File Types (*."+(pAppFrame->m_VarNuclear.m_csImage)+") | *."+(pAppFrame->m_VarNuclear.m_csImage)+";;|All files (*.*) | *.*; ||"; LPCSTR lpszFilter =(LPCSTR) (aux); // Create a File Open CFileDialog CFileDialog dlg( bOpen, lpszDefExt, NULL, dwFlags, lpszFilter ); if( dlg.DoModal() == IDOK ) // Open the File Dialog { CString fileName = dlg.GetPathName(); // Get file name MbufExport(fileName.GetBuffer(256),pAppFrame->m_VarNuclear.m_MILImageType,pAppFrame->m_VarNuclear.MilImage[0]); if (pAppFrame->m_VarNuclear.m_csImage == "bmp") if (pAppFrame->m_VarNuclear.m_bSignature) bmpsave(fileName,pAppFrame->m_VarNuclear.m_cstext); pAppFrame->m_VarNuclear.aux=fileName; if (pAppFrame->m_VarNuclear.m_bVisualize) PostThreadMessage((DWORD) pAppFrame->m_VarNuclear.id, WM_NUCLEAR, 0 ,0); } UpdateData(FALSE); MdigGrabContinuous(pAppFrame->m_VarNuclear.MilDigitizer, pAppFrame->m_VarNuclear.MilImage[0]); } void CDImage::OnSelchangeCombo1() { // TODO: Add your control notification handler code here CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame)));

CComboBox* combo=(CComboBox*) GetDlgItem(IDC_COMBO1); MdigHalt(pAppFrame->m_VarNuclear.MilDigitizer); if (combo->GetCurSel() == 0) MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,M_CH0); else if(combo->GetCurSel() == 1) MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,M_CH1); else if(combo->GetCurSel() == 2) MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,M_CH2); else if(combo->GetCurSel() == 3) MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,M_CH3); MdigGrabContinuous(pAppFrame->m_VarNuclear.MilDigitizer, pAppFrame->m_VarNuclear.MilImage[0]); UpdateData(TRUE); } void CDImage::OnOK() { // TODO: Add extra validation here CDialog::OnOK(); } void CDImage::OnCancel() { // TODO: Add extra cleanup here CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); if (pAppFrame->m_VarNuclear.m_CameraNum1!=FALSE) { MdigReference(pAppFrame->m_VarNuclear.MilDigitizer,M_BRIGHTNESS_REF,M_DEFAULT); MdigReference(pAppFrame->m_VarNuclear.MilDigitizer,M_CONTRAST_REF,M_DEFAULT); MdigReference(pAppFrame->m_VarNuclear.MilDigitizer,M_HUE_REF,M_DEFAULT);

Page 275: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

MdigReference(pAppFrame->m_VarNuclear.MilDigitizer,M_SATURATION_REF,M_DEFAULT); MdigInquire(pAppFrame->m_VarNuclear.MilDigitizer,M_BRIGHTNESS_REF,&pAppFrame->m_VarNuclear.m_iBrightness); MdigInquire(pAppFrame->m_VarNuclear.MilDigitizer,M_CONTRAST_REF,&pAppFrame->m_VarNuclear.m_iContrast); MdigInquire(pAppFrame->m_VarNuclear.MilDigitizer,M_HUE_REF,&pAppFrame->m_VarNuclear.m_iHue); MdigInquire(pAppFrame->m_VarNuclear.MilDigitizer,M_SATURATION_REF,&pAppFrame->m_VarNuclear.m_iSaturation); } else { pAppFrame->m_VarNuclear.m_iBrightness=M_DEFAULT; pAppFrame->m_VarNuclear.m_iContrast=M_DEFAULT; pAppFrame->m_VarNuclear.m_iHue=M_DEFAULT; pAppFrame->m_VarNuclear.m_iSaturation=M_DEFAULT; } CDialog::OnCancel(); } void CDImage::OnCheck1() { // TODO: Add your control notification handler code here CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); UpdateData(TRUE); pAppFrame->m_VarNuclear.m_bVisualize=m_bcheck1; } ///////////////////////////////////////////////////////////////////////////// // CDComents dialog CDComents::CDComents(CWnd* pParent /*=NULL*/) : CDialog(CDComents::IDD, pParent)

{ //{{AFX_DATA_INIT(CDComents) m_csedit1 = _T(""); //}}AFX_DATA_INIT } void CDComents::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDComents) DDX_Text(pDX, IDC_EDIT1, m_csedit1); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDComents, CDialog) //{{AFX_MSG_MAP(CDComents) ON_BN_CLICKED(IDC_BUTTON1, OnButton1) ON_BN_CLICKED(IDC_BUTTON2, OnButton2) ON_WM_KEYDOWN() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDComents message handlers void CDComents::OnButton1() { // TODO: Add your control notification handler code here DestroyWindow(); delete this; } void CDComents::OnButton2() { // TODO: Add your control notification handler code here CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); ReleaseSemaphore(pAppFrame->m_VarNuclear.Semaphore, 1, NULL);

Page 276: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

} void CDComents::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); if (!pAppFrame->m_VarNuclear.m_bTecla) return; char lsChar; // The current character being pressed // Convert the key pressed to a character lsChar = char(nChar); // Is the character "A" if (lsChar == pAppFrame->m_VarNuclear.m_csTecla) ReleaseSemaphore(pAppFrame->m_VarNuclear.SerialSem, 1, NULL); CDialog::OnKeyDown(nChar, nRepCnt, nFlags); } BOOL CDComents::PreTranslateMessage(MSG* pMsg) { // TODO: Add your specialized code here and/or call the base class if (pMsg->message == WM_KEYDOWN) OnKeyDown(pMsg->wParam, LOWORD(pMsg->lParam), HIWORD(pMsg->lParam)); return CDialog::PreTranslateMessage(pMsg); } conversion2x2D_3D.h

typedef struct{ double x; double y; CString tag; } tag_mark; typedef struct{ double x; double y; double z; CString tag; } mark_3D; typedef struct{ bool left; bool right; bool final3D; } verified; void compdeep(); int compute_mpp(double mpp[][4],double f, int c); int frame_undistorted(int xf,int yf, double *xu, double *yu,double k,double dxl,double dy,int cx,int cy); void svdfit( double **xin,double *yin, int ndata, double *ain, int ma); void svbksb(double **u,double w[],double **v,int m,int n,double b[],double x[]); void svdcmp(double **a,int m,int n,double w[],double **v); int stereo_eq(double mpp1[][4],double mpp2[][4],double xu1,double yu1,double xu2,double yu2,double *a); class CVariaveisCalib{ public: CVariaveisCalib(); bool camerasF1_T2,matrix1_exist,matrix2_exist; double mpp1[3][4],mpp2[3][4] ,f1, f2, dx, sx, dy, k1, k2; int cx, cy,npoints,reference_number;//Numero de referencia na matriz da imagem de referencia

Page 277: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

UINT pict_numb; float array[300][2]; float out_array[300][3]; tag_mark marks[60]; tag_mark marks2[60]; mark_3D final_mark3D[60]; tag_mark markarrayL[50][60]; tag_mark markarrayR[50][60]; mark_3D markarray3D[50][60]; //Verificação de detecção da esquerda , direita e 3D verified made[50]; //3D double *a, xu1, xu2, yu1, yu2,xu,yu,**v, *w,*aa,**x; double tx,ty,r,xxxx,yyyy; bool flag; }; conversion2x2D_3D.cpp #include "stdafx.h" #include "project.h" #include "MainFrm.h" #include <stdio.h> #include <math.h> #include <stdlib.h> #include "my_memory.h" #include "gdefs.h" //#include "conversion2x2D_3D.h" #include "detect.h" /*P:compdeep* ________________________________________________________________

compdeep ________________________________________________________________ Name: compdeep - computing the world coordinates of points from the buffer's coondinates Syntax: | compdeep [-s <sx>] [-dx <dx>] [-dy <dy>] [-cx <xCenterBuf>] | [-cy <yCenterBuf>] <focalDist> <radialLensDist> Description: 'deep' performs the computing of the world coordinates of points from the buffer's coordinates. The camera's model is the Tsai's model. For the computing of the world's coordinates is used the correspondent solution of the stereo projection's equations by the linear least-squares regression using SVD decomposition. The horizontal scale factor is indicate trough flag '-s'. By default 'sx' is 0.710935. The center to center distance between adjacent sensor elements in x (scanline) direction is indicate trough flag '-dx'. By default 'dx' is 8.37765957e-3. The center to center distance between adjacent CCD sensor in the y direction is indicate trough flag '-dy'. By default 'dy' is 8.07560136e-3. The center of frame buffer in directions x and y are indicate through flags '-cx' and '-cy'. By default 'xcenterbuf' is 256 and 'ycenterbuf' is 256. 'focalDist' is the effective focal length. 'radialLensDist' is the lens's radial distortion. To quit the user must enter 9999 for the point's frame's buffer coordinate x in camera one. Return value: | 1 => Wrong value for dx <dx>, it must be greater than zero. | 2 => Wrong value for dy <dy>, it must be greater than zero. | 3 => Wrong value for f, it must be different of zero. | 4 => Wrong value for sx, it must be different of zero. Restrictions: The values for f and sx must be different of zero. The values for dx and dy must be greater than zero. Author: Sergio Barros; Nuno Sá Couto; Joao Tavares Based On: Code By João Tavares ________________________________________________________________

Page 278: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

*/ void compdeep() { CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); double mpp1[3][4], mpp2[3][4], a[3], xu1, xu2, yu1, yu2, dxl, f1,f2, dx, sx, dy, k1,k2; int xf1, yf1, xf2, yf2, cx, cy; sx = pAppFrame->m_VarCalib.sx; dx = pAppFrame->m_VarCalib.dx; dy = pAppFrame->m_VarCalib.dy; cx =pAppFrame->m_VarCalib.cy; cy = pAppFrame->m_VarCalib.cx; f1 = pAppFrame->m_VarCalib.f1; k1 = pAppFrame->m_VarCalib.k1; f2 = pAppFrame->m_VarCalib.f2; k2 = pAppFrame->m_VarCalib.k2; dxl = dx*sx; mpp1[0][0] = pAppFrame->m_VarCalib.mpp1[0][0]; mpp1[0][1] = pAppFrame->m_VarCalib.mpp1[0][1]; mpp1[0][2] = pAppFrame->m_VarCalib.mpp1[0][2]; mpp1[0][3] = pAppFrame->m_VarCalib.mpp1[0][3]; mpp1[1][0] = pAppFrame->m_VarCalib.mpp1[1][0]; mpp1[1][1] = pAppFrame->m_VarCalib.mpp1[1][1]; mpp1[1][2] = pAppFrame->m_VarCalib.mpp1[1][2]; mpp1[1][3] = pAppFrame->m_VarCalib.mpp1[1][3]; mpp1[2][0] = pAppFrame->m_VarCalib.mpp1[2][0]; mpp1[2][1] = pAppFrame->m_VarCalib.mpp1[2][1]; mpp1[2][2] = pAppFrame->m_VarCalib.mpp1[2][2]; mpp1[2][3] = pAppFrame->m_VarCalib.mpp1[2][3]; mpp2[0][0] = pAppFrame->m_VarCalib.mpp2[0][0]; mpp2[0][1] = pAppFrame->m_VarCalib.mpp2[0][1];

mpp2[0][2] = pAppFrame->m_VarCalib.mpp2[0][2]; mpp2[0][3] = pAppFrame->m_VarCalib.mpp2[0][3]; mpp2[1][0] = pAppFrame->m_VarCalib.mpp2[1][0]; mpp2[1][1] = pAppFrame->m_VarCalib.mpp2[1][1]; mpp2[1][2] = pAppFrame->m_VarCalib.mpp2[1][2]; mpp2[1][3] = pAppFrame->m_VarCalib.mpp2[1][3]; mpp2[2][0] = pAppFrame->m_VarCalib.mpp2[2][0]; mpp2[2][1] = pAppFrame->m_VarCalib.mpp2[2][1]; mpp2[2][2] = pAppFrame->m_VarCalib.mpp2[2][2]; mpp2[2][3] = pAppFrame->m_VarCalib.mpp2[2][3]; for (i=0 ; i< pAppFrame->m_VarCalib.npoints;i++ ){ /* input the frame buffer's coordinates of the desired point in camera's first position */ xf1=(int)pAppFrame->m_VarCalib.marks[i].x; yf1=(int)pAppFrame->m_VarCalib.marks[i].y; //xf1=195; //yf1=301; /* compute the undistorced's coordinates of the desired point in camera one's image plane */ frame_undistorted(xf1, yf1, &xu1, &yu1, k1, dxl, dy, cx, cy); /* input the frame buffer's coordinates of the desired point in camera two */ xf2=(int)pAppFrame->m_VarCalib.marks2[i].x; yf2=(int)pAppFrame->m_VarCalib.marks2[i].y; //xf2=193; //yf2=179; /* compute the undistorced's coordinates of the desired point in camera's second position */ frame_undistorted(xf2, yf2, &xu2, &yu2, k2, dxl, dy, cx, cy); /* compute the world's coordinates of the desired point */ stereo_eq(mpp1, mpp2, xu1, yu1, xu2, yu2, a); pAppFrame->m_VarCalib.final_mark3D[i].x=a[0]; pAppFrame->m_VarCalib.final_mark3D[i].y=a[1];

Page 279: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

pAppFrame->m_VarCalib.final_mark3D[i].z=a[2]; pAppFrame->m_VarCalib.final_mark3D[i].tag = pAppFrame->m_VarCalib.marks[i].tag; } return; } /*******************************************************************/ /*F:compute_mpp* ________________________________________________________________ compute_mpp ________________________________________________________________ Name: compute_mpp - compute the perspective projection matrix Syntax: | int compute_mpp(mpp, rot, trans, f, c) | int c; | float rot[], trans[]; | double mpp[][4], f; Description: 'compute_mpp' performs the determination of the perpective projection matrix. 'mpp[][4]' is the perpective projection matrix. 'rot[]' is the rotation's vector from object world coordinate system to the camera 3D coordinate system. 'trans[]' is the translation's vector from object world coordinate system to the camera 3D coordinate system. 'f' is the efective focal distance. If 'c' is 1 the angles are convert to rad. Return value: | 0 => Ok. Author: Sergio Barros; Nuno Sá Couto; Joao Tavares Based On: Code By João Tavares ________________________________________________________________

*/ int compute_mpp(double mpp[][4], float rot[],float trans[],double f, int c) { //double aux1, aux2, aux3, aux4, aux5, aux6; CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); /* compute the matrix perpective projection */ if ( c == 0 ) { mpp[0][0] = pAppFrame->m_VarCalib.mpp1[0][0];// aux3*aux5; mpp[0][1] = pAppFrame->m_VarCalib.mpp1[0][1];//aux3*aux6; mpp[0][2] = pAppFrame->m_VarCalib.mpp1[0][2];//-aux4; mpp[0][3] = pAppFrame->m_VarCalib.mpp1[0][3];//trans[0]; mpp[1][0] = pAppFrame->m_VarCalib.mpp1[1][0];//aux5*aux2*aux4-aux1*aux6; mpp[1][1] = pAppFrame->m_VarCalib.mpp1[1][1];//-aux6*aux2*aux4+aux1*aux5; mpp[1][2] = pAppFrame->m_VarCalib.mpp1[1][2];//aux2*aux3; mpp[1][3] = pAppFrame->m_VarCalib.mpp1[1][3];//trans[1]; mpp[2][0] = pAppFrame->m_VarCalib.mpp1[2][0];//(aux5*aux4*aux1+aux2*aux6)/f; mpp[2][1] = pAppFrame->m_VarCalib.mpp1[2][1];//(-aux2*aux5+aux6*aux4*aux1)/f; mpp[2][2] = pAppFrame->m_VarCalib.mpp1[2][2];//aux3*aux1/f; mpp[2][3] = pAppFrame->m_VarCalib.mpp1[2][3];//trans[2]/f; } else if (c == 1 ) { mpp[0][0] = pAppFrame->m_VarCalib.mpp2[0][0];// aux3*aux5; mpp[0][1] = pAppFrame->m_VarCalib.mpp2[0][1];//aux3*aux6; mpp[0][2] = pAppFrame->m_VarCalib.mpp2[0][2];//-aux4; mpp[0][3] = pAppFrame->m_VarCalib.mpp2[0][3];//trans[0]; mpp[1][0] = pAppFrame->m_VarCalib.mpp2[1][0];//aux5*aux2*aux4-aux1*aux6; mpp[1][1] = pAppFrame->m_VarCalib.mpp2[1][1];//-aux6*aux2*aux4+aux1*aux5; mpp[1][2] = pAppFrame->m_VarCalib.mpp2[1][2];//aux2*aux3; mpp[1][3] = pAppFrame->m_VarCalib.mpp2[1][3];//trans[1]; mpp[2][0] = pAppFrame->m_VarCalib.mpp2[2][0];//(aux5*aux4*aux1+aux2*aux6)/f; mpp[2][1] = pAppFrame->m_VarCalib.mpp2[2][1];//(-aux2*aux5+aux6*aux4*aux1)/f;

Page 280: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

mpp[2][2] = pAppFrame->m_VarCalib.mpp2[2][2];//aux3*aux1/f; mpp[2][3] = pAppFrame->m_VarCalib.mpp2[2][3];//trans[2]/f; } return(0); } /*******************************************************************/ /*F:frame_undistorted* ________________________________________________________________ frame_undistorted ________________________________________________________________ Name: frame_undistorted - compute the undistorted coordinates from the frame buffer's coordinates Syntax: | int frame_undistorted(xf, yf, xu, yu, k, dxl, dy, cx, cy) | int xf, yf, cx, cy; | double *xu, *yu, k, dxl, dy; Description: 'frame_undistorted' performs the determination of the undistorted coordinates of a point from the frame buffer's coordinates by TSAI's model. 'xf' and 'yf' are the frame buffer's coordinates's. 'xu' and 'yu' passed by reference are the undistorced's coordinates's. 'k' is the lens's radial distortion. 'dxl' is sx*dx where dx is the distance between adjacent sensor elements in x (scan line) direction and sx is the horizontal scale factor. 'dy' is the center to center distance between adjacent CCD sensor in the y direction. 'cx' and 'cy' are the row and column numbers of the center of frame buffer. Return value: | 0 => Ok.

Restrictions: 'dx' and 'dy' must be different of zero. Author: Sergio Barros; Nuno Sá Couto; Joao Tavares Based On: Code By João Tavares ________________________________________________________________ */ int frame_undistorted(int xf,int yf, double *xu, double *yu,double k,double dxl,double dy,int cx,int cy) { /* compute from frame coordinates the undistorted coordinates */ double r2, xd, yd, aux1, aux2, aux3; aux1 = (double)(xf-cx); aux2 = (double)(yf-cy); xd = dxl*aux1; yd = dy*aux2; r2 = SQR(xd)+SQR(yd); aux3 = 1.0+k*r2; *xu = xd*aux3; *yu = yd*aux3; return(0); } /*******************************************************************/ int stereo_eq(double mpp1[][4],double mpp2[][4],double xu1,double yu1,double xu2,double yu2,double *a) { double **z, *y; z = matrix(3,2); y = vector(3); /* compute the vector of the observed values */

Page 281: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

y[0] = mpp1[2][3]*xu1-mpp1[0][3]; y[1] = mpp1[2][3]*yu1-mpp1[1][3]; y[2] = mpp2[2][3]*xu2-mpp2[0][3]; y[3] = mpp2[2][3]*yu2-mpp2[1][3]; /* compute the matrix of the observed values */ z[0][0] = mpp1[0][0]-mpp1[2][0]*xu1; z[0][1] = mpp1[0][1]-mpp1[2][1]*xu1; z[0][2] = mpp1[0][2]-mpp1[2][2]*xu1; z[1][0] = mpp1[1][0]-mpp1[2][0]*yu1; z[1][1] = mpp1[1][1]-mpp1[2][1]*yu1; z[1][2] = mpp1[1][2]-mpp1[2][2]*yu1; z[2][0] = mpp2[0][0]-mpp2[2][0]*xu2; z[2][1] = mpp2[0][1]-mpp2[2][1]*xu2; z[2][2] = mpp2[0][2]-mpp2[2][2]*xu2; z[3][0] = mpp2[1][0]-mpp2[2][0]*yu2; z[3][1] = mpp2[1][1]-mpp2[2][1]*yu2; z[3][2] = mpp2[1][2]-mpp2[2][2]*yu2; /* call svdfit function */ svdfit(z, y, 4, a, 3); free_matrix(z,3,2); free_vector(y,3); return(0); } /******************************************************************/ /*F:svdfit* ________________________________________________________________ svdfit ________________________________________________________________ Name: svdfit - make the linear least-squares regression using SVD decomposition Syntax: | void svdfit(xin, yin, ndata, ain, ma) | double **xin, *yin, *ain; | int ndata, ma;

Description: 'svdfit' performs the linear least-squares regression using the singular value decomposition. 'xin' is the matrix of the observed values for the independent variable. 'ma' is the number of variables in the model and 'ndata' is the number of data points. The vector 'yin' contains the observed values of the dependent variable. The vector 'ain' contains the unknown coefficients. Return value: | None. Author: Sergio Barros; Nuno Sá Couto; Joao Tavares Based On: Code By João Tavares ________________________________________________________________ */ void svdfit( double **xin,double *yin, int ndata, double *ain, int ma) { /* void svbksb(); void svdcmp(); */ register int i, j; double wmax, thresh, **v, *w, **x, *y, *a; w = vector(ma); v = matrix(ma,ma); y = vector(ndata); x = matrix(ndata,ma); a = vector(ma); for (i = 1; i <= ndata; i++) { y[i] = yin[i-1]; for (j = 1; j <= ma; j++) x[i][j] = xin[i-1][j-1]; } /* Singular value decomposition */ svdcmp(x, ndata, ma, w, v);

Page 282: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

/* Edit the singular values, given TOL from the #define statement, between here ... */ wmax = 0.0; for (j = 1; j <= ma; j++) if (w[j] > wmax) wmax = w[j]; thresh = TOL*wmax; for (j = 1; j <= ma; j++) if (w[j] < thresh) w[j] = 0.0; /* ... and here. */ svbksb(x, w, v, ndata, ma, y, a); for (i = 1 ; i <= ma ; i++) ain[i-1] = a[i]; free_vector(w,ma); free_matrix(v,ma,ma); free_vector(y,ndata); free_matrix(x,ndata, ma); free_vector(a,ma); return; } /******************************************************************/ /*F:svbksb* ________________________________________________________________ svbksb ________________________________________________________________ Name: svbksb - compute A.X=B Syntax: | void svbksb(u, w, v, m, n, b, x) | double **u, w[], **v, b[], x[]; | int m, n; Description: 'svbksb' solves A.X=B for a vector X, where A is specified by the arrays 'u[1..m][1..n]', 'w[1..n]' , 'v[1..n][1..n]', as returnd by svdcmp. 'm' and 'n' are the dimensions of 'a' and will be equal for squares matrices. 'b[1..m]' is the right-hand side. 'x[1..n]' is the output solution vector.

Return value: | None. Author: Sergio Barros; Nuno Sá Couto; Joao Tavares Based On: Code By João Tavares ________________________________________________________________ */ void svbksb(double **u,double w[],double **v,int m,int n,double b[],double x[]) { int jj, j, i; double s, *tmp; tmp = vector(n); /* Calculate (trans[U])*[B] */ for (j = 1; j <= n; j++) { s = 0.0; /* Nonzero result only if w(j) is non zero */ if (w[j]) { for ( i = 1; i <= m; i++) s += u[i][j]*b[i]; /* This is the divide by w(j) */ s /= w[j]; } tmp[j] = s; } /* Matrix multiply by [V] to get answer */ for (j = 1; j <= n; j++) { s = 0.0; for (jj = 1; jj <= n; jj++) s += v[j][jj]*tmp[jj]; x[j] = s;

Page 283: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

} free_vector(tmp,n); return; } /******************************************************************/ /*F:svdcmp* ________________________________________________________________ svdcmp ________________________________________________________________ Name: svdcmp - construct the singular value decomposition Syntax: | void svdcmp(a, m, n, w, v) | double **a, w[], **v; | int m, n; Description: Given a matrix 'a[1..m][1..n]' 'svdcmp' computes its singular decomposition, A=U.W.(transpose)V. The matrix U replaces 'a' on output. The diagonal matrix of singular values W is output as a vector 'w[1..n]'. The matrix V (not the transpose) is output as 'v[1..n][1..n]'. Return value: | 1 => No converge in 30 svdcmp iterations. EAuthor: Sergio Barros; Nuno Sá Couto; Joao Tavares Based On: Code By João Tavares ________________________________________________________________ */ void svdcmp(double **a,int m,int n,double w[],double **v) { int flag, i, its, j, jj, l, k, nm; double anorm, c, f, g, h, s, scale, x, y, z, *rv1;

rv1 = vector(n); g = scale = anorm = 0.0;

(sqrt(s), f); h = f*g-s;

{

/* Householder reduction to bidiagonal form */ for ( i = 1; i <= n; i++) { l = i+1; rv1[i] = scale*g; g = s = scale = 0.0; if (i <= m) { for (k = i; k <= m; k++) scale += fabs(a[k][i]); if (scale) { for ( k = i; k <= m; k++) { a[k][i] /= scale; s += a[k][i]*a[k][i]; } f = a[i][i]; g = -SIGN2

a[i][i] = f-g; for (j = l; j <= n; j++) { for (s = 0.0, k = i; k <= m; k++) s += a[k][i]*a[k][j]; f = s/h; for ( k = i; k <= m; k++) a[k][j] += f*a[k][i]; } for (k = i; k <= m; k++) a[k][i] *= scale; } } w[i] = scale*g; g = s = scale = 0.0; if (i <= m && i != n) for (k = l; k <= n; k++) scale += fabs(a[i][k]); if (scale) { for ( k = l; k <= n; k++) {

Page 284: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

a[i][k] /= scale; s += a[i][k]*a[i][k]; } f = a[i][l]; g = - SIGN2(sqrt(s), f); h = f*g-s; a[i][l] = f-g; for (k = l; k <= n; k++) rv1[k] = a[i][k]/h; for (j = l; j <= m; j++) { for (s = 0.0, k = l; k <= n; k++) s += a[j][k]*a[i][k]; for (k = l; k <= n; k++) a[j][k] += s*rv1[k]; } for (k = l; k <= n; k++) a[i][k] *= scale; } } anorm = DMAX(anorm, (fabs(w[i])+fabs(rv1[i]))); } /* Accumulation of right-hand transformations */ for (i = n; i >= 1; i--) { if (i < n) { if (g) { /* Double division to avoid possible underflow */ for (j = l; j <= n; j++) v[j][i] = (a[i][j]/a[i][l])/g; for (j = l; j <= n; j++) { for (s = 0.0, k = l; k <= n; k++) s += a[i][k]*v[k][j]; for (k = l; k <= n; k++) v[k][j] += s*v[k][i]; } } for (j = 1; j <= n; j++) v[i][j] = v [j][i] = 0.0; }

v[i][i] = 1.0; g = rv1[i]; l = i; } /* Accumulation of left-hand transformations */ for(i = IMIN(m, n); i >=1 ; i--) { l = i+1;

for ( j = i; j <= m; j++) a[j][i] *= g;

g = w[i]; for ( j = l; j <= n; j++) a[i][j] = 0.0; if (g) { g = 1.0/g; for (j = l; j <= n; j++) { for (s = 0.0, k = l; k <= m; k++) s += a[k][i]*a[k][j]; f = (s/a[i][i])*g; for (k = i; k <= m; k++) a[k][j] += f*a[k][i]; } } else for (j = i; j <= m; j++) a[j][i] = 0.0; ++a[i][i]; } /* Diagonalization of the bidiagonal form: Loop over singular values, and over allowed iterations */ for (k = n; k >= 1; k--) { for (its = 1; its <= 30; its++) { flag = 1; /* Test for splitting */ for ( l = k; l >= 1; l--) { nm = l-1; /* Note that rv1[1] is always zero */

Page 285: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

if ((double)(fabs(rv1[l]+anorm)) == anorm) { flag = 0; break; } if ((double)(fabs(w[nm]+anorm)) == anorm) break; } if (flag) { /* Cancellation of rv1[l], if l>1 */ c = 0.0; s = 1.0; for (i = l; i <= k; i++) { f = s*rv1[i]; rv1[i] = c*rv1[i]; if ((double)(fabs(f)+anorm) == anorm) break; g = w[i]; h = PYTHAG(f, g); w[i] = h; h = 1.0/h; c = g*h; s = -f*h; for (j = 1; j <= m; j++) { y = a[j][nm]; z = a[j][i]; a[j][nm] = y*c+z*s; a[j][i] = z*c-y*s; } } } z = w[k]; if (l == k) { /* Convergence */ if (z < 0.0) {

/* Singular value is made nonnegative */ w[k] = -z; for (j = 1; j <= n; j++) v[j][k] = -v[j][k]; } break; } //if (its == 30) exit(Error(1, "\nNo converge in 30 svdcmp iterations.\n")); /* Shift from bottom 2-by-2 minor */ x = w[l];

; g = rv1[nm];

/(f+SIGN2(g, f)))-h))/x;

nm = k-1; y = w[nm]

h = rv1[k]; f = ((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y); g = PYTHAG(f, 1.0); f = ((x-z)*(x+z)+h*((y c = s = 1.0; /* Next QR transformation */ for (j = l; j <= nm; j++) { i = j+1; g = rv1[i]; y = w[i]; h = s*g; g = c*g; z = PYTHAG(f, h); rv1[j] = z; c = f/z; s = h/z; f = x*c+g*s; g = g*c-x*s; h = y*s; y *= c; for (jj = 1; jj <= n; jj++) { x = v[jj][j]; z = v[jj][i]; v[jj][j] = x*c+z*s; v[jj][i] = z*c-x*s;

Page 286: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

} z = PYTHAG(f, h); w[j] = z; /* Rotation can be arbitrary if z=0 */ if (z) { z = 1.0/z; c = f*z; s = h*z; } f = c*g+s*y; x = c*y-s*g; for (jj = 1; jj <= m; jj++) { y = a[jj][j]; z = a[jj][i]; a[jj][j] = y*c+z*s; a[jj][i]= z*c-y*s; }

}

E;

} rv1[l] = 0.0; rv1[k] = f; w[k] = x;

} free_vector(rv1,n); return; } /******************************************************************/ /******************************************************************/ CVariaveisCalib::CVariaveisCalib() {

sx =0.710935; dx =8.37765957e-3; dy =8.07560136e-3; cx =256; cy =256; camerasF1_T2=TRU matrix1_exist=FALSE; matrix2_exist=FALSE; npoints=0; x = matrix(4,3); a = vector(3); xu=0; yu=0; xu1=0; xu2=0; yu1=0; yu2=0; w = vector(3); v = matrix(3,3); aa = vector(3); //Last boxes //number_pairs=0; reference_number=0; flag=FALSE; pict_numb=1; } Ddetect.h #include "resource.h" ///////////////////////////////////////////////////////////////////////////// // CDdetect_3D dialog class CDdetect_3D : public CDialog { // Construction public: CDdetect_3D(CWnd* pParent = NULL); // standard constructor

Page 287: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

// Dialog Data //{{AFX_DATA(CDdetect_3D) enum { IDD = IDD_DETECTAND3D }; UINT size; CBitmapButton left; CBitmapButton right; CBitmapButton final3D; UINT m_iedit2; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDdetect_3D) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CDdetect_3D) afx_msg void OnDeltaposSpin1(NMHDR* pNMHDR, LRESULT* pResult); virtual BOOL OnInitDialog(); virtual void OnCancel(); afx_msg void OnButton2(); afx_msg void OnButton5(); afx_msg void OnButton4(); afx_msg void OnButton1(); virtual void OnOK(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////// // CDInitDetect3D dialog class CDInitDetect3D : public CDialog { // Construction public: CDInitDetect3D(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CDInitDetect3D)

enum { IDD = IDD_INITDETECT3D }; int m_iradio1; DOUBLE m_edit9; DOUBLE m_edit8; DOUBLE m_edit7; DOUBLE m_edit6; DOUBLE m_edit5; DOUBLE m_edit4; DOUBLE m_edit34; DOUBLE m_edit31; DOUBLE m_edit30; DOUBLE m_edit29; DOUBLE m_edit28; DOUBLE m_edit27; DOUBLE m_edit26; DOUBLE m_edit25; DOUBLE m_edit24; DOUBLE m_edit23; DOUBLE m_edit22; DOUBLE m_edit21; DOUBLE m_edit20; DOUBLE m_edit2; DOUBLE m_edit19; DOUBLE m_edit18; DOUBLE m_edit17; DOUBLE m_edit16; DOUBLE m_edit15; DOUBLE m_edit14; DOUBLE m_edit13; DOUBLE m_edit12; DOUBLE m_edit11; DOUBLE m_edit10; DOUBLE m_edit1; UINT m_edit3; int m_edit32; int m_edit33; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDInitDetect3D) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL

Page 288: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

// Implementation protected: // Generated message map functions //{{AFX_MSG(CDInitDetect3D) afx_msg void OnRadio1(); afx_msg void OnRadio2(); afx_msg void OnButton4(); afx_msg void OnButton5(); afx_msg void OnButton6(); afx_msg void OnButton1(); afx_msg void OnButton2(); virtual void OnOK(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////// // CDCorrect dialog class CDCorrect : public CDialog { // Construction public: CDCorrect(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CDCorrect) enum { IDD = IDD_CORRECT }; CBitmapButton final3D; UINT m_iedit2; double m_x; double m_y; double m_r; UINT m_xr; UINT m_yr; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDCorrect) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation

protected: // Generated message map functions //{{AFX_MSG(CDCorrect) afx_msg void OnDeltaposSpin1(NMHDR* pNMHDR, LRESULT* pResult);

rtual BOOL OnInitDialog(); vi afx_msg void OnButton2(); afx_msg void OnButton1(); virtual void OnOK(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////// // // CDrotation dialog // ///////////////////////////////////////////////////////////////////////////// class CDrotation : public CDialog { // Construction public: CDrotation(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CDrotation) enum { IDD = IDD_ROTATION }; int m_bg; int m_ip; double m_rx; double m_ry; double m_theta; CBitmapButton m_ok; CBitmapButton m_cancel; BOOL m_center; double m_xsize; double m_ysize; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDrotation) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

Page 289: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

//}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CDrotation) virtual BOOL OnInitDialog(); afx_msg void OnDeltaposSpin(NMHDR* pNMHDR, LRESULT* pResult); afx_msg void OnCenter(); afx_msg void OnPreprocessingImagemirror(); afx_msg void OnUpdatePreprocessingImagemirror(CCmdUI* pCmdUI);

//{{AFX_DATA_INIT(CDdetect_3D)

//}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////// // CDtranslation dialog class CDtranslation : public CDialog { // Construction public: CDtranslation(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CDtranslation) enum { IDD = IDD_TRANSLATE }; int m_tx; int m_ty; int m_bg; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDtranslation) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CDtranslation) // NOTE: the ClassWizard will add member functions here

//}}AFX_MSG DECLARE_MESSAGE_MAP() }; Ddetect.cpp #include "stdafx.h" #include "Project.h" #include "DDetect.h" #include "MainFrm.h" #include "detect.h" #include "calcamera.h" #include "detect_points.h" #include "geometry.h" #include "gdefs.h" ///////////////////////////////////////////////////////////////////////////// // CDdetect_3D dialog CDdetect_3D::CDdetect_3D(CWnd* pParent /*=NULL*/) : CDialog(CDdetect_3D::IDD, pParent) {

m_iedit2 = 1; //}}AFX_DATA_INIT } void CDdetect_3D::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDdetect_3D) DDX_Text(pDX, IDC_EDIT2, m_iedit2); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDdetect_3D, CDialog) //{{AFX_MSG_MAP(CDdetect_3D) ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN1, OnDeltaposSpin1) ON_BN_CLICKED(IDC_BUTTON2, OnButton2) ON_BN_CLICKED(IDC_BUTTON5, OnButton5) ON_BN_CLICKED(IDC_BUTTON4, OnButton4)

Page 290: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

ON_BN_CLICKED(IDC_BUTTON1, OnButton1) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDdetect_3D message handlers void CDdetect_3D::OnDeltaposSpin1(NMHDR* pNMHDR, LRESULT* pResult) { NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR; // TODO: Add your control notification handler code here CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); UpdateData(TRUE); if (pNMUpDown->iDelta == -1 && m_iedit2 > 0 ) m_iedit2 -= 1; else if(pNMUpDown->iDelta == +1 && m_iedit2 <= size ) m_iedit2 += 1; if (m_iedit2 == 0 ) m_iedit2=1; if (m_iedit2 > size ) m_iedit2 = size; if (! pAppFrame->m_VarCalib.made[m_iedit2-1].left) { left.LoadBitmaps(IDB_NO,0,0,0); left.InvalidateRect(NULL,TRUE); } else{ left.LoadBitmaps(IDB_YES,0,0,0); left.InvalidateRect(NULL,TRUE); } if (! pAppFrame->m_VarCalib.made[m_iedit2-1 ].right) { right.LoadBitmaps(IDB_NO,0,0,0); right.InvalidateRect(NULL,TRUE); }

else{ right.LoadBitmaps(IDB_YES,0,0,0); right.InvalidateRect(NULL,TRUE); } if (! pAppFrame->m_VarCalib.made[m_iedit2-1 ].final3D) { final3D.LoadBitmaps(IDB_NO,0,0,0); final3D.InvalidateRect(NULL,TRUE); } else{ final3D.LoadBitmaps(IDB_YES,0,0,0); final3D.InvalidateRect(NULL,TRUE); } UpdateData(FALSE); *pResult = 0; } BOOL CDdetect_3D::OnInitDialog() { CDialog::OnInitDialog(); CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); // TODO: Add extra initialization here CSpinButtonCtrl* control; control= (CSpinButtonCtrl*) GetDlgItem(IDC_SPIN1); control->SetRange( 1, size +1 ); UINT i; for (i=0; i<= size ;i++) { pAppFrame->m_VarCalib.made[i].left=FALSE; pAppFrame->m_VarCalib.made[i].right=FALSE; pAppFrame->m_VarCalib.made[i].final3D=FALSE; } VERIFY(left.AutoLoad(IDC_LEFT, this)); VERIFY(right.AutoLoad(IDC_RIGHT, this)); VERIFY(final3D.AutoLoad(IDC_FINAL3D, this));

Page 291: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

UpdateData(FALSE); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CDdetect_3D::OnCancel() { // TODO: Add extra cleanup here

indow();

CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd;

//DestroyW //delete this; CDialog::OnCancel(); } void CDdetect_3D::OnButton2() { // TODO: Add your control notification handler code here // 3D // CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); int i; UpdateData(TRUE); BeginWaitCursor(); for (i =0;i<60;i++) { pAppFrame->m_VarCalib.marks2[i].x=pAppFrame->m_VarCalib.markarrayR[m_iedit2-1][i].x; pAppFrame->m_VarCalib.marks2[i].y=pAppFrame->m_VarCalib.markarrayR[m_iedit2-1][i].y; pAppFrame->m_VarCalib.marks2[i].tag=pAppFrame->m_VarCalib.markarrayR[m_iedit2-1][i].tag; pAppFrame->m_VarCalib.marks[i].x=pAppFrame->m_VarCalib.markarrayL[m_iedit2-1][i].x;

pAppFrame->m_VarCalib.marks[i].y=pAppFrame->m_VarCalib.markarrayL[m_iedit2-1][i].y; pAppFrame->m_VarCalib.marks[i].tag=pAppFrame->m_VarCalib.markarrayL[m_iedit2-1][i].tag; } compdeep(); for (i =0;i<60;i++) { pAppFrame->m_VarCalib.markarray3D[m_iedit2-1][i].x=pAppFrame->m_VarCalib.final_mark3D[i].x; pAppFrame->m_VarCalib.markarray3D[m_iedit2-1][i].y=pAppFrame->m_VarCalib.final_mark3D[i].y; pAppFrame->m_VarCalib.markarray3D[m_iedit2-1][i].z=pAppFrame->m_VarCalib.final_mark3D[i].z; pAppFrame->m_VarCalib.markarray3D[m_iedit2-1][i].tag=pAppFrame->m_VarCalib.final_mark3D[i].tag; } pAppFrame->m_VarCalib.made[m_iedit2-1].final3D=TRUE; final3D.LoadBitmaps(IDB_YES,0,0,0); final3D.InvalidateRect(NULL,TRUE); EndWaitCursor(); UpdateData(FALSE); } void CDdetect_3D::OnButton4() { // TODO: Add your control notification handler code here CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); UpdateData(TRUE); pAppFrame->m_VarCalib.reference_number=m_iedit2-1; } void CDdetect_3D::OnButton1() { // TODO: Add your control notification handler code here

Page 292: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); UpdateData(TRUE); HDIB hNewDIB = NULL; BeginWaitCursor(); CMDIFrameWnd* pChild = (CMDIFrameWnd*) pAppFrame->MDIGetActive(); CProjectDoc* pDoc = (CProjectDoc*) pChild->GetActiveDocument(); //hNewDIB = (HDIB) CopyHandle(pDoc->m_hDIB); // copy the input DIB cal_marks(pDoc->m_hDIB,1); for (int i =0;i<60;i++) { pAppFrame->m_VarCalib.markarrayL[m_iedit2-1][i].x=pAppFrame->m_VarCalib.marks[i].x; pAppFrame->m_VarCalib.markarrayL[m_iedit2-1][i].y=pAppFrame->m_VarCalib.marks[i].y; pAppFrame->m_VarCalib.markarrayL[m_iedit2-1][i].tag=pAppFrame->m_VarCalib.marks[i].tag; } pAppFrame->m_VarCalib.made[m_iedit2-1].left=TRUE; left.LoadBitmaps(IDB_YES,0,0,0); left.InvalidateRect(NULL,TRUE); EndWaitCursor(); // message beep pAppFrame->OnEnd(); UpdateData(FALSE); } void CDdetect_3D::OnButton5() { // TODO: Add your control notification handler code here

dateData(TRUE); Up

B = (HDIB) CopyHandle(pDoc->m_hDIB); // copy the input DIB

oid CDdetect_3D::OnOK()

CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); HDIB hNewDIB = NULL;

BeginWaitCursor(); CMDIFrameWnd* pChild = (CMDIFrameWnd*) pAppFrame->MDIGetActive(); CProjectDoc* pDoc = (CProjectDoc*) pChild->GetActiveDocument(); //hNewDI cal_marks(pDoc->m_hDIB,2); for (int i =0;i<60;i++) { pAppFrame->m_VarCalib.markarrayR[m_iedit2-1][i].x=pAppFrame->m_VarCalib.marks2[i].x; pAppFrame->m_VarCalib.markarrayR[m_iedit2-1][i].y=pAppFrame->m_VarCalib.marks2[i].y; pAppFrame->m_VarCalib.markarrayR[m_iedit2-1][i].tag=pAppFrame->m_VarCalib.marks2[i].tag; } pAppFrame->m_VarCalib.made[m_iedit2-1].right=TRUE; right.LoadBitmaps(IDB_YES,0,0,0); right.InvalidateRect(NULL,TRUE); EndWaitCursor(); // message beep pAppFrame->OnEnd(); UpdateData(FALSE); } v{ BOOL bOpen = FALSE; // File Open Dialog LPCSTR lpszDefExt = "txt"; // Default Extension DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; // default // TODO: Add extra validation here CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); int i,j, dummy;

Page 293: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

char arg[200]; FILE *outftp; LPTSTR name1; CString m_strInputfile; LPCSTR lpszFilter = "Project File Types (*.txt) | *.txt;;|All files (*.*) | *.*; ||"; CFileDialog dlg( bOpen, lpszDefExt,NULL, dwFlags, lpszFilter ); if (dlg.DoModal() == IDOK) m_strInputfile = dlg.GetPathName(); name1= m_strInputfile.GetBuffer(100); outftp = fopen(name1, "w"); if (outftp == NULL){ MessageBox("Can not open input file", "Calibration Error", MB_ICONERROR | MB_OK); } sprintf(arg, "Results for the 3D coordinates algorithm.\n\n"); fprintf(outftp, arg); sprintf(arg, "Number of Image Pairs:\t%d\n\n.", size); fprintf(outftp, arg); CString teste; for(j=0;j <(int)size;j++) { dummy = j+1; sprintf(arg, "\t3D Coordinates for Image Pair number:\t%d\n\n", dummy); fprintf(outftp, arg); sprintf(arg, "\t\tX coord\t\tY coord\t\tZ coord\t\tTAG\n"); fprintf(outftp, arg); for(i=0;i<pAppFrame->m_VarCalib.npoints;i++)

CDInitDetect3D::CDInitDetect3D(CWnd* pParent /*=NULL*/)

{ teste = pAppFrame->m_VarCalib.markarray3D[j][i].tag; sprintf(arg, "\t\t %g \t %g \t %g \t %s \n", pAppFrame->m_VarCalib.markarray3D[j][i].x, pAppFrame->m_VarCalib.markarray3D[j][i].y, pAppFrame->m_VarCalib.markarray3D[j][i].z, (LPCTSTR) teste.GetBuffer(256)); fprintf(outftp, arg);; } } fclose(outftp);

//correct// pAppFrame->m_VarCalib.pict_numb=size; CDialog::OnOK(); } ///////////////////////////////////////////////////////////////////////////// // CDInitDetect3D dialog

: CDialog(CDInitDetect3D::IDD, pParent) { //{{AFX_DATA_INIT(CDInitDetect3D) m_iradio1 = 0; m_edit9 = 0.0f; m_edit8 = 0.0f; m_edit7 = 0.0f; m_edit6 = 0.0f; m_edit5 = 0.0f; m_edit4 = 0.0f; m_edit34 = 0.0f; m_edit31 = 0.0f; m_edit30 = 0.0f; m_edit29 = 0.0f; m_edit28 = 0.0f; m_edit27 = 0.0f; m_edit26 = 0.0f; m_edit25 = 0.0f; m_edit24 = 0.0f; m_edit23 = 0.0f; m_edit22 = 0.0f; m_edit21 = 0.0f; m_edit20 = 0.0f; m_edit2 = 0.0f; m_edit19 = 0.0f; m_edit18 = 0.0f; m_edit17 = 0.0f; m_edit16 = 0.0f; m_edit15 = 0.0f; m_edit14 = 0.0f; m_edit13 = 0.0f; m_edit12 = 0.0f; m_edit11 = 0.0f;

Page 294: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

m_edit10 = 0.0f; m_edit1 = 0.0f; m_edit3 = 1; m_edit32 = 0; m_edit33 = 0; //}}AFX_DATA_INIT } void CDInitDetect3D::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDInitDetect3D) DDX_Radio(pDX, IDC_RADIO1, m_iradio1); DDX_Text(pDX, IDC_EDIT9, m_edit9); DDX_Text(pDX, IDC_EDIT8, m_edit8); DDX_Text(pDX, IDC_EDIT7, m_edit7); DDX_Text(pDX, IDC_EDIT6, m_edit6); DDX_Text(pDX, IDC_EDIT5, m_edit5); DDX_Text(pDX, IDC_EDIT4, m_edit4); DDX_Text(pDX, IDC_EDIT34, m_edit34); DDX_Text(pDX, IDC_EDIT31, m_edit31); DDX_Text(pDX, IDC_EDIT30, m_edit30); DDX_Text(pDX, IDC_EDIT29, m_edit29); DDX_Text(pDX, IDC_EDIT28, m_edit28); DDX_Text(pDX, IDC_EDIT27, m_edit27); DDX_Text(pDX, IDC_EDIT26, m_edit26); DDX_Text(pDX, IDC_EDIT25, m_edit25); DDX_Text(pDX, IDC_EDIT24, m_edit24); DDX_Text(pDX, IDC_EDIT23, m_edit23); DDX_Text(pDX, IDC_EDIT22, m_edit22); DDX_Text(pDX, IDC_EDIT21, m_edit21); DDX_Text(pDX, IDC_EDIT20, m_edit20); DDX_Text(pDX, IDC_EDIT2, m_edit2); DDX_Text(pDX, IDC_EDIT19, m_edit19); DDX_Text(pDX, IDC_EDIT18, m_edit18); DDX_Text(pDX, IDC_EDIT17, m_edit17); DDX_Text(pDX, IDC_EDIT16, m_edit16); DDX_Text(pDX, IDC_EDIT15, m_edit15); DDX_Text(pDX, IDC_EDIT14, m_edit14); DDX_Text(pDX, IDC_EDIT13, m_edit13); DDX_Text(pDX, IDC_EDIT12, m_edit12); DDX_Text(pDX, IDC_EDIT11, m_edit11); DDX_Text(pDX, IDC_EDIT10, m_edit10); DDX_Text(pDX, IDC_EDIT1, m_edit1); DDX_Text(pDX, IDC_EDIT3, m_edit3);

DDV_MinMaxUInt(pDX, m_edit3, 1, 100); DDX_Text(pDX, IDC_EDIT32, m_edit32); DDX_Text(pDX, IDC_EDIT33, m_edit33); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDInitDetect3D, CDialog) //{{AFX_MSG_MAP(CDInitDetect3D)

(TRUE);

ON_BN_CLICKED(IDC_RADIO1, OnRadio1) ON_BN_CLICKED(IDC_RADIO2, OnRadio2) ON_BN_CLICKED(IDC_BUTTON4, OnButton4) ON_BN_CLICKED(IDC_BUTTON5, OnButton5) ON_BN_CLICKED(IDC_BUTTON6, OnButton6) ON_BN_CLICKED(IDC_BUTTON1, OnButton1) ON_BN_CLICKED(IDC_BUTTON2, OnButton2) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDInitDetect3D message handlers void CDInitDetect3D::OnRadio1() { // TODO: Add your control notification handler code here UpdateData if (m_iradio1==1) { GetDlgItem(IDC_EDIT14)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT15)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT16)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT17)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT18)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT19)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT20)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT21)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT22)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT23)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT24)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT25)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT28)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT29)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE);

Page 295: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

GetDlgItem(IDC_BUTTON5)->EnableWindow(FALSE); } else { GetDlgItem(IDC_EDIT14)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT15)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT16)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT17)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT18)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT19)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT20)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT21)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT22)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT23)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT24)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT25)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT28)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT29)->EnableWindow(TRUE); GetDlgItem(IDC_BUTTON2)->EnableWindow(TRUE); GetDlgItem(IDC_BUTTON5)->EnableWindow(TRUE); } UpdateData(FALSE); } void CDInitDetect3D::OnRadio2() { // TODO: Add your control notification handler code here UpdateData(TRUE); if (m_iradio1==1) { GetDlgItem(IDC_EDIT14)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT15)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT16)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT17)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT18)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT19)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT20)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT21)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT22)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT23)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT24)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT25)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT28)->EnableWindow(FALSE);

GetDlgItem(IDC_EDIT29)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON5)->EnableWindow(FALSE); } else { GetDlgItem(IDC_EDIT14)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT15)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT16)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT17)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT18)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT19)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT20)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT21)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT22)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT23)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT24)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT25)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT28)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT29)->EnableWindow(TRUE); GetDlgItem(IDC_BUTTON2)->EnableWindow(TRUE); GetDlgItem(IDC_BUTTON5)->EnableWindow(TRUE); } UpdateData(FALSE); } void CDInitDetect3D::OnButton4() { // TODO: Add your control notification handler code here CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); UpdateData(TRUE); m_edit1=pAppFrame->m_VarCalib.mpp1[0][0]; m_edit5=pAppFrame->m_VarCalib.mpp1[0][1]; m_edit8=pAppFrame->m_VarCalib.mpp1[0][2]; m_edit11=pAppFrame->m_VarCalib.mpp1[0][3]; m_edit2=pAppFrame->m_VarCalib.mpp1[1][0];

Page 296: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

m_edit6=pAppFrame->m_VarCalib.mpp1[1][1]; m_edit9=pAppFrame->m_VarCalib.mpp1[1][2]; m_edit12=pAppFrame->m_VarCalib.mpp1[1][3]; m_edit4=pAppFrame->m_VarCalib.mpp1[2][0]; m_edit7=pAppFrame->m_VarCalib.mpp1[2][1]; m_edit10=pAppFrame->m_VarCalib.mpp1[2][2]; m_edit13=pAppFrame->m_VarCalib.mpp1[2][3]; m_edit26=pAppFrame->m_VarCalib.f1; m_edit27=pAppFrame->m_VarCalib.k1; UpdateData(FALSE); } void CDInitDetect3D::OnButton5() { // TODO: Add your control notification handler code here CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); UpdateData(TRUE); m_edit14=pAppFrame->m_VarCalib.mpp2[0][0]; m_edit17=pAppFrame->m_VarCalib.mpp2[0][1]; m_edit20=pAppFrame->m_VarCalib.mpp2[0][2]; m_edit23=pAppFrame->m_VarCalib.mpp2[0][3]; m_edit15=pAppFrame->m_VarCalib.mpp2[1][0]; m_edit18=pAppFrame->m_VarCalib.mpp2[1][1]; m_edit21=pAppFrame->m_VarCalib.mpp2[1][2]; m_edit24=pAppFrame->m_VarCalib.mpp2[1][3]; m_edit16=pAppFrame->m_VarCalib.mpp2[2][0]; m_edit19=pAppFrame->m_VarCalib.mpp2[2][1]; m_edit22=pAppFrame->m_VarCalib.mpp2[2][2]; m_edit25=pAppFrame->m_VarCalib.mpp2[2][3]; m_edit28=pAppFrame->m_VarCalib.f2; m_edit29=pAppFrame->m_VarCalib.k2; UpdateData(FALSE); }

void CDInitDetect3D::OnButton6() { // TODO: Add your control notification handler code here CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); UpdateData(TRUE); m_edit30=pAppFrame->m_VarCalib.dx; m_edit31=pAppFrame->m_VarCalib.dy; m_edit32=pAppFrame->m_VarCalib.cx; m_edit33=pAppFrame->m_VarCalib.cy; m_edit34=pAppFrame->m_VarCalib.sx; UpdateData(FALSE); } void CDInitDetect3D::OnButton1() { // TODO: Add your control notification handler code here UpdateData(TRUE); BOOL bOpen = TRUE; // File Open Dialog LPCSTR lpszDefExt = "txt"; // Default Extension DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; // default LPCSTR lpszFilter; FILE *infpt; LPTSTR name1; char valid[500], *pdest; calpoint rot[6], trans[2]; int i; float k1, f1; int ch = 'C',result=0; // file filters lpszFilter = "Windows Bitmap (*.txt) | *.txt; |Cmis ASCII File (*.cmi) | *.cmi; |All files (*.*) | *.*; ||"; // Criação do ficheiro de destino CFileDialog dlg( bOpen, lpszDefExt,FALSE, dwFlags, lpszFilter );

Page 297: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

if( dlg.DoModal() != IDOK ) return; // Open the File Dialog CString fileName = dlg.GetPathName(); // Busca o nome do ficheiro name1= fileName.GetBuffer(100); infpt = fopen(name1, "r"); if (infpt == NULL){ MessageBox("Can not open input file", "3 D - Error", MB_ICONERROR | MB_OK); } // Get data points //

fscanf (infpt, "%g", &k1);

// TODO: Add your control notification handler code here

fscanf (infpt,"%s", valid); pdest = strchr( valid, ch ); result = pdest - valid + 1; if( result != 8 ){ MessageBox("Invalid data file!! Input proper calibration data!!", "Calibration error", MB_ICONERROR | MB_OK); return; } for ( i=1; i< 27; i++) fscanf (infpt,"%s", valid); // Points to real data // for (i=1; i<= 3; i++) fscanf(infpt, "%g %g %g", &rot[i].xw, &rot[i].yw, &rot[i].xf); for (i=1; i<= 3; i++) fscanf (infpt,"%s", valid); fscanf (infpt, "%g %g %g", &trans[1].xw, &trans[1].yw, &trans[1].xf ); for (i=1; i<= 3; i++) fscanf (infpt,"%s", valid); fscanf (infpt, "%g", &f1); for (i=1; i<= 4; i++) fscanf (infpt,"%s", valid);

m_edit1 = rot[1].xw; m_edit5 = rot[1].yw; m_edit8 = rot[1].xf; m_edit2 = rot[2].xw; m_edit6 = rot[2].yw; m_edit9 = rot[2].xf; m_edit4 = rot[3].xw/f1; m_edit7 = rot[3].yw/f1; m_edit10 = rot[3].xf/f1; m_edit11 = trans[1].xw; m_edit12= trans[1].yw; m_edit13 = trans[1].xf/f1; m_edit26 = f1; m_edit27 = k1; UpdateData(FALSE); } void CDInitDetect3D::OnButton2() { UpdateData(TRUE); BOOL bOpen = TRUE; // File Open Dialog LPCSTR lpszDefExt = "txt"; // Default Extension DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; // default LPCSTR lpszFilter; FILE *infpt; LPTSTR name1; char valid[500], *pdest; calpoint rot[6], trans[2]; int i; float k1, f1; int ch = 'C',result=0; // file filters

Page 298: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

lpszFilter = "Windows Bitmap (*.txt) | *.txt; |Cmis ASCII File (*.cmi) | *.cmi; |All files (*.*) | *.*; ||"; // Criação do ficheiro de destino CFileDialog dlg( bOpen, lpszDefExt,NULL, dwFlags, lpszFilter ); if( dlg.DoModal() != IDOK ) return; // Open the File Dialog CString fileName = dlg.GetPathName(); // Busca o nome do ficheiro name1= fileName.GetBuffer(100); infpt = fopen(name1, "r"); if (infpt == NULL){ MessageBox("Can not open input file", "3 D - Error", MB_ICONERROR | MB_OK); } // Get data points // fscanf (infpt,"%s", valid); pdest = strchr( valid, ch ); result = pdest - valid + 1; if( result != 8 ){ MessageBox("Invalid data file!! Input proper calibration data!!", "Calibration error", MB_ICONERROR | MB_OK); return; } for ( i=1; i< 27; i++) fscanf (infpt,"%s", valid); // Points to real data // for (i=1; i<= 3; i++) fscanf(infpt, "%g %g %g", &rot[i].xw, &rot[i].yw, &rot[i].xf); for (i=1; i<= 3; i++) fscanf (infpt,"%s", valid); fscanf (infpt, "%g %g %g", &trans[1].xw, &trans[1].yw, &trans[1].xf ); for (i=1; i<= 3; i++) fscanf (infpt,"%s", valid);

fscanf (infpt, "%g", &f1); for (i=1; i<= 4; i++) fscanf (infpt,"%s", valid); fscanf (infpt, "%g", &k1); m_edit14 = rot[1].xw; m_edit17 = rot[1].yw; m_edit20 = rot[1].xf; m_edit15 = rot[2].xw; m_edit18 = rot[2].yw; m_edit21 = rot[2].xf; m_edit16= rot[3].xw/f1; m_edit19 = rot[3].yw/f1; m_edit22 = rot[3].xf/f1; m_edit23 = trans[1].xw; m_edit24= trans[1].yw; m_edit25 = trans[1].xf/f1; m_edit28 = f1; m_edit29 = k1; UpdateData(FALSE); } void CDInitDetect3D::OnOK() { // TODO: Add extra validation here CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); UpdateData(TRUE); //LEFT pAppFrame->m_VarCalib.mpp1[0][0]=m_edit1; pAppFrame->m_VarCalib.mpp1[0][1]=m_edit5;

Page 299: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

pAppFrame->m_VarCalib.mpp1[0][2]=m_edit8; pAppFrame->m_VarCalib.mpp1[0][3]=m_edit11; pAppFrame->m_VarCalib.mpp1[1][0]=m_edit2; pAppFrame->m_VarCalib.mpp1[1][1]=m_edit6; pAppFrame->m_VarCalib.mpp1[1][2]=m_edit9; pAppFrame->m_VarCalib.mpp1[1][3]=m_edit12; pAppFrame->m_VarCalib.mpp1[2][0]=m_edit4; pAppFrame->m_VarCalib.mpp1[2][1]=m_edit7; pAppFrame->m_VarCalib.mpp1[2][2]=m_edit10; pAppFrame->m_VarCalib.mpp1[2][3]=m_edit13; pAppFrame->m_VarCalib.f1=m_edit26; pAppFrame->m_VarCalib.k1=m_edit27; //RIGHT pAppFrame->m_VarCalib.mpp2[0][0]=m_edit14; pAppFrame->m_VarCalib.mpp2[0][1]=m_edit17; pAppFrame->m_VarCalib.mpp2[0][2]=m_edit20; pAppFrame->m_VarCalib.mpp2[0][3]=m_edit23; pAppFrame->m_VarCalib.mpp2[1][0]=m_edit15; pAppFrame->m_VarCalib.mpp2[1][1]=m_edit18; pAppFrame->m_VarCalib.mpp2[1][2]=m_edit21; pAppFrame->m_VarCalib.mpp2[1][3]=m_edit24; pAppFrame->m_VarCalib.mpp2[2][0]=m_edit16;

m_ =

pAppFrame->m_VarCalib.mpp2[2][1]=m_edit19; pAppFrame->m_VarCalib.mpp2[2][2]=m_edit22; pAppFrame->m_VarCalib.mpp2[2][3]=m_edit25; pAppFrame->m_VarCalib.f2=m_edit28; pAppFrame->m_VarCalib.k2=m_edit29; pAppFrame->m_VarCalib.dx=m_edit30; pAppFrame->m_VarCalib.dy=m_edit31; pAppFrame->m_VarCalib.cx=m_edit32; pAppFrame->m_VarCalib.cy=m_edit33; pAppFrame->m_VarCalib.sx=m_edit34;

CDialog::OnOK(); } ///////////////////////////////////////////////////////////////////////////// // CDCorrect dialog CDCorrect::CDCorrect(CWnd* pParent /*=NULL*/) : CDialog(CDCorrect::IDD, pParent) { //{{AFX_DATA_INIT(CDCorrect) m_iedit2 = 0; m_x = 0.0; m_y = 0.0; m_r = 0.0;

xr 0; m_yr = 0; //}}AFX_DATA_INIT } void CDCorrect::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDCorrect) DDX_Text(pDX, IDC_EDIT2, m_iedit2); DDX_Text(pDX, IDC_EDIT3, m_x); DDX_Text(pDX, IDC_EDIT4, m_y); DDX_Text(pDX, IDC_EDIT5, m_r); DDX_Text(pDX, IDC_EDIT6, m_xr); DDX_Text(pDX, IDC_EDIT7, m_yr); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDCorrect, CDialog) //{{AFX_MSG_MAP(CDCorrect) ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN1, OnDeltaposSpin1) ON_BN_CLICKED(IDC_BUTTON2, OnButton2) ON_BN_CLICKED(IDC_BUTTON1, OnButton1) //}}AFX_MSG_MAP END_MESSAGE_MAP()

Page 300: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

///////////////////////////////////////////////////////////////////////////// // CDCorrect message handlers void CDCorrect::OnDeltaposSpin1(NMHDR* pNMHDR, LRESULT* pResult) { NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR; // TODO: Add your control notification handler code here CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); UpdateData(TRUE); if (pNMUpDown->iDelta == -1 && m_iedit2 > 0 ) m_iedit2 -= 1; else if(pNMUpDown->iDelta == +1 && m_iedit2 <= pAppFrame->m_VarCalib.pict_numb ) m_iedit2 += 1; if (m_iedit2 == 0 ) m_iedit2=1; if (m_iedit2 > pAppFrame->m_VarCalib.pict_numb ) m_iedit2 = pAppFrame->m_VarCalib.pict_numb ; if (! pAppFrame->m_VarCalib.made[m_iedit2-1 ].final3D) { final3D.LoadBitmaps(IDB_NO,0,0,0); final3D.InvalidateRect(NULL,TRUE); } else{ final3D.LoadBitmaps(IDB_YES,0,0,0); final3D.InvalidateRect(NULL,TRUE); } UpdateData(FALSE); *pResult = 0; } BOOL CDCorrect::OnInitDialog() { CDialog::OnInitDialog();

// TODO: Add extra initialization here CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); CSpinButtonCtrl* control; control= (CSpinButtonCtrl*) GetDlgItem(IDC_SPIN1); control->SetRange( 1, pAppFrame->m_VarCalib.pict_numb +1 ); UINT i; for (i=0; i<= pAppFrame->m_VarCalib.pict_numb ;i++) { pAppFrame->m_VarCalib.made[i].final3D=FALSE; } VERIFY(final3D.AutoLoad(IDC_FINAL3D, this)); UpdateData(FALSE); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CDCorrect::OnButton2() { // TODO: Add your control notification handler code here //Movement UpdateData(TRUE); CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); //Testing pAppFrame->m_VarCalib.markarray3D[0][0].x=7; pAppFrame->m_VarCalib.markarray3D[0][1].x=7.5; pAppFrame->m_VarCalib.markarray3D[0][2].x=8.5; pAppFrame->m_VarCalib.markarray3D[0][3].x=9; pAppFrame->m_VarCalib.markarray3D[0][4].x=6.5; pAppFrame->m_VarCalib.markarray3D[0][5].x=5.5;

Page 301: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

pAppFrame->m_VarCalib.markarray3D[0][6].x=5; pAppFrame->m_VarCalib.markarray3D[0][7].x=-8; pAppFrame->m_VarCalib.markarray3D[0][8].x=-7.5; pAppFrame->m_VarCalib.markarray3D[0][9].x=-6.5; pAppFrame->m_VarCalib.markarray3D[0][10].x=-6; pAppFrame->m_VarCalib.markarray3D[0][11].x=-8.5; pAppFrame->m_VarCalib.markarray3D[0][12].x=-9.5; pAppFrame->m_VarCalib.markarray3D[0][13].x=-10; pAppFrame->m_VarCalib.markarray3D[0][14].x=3; pAppFrame->m_VarCalib.markarray3D[0][15].x=1; pAppFrame->m_VarCalib.markarray3D[0][16].x=4; pAppFrame->m_VarCalib.markarray3D[0][17].x=3; pAppFrame->m_VarCalib.markarray3D[0][18].x=1; pAppFrame->m_VarCalib.markarray3D[0][19].x=0; pAppFrame->m_VarCalib.markarray3D[0][20].x=4; pAppFrame->m_VarCalib.markarray3D[0][21].x=3; pAppFrame->m_VarCalib.markarray3D[0][22].x=1; pAppFrame->m_VarCalib.markarray3D[0][23].x=0; pAppFrame->m_VarCalib.markarray3D[0][24].x=3; pAppFrame->m_VarCalib.markarray3D[0][25].x=1; pAppFrame->m_VarCalib.markarray3D[0][26].x=-1; pAppFrame->m_VarCalib.markarray3D[0][27].x=-5; pAppFrame->m_VarCalib.markarray3D[0][28].x=-1; pAppFrame->m_VarCalib.markarray3D[0][29].x=-5; pAppFrame->m_VarCalib.markarray3D[0][30].x=-1; pAppFrame->m_VarCalib.markarray3D[0][31].x=-5; pAppFrame->m_VarCalib.markarray3D[0][32].x=-1; pAppFrame->m_VarCalib.markarray3D[0][33].x=-5; pAppFrame->m_VarCalib.markarray3D[0][0].y=-2; pAppFrame->m_VarCalib.markarray3D[0][1].y=-1; pAppFrame->m_VarCalib.markarray3D[0][2].y=1; pAppFrame->m_VarCalib.markarray3D[0][3].y=2; pAppFrame->m_VarCalib.markarray3D[0][4].y=-1; pAppFrame->m_VarCalib.markarray3D[0][5].y=1; pAppFrame->m_VarCalib.markarray3D[0][6].y=2; pAppFrame->m_VarCalib.markarray3D[0][7].y=-2; pAppFrame->m_VarCalib.markarray3D[0][8].y=-1; pAppFrame->m_VarCalib.markarray3D[0][9].y=1; pAppFrame->m_VarCalib.markarray3D[0][10].y=2; pAppFrame->m_VarCalib.markarray3D[0][11].y=-1; pAppFrame->m_VarCalib.markarray3D[0][12].y=1; pAppFrame->m_VarCalib.markarray3D[0][13].y=2; pAppFrame->m_VarCalib.markarray3D[0][14].y=2; pAppFrame->m_VarCalib.markarray3D[0][15].y=2;

pAppFrame->m_VarCalib.markarray3D[0][16].y=1; pAppFrame->m_VarCalib.markarray3D[0][17].y=1; pAppFrame->m_VarCalib.markarray3D[0][18].y=1; pAppFrame->m_VarCalib.markarray3D[0][19].y=1; pAppFrame->m_VarCalib.markarray3D[0][20].y=-1; pAppFrame->m_VarCalib.markarray3D[0][21].y=-1; pAppFrame->m_VarCalib.markarray3D[0][22].y=-1; pAppFrame->m_VarCalib.markarray3D[0][23].y=-1; pAppFrame->m_VarCalib.markarray3D[0][24].y=-2; pAppFrame->m_VarCalib.markarray3D[0][25].y=-2; pAppFrame->m_VarCalib.markarray3D[0][26].y=2; pAppFrame->m_VarCalib.markarray3D[0][27].y=2; pAppFrame->m_VarCalib.markarray3D[0][28].y=1; pAppFrame->m_VarCalib.markarray3D[0][29].y=1; pAppFrame->m_VarCalib.markarray3D[0][30].y=-1; pAppFrame->m_VarCalib.markarray3D[0][31].y=-1; pAppFrame->m_VarCalib.markarray3D[0][32].y=-2; pAppFrame->m_VarCalib.markarray3D[0][33].y=-2; //Triangle pAppFrame->m_VarCalib.markarray3D[1][0].x=4*1.414; pAppFrame->m_VarCalib.markarray3D[1][1].x=4.75*1.414; pAppFrame->m_VarCalib.markarray3D[1][2].x=6.25*1.414; pAppFrame->m_VarCalib.markarray3D[1][3].x=7*1.414; pAppFrame->m_VarCalib.markarray3D[1][4].x=4.25*1.414; pAppFrame->m_VarCalib.markarray3D[1][5].x=4.75*1.414; pAppFrame->m_VarCalib.markarray3D[1][6].x=5*1.414; pAppFrame->m_VarCalib.markarray3D[1][7].x=-3.5*1.414; pAppFrame->m_VarCalib.markarray3D[1][8].x=-2.75*1.414; pAppFrame->m_VarCalib.markarray3D[1][9].x=-1.25*1.414; pAppFrame->m_VarCalib.markarray3D[1][10].x=-0.5*1.414; pAppFrame->m_VarCalib.markarray3D[1][11].x=-3.25*1.414; pAppFrame->m_VarCalib.markarray3D[1][12].x=-2.75*1.414; pAppFrame->m_VarCalib.markarray3D[1][13].x=-2.5*1.414; //cross pAppFrame->m_VarCalib.markarray3D[1][14].x=4*1.414; pAppFrame->m_VarCalib.markarray3D[1][15].x=3*1.414; pAppFrame->m_VarCalib.markarray3D[1][16].x=4*1.414; pAppFrame->m_VarCalib.markarray3D[1][17].x=3.5*1.414; pAppFrame->m_VarCalib.markarray3D[1][18].x=2.5*1.414; pAppFrame->m_VarCalib.markarray3D[1][19].x=2*1.414; pAppFrame->m_VarCalib.markarray3D[1][20].x=3*1.414; pAppFrame->m_VarCalib.markarray3D[1][21].x=2.5*1.414;

Page 302: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

pAppFrame->m_VarCalib.markarray3D[1][22].x=1.5*1.414; pAppFrame->m_VarCalib.markarray3D[1][23].x=1*1.414; pAppFrame->m_VarCalib.markarray3D[1][24].x=2*1.414; pAppFrame->m_VarCalib.markarray3D[1][25].x=1*1.414; //Square pAppFrame->m_VarCalib.markarray3D[1][26].x=2*1.414; pAppFrame->m_VarCalib.markarray3D[1][27].x=0; pAppFrame->m_VarCalib.markarray3D[1][28].x=1.5*1.414; pAppFrame->m_VarCalib.markarray3D[1][29].x=-0.5*1.414; pAppFrame->m_VarCalib.markarray3D[1][30].x=0.5*1.414; pAppFrame->m_VarCalib.markarray3D[1][31].x=-1.5*1.414; pAppFrame->m_VarCalib.markarray3D[1][32].x=0; pAppFrame->m_VarCalib.markarray3D[1][33].x=-2*1.414; //Triangle pAppFrame->m_VarCalib.markarray3D[1][0].y=-8*1.414; pAppFrame->m_VarCalib.markarray3D[1][1].y=-7.75*1.414; pAppFrame->m_VarCalib.markarray3D[1][2].y=-7.25*1.414; pAppFrame->m_VarCalib.markarray3D[1][3].y=-7*1.414; pAppFrame->m_VarCalib.markarray3D[1][4].y=-7.25*1.414; pAppFrame->m_VarCalib.markarray3D[1][5].y=-5.75*1.414; pAppFrame->m_VarCalib.markarray3D[1][6].y=-5*1.414; pAppFrame->m_VarCalib.markarray3D[1][7].y=-0.5*1.414; pAppFrame->m_VarCalib.markarray3D[1][8].y=-0.25*1.414; pAppFrame->m_VarCalib.markarray3D[1][9].y=0.25*1.414; pAppFrame->m_VarCalib.markarray3D[1][10].y=0.5*1.414; pAppFrame->m_VarCalib.markarray3D[1][11].y=0.25*1.414; pAppFrame->m_VarCalib.markarray3D[1][12].y=1.75*1.414; pAppFrame->m_VarCalib.markarray3D[1][13].y=2.5*1.414; //Cross pAppFrame->m_VarCalib.markarray3D[1][14].y=-4*1.414; pAppFrame->m_VarCalib.markarray3D[1][15].y=-3*1.414; pAppFrame->m_VarCalib.markarray3D[1][16].y=-5*1.414; pAppFrame->m_VarCalib.markarray3D[1][17].y=-4.5*1.414; pAppFrame->m_VarCalib.markarray3D[1][18].y=-3.5*1.414; pAppFrame->m_VarCalib.markarray3D[1][19].y=-3*1.414; pAppFrame->m_VarCalib.markarray3D[1][20].y=-6*1.414; pAppFrame->m_VarCalib.markarray3D[1][21].y=-5.5*1.414; pAppFrame->m_VarCalib.markarray3D[1][22].y=-4.5*1.414; pAppFrame->m_VarCalib.markarray3D[1][23].y=-4*1.414; pAppFrame->m_VarCalib.markarray3D[1][24].y=-6*1.414; pAppFrame->m_VarCalib.markarray3D[1][25].y=-5*1.414; //Square pAppFrame->m_VarCalib.markarray3D[1][26].y=-2*1.414;

pAppFrame->m_VarCalib.markarray3D[1][27].y=0; pAppFrame->m_VarCalib.markarray3D[1][28].y=-2.5*1.414; pAppFrame->m_VarCalib.markarray3D[1][29].y=-0.5*1.414; pAppFrame->m_VarCalib.markarray3D[1][30].y=-3.5*1.414; pAppFrame->m_VarCalib.markarray3D[1][31].y=-1.5*1.414; pAppFrame->m_VarCalib.markarray3D[1][32].y=-4*1.414; pAppFrame->m_VarCalib.markarray3D[1][33].y=-2*1.414; //Testing movement(1);//m_iedit2-1); m_x=pAppFrame->m_VarCalib.tx; m_y=pAppFrame->m_VarCalib.ty; m_r=pAppFrame->m_VarCalib.r; UpdateData(FALSE); } void CDCorrect::OnButton1() { // TODO: Add your control notification handler code here //Correct CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); UpdateData(TRUE); CMDIFrameWnd* pChild = (CMDIFrameWnd*) pAppFrame->MDIGetActive(); CProjectDoc* pDoc = (CProjectDoc*) pChild->GetActiveDocument(); LPBITMAPINFOHEADER lpDIBHdr_in = (LPBITMAPINFOHEADER) GlobalLock( pDoc->m_hDIB); HDIB hNewDIB = NULL; HDIB hNewDIB2 = NULL; BeginWaitCursor();

Page 303: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

hNewDIB = (HDIB) CopyHandle(pDoc->m_hDIB); // copy the input DIB LPBITMAPINFOHEADER lpDIBHdr_out = (LPBITMAPINFOHEADER) GlobalLock( hNewDIB); hNewDIB2 = (HDIB) CopyHandle(pDoc->m_hDIB); // copy the input DIB LPBITMAPINFOHEADER lpDIBHdr_out2 = (LPBITMAPINFOHEADER) GlobalLock( hNewDIB2); int status = translateDib(lpDIBHdr_in, lpDIBHdr_out,(double) m_x,(double) - m_y, 0); double theta = ANG_DEG_RAD(m_r); int status2 = rotateDib(lpDIBHdr_out, lpDIBHdr_out2, theta, m_xr, m_yr, 0, 0); ::GlobalUnlock(pDoc->m_hDIB); GlobalUnlock(hNewDIB); GlobalUnlock(hNewDIB2); if (!status) { CString title = pDoc->GetTitle(); title = title + "_Corrected"; pAppFrame->OpenNewDocument( hNewDIB2, TRUE, (const char*) title); } else ::GlobalFree((HGLOBAL) hNewDIB); EndWaitCursor(); // message beep pAppFrame->OnEnd(); pAppFrame->m_VarCalib.made[m_iedit2-1].final3D=TRUE; final3D.LoadBitmaps(IDB_YES,0,0,0); final3D.InvalidateRect(NULL,TRUE); UpdateData(FALSE); }

void CDCorrect::OnOK() { // TODO: Add extra validation here CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); pAppFrame->m_VarCalib.flag=FALSE; CDialog::OnOK(); } ///////////////////////////////////////////////////////////////////////////// // // CDrotation dialog // Dialog class to ratation of a dib // ///////////////////////////////////////////////////////////////////////////// CDrotation::CDrotation(CWnd* pParent /*=NULL*/) : CDialog(CDrotation::IDD, pParent) { //{{AFX_DATA_INIT(CDrotation) m_bg = 0;

ip -1; m_ = m_rx = 0.0; m_ry = 0.0; m_theta = 0.0; m_center = FALSE; //}}AFX_DATA_INIT } void CDrotation::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDrotation) DDX_Text(pDX, IDC_BG, m_bg); DDV_MinMaxInt(pDX, m_bg, 0, 255); DDX_Radio(pDX, IDC_IP, m_ip); DDX_Text(pDX, IDC_RX, m_rx); DDX_Text(pDX, IDC_RY, m_ry);

Page 304: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

DDX_Text(pDX, IDC_THETA, m_theta); DDV_MinMaxDouble(pDX, m_theta, -360.0, 360.0); DDX_Check(pDX, IDC_CENTER, m_center); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDrotation, CDialog) //{{AFX_MSG_MAP(CDrotation) ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN, OnDeltaposSpin) ON_BN_CLICKED(IDC_CENTER, OnCenter) ON_COMMAND(ID_PREPROCESSING_IMAGEMIRROR, OnPreprocessingImagemirror) ON_UPDATE_COMMAND_UI(ID_PREPROCESSING_IMAGEMIRROR, OnUpdatePreprocessingImagemirror) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDrotation message handlers BOOL CDrotation::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here CenterWindow(); if (m_center) { GetDlgItem(IDC_RX)->EnableWindow(FALSE); GetDlgItem(IDC_RY)->EnableWindow(FALSE); m_rx = m_xsize/2.0; m_ry = m_ysize/2.0; UpdateData(FALSE); } else { GetDlgItem(IDC_RX)->EnableWindow(TRUE); GetDlgItem(IDC_RY)->EnableWindow(TRUE); } return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CDrotation::OnDeltaposSpin(NMHDR* pNMHDR, LRESULT* pResult) { NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;

// TODO: Add your control notification handler code here UpdateData(TRUE); m_theta -= (double) (pNMUpDown->iDelta); if (m_theta < -360.0) m_theta = 360.0; else if (m_theta > 360.0) m_theta = -360.0; UpdateData(FALSE); *pResult = 0; } void CDrotation::OnCenter() { // TODO: Add your control notification handler code here UpdateData(TRUE); if (m_center) { GetDlgItem(IDC_RX)->EnableWindow(FALSE); GetDlgItem(IDC_RY)->EnableWindow(FALSE); m_rx = m_xsize/2.0; m_ry = m_ysize/2.0; UpdateData(FALSE); } else { GetDlgItem(IDC_RX)->EnableWindow(TRUE); GetDlgItem(IDC_RY)->EnableWindow(TRUE); } } void CDrotation::OnPreprocessingImagemirror() { // TODO: Add your command handler code here } void CDrotation::OnUpdatePreprocessingImagemirror(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here } ///////////////////////////////////////////////////////////////////////////// // CDtranslation dialog CDtranslation::CDtranslation(CWnd* pParent /*=NULL*/) : CDialog(CDtranslation::IDD, pParent) {

Page 305: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

//{{AFX_DATA_INIT(CDtranslation) m_tx = 0; m_ty = 0; m_bg = 0; //}}AFX_DATA_INIT } void CDtranslation::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDtranslation) DDX_Text(pDX, IDC_TX, m_tx); DDX_Text(pDX, IDC_TY, m_ty); DDX_Text(pDX, IDC_BG, m_bg); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDtranslation, CDialog) //{{AFX_MSG_MAP(CDtranslation) // NOTE: the ClassWizard will add message map macros here //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDtranslation message handlers detect_points.h void p1(mark_3D t8,mark_3D t9,mark_3D t10,mark_3D t11,mark_3D t12, mark_3D t13,mark_3D t14); void p2(mark_3D q1,mark_3D q2,mark_3D q3,mark_3D q4,mark_3D q5,mark_3D q6, mark_3D q7,mark_3D q8); void p3(mark_3D c1,mark_3D c2,mark_3D c3,mark_3D c4,mark_3D c5,mark_3D c6, mark_3D c7,mark_3D c8,mark_3D c9, mark_3D c10,mark_3D c11,mark_3D c12); void p4(mark_3D t1,mark_3D t2,mark_3D t3,mark_3D t4,mark_3D t5,mark_3D t6 ,mark_3D t7); void movement(int pos);

detect_points.cpp #include "stdafx.h" #include "project.h" #include "MainFrm.h" #include <stdio.h> #include <math.h> #include <stdlib.h> #include "gdefs.h" #include "detect_points.h" void p1(mark_3D t8,mark_3D t9,mark_3D t10,mark_3D t11,mark_3D t12, mark_3D t13,mark_3D t14) { p4(t8,t9,t10,t11,t12,t13,t14); return; } void p2(mark_3D q1,mark_3D q2,mark_3D q3,mark_3D q4,mark_3D q5,mark_3D q6, mark_3D q7,mark_3D q8) { CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); //Square double aux,aux2; mark_3D point,point2; //first point.x=(q6.x+q5.x)/2; point.y=(q6.y+q5.y)/2; aux=(q4.x+q3.x)/2; aux2=(q4.y+q3.y)/2; point.x=(point.x+aux)/2; point.y=(point.y+aux2)/2; //Second point2.x=(q2.x+q8.x)/2;

Page 306: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

point2.y=(q2.y+q8.y)/2; aux=(q1.x+q7.x)/2; aux2=(q1.y+q7.y)/2; point2.x=(point2.x+aux)/2; point2.y=(point2.y+aux2)/2; pAppFrame->m_VarCalib.xxxx=(point.x+point2.x)/2; pAppFrame->m_VarCalib.yyyy=(point.y+point2.y)/2; return; } void p3(mark_3D c1,mark_3D c2,mark_3D c3,mark_3D c4,mark_3D c5,mark_3D c6,mark_3D c7,mark_3D c8,mark_3D c9, mark_3D c10,mark_3D c11,mark_3D c12) { CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); //Cross double aux,aux2; mark_3D point,point2,point3; //first point.x=(c12.x+c11.x)/2; point.y=(c12.y+c11.y)/2; aux=(c2.x+c1.x)/2; aux2=(c2.y+c1.y)/2; point.x=(point.x+aux)/2; point.y=(point.y+aux2)/2; //Second point2.x=(c6.x+c10.x)/2; point2.y=(c6.y+c10.y)/2; aux=(c3.x+c7.x)/2; aux2=(c3.y+c7.y)/2; point2.x=(point2.x+aux)/2; point2.y=(point2.y+aux2)/2;

//Third point3.x=(c8.x+c9.x)/2; point3.y=(c8.y+c9.y)/2; aux=(c4.x+c5.x)/2; aux2=(c4.y+c5.y)/2; point3.x=(point3.x+aux)/2; point3.y=(point3.y+aux2)/2; pAppFrame->m_VarCalib.xxxx=((point.x+point2.x)/2 + point3.x)/2; pAppFrame->m_VarCalib.yyyy=((point.y+point2.y)/2 + point3.y)/2; return; } void p4(mark_3D t1,mark_3D t2,mark_3D t3,mark_3D t4,mark_3D t5,mark_3D t6,mark_3D t7) { CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); //Triangle double aux,aux2; mark_3D point,point2; //first point.x=(t5.x+t2.x)/2; point.y=(t5.y+t2.y)/2; aux=(t6.x+t3.x)/2; aux2=(t6.y+t3.y)/2; point.x=(point.x+aux)/2; point.y=(point.y+aux2)/2; //Second point2.x=(t7.x+t4.x)/2; point2.y=(t7.y+t4.y)/2; point2.x=(point2.x+t1.x)/2; point2.y=(point2.y+t1.y)/2;

Page 307: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

pAppFrame->m_VarCalib.xxxx=(point.x+point2.x)/2; pAppFrame->m_VarCalib.yyyy=(point.y+point2.y)/2; return; } void movement(int pos) { CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); mark_3D point1,point2,point3,point4; mark_3D ref_point1,ref_point2,ref_point3,ref_point4; //Image Pair wanted p2( pAppFrame->m_VarCalib.markarray3D[pos][26],pAppFrame->m_VarCalib.markarray3D[pos][27], pAppFrame->m_VarCalib.markarray3D[pos][28],pAppFrame->m_VarCalib.markarray3D[pos][29], pAppFrame->m_VarCalib.markarray3D[pos][30],pAppFrame->m_VarCalib.markarray3D[pos][31], pAppFrame->m_VarCalib.markarray3D[pos][32],pAppFrame->m_VarCalib.markarray3D[pos][33] ); point2.x=pAppFrame->m_VarCalib.xxxx; point2.y=pAppFrame->m_VarCalib.yyyy; p3(pAppFrame->m_VarCalib.markarray3D[pos][14],pAppFrame->m_VarCalib.markarray3D[pos][15], pAppFrame->m_VarCalib.markarray3D[pos][16],pAppFrame->m_VarCalib.markarray3D[pos][17], pAppFrame->m_VarCalib.markarray3D[pos][18],pAppFrame->m_VarCalib.markarray3D[pos][19], pAppFrame->m_VarCalib.markarray3D[pos][20],pAppFrame->m_VarCalib.markarray3D[pos][21], pAppFrame->m_VarCalib.markarray3D[pos][22],pAppFrame->m_VarCalib.markarray3D[pos][23], pAppFrame->m_VarCalib.markarray3D[pos][24],pAppFrame->m_VarCalib.markarray3D[pos][25] );

point3.x=pAppFrame->m_VarCalib.xxxx; point3.y=pAppFrame->m_VarCalib.yyyy; p4(pAppFrame->m_VarCalib.markarray3D[pos][0],pAppFrame->m_VarCalib.markarray3D[pos][1], pAppFrame->m_VarCalib.markarray3D[pos][2],pAppFrame->m_VarCalib.markarray3D[pos][3], pAppFrame->m_VarCalib.markarray3D[pos][4],pAppFrame->m_VarCalib.markarray3D[pos][5], pAppFrame->m_VarCalib.markarray3D[pos][6]); point4.x=pAppFrame->m_VarCalib.xxxx; point4.y=pAppFrame->m_VarCalib.yyyy; p1(pAppFrame->m_VarCalib.markarray3D[pos][7],pAppFrame->m_VarCalib.markarray3D[pos][8], pAppFrame->m_VarCalib.markarray3D[pos][9],pAppFrame->m_VarCalib.markarray3D[pos][10], pAppFrame->m_VarCalib.markarray3D[pos][11],pAppFrame->m_VarCalib.markarray3D[pos][12], pAppFrame->m_VarCalib.markarray3D[pos][13]); point1.x=pAppFrame->m_VarCalib.xxxx; point1.y=pAppFrame->m_VarCalib.yyyy; if (!pAppFrame->m_VarCalib.flag){ pAppFrame->m_VarCalib.flag=TRUE; pos=pAppFrame->m_VarCalib.reference_number; //Referência// p2( pAppFrame->m_VarCalib.markarray3D[pos][26],pAppFrame->m_VarCalib.markarray3D[pos][27], pAppFrame->m_VarCalib.markarray3D[pos][28],pAppFrame->m_VarCalib.markarray3D[pos][29], pAppFrame->m_VarCalib.markarray3D[pos][30],pAppFrame->m_VarCalib.markarray3D[pos][31], pAppFrame->m_VarCalib.markarray3D[pos][32],pAppFrame->m_VarCalib.markarray3D[pos][33] ); ref_point2.x=pAppFrame->m_VarCalib.xxxx; ref_point2.y=pAppFrame->m_VarCalib.yyyy;

Page 308: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

p3(pAppFrame->m_VarCalib.markarray3D[pos][14],pAppFrame->m_VarCalib.markarray3D[pos][15], pAppFrame->m_VarCalib.markarray3D[pos][16],pAppFrame->m_VarCalib.markarray3D[pos][17], pAppFrame->m_VarCalib.markarray3D[pos][18],pAppFrame->m_VarCalib.markarray3D[pos][19], pAppFrame->m_VarCalib.markarray3D[pos][20],pAppFrame->m_VarCalib.markarray3D[pos][21], pAppFrame->m_VarCalib.markarray3D[pos][22],pAppFrame->m_VarCalib.markarray3D[pos][23], pAppFrame->m_VarCalib.markarray3D[pos][24],pAppFrame->m_VarCalib.markarray3D[pos][25] ); ref_point3.x=pAppFrame->m_VarCalib.xxxx; ref_point3.y=pAppFrame->m_VarCalib.yyyy; p4(pAppFrame->m_VarCalib.markarray3D[pos][0],pAppFrame->m_VarCalib.markarray3D[pos][1], pAppFrame->m_VarCalib.markarray3D[pos][2],pAppFrame->m_VarCalib.markarray3D[pos][3], pAppFrame->m_VarCalib.markarray3D[pos][4],pAppFrame->m_VarCalib.markarray3D[pos][5], pAppFrame->m_VarCalib.markarray3D[pos][6]); ref_point4.x=pAppFrame->m_VarCalib.xxxx; ref_point4.y=pAppFrame->m_VarCalib.yyyy; p1(pAppFrame->m_VarCalib.markarray3D[pos][7],pAppFrame->m_VarCalib.markarray3D[pos][8], pAppFrame->m_VarCalib.markarray3D[pos][9],pAppFrame->m_VarCalib.markarray3D[pos][10], pAppFrame->m_VarCalib.markarray3D[pos][11],pAppFrame->m_VarCalib.markarray3D[pos][12], pAppFrame->m_VarCalib.markarray3D[pos][13]); ref_point1.x=pAppFrame->m_VarCalib.xxxx; ref_point1.y=pAppFrame->m_VarCalib.yyyy; } //Translation pAppFrame->m_VarCalib.tx=point3.x-ref_point3.x; pAppFrame->m_VarCalib.ty=point3.y-ref_point3.y;

//Rotation double teta1,teta2,teta3,ref_teta1,ref_teta2,ref_teta3; teta1=-(point3.y-point1.y)/(point3.x-point1.x);//p1p3 teta2=-(point2.y-point4.y)/(point2.x-point4.x);//p2p4 teta3=-(point1.y-point4.y)/(point1.x-point4.x);//p1p4 ref_teta1=-(ref_point3.y-ref_point1.y)/(ref_point3.x-ref_point1.x);//p1p3 ref_teta2=-(ref_point2.y-ref_point4.y)/(ref_point2.x-ref_point4.x);//p2p4 ref_teta3=-(ref_point1.y-ref_point4.y)/(ref_point1.x-ref_point4.x);//p1p4 pAppFrame->m_VarCalib.r=ANG_RAD_DEG(atan((teta1+teta2+teta3)/3-(ref_teta1+ref_teta2+ref_teta3)/3)); return; } Mainfrm.h //Nuclear// #include "acquire.h" #include "conversion2x2D_3D.h" //Nuclear// //Nuclear// CVariaveisNuclear m_VarNuclear; CVariaveisCalib m_VarCalib; //Nuclear// Mainfrm.cpp //Nuclear// #include <afxwin.h> #include "DAcquire.h" #include "DCalibration.h" #include "Splash1.h" #include "input.h" #include "calib_sim3.h" #include "calcamera.h"

Page 309: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

#define BUFFERSIZEX 640 #define BUFFERSIZEY 480 #define BUFFERSIZEBAND 1 //Nuclear// CMainFrame::CMainFrame() { // TODO: add member initialization code here register int i, j; m_sizeChild = CSize(-1,-1); m_storeDIB = NULL; m_operation = 0; // kernel parameters m_Kernel = int_matrix(MAX_XY-1, MAX_XY-1); for(i = 0; i < MAX_XY; i++) for(j = 0; j < MAX_XY; j++) m_Kernel[i][j] = (int) 0; m_sizeKernel = CSize(DefaultKernelDX, DefaultKernelDY); // parameters for movies m_movieN = 0; // others parameters m_Interactive = 0; m_modeless = FALSE; //nuclear// for (i=0;i<300;i++) { m_VarCalib.array[i][0]=0.0; m_VarCalib.array[i][1]=0.0; m_VarCalib.out_array[i][0]=0.0; m_VarCalib.out_array[i][1]=0.0; m_VarCalib.out_array[i][2]=0.0; } //nuclear// // set default aplication options

defaultValues(); } void CMainFrame::OnCalibSetParams() { // TODO: Add your command handler code here CDCalibration dlg; if (dlg.DoModal() == IDOK) calibrate (dlg.m_cksave, dlg.m_isx, dlg.m_ckFindCenter, dlg.m_icx, dlg.m_icy , dlg.m_idx, dlg.m_idy, dlg.m_itolerance, dlg.m_strInputFile, dlg.m_strOutputFile); } void CMainFrame::OnCalibSimul() { // TODO: Add your command handler code here CDCalib_simul dlg; if (dlg.DoModal() == IDOK) simcam3(dlg.m_inpoint, dlg.m_izw, dlg.m_dtx, dlg.m_dty, dlg.m_dtz , dlg.m_drotx, dlg.m_droty, dlg.m_drotz, dlg.m_df, dlg.m_ddx, dlg.m_ddy , dlg.m_dsx, dlg.m_dk1, dlg.m_inx, dlg.m_iny, dlg.m_iCX, dlg.m_iCY , dlg.m_strOutputfile, dlg.m_cksave, dlg.m_ckshow); } void CMainFrame::OnMednuclearCalibracaoSetparams() { // TODO: Add your command handler code here // TODO: Add your command handler code here CDCalibration dlg; if (dlg.DoModal() == IDOK) calibrate (dlg.m_cksave, dlg.m_isx, dlg.m_ckFindCenter, dlg.m_icx, dlg.m_icy

Page 310: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

, dlg.m_idx, dlg.m_idy, dlg.m_itolerance, dlg.m_strInputFile, dlg.m_strOutputFile); } void CMainFrame::OnMednuclearCalibracaoSimulate() { // TODO: Add your command handler code here CDCalib_simul dlg; if (dlg.DoModal() == IDOK) simcam3(dlg.m_inpoint, dlg.m_izw, dlg.m_dtx, dlg.m_dty, dlg.m_dtz , dlg.m_drotx, dlg.m_droty, dlg.m_drotz, dlg.m_df, dlg.m_ddx, dlg.m_ddy , dlg.m_dsx, dlg.m_dk1, dlg.m_inx, dlg.m_iny, dlg.m_iCX, dlg.m_iCY , dlg.m_strOutputfile, dlg.m_cksave, dlg.m_ckshow); } void CMainFrame::OnMednuclearCalibracaoInputpoints() { // TODO: Add your command handler code here CDCalib_input dlg; if (dlg.DoModal() == IDOK) format(dlg.m_strInputfile, dlg.m_strOutputfile); } void CMainFrame::OnMednuclearAquisioAdquirir() { // TODO: Add your command handler code here //Opens Dialog box to begin acquisition and sets global variables// DWORD m_myID = GetCurrentThreadId(); CDAcquire dialog; if (dialog.DoModal()== IDOK) { UpdateData(TRUE); if (dialog.m_iradio1==0) {

m_VarNuclear.m_bSequencia=TRUE; //Number of Images// m_VarNuclear.m_iNbFrames=dialog.m_iedit5; //Time Between// m_VarNuclear.m_bTimeBetween=dialog.m_bcheck5; if ( dialog.m_bcheck5) { m_VarNuclear.m_iTimeBetween=dialog.m_iedit7; if (dialog.m_cscombo10=="seg") m_VarNuclear.m_dTimeBetweenUnit=1; else if (dialog.m_cscombo10=="min") m_VarNuclear.m_dTimeBetweenUnit=60; else if (dialog.m_cscombo10=="ms") m_VarNuclear.m_dTimeBetweenUnit=1/1000; } m_VarNuclear.m_csFileName=dialog.m_csedit4; } else { m_VarNuclear.m_bSequencia=FALSE; //Shot m_VarNuclear.m_iNbFrames=dialog.m_iedit8; if ( m_VarNuclear.m_csImage != "bmp") m_VarNuclear.m_bVisualize=FALSE; else m_VarNuclear.m_bVisualize=dialog.m_bcheck3; if (dialog.m_iradio3==0) { m_VarNuclear.m_bTriggerMode=FALSE; m_VarNuclear.m_iInitialTime=dialog.m_iedit1; if (dialog.m_cscombo5=="seg") m_VarNuclear.m_dInitialTimeUnit=1; else if (dialog.m_cscombo5=="min") m_VarNuclear.m_dInitialTimeUnit=60; else if (dialog.m_cscombo5=="ms") m_VarNuclear.m_dInitialTimeUnit=1/1000; m_VarNuclear.m_iBetweenTime=dialog.m_iedit2; if (dialog.m_cscombo6=="seg")

Page 311: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

m_VarNuclear.m_dBetweenTimeUnit=1; else if (dialog.m_cscombo6=="min") m_VarNuclear.m_dBetweenTimeUnit=60;

nd* pChild = (CMDIFrameWnd*) MDIGetActive();

ociate with View CMDIChildWnd* pMDIChildWnd = MDIGetActive();

else if (dialog.m_cscombo6=="ms") m_VarNuclear.m_dBetweenTimeUnit=1/1000; } else { m_VarNuclear.m_bTriggerMode=TRUE; if ( dialog.m_bcheck1) { if (dialog.m_cscombo7 == "SPACE" ) m_VarNuclear.m_csTecla= " " ; else m_VarNuclear.m_csTecla=dialog.m_cscombo7; m_VarNuclear.m_bTecla=TRUE; } if ( dialog.m_bcheck2) { m_VarNuclear.m_csTriggerExterno=dialog.m_cscombo8; m_VarNuclear.m_bTriggerExterno=TRUE; } } m_VarNuclear.m_csFileName=dialog.m_csedit3; } } else return; ////////////////////////////////////////////////////////////////////////////////////////// //Tests if it is one or 2 cameras/////////////////////////////////////////////////////////

if (m_VarNuclear.m_iCamera==1) { m_VarNuclear.m_CameraNum1=TRUE; m_VarNuclear.m_CameraNum2=FALSE; //Opens 1ª frame MDI SendMessage( WM_COMMAND, ID_FILE_NEW ); //pointer to Doc CMDIFrameW CProjectDoc* pDoc = (CProjectDoc*) pChild->GetActiveDocument(); pDoc->SetTitle("Camera"); m_VarNuclear.m_bvideo = TRUE; //Activates MDI to ass

if (pMDIChildWnd == NULL) { MessageBox ("Não existe uma MDI child frame activa", "", MB_ICONERROR); return; } //Associates View to frame 1 CView* pView = pMDIChildWnd->GetActiveView(); ASSERT(pView != NULL); //Handle of the window// m_VarNuclear.m_hWndNuclear = pView->m_hWnd; ///Initialization of frame grabber////// /* allocation of MIL application. */ MappAlloc(M_DEFAULT, &m_VarNuclear.MilApplication); MappControl(M_ERROR,M_PRINT_DISABLE);

/* allocation of MIL system. */ MsysAlloc(M_DEF_SYSTEM_TYPE, M_DEV0, M_DEFAULT, &m_VarNuclear.MilSystem); /* allocation of MIL display. */

Page 312: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

MdispAlloc(m_VarNuclear.MilSystem, M_DEFAULT, M_DEF_DISPLAY_FORMAT,m_VarNuclear.m_lDispMode, &m_VarNuclear.MilDisplay[0]); /* allocation of MIL digitizer and size of target image*/ if (MsysInquire(m_VarNuclear.MilSystem, M_DIGITIZER_NUM, M_NULL) > 0) { MdigAlloc(m_VarNuclear.MilSystem, M_DEV0,m_VarNuclear.m_pcDataFormat , M_DEFAULT, &m_VarNuclear.MilDigitizer); (long)(MdigInquire(m_VarNuclear.MilDigitizer, M_SIZE_X, &m_VarNuclear.BufSizeX) ); (long)(MdigInquire(m_VarNuclear.MilDigitizer, M_SIZE_Y, &m_VarNuclear.BufSizeY) ); } else { m_VarNuclear.MilDigitizer = M_NULL; m_VarNuclear.BufSizeX = BUFFERSIZEX; m_VarNuclear.BufSizeY = BUFFERSIZEY; m_VarNuclear.BufSizeBand = BUFFERSIZEBAND; } //ERROR////////////////////////////////////// MappGetError(M_CURRENT,&m_VarNuclear.ErrorPtr); if ( m_VarNuclear.ErrorPtr != M_NULL) { MessageBox("Some kind of invalide parameter","Error Reporting",MB_OK); //CWnd* destrwnd; //destrwnd->Attach(m_VarNuclear.m_hWndNuclear); //MDIActivate(destrwnd); CMDIFrameWnd* frame = (CMDIFrameWnd*) MDIGetActive(); CProjectDoc* documento = (CProjectDoc*) frame->GetActiveDocument(); documento->OnCloseDocument(); return; } /////////////////////////////////////////////

//Size of the window/// CFrameWnd* pFrame = (CFrameWnd*) pView->GetParentFrame(); ASSERT(pFrame != NULL); pFrame->SetWindowPos(NULL, 0, 0,(UINT)(m_VarNuclear.BufSizeX* m_VarNuclear.m_dImageScale + 12),(UINT)(m_VarNuclear.BufSizeY* m_VarNuclear.m_dImageScale+ 31), SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE ); ////////////////////// /* Allocation of MIL buffer. */ if (m_VarNuclear.m_bDataTypeRGB == TRUE) { MbufAllocColor(m_VarNuclear.MilSystem, m_VarNuclear.BufSizeBand ,(long) (m_VarNuclear.BufSizeX*m_VarNuclear.m_dImageScale) , (long)(m_VarNuclear.BufSizeY*m_VarNuclear.m_dImageScale) , 8+M_UNSIGNED,M_IMAGE + M_DISP + M_GRAB , &m_VarNuclear.MilImage[0]); } else if (m_VarNuclear.m_bDataTypeRGB == FALSE) { MbufAlloc2d(m_VarNuclear.MilSystem ,(long) (m_VarNuclear.BufSizeX*m_VarNuclear.m_dImageScale ) ,(long) (m_VarNuclear.BufSizeY*m_VarNuclear.m_dImageScale) , 8 + M_UNSIGNED , M_IMAGE + M_DISP + M_GRAB , &m_VarNuclear.MilImage[0]); } /* Clear the buffer */ MbufClear(m_VarNuclear.MilImage[0],0); //Display initialization MdispSelectWindow(m_VarNuclear.MilDisplay[0], m_VarNuclear.MilImage[0], m_VarNuclear.m_hWndNuclear ); MdispControl(m_VarNuclear.MilDisplay[0], M_WINDOW_OVERLAP , M_ENABLE);

Page 313: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

//Image contrast.... MdigReference(m_VarNuclear.MilDigitizer,M_BRIGHTNESS_REF,m_VarNuclear.m_iBrightness); MdigReference(m_VarNuclear.MilDigitizer,M_CONTRAST_REF,m_VarNuclear.m_iContrast); MdigReference(m_VarNuclear.MilDigitizer,M_HUE_REF,m_VarNuclear.m_iHue); MdigReference(m_VarNuclear.MilDigitizer,M_SATURATION_REF,m_VarNuclear.m_iSaturation); //Digitizer initialization MdigControl(m_VarNuclear.MilDigitizer, M_GRAB_SCALE, m_VarNuclear.m_dImageScale); //ERROR//////////////////////////////////////

MappGetError(M_CURRENT,&m_V arNuclear.ErrorPtr);

if ( m_VarNuclear.ErrorPtr != M_NULL) { MessageBox("Some kind of invalide parameter","Error Reporting",MB_OK); //CWnd* destrwnd; //destrwnd->Attach(m_VarNuclear.m_hWndNuclear); //MDIActivate(destrwnd); CMDIFrameWnd* frame = (CMDIFrameWnd*) MDIGetActive(); CProjectDoc* documento = (CProjectDoc*) frame->GetActiveDocument(); documento->OnCloseDocument(); return; } ///////////////////////////////////////////// //Calls right function/// if (m_VarNuclear.m_bSequencia == TRUE) { // Print a message. //////////////////////////////////////

m_VarNuclear.dlg = new CDComents; if(m_VarNuclear.dlg != NULL) { BOOL ret = m_VarNuclear.dlg->Create(IDD_COMMENT,NULL); if(!ret) //Create failed. AfxMessageBox("Error creating Dialog"); m_VarNuclear.dlg->CenterWindow(); m_VarNuclear.dlg->ShowWindow(SW_SHOW); } else AfxMessageBox("Error Creating Dialog Object");

CEdit* edit=(CEdit*) m_VarNuclear.dlg->GetDlgItem(IDC_EDIT1); CButton* button=(CButton*) m_VarNuclear.dlg->GetDlgItem(IDC_BUTTON1); CButton* button2=(CButton*) m_VarNuclear.dlg->GetDlgItem(IDC_BUTTON2); CString aux; aux="Begin sequence acquisition "; edit->ReplaceSel( aux,FALSE ); aux=""; //////////////////////////////////////////////////////////// AfxBeginThread (SequenciaNuclear,(LPVOID) NULL , THREAD_PRIORITY_NORMAL); } else { if (m_VarNuclear.m_bTriggerMode == FALSE) { // Print a message. / m_VarNuclear.dlg = new CDComents; if(m_VarNuclear.dlg != NULL) {

Page 314: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

BOOL ret = m_VarNuclear.dlg->Create(IDD_COMMENT,NULL); if(!ret) //Create failed. AfxMessageBox("Error creating Dialog"); m_VarNuclear.dlg->CenterWindow(); m_VarNuclear.dlg->ShowWindow(SW_SHOW); } else AfxMessageBox("Error Creating Dialog Object"); CEdit* edit=(CEdit*) m_VarNuclear.dlg->GetDlgItem(IDC_EDIT1);

tion... ";

edit->ReplaceSel( aux,FALSE );

AfxBeginThread (ShotTemp,(LPVOID) m_myID , THREAD_PRIORITY_NORMAL);

CButton* button=(CButton*) m_VarNuclear.dlg->GetDlgItem(IDC_BUTTON1); CButton* button2=(CButton*) m_VarNuclear.dlg->GetDlgItem(IDC_BUTTON2); CString aux; char numero[4]; aux="Multiple shot acquisi aux+=(_itoa(m_VarNuclear.m_iNbFrames , numero, 10 )); aux+=" shot to be taken ";

aux="";

} else if (m_VarNuclear.m_bTriggerMode == TRUE) { // Print a message. ////////////////////////////////////// m_VarNuclear.dlg = new CDComents; if(m_VarNuclear.dlg != NULL) {

BOOL ret = m_VarNuclear.dlg->Create(IDD_COMMENT,NULL); if(!ret) //Create failed. AfxMessageBox("Error creating Dialog"); m_VarNuclear.dlg->CenterWindow(); m_VarNuclear.dlg->ShowWindow(SW_SHOW); } else AfxMessageBox("Error Creating Dialog Object"); CEdit* edit=(CEdit*) m_VarNuclear.dlg->GetDlgItem(IDC_EDIT1); CButton* button=(CButton*) m_VarNuclear.dlg->GetDlgItem(IDC_BUTTON1); CButton* button2=(CButton*) m_VarNuclear.dlg->GetDlgItem(IDC_BUTTON2); CString aux; aux="Begin acquisition "; edit->ReplaceSel( aux,FALSE ); aux=""; //////////////////////////////////////////////////////////// AfxBeginThread (ShotTrigger,(LPVOID) m_myID , THREAD_PRIORITY_NORMAL); } } } else if (m_VarNuclear.m_iCamera==2) { m_VarNuclear.m_CameraNum1=TRUE; m_VarNuclear.m_CameraNum2=TRUE; m_VarNuclear.m_bvideo = TRUE; //Opens 1ª frame MDI SendMessage( WM_COMMAND, ID_FILE_NEW ); //pointer to Doc CMDIFrameWnd* pChild = (CMDIFrameWnd*) MDIGetActive();

Page 315: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

CProjectDoc* pDoc = (CProjectDoc*) pChild->GetActiveDocument(); oc->SetTitle("Camera 1"); pD

GetActive();

//ERROR//////////////////////////////////////

CProjectView *pView = (CProjectView *) pChild->GetActiveView(); //Opens 2ª frame MDI SendMessage( WM_COMMAND, ID_FILE_NEW ); //pointer to Doc CMDIFrameWnd* pChild2 = (CMDIFrameWnd*) MDIGetActive(); CProjectDoc* pDoc2 = (CProjectDoc*) pChild2->GetActiveDocument(); pDoc2->SetTitle("Camera 2"); //Activates MDI to associate with View CMDIChildWnd* pMDIChildWnd2 = MDIGetActive(); if (pMDIChildWnd2 == NULL) { MessageBox ("Não existe uma MDI child frame activa", "", MB_ICONERROR); return; } //Associates View to frame 2 CView* pView2 = pMDIChildWnd2->GetActiveView(); ASSERT(pView2 != NULL); //Activates MDI associated with pChild ( 1st window) pChild->SetActiveView(pView,TRUE ); //Activates MDI to associate with View CMDIChildWnd* pMDIChildWnd = MDI if (pMDIChildWnd == NULL) { MessageBox ("Não existe uma MDI child frame activa", "", MB_ICONERROR); return; } //Variaveis Globais com handle das MDI sao associadas m_VarNuclear.m_hWndNuclear = pView->m_hWnd; m_VarNuclear.m_hWndNuclear2 = pView2->m_hWnd; ///Initialization of acquisition//////

/* Allocation of MIL application. */ MappAlloc(M_DEFAULT, &m_VarNuclear.MilApplication); MappControl(M_ERROR,M_PRINT_DISABLE); /* Allocation of MIL system. */ MsysAlloc(M_DEF_SYSTEM_TYPE, M_DEV0, M_DEFAULT, &m_VarNuclear.MilSystem); /* Allocation of MIL display. */ MdispAlloc(m_VarNuclear.MilSystem, M_DEFAULT, M_DEF_DISPLAY_FORMAT,m_VarNuclear.m_lDispMode, &m_VarNuclear.MilDisplay[0]); MdispAlloc(m_VarNuclear.MilSystem, M_DEFAULT, M_DEF_DISPLAY_FORMAT,m_VarNuclear.m_lDispMode, &m_VarNuclear.MilDisplay[1]); /* Allocation of MIL digitizer and size of image target*/ if (MsysInquire(m_VarNuclear.MilSystem, M_DIGITIZER_NUM, M_NULL) > 0) { MdigAlloc(m_VarNuclear.MilSystem, M_DEV0,m_VarNuclear.m_pcDataFormat , M_DEFAULT, &m_VarNuclear.MilDigitizer); (long)(MdigInquire(m_VarNuclear.MilDigitizer, M_SIZE_X, &m_VarNuclear.BufSizeX)); (long)(MdigInquire(m_VarNuclear.MilDigitizer, M_SIZE_Y, &m_VarNuclear.BufSizeY)); } else { m_VarNuclear.MilDigitizer = M_NULL; m_VarNuclear.BufSizeX = BUFFERSIZEX; m_VarNuclear.BufSizeY = BUFFERSIZEY; m_VarNuclear.BufSizeBand = BUFFERSIZEBAND; } ///////////////////// MappGetError(M_CURRENT,&m_VarNuclear.ErrorPtr); if ( m_VarNuclear.ErrorPtr != M_NULL) { MessageBox("Some kind of invalide parameter","Error Reporting",MB_OK); //CWnd* destrwnd; //destrwnd->Attach(m_VarNuclear.m_hWndNuclear);

Page 316: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

//MDIActivate(destrwnd); CMDIFrameWnd* frame = (CMDIFrameWnd*) MDIGetActive();

MbufAllocColor(m_VarNuclear.MilSystem, m_VarNuclear.BufSizeBand

se if (m_VarNuclear.m_bDataTypeRGB == FALSE)

ear.MilDisplay[0], m_VarNuclear.MilImage[0], m_VarNuclear.m_hWndNuclear );

CProjectDoc* documento = (CProjectDoc*) frame->GetActiveDocument(); documento->OnCloseDocument(); CProjectDoc* documento2 = (CProjectDoc*) frame->GetActiveDocument(); documento2->OnCloseDocument(); return; } ///////////////////////////////////////////// //Windows sizes CFrameWnd* pFrame = (CFrameWnd*) pView->GetParentFrame(); ASSERT(pFrame != NULL); pFrame->SetWindowPos(NULL, 0, 0,(UINT)(m_VarNuclear.BufSizeX* m_VarNuclear.m_dImageScale + 12), (UINT)(m_VarNuclear.BufSizeY* m_VarNuclear.m_dImageScale+ 31),SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE );

MbufAlloc2d(m_VarNuclear.MilSystem

CFrameWnd* pFrame2 = (CFrameWnd*) pView2->GetParentFrame(); ASSERT(pFrame2 != NULL); pFrame2->SetWindowPos(NULL, 0, 0,(UINT)(m_VarNuclear.BufSizeX* m_VarNuclear.m_dImageScale + 12), (UINT)(m_VarNuclear.BufSizeY* m_VarNuclear.m_dImageScale+ 31), SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE ); /////////////// /* Allocation of MIL buffer. */ if (m_VarNuclear.m_bDataTypeRGB == TRUE) { MbufAllocColor(m_VarNuclear.MilSystem, m_VarNuclear.BufSizeBand ,(long) (m_VarNuclear.BufSizeX*m_VarNuclear.m_dImageScale) , (long) (m_VarNuclear.BufSizeY*m_VarNuclear.m_dImageScale) , 8+M_UNSIGNED,M_IMAGE + M_DISP + M_GRAB , &m_VarNuclear.MilImage[0]);

, (long) (m_VarNuclear.BufSizeX*m_VarNuclear.m_dImageScale) , (long) (m_VarNuclear.BufSizeY*m_VarNuclear.m_dImageScale) , 8+M_UNSIGNED,M_IMAGE + M_DISP + M_GRAB , &m_VarNuclear.MilImage[1]); } el { MbufAlloc2d(m_VarNuclear.MilSystem ,(long) (m_VarNuclear.BufSizeX*m_VarNuclear.m_dImageScale) ,(long) (m_VarNuclear.BufSizeY*m_VarNuclear.m_dImageScale) , 8 + M_UNSIGNED , M_IMAGE+M_DISP+M_GRAB , &m_VarNuclear.MilImage[0]);

,(long) (m_VarNuclear.BufSizeX * m_VarNuclear.m_dImageScale) ,(long) (m_VarNuclear.BufSizeY * m_VarNuclear.m_dImageScale) , 8 + M_UNSIGNED , M_IMAGE+M_DISP+M_GRAB , &m_VarNuclear.MilImage[1]); } //////////////////////////// /* Clear the buffer */ MbufClear(m_VarNuclear.MilImage[0],0); MbufClear(m_VarNuclear.MilImage[1],0); //Display intialization MdispSelectWindow(m_VarNucl

MdispSelectWindow(m_VarNuclear.MilDisplay[1], m_VarNuclear.MilImage[1], m_VarNuclear.m_hWndNuclear2 ); //Control of the display MdispControl(m_VarNuclear.MilDisplay[0], M_WINDOW_OVERLAP , M_ENABLE);

Page 317: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

MdispControl(m_VarNuclear.MilDisplay[1], M_WINDOW_OVERLAP , M_ENABLE); //Control initialization MdigControl(m_VarNuclear.MilDigitizer, M_GRAB_SCALE, m_VarNuclear.m_dImageScale); //Digitizer initialization //MdigControl(m_VarNuclear.MilDigitizer,M_GRAB_FAIL_RETRY_NUMBER,3); //ERROR////////////////////////////////////// MappGetError(M_CURRENT,&m_VarNuclear.ErrorPtr); if ( m_VarNuclear.ErrorPtr != M_NULL) { MessageBox("Some kind of invalide parameter","Error Reporting",MB_OK); //CWnd* destrwnd; //destrwnd->Attach(m_VarNuclear.m_hWndNuclear); //MDIActivate(destrwnd); CMDIFrameWnd* frame = (CMDIFrameWnd*) MDIGetActive(); CProjectDoc* documento = (CProjectDoc*) frame->GetActiveDocument(); documento->OnCloseDocument(); CProjectDoc* documento2 = (CProjectDoc*) frame->GetActiveDocument(); documento2->OnCloseDocument(); return; } ///////////////////////////////////////////// if (m_VarNuclear.m_bSequencia == TRUE) { // Print a message. //////////////////////////////////////

m_VarNuclear.dlg = new CDComents; if(m_VarNuclear.dlg != NULL) { BOOL ret = m_VarNuclear.dlg->Create(IDD_COMMENT,NULL); if(!ret) //Create failed. AfxMessageBox("Error creating Dialog"); m_VarNuclear.dlg->CenterWindow(); m_VarNuclear.dlg->ShowWindow(SW_SHOW); } else AfxMessageBox("Error Creating Dialog Object"); CEdit* edit=(CEdit*) m_VarNuclear.dlg->GetDlgItem(IDC_EDIT1); CButton* button=(CButton*) m_VarNuclear.dlg->GetDlgItem(IDC_BUTTON1); CButton* button2=(CButton*) m_VarNuclear.dlg->GetDlgItem(IDC_BUTTON2); CString aux; aux="Begin sequence acquisition "; edit->ReplaceSel( aux,FALSE ); aux=""; //////////////////////////////////////////////////////////// AfxBeginThread (SequenciaNuclear,(LPVOID) NULL , THREAD_PRIORITY_NORMAL); } else { if (m_VarNuclear.m_bTriggerMode == FALSE) { // Print a message. ////////////////////////////////////// m_VarNuclear.dlg = new CDComents; if(m_VarNuclear.dlg != NULL) { BOOL ret = m_VarNuclear.dlg->Create(IDD_COMMENT,NULL); if(!ret) //Create failed.

Page 318: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

AfxMessageBox("Error creating Dialog"); m_VarNuclear.dlg->CenterWindow(); m_VarNuclear.dlg->ShowWindow(SW_SHOW); } else AfxMessageBox("Error Creating Dialog Object"); CEdit* edit=(CEdit*) m_VarNuclear.dlg->GetDlgItem(IDC_EDIT1); CButton* button=(CButton*) m_VarNuclear.dlg->GetDlgItem(IDC_BUTTON1); CButton* button2=(CButton*) m_VarNuclear.dlg->GetDlgItem(IDC_BUTTON2); CString aux; aux="Begin acquisition "; edit->ReplaceSel( aux,FALSE ); aux=""; //////////////////////////////////////////////////////////// AfxBeginThread (ShotTemp,(LPVOID) m_myID , THREAD_PRIORITY_NORMAL); } else if (m_VarNuclear.m_bTriggerMode == TRUE) { // Print a message. ////////////////////////////////////// m_VarNuclear.dlg = new CDComents;

xMessageBox("Error Creating Dialog Object");

if(m_VarNuclear.dlg != NULL) { BOOL ret = m_VarNuclear.dlg->Create(IDD_COMMENT,NULL); if(!ret) //Create failed. AfxMessageBox("Error creating Dialog"); m_VarNuclear.dlg->CenterWindow(); m_VarNuclear.dlg->ShowWindow(SW_SHOW); } else Af

CEdit* edit=(CEdit*) m_VarNuclear.dlg->GetDlgItem(IDC_EDIT1); CButton* button=(CButton*) m_VarNuclear.dlg->GetDlgItem(IDC_BUTTON1); CButton* button2=(CButton*) m_VarNuclear.dlg->GetDlgItem(IDC_BUTTON2); CString aux; aux="Begin acquisition "; edit->ReplaceSel( aux,FALSE ); aux=""; //////////////////////////////////////////////////////////// AfxBeginThread (ShotTrigger,(LPVOID) m_myID , THREAD_PRIORITY_NORMAL); } } } } void CMainFrame::OnUpdateMednuclearAquisioAdquirir(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here if ( !m_VarNuclear.m_bvideo ) pCmdUI->Enable(TRUE); else pCmdUI->Enable(FALSE); } void CMainFrame::OnFileAcquisitionOptions() { // TODO: Add your command handler code here //Otions Dialog// CDAcquireOptions dlg; CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame)));

Page 319: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

if (dlg.DoModal()==IDOK)

UpdateData(TRUE);

scombo1=="CH1")

{

pAppFrame->m_VarNuclear.m_csSinal=dlg.m_cscombo4; pAppFrame->m_VarNuclear.m_csData=dlg.m_cscombo3; pAppFrame->m_VarNuclear.m_csCh1=dlg.m_cscombo1; pAppFrame->m_VarNuclear.m_csCh2=dlg.m_cscombo2; pAppFrame->m_VarNuclear.m_csScale=dlg.m_cscombo5; pAppFrame->m_VarNuclear.m_csDisplay=dlg.m_cscombo6; } if (dlg.m_iradio1==0) { pAppFrame->m_VarNuclear.m_iCamera=1; if (dlg.m_cscombo1=="CH1") pAppFrame->m_VarNuclear.m_lChannel1=M_CH0; else if (dlg.m_cscombo1=="CH2") pAppFrame->m_VarNuclear.m_lChannel1=M_CH1; else if (dlg.m_cscombo1=="CH3") pAppFrame->m_VarNuclear.m_lChannel1=M_CH2; else if (dlg.m_cscombo1=="CH4") pAppFrame->m_VarNuclear.m_lChannel1=M_CH3; } else { pAppFrame->m_VarNuclear.m_iCamera=2; if (dlg.m_c pAppFrame->m_VarNuclear.m_lChannel1=M_CH0; else if (dlg.m_cscombo1=="CH2") pAppFrame->m_VarNuclear.m_lChannel1=M_CH1; else if (dlg.m_cscombo1=="CH3") pAppFrame->m_VarNuclear.m_lChannel1=M_CH2; else if (dlg.m_cscombo1=="CH4") pAppFrame->m_VarNuclear.m_lChannel1=M_CH3; if (dlg.m_cscombo2=="CH1") pAppFrame->m_VarNuclear.m_lChannel2=M_CH0; else if (dlg.m_cscombo2=="CH2") pAppFrame->m_VarNuclear.m_lChannel2=M_CH1; else if (dlg.m_cscombo2=="CH3") pAppFrame->m_VarNuclear.m_lChannel2=M_CH2;

else if (dlg.m_cscombo2=="CH4") pAppFrame->m_VarNuclear.m_lChannel2=M_CH3; } if (dlg.m_cscombo4=="RS-170") pAppFrame->m_VarNuclear.m_pcDataFormat="M_RS170"; if (dlg.m_cscombo4=="CCIR") pAppFrame->m_VarNuclear.m_pcDataFormat="M_CCIR"; if (dlg.m_cscombo4=="PAL I") pAppFrame->m_VarNuclear.m_pcDataFormat="M_PAL"; if (dlg.m_cscombo4=="SECAM") pAppFrame->m_VarNuclear.m_pcDataFormat="M_SECAM"; if (dlg.m_cscombo4=="NTSC") pAppFrame->m_VarNuclear.m_pcDataFormat="M_NTSC"; if (dlg.m_cscombo3=="RGB") { pAppFrame->m_VarNuclear.m_bDataTypeRGB=TRUE; pAppFrame->m_VarNuclear.BufSizeBand=3; } else { pAppFrame->m_VarNuclear.m_bDataTypeRGB=FALSE; pAppFrame->m_VarNuclear.BufSizeBand=1; } if (dlg.m_cscombo5=="Normal") pAppFrame->m_VarNuclear.m_dImageScale=1; else if (dlg.m_cscombo5=="Half") pAppFrame->m_VarNuclear.m_dImageScale=0.5; else if (dlg.m_cscombo5=="Quarter") pAppFrame->m_VarNuclear.m_dImageScale=0.25; if (dlg.m_cscombo6=="Enhanced") pAppFrame->m_VarNuclear.m_lDispMode=M_WINDOWED+M_DISPLAY_24_ENHANCED+M_DISPLAY_8_ENHANCED; else if (dlg.m_cscombo6=="Basic") pAppFrame->m_VarNuclear.m_lDispMode=M_WINDOWED+M_DISPLAY_24_BASIC+M_DISPLAY_8_BASIC; else if (dlg.m_cscombo6=="Basic Optimized") pAppFrame->m_VarNuclear.m_lDispMode=M_WINDOWED+M_DISPLAY_24_WINDOWS+M_DISPLAY_8_BASIC;

Page 320: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

pAppFrame->m_VarNuclear.m_csSequence=dlg.m_cscombo7; pAppFrame->m_VarNuclear.m_csImage=dlg.m_cscombo8; pAppFrame->m_VarNuclear.m_csImage.MakeLower(); pAppFrame->m_VarNuclear.Q_FACTOR=dlg.m_level; if (dlg.m_cscombo7=="AVI-MJPG") { pAppFrame->m_VarNuclear.m_bCompressed=TRUE; pAppFrame->m_VarNuclear.m_MILSequenceType=M_AVI_MJPG; } else if (dlg.m_cscombo7=="AVI-DIB") { pAppFrame->m_VarNuclear.m_MILSequenceType=M_AVI_DIB; pAppFrame->m_VarNuclear.m_bCompressed=FALSE; } if (dlg.m_cscombo8=="BMP") pAppFrame->m_VarNuclear.m_MILImageType=M_BMP; else if (dlg.m_cscombo8=="MIL") pAppFrame->m_VarNuclear.m_MILImageType=M_MIL; else if (dlg.m_cscombo8=="RAW") pAppFrame->m_VarNuclear.m_MILImageType=M_RAW; else if (dlg.m_cscombo8=="TIFF") pAppFrame->m_VarNuclear.m_MILImageType=M_TIFF; if (dlg.m_bcheck2) pAppFrame->m_VarNuclear.m_bSignature=TRUE; else pAppFrame->m_VarNuclear.m_bSignature=FALSE; pAppFrame->m_VarNuclear.m_cstext=dlg.m_csedit1; } void CMainFrame::OnFileAcquisitionTest() {

// TODO: Add your command handler code here m_VarNuclear.id = GetCurrentThreadId(); m_VarNuclear.m_CameraNum1=TRUE; m_VarNuclear.m_CameraNum2=FALSE; //Opens 1ª frame MDI SendMessage( WM_COMMAND, ID_FILE_NEW ); //pointer to Doc CMDIFrameWnd* pChild = (CMDIFrameWnd*) MDIGetActive(); CProjectDoc* pDoc = (CProjectDoc*) pChild->GetActiveDocument(); pDoc->SetTitle("Camera"); m_VarNuclear.m_bvideo = TRUE; //Activates MDI to associate with View CMDIChildWnd* pMDIChildWnd = MDIGetActive(); if (pMDIChildWnd == NULL) { MessageBox ("Não existe uma MDI child frame activa", "", MB_ICONERROR); return; } //Associates View to frame 1 CView* pView = pMDIChildWnd->GetActiveView(); ASSERT(pView != NULL); //Handle of the window// m_VarNuclear.m_hWndNuclear = pView->m_hWnd; ///Initialization of frame grabber////// /* allocation of MIL application. */ MappAlloc(M_DEFAULT, &m_VarNuclear.MilApplication); MappControl(M_ERROR,M_PRINT_DISABLE); /* allocation of MIL system. */ MsysAlloc(M_DEF_SYSTEM_TYPE, M_DEV0, M_DEFAULT, &m_VarNuclear.MilSystem); /* allocation of MIL display. */

Page 321: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

MdispAlloc(m_VarNuclear.MilSystem, M_DEFAULT, M_DEF_DISPLAY_FORMAT,m_VarNuclear.m_lDispMode, &m_VarNuclear.MilDisplay[0]); /* allocation of MIL digitizer and size of target image*/ if (MsysInquire(m_VarNuclear.MilSystem, M_DIGITIZER_NUM, M_NULL) > 0) { MdigAlloc(m_VarNuclear.MilSystem, M_DEV0,m_VarNuclear.m_pcDataFormat , M_DEFAULT, &m_VarNuclear.MilDigitizer); (long)(MdigInquire(m_VarNuclear.MilDigitizer, M_SIZE_X, &m_VarNuclear.BufSizeX) ); (long)(MdigInquire(m_VarNuclear.MilDigitizer, M_SIZE_Y, &m_VarNuclear.BufSizeY) );

//Display initialization

uclear.MilDisplay[0], M_WINDOW_OVERLAP , M_ENABLE);

} else { m_VarNuclear.MilDigitizer = M_NULL; m_VarNuclear.BufSizeX = BUFFERSIZEX; m_VarNuclear.BufSizeY = BUFFERSIZEY; m_VarNuclear.BufSizeBand = BUFFERSIZEBAND; } //ERROR////////////////////////////////////// MappGetError(M_CURRENT,&m_VarNuclear.ErrorPtr); if ( m_VarNuclear.ErrorPtr != M_NULL) { MessageBox("Some kind of invalide parameter","Error Reporting",MB_OK); //CWnd* destrwnd; //destrwnd->Attach(m_VarNuclear.m_hWndNuclear); //MDIActivate(destrwnd); CMDIFrameWnd* frame = (CMDIFrameWnd*) MDIGetActive(); CProjectDoc* documento = (CProjectDoc*) frame->GetActiveDocument(); documento->OnCloseDocument(); return; } /////////////////////////////////////////////

//Size of the window/// CFrameWnd* pFrame = (CFrameWnd*) pView->GetParentFrame(); ASSERT(pFrame != NULL); pFrame->SetWindowPos(NULL, 0, 0,(UINT)(m_VarNuclear.BufSizeX* m_VarNuclear.m_dImageScale + 12),(UINT)(m_VarNuclear.BufSizeY* m_VarNuclear.m_dImageScale+ 31), SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE ); ////////////////////// /* Allocation of MIL buffer. */ if (m_VarNuclear.m_bDataTypeRGB == TRUE) { MbufAllocColor(m_VarNuclear.MilSystem, m_VarNuclear.BufSizeBand ,(long) (m_VarNuclear.BufSizeX*m_VarNuclear.m_dImageScale) , (long) (m_VarNuclear.BufSizeY*m_VarNuclear.m_dImageScale) , 8+M_UNSIGNED,M_IMAGE + M_DISP + M_GRAB , &m_VarNuclear.MilImage[0]); } else if (m_VarNuclear.m_bDataTypeRGB == FALSE) { MbufAlloc2d(m_VarNuclear.MilSystem ,(long) (m_VarNuclear.BufSizeX*m_VarNuclear.m_dImageScale ) ,(long) (m_VarNuclear.BufSizeY*m_VarNuclear.m_dImageScale ) , 8 + M_UNSIGNED , M_IMAGE + M_DISP + M_GRAB , &m_VarNuclear.MilImage[0]); } /* Clear the buffer */ MbufClear(m_VarNuclear.MilImage[0],0);

MdispSelectWindow(m_VarNuclear.MilDisplay[0], m_VarNuclear.MilImage[0], m_VarNuclear.m_hWndNuclear ); MdispControl(m_VarN

Page 322: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

if (!m_VarNuclear.first) { MdigInquire(m_VarNuclear.MilDigitizer,M_BRIGHTNESS_REF,&m_VarNuclear.m_iBrightness); MdigInquire(m_VarNuclear.MilDigitizer,M_CONTRAST_REF,&m_VarNuclear.m_iContrast); MdigInquire(m_VarNuclear.MilDigitizer,M_HUE_REF,&m_VarNuclear.m_iHue); MdigInquire(m_VarNuclear.MilDigitizer,M_SATURATION_REF,&m_VarNuclear.m_iSaturation); } //Digitizer initialization MdigControl(m_VarNuclear.MilDigitizer, M_GRAB_SCALE, m_VarNuclear.m_dImageScale); //ERROR////////////////////////////////////// MappGetError(M_CURRENT,&m_VarNuclear.ErrorPtr); if ( m_VarNuclear.ErrorPtr != M_NULL) { MessageBox("Some kind of invalide parameter","Error Reporting",MB_OK); //CWnd* destrwnd; //destrwnd->Attach(m_VarNuclear.m_hWndNuclear); //MDIActivate(destrwnd); CMDIFrameWnd* frame = (CMDIFrameWnd*) MDIGetActive(); CProjectDoc* documento = (CProjectDoc*) frame->GetActiveDocument(); documento->OnCloseDocument(); return; } ///////////////////////////////////////////// CDImage* dlg; dlg = new CDImage; if(dlg != NULL) { BOOL ret = dlg->Create(IDD_IMAGE,this); if(!ret) //Create failed. AfxMessageBox("Error creating Dialog"); dlg->ShowWindow(SW_SHOW); } else

AfxMessageBox("Error Creating Dialog Object"); //if (m_VarNuclear.m_bSignature) //writetext((LPTSTR) m_VarNuclear.m_cstext.GetBuffer(m_VarNuclear.m_cstext.GetLength()) ,m_VarNuclear.m_cstext.GetLength() ,m_VarNuclear.m_icolor,m_VarNuclear.m_bposition,m_VarNuclear.m_bonlysave,m_VarNuclear.MilImage[0]); StartThreadNuclear(); AfxBeginThread (MilApplication,(LPVOID) NULL , THREAD_PRIORITY_NORMAL); } ProjectDoc.h //nuclear// BOOL m_video_nuclear; //nuclear ProjectDoc.cpp void CProjectDoc::OnCloseDocument() { // TODO: Add your specialized code here and/or call the base class if (m_modelessDoc) { // this document belongs to a modeless Dialog CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); pAppFrame->m_modeless = FALSE; } //Nuclear// CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame )));

Page 323: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

if (pAppFrame->m_VarNuclear.m_bvideo == TRUE)//m_video_nuclear == TRUE) { POSITION posView = GetFirstViewPosition(); CProjectView* pView; pView = (CProjectView*)GetNextView( posView ); if (pView->m_hWnd == pAppFrame->m_VarNuclear.m_hWndNuclear) { pAppFrame->m_VarNuclear.m_CameraNum1 = FALSE; if((!pAppFrame->m_VarNuclear.m_CameraNum1) && (!pAppFrame->m_VarNuclear.m_CameraNum2 ) )

/* Deselect the MIL buffer from the display. */

readNuclear();

StopThreadNuclear(); MdispDeselect(pAppFrame->m_VarNuclear.MilDisplay[0], pAppFrame->m_VarNuclear.MilImage[0]); } if (pView->m_hWnd == pAppFrame->m_VarNuclear.m_hWndNuclear2) { pAppFrame->m_VarNuclear.m_CameraNum2 = FALSE; if((!pAppFrame->m_VarNuclear.m_CameraNum1) && (!pAppFrame->m_VarNuclear.m_CameraNum2 ) ) StopTh /* Deselect the MIL buffer from the display. */ MdispDeselect(pAppFrame->m_VarNuclear.MilDisplay[1], pAppFrame->m_VarNuclear.MilImage[1]); } if( (!pAppFrame->m_VarNuclear.m_CameraNum1) && (!pAppFrame->m_VarNuclear.m_CameraNum2 ) ) { /* Free allocated objects. */ if (pAppFrame->m_VarNuclear.m_hWndNuclear != NULL) { MbufFree(pAppFrame->m_VarNuclear.MilImage[0]);

MdispFree(pAppFrame->m_VarNuclear.MilDisplay[0]); } if (pAppFrame->m_VarNuclear.m_hWndNuclear2 != NULL) { MbufFree(pAppFrame->m_VarNuclear.MilImage[1]); MdispFree(pAppFrame->m_VarNuclear.MilDisplay[1]); } pAppFrame->m_VarNuclear.m_hWndNuclear = NULL; pAppFrame->m_VarNuclear.m_hWndNuclear2 = NULL; if (pAppFrame->m_VarNuclear.MilDigitizer) MdigFree(pAppFrame->m_VarNuclear.MilDigitizer); MsysFree(pAppFrame->m_VarNuclear.MilSystem); MappFree(pAppFrame->m_VarNuclear.MilApplication); pAppFrame->m_VarNuclear.m_bvideo=FALSE; } Sleep(30); } //Nuclear// … ProjectView.cpp //Nuclear// #include "cal_points.h" #include "detect.h" #include "ddetect.h" //Nuclear// … //Nuclear// void CProjectView::OnMednuclearCalibracaoGetpoints() {

Page 324: Capitulo I - Apresentaçãotavares/downloads/publications/relatorios/... · Capitulo I - Apresentação Agradecimentos Ao Instituto de Engenharia Biomédica da Universidade de Karlsruhe

// TODO: Add your command handler code here

CDdetect_3D* dialog;

xMessageBox("Error Creating Dialog Object");

CProjectDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); HDIB hDIB = pDoc->GetHDIB(); cal_point(hDIB); } //Nuclear// void CProjectView::OnMednuclearDetectand3d() { // TODO: Add your command handler code here CDInitDetect3D dlg; if (dlg.DoModal() != IDOK ) return;

dialog = new CDdetect_3D; dialog->size=dlg.m_edit3; if(dialog != NULL) { BOOL ret = dialog->Create(IDD_DETECTAND3D,this); if(!ret) //Create failed. AfxMessageBox("Error creating Dialog"); dialog->ShowWindow(SW_SHOW); } else Af } void CProjectView::OnCorrect() { // TODO: Add your command handler code here

CDCorrect* dialog; dialog = new CDCorrect; if(dialog != NULL) { BOOL ret = dialog->Create(IDD_CORRECT,this); if(!ret) //Create failed. AfxMessageBox("Error creating Dialog"); dialog->ShowWindow(SW_SHOW); } else AfxMessageBox("Error Creating Dialog Object"); }