Vous êtes sur la page 1sur 324

Capitulo I - Apresentao

Capitulo I - Apresentao

PD 77 - Alinhamento de Imagens Mdicas

Relatrio final submetido ao Departamento de Engenharia Electrotcnica e de Computadores para satisfao parcial dos requisitos do:

Projecto, Seminrio, Trabalho de Fim de Curso

Por: Nuno Jos S Couto Srgio Vasconcelos de Barros


Finalistas do curso de Engenharia Electrotcnica e de Computadores da Universidade do Porto

Orientador: Armando Jorge Padilha


Prof. Associado do Departamento de Engenharia Electrotcnica e de Computadores da Faculdade de Engenharia da Universidade do Porto
2

Capitulo I - Apresentao

Agradecimentos Ao Instituto de Engenharia Biomdica 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 orientao e oportunidade que nos deu de trabalharmos numa rea que sempre nos motivou. Ao Eng. Joo Tavares por toda a sua disponibilidade e pela disponibilizao de funes 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 ligao ao Instituto de Qumica Fisiolgica, laboratrio de radioistopos da Faculdade de Medicina de Coimbra, em particular ao Prof. Adriano Rodrigues, e ao departamento de medicina nuclear do Hospital de S. Joo, em particular ao director de servio Dr. Jorge Rodrigues.

Capitulo I - Apresentao

ndice
Captulo I - Apresentao
1. Proposio
1.1 Objectivos do Projecto 1.2 Estrutura do Relatrio
1 2 3 4

2. Etapas do Projecto

Captulo II Medicina Nuclear, SPECT e PET


Introduo 1. Medicina Nuclear
1.1 Introduo 1.2 Histria 1.3 Factos 1.4 Computadores em Medicina Nuclear
1.4.1 Introduo 1.4.2 Imagens Digitais 1.4.3 Aquisio de Imagem 1.4.4 Concluso 7 8 8 8 9 10 10 10 11 11 11 12 13 13 14 15 15 17 17 18 18 19 19 19 20 20 21 21 21

1.5 Segurana e Controlo da Qualidade 1.6 Futuro

2. Single Photon Emission Computed Tomography (SPECT)


2.1 Introduo ao SPECT 2.2 Histria do SPECT 2.3 Teoria e Instrumentao 2.4 Aquisio e Processamento de Imagem em SPECT 2.5 Reconstruo de Imagem
2.5.1 Projeco Inversa Filtrada 2.5.2 Mtodo dos Parmetros Directos 2.5.3 Mtodo dos Mnimos Quadrados com Restrio Linear 2.5.4 Reconstruo Iterativa

2.6 A Cmara Gama


2.6.1 Caractersticas da Cmara Gama 2.6.2 Controlo de Qualidade da cmara

2.7 Colimador
2.7.1 Resoluo e Sensibilidade 2.7.2 Tipos de Colimadores
2.7.2.1 Converging Hole

Capitulo I - Apresentao
2.7.2.2 Convergncia e divergncia 2.7.2.3 Pin- Hole

2.8 Detector de Cintilao 2.9 Tubos Fotomultiplicadores 2.10 Circuitos de Posicionamento 2.11 Computador para Anlise de Dados 2.12 Visualizao SPECT
2.12.2 Artefactos que influenciam a visualizao SPECT

2.13 Protocolos de Aquisio


2.13.1 Imagem Planar
2.13.1.1 Aquisio de imagem planar dinmica

2.13.2 Aquisio de Imagem SPECT


2.13.2.1 Aquisio de Imagem SPECT Dinmica

2.13.3 Aquisio SPECT GATED

2.14 Aplicaes SPECT 2.15 Avanos Tcnicos do SPECT


2.15.1 Cmara de Compton

2.16 Concluso

21 22 22 22 23 23 23 23 25 25 26 26 26 26 26 28 29 29 29 29 30 30 31 31 32 32 32

3. Positron Emission Tomography (PET)


3.1 Introduo ao PET 3.2 Aspectos Histricos do PET 3.3 Teoria e Instrumentao 3.4 Radionuclidos 3.5 Metabolismo da glucose 3.6 Aquisio e Processamento de Imagem em PET 3.7 Funes do PET 3.8 Aplicaes e Investigao Associada ao PET

Captulo III Fundamentos Tericos


1. Introduo Viso por Computador
1.1 Introduo 1.2 Viso por Computador 1.3 reas Associadas Viso por Computador
1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 Processamento de imagem Grficos Computadorizados Reconhecimento de Padres Inteligncia Artificial Psicofsica 35 35 35 36 36 36 36 36 37 37 37 37 38 38

1.4 reas de Aplicao

2. Tcnicas de Aquisio de Informao Tridimensional


2.1 Introduo 2.2 Tcnicas Activas de Aquisio Tridimensional 2.3 Tcnicas Passivas de Aquisio Tridimensional

II

Capitulo I - Apresentao

3. Processamento e Anlise de Imagem


3.1 Thresholding 3.2 Filtragem de Imagem
3.2.1 Filtros de Suavizao e Realce
3.2.1.1 Filtro de mdia 3.2.1.2 Filtro de mediana 3.2.1.3 Filtro Gaussiano

3.2.2 Filtros Derivativos


3.2.2.1 Operadores de Gradiente 3.2.2.2 Operadores Laplacianos

3.3 Deteco de Orlas de Intensidade


3.3.1 Deteco de Orlas de Intensidade Canny 3.3.2 Deteco de Orlas de Intensidade Deriche 3.3.3 Operaes Complementares

3.4 Transformao de Hough


3.4.1 Deteco de Linhas 3.4.2 Deteco de Crculos 3.4.3 Deteco de Elipses

3.5 Transformaes e Coordenadas Homogneas 3.6 Modelos Deformveis


3.6.1 Snakes 3.6.2 Balloons

39 39 40 40 40 41 42 43 43 44 45 45 45 46 47 47 48 49 50 50 51 52

Captulo IV Sistema Desenvolvido


1. Introduo ao Sistema Desenvolvido
1.1 Problemtica do Projecto 1.2 Mtodo 1.3 Conceitos Bsicos
1.3.1 Esteroscopia Passiva 1.3.2 Triangulao 1.3.3 ptica
1.3.3.1 Equao da Lente 1.3.3.2 Resoluo da Imagem 1.3.3.3 Profundidade de Campo

53 53 53 55 55 55 56 56 56 57 57 57 57 58 58 59 59 59 59 60 60

2. Sistema Desenvolvido
2.1 Material Utilizado
2.1.1 Cmaras e Lentes 2.1.2 Suporte para Cmaras 2.1.3 Frame Grabber 2.1.4 PC 2.1.5 Alvo a Colocar no Paciente 2.1.6 Alvo para Calibrao das Cmaras 2.1.7 Transformadores e Cabos de Ligao 2.1.8 Interruptor Porta Srie

2.2 Aquisio de imagens Estereoscopicas

III

Capitulo I - Apresentao
2.2.1 Introduo 2.2.2 Software Desenvolvido
2.2.2.1 Opes de Aquisio 2.2.2.2 Esquemas de Aquisio 2.2.2.3 Configurao de Nveis de Referncia 2.2.2.4 Anlise do Software Desenvolvido

2.3 Calibrao das Cmaras


2.3.1 Introduo 2.3.2 Fundamentos Tericos 2.3.3 Abordagem seguida no Projecto
2.3.3.1 Introduo 2.3.3.2 Modelo de Cmara 2.3.3.3 Calibrao de uma Cmara 2.3.3.4 Consideraes sobre o Modelo Utilizado 2.3.3.5 Influncia de uma Determinao Incorrecta do Centro de Imagem 2.3.3.6 Determinao das Coordenadas dos Pontos de Calibrao

2.3.4 Software Desenvolvido


2.3.4.1 Calibrao de uma Cmara 2.3.4.2 Determinao das Coordenadas na Memria Frame 2.3.4.3 Formatao dos Pontos de Calibrao 2.3.4.4 Simulador de uma Cmara

2.3.5 Resultados Experimentais


2.3.5.1 Determinao das Coordenadas dos Pontos de Calibrao 2.3.5.2 Simulao de Calibraes de Cmaras 2.3.5.3 Formatao dos Pontos de calibrao 2.3.5.4 Calibrao de Cmaras

2.4 Deteco de Alvos e Obteno de Informao 3D


2.4.1 Introduo 2.4.2 Deteco de Pontos Caractersticos
2.4.2.1 Dimensionamento do Alvo 2.4.2.2 Deteco do Alvo

2.4.3 Emparelhamento de Pontos Caractersticos 2.4.4 Obteno de Informao Tridimensional


2.4.4.1 Princpio da Triangulao Estereoscopica 2.4.4.2 Implementao Desenvolvida

2.4.5 Software Desenvolvido


2.4.5.1 Comprovao dos Algoritmos Desenvolvidos 2.4.5.2 Implementao do software

2.5 Estimao e Correco de Movimento


2.5.1 Introduo 2.5.2 Mtodo Utilizado 2.5.3 Software Desenvolvido
2.5.3.1 Comprovao dos algoritmos desenvolvidos 2.5.3.2 Implementao do Software

60 60 60 62 63 63 63 63 64 65 66 66 69 72 72 73 74 74 76 77 78 80 80 83 85 86 86 86 87 87 89 91 92 92 93 93 93 96 100 100 100 103 103 104

IV

Capitulo I - Apresentao

Captulo V Anlise de Resultados


1. Introduo 2. Estimao do ngulo de Viso das Cmaras 3. Testes Efectuados 4. Influncia dos Parmetros de Calibrao
105 106 107 116

Captulo VI Concluses e Trabalho Futuro


1. Pesquisa de Informao 2. Etapas do Projecto 3. Abordagem Seguida 4. Equipamento utilizado 5. Algoritmos desenvolvidos
119 119 120 120 121

Bibliografia_____________________________________
1. Publicaes 2. Internet
123 126

Capitulo I - Apresentao

Captulo I

1 Proposio
Cada vez mais a Engenharia torna-se uma aliada poderosa da Medicina. Os sistemas de apoio deciso contribuem significativamente para um melhor e mais rpido diagnstico por parte do pessoal mdico. Isto deve-se ao facto da capacidade de processamento e de armazenamento de informao dos computadores actuais ser de tal ordem elevada, que estes conseguem processar e analisar grandes quantidades de informao em espaos de tempo extremamente curtos. Se essa mesma informao fosse analisada por pessoas, alm de levar um tempo de processamento e anlise muito superior, levaria a que as concluses fossem imprecisas e variveis, devido a influncias externas tais como cansao, ms condies de visualizao, etc. Assim, no mbito deste projecto foi desenvolvido um sistema de apoio deciso mdica atravs do processamento e anlise 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 rgos, como por exemplo os rins. O funcionamento do rgo avaliado atravs da anlise da quantidade de um determinado radionuclido que est presente nesse rgo durante um determinado perodo de tempo. Este tipo de exame necessita de alguns requisitos para que o diagnstico final seja o mais preciso possvel, sendo um desses requisitos, o paciente permanecer imvel durante todo o perodo de tempo do exame mdico. Se esse requisito no for preenchido, a capacidade de diagnstico deteriora-se de tal forma que a soluo geralmente usadas nestes casos a repetio do exame. Assim a motivao para este trabalho dimensionar e implementar um sistema de aquisio de imagem com duas cmaras para detectar movimentos do paciente de modo a efectuar a correco desse movimento nas imagens mdicas finais. Para a implementao torna-se assim importante obter informao tridimensional. Existem actualmente vrias tcnicas para tornar possvel esta obteno utilizando viso por computador. Normalmente as tcnicas existentes so divididas em duas categorias: activas e passivas. O sistema a desenvolver ser um sistema do tipo passivo. Neste caso iro ser utilizadas duas cmaras, ligadas a um computador (que ser responsvel pela aquisio das imagens digitais), com um suporte fsico e alvos para deteco devidamente dimensionados. O presente trabalho enquadra-se assim numa tcnica passiva de estereoscopia de obteno de informao tridimensional. Quando se pretende obter informao tridimensional de uma cena, a partir de uma sequncia de pares de imagens obtidas simultaneamente por duas cmaras, torna-se indispensvel o prvio conhecimento do modelo da cmara utilizada. Assim, necessrio conhecer previamente o modo como os pontos no espao tridimensional so transformados em pontos plano imagem da cmara, para cada par de imagens ao longo da sequncia. Essa determinao do modelo da cmara isto , a

Capitulo I - Apresentao
determinao da geometria interna e das caractersticas pticas (parmetros intrnsecos) e a orientao e posio da cmara relativamente a um certo sistema de coordenadas mundo (parmetros extrnsecos) designada por calibrao da cmara. Estes parmetros so conseguidos atravs da anlise da posio de diversos pontos ao longo de um plano de calibrao propriamente dimensionado para este efeito. A calibrao geralmente realizada apenas uma vez e constitui a primeira fase da abordagem seguida neste projecto. Aps a calibrao da cmara, ento possvel obter-se a sequncia de pares de imagens, ou a sequncia de imagens - dado que, a abordagem seguida teve como maior preocupao a execuo de um sistema modular e flexvel de modo a ser possvel a sua utilizao em diversas situaes (no s especificamente direccionada para os exames mdicos) e de diversas formas (por exemplo, ser possvel a utilizao de uma ou de duas cmaras). Em cada imagem surge a necessidade de determinar as entidades que iro ser consideradas, sendo estas entidades, formas geomtricas colocadas num cinto. Este cinto por sua vez ser colocado no paciente e ser este o alvo que vai permitir a anlise do movimento do paciente. Para a deteco 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.), aps o que executado um seguimento das linhas determinadas e consequente determinao da forma geomtrica detectada. Desta forma para o dimensionamento do alvo a colocar no paciente procurou-se colocar o maior nmero de formas diferentes geomtricas, de maneira a que a identificao de cada uma destas entidades fosse mais eficiente facilitando o emparelhamento destas nos pares de imagens e consequentemente a extraco de coordenadas 3D. Assim como candidatos surgiram as seguintes figuras geomtricas: tringulos, quadrados, rectngulos, losngulos e cruzes. Destas figuras existem algumas que se destacam por algumas caractersticas internas, que por si s facilitam a sua deteco. Como perceptvel existem muitas hipteses para o dimensionamento deste alvo, que sero objecto de estudo deste relatrio. Estando o emparelhamento das vrias figuras geomtricas (em pares de imagens sucessivas) devidamente realizado, torna-se ento possvel extrair as coordenadas 3D dos pontos de cada figura. Determinadas as coordenadas 3D destes pares de imagens possvel 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: rotao e translao. Finalmente, aps a classificao do movimento efectuado pelo paciente feita a correco das imagens mdicas. Esta correco feita atravs de um modelo fisiolgico que associa os movimentos dos pontos detectados das figuras geomtricas com o movimento efectuado pelo rgo. Este modelo inicialmente vai ser um modelo simplificado, que poder ser refinado adquirindo-se mais informao acerca da posio relativa dos rins no corpo humano, e se se verificam e quais os tipos de movimentos solidrios que se efectuam com o movimento do corpo humano. Este projecto foi realizado no INEB Instituto de Engenharia Biomdica no laboratrio de Sinal de Imagem Biomdica, situado na Faculdade de Engenharia da Universidade do Porto.

1.1 Objectivos do projecto:


Este projecto tem como objectivo geral a concepo e implementao de mtodos de captura de informao posicional (3D) para alinhar imagens renais de medicina nuclear obtidas em sequncia temporal, com vista a potenciar a capacidade de anlise diagnstica. Para ser atingido este objectivo, foram realizadas vrias 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 informao relevante para o projecto, em particular no que respeita ao processo de obteno de imagens de radioistopos e aos mtodos passivos de aquisio de informao tridimensional. Implementao do sistema de aquisio 3D, incluindo concepo de alvos e/ ou marcas corporais. Realizao do alinhamento geomtrico da sequncia de imagens, a partir da estimao da posio e pose da zona renal. Montagem e ensaios prticos em exames clnicos reais e, se necessrio, com recurso a fantomas.

2. 3. 4.

Capitulo I - Apresentao

1.2 Estrutura do relatrio:


Pretendeu-se estruturar este relatrio em seces que se apresentem de forma completamente autnoma e independente, de maneira a permitir uma fcil leitura e compreenso deste relatrio. Em seguida, de forma resumida, so apresentados os restantes captulos e anexos deste relatrio. Captulo II Medicina Nuclear e seus Protocolos de Aquisio Neste captulo apresentada a recolha de informao realizada sobre a rea de medicina nuclear e dos seus protocolos de aquisio, SPECT e PET. feita uma pequena introduo, onde referida como e quais as condies em que se fez esta recolha de informao. O objectivo deste captulo dar a conhecer esta rea especfica da medicina, a sua misso, suas condicionantes, os princpios fsicos e de funcionamento dos protocolos, seus constituintes e suas problemticas e tambm aquilo que se est a fazer para que este tipo de anlise chegue cada vez mais a um maior nmero de pessoas sem que isso implique um custo econmico (para as pessoas e para as instituies que detm os equipamentos) incomportvel. Captulo III Fundamentos Tericos Neste captulo abordado o tema da viso por computador, importncia e riqueza de informao que este tipo de viso nos faculta, informao esta que permite a deteco e o seguimento de alvos. De uma forma geral existem vrias reas associadas viso por computador tal como o processamento e anlise de imagem, reconhecimento de padres, etc. Sero tambm apresentadas as reas de aplicao da viso por computador. Como rea associada da viso por computador apresentada o processamento e anlise de imagem. Nesta seco so apresentados as ferramentas de anlise e extraco de informao das imagens. So assim apresentados vrios tipos de filtros e seus critrios de desempenho, transformaes para deteco de formas geomtricas, coordenadas homogneas e uma introduo aos modelos deformveis. O objectivo deste captulo fornecer as bases do processamento e anlise de imagem, bases estas que constituem os pilares deste projecto. Captulo IV Sistema Desenvolvido Neste captulo apresentada uma soluo global para a problemtica do projecto. feita uma descrio detalhada do material usado e suas caractersticas. Em seguida so apresentados os diversos mdulos que constituem a soluo apresentada. Pretendeu-se que estes mdulos fossem independentes entre si, de modo a poderem, por si s, ser acompanhadas e utilizadas independentemente em outros domnios da viso por computador. Os mdulos a apresentar so os de: aquisio de imagem, calibrao de cmaras, deteco e obteno de informao 3D e correco das imagens de medicina nuclear. Em cada um dos mdulos feita a apresentao do mtodo utilizado, abordagem seguida no projecto e demonstrado o software desenvolvido assim como alguns resultados experimentais obtidos. Captulo V Anlise de resultados e concluses. Aps a apresentao da abordagem global utilizada, neste captulo so apresentados resultados desse processo. So assim apresentados resultados experimentais obtidos para a calibrao das cmaras, aquisio simultnea, determinao das entidades a considerar em cada imagem da sequncia e para a obteno de informao tridimensional, assim como para a estimao e correco do movimento. Na apresentao destes resultados sero feitas anlises e concluses dos resultados obtidos. Ser tambm apresentada uma anlise crtica, onde ser referido aquilo que foi feito e o que deveria ter sido feito, o que faltou (ou no) fazer e condies a nvel de equipamento e acessibilidades. Sero tambm apresentadas concluses globais referentes a todo o projecto em si.

Capitulo I - Apresentao
Captulo VI Trabalho Futuro Neste captulo sero apresentadas mtodos para o desenvolvimento da soluo apresentada assim como alternativas soluo apresentada. Como anexos ao relatrio, sero apresentados os seguintes: Anexo A Manual do Utilizador Anexo B - Caractersticas da cmara Anexo C - Caractersticas do frame grabber Anexo D - Transformaes geomtricas em 2D e 3D Anexo E - Exemplo de imagens obtidas por exame SPECT planar Anexo F - Radionuclidos Anexo F - Cdigo implementado

2 Etapas do projecto
Nesta seco sero apresentadas, em ordem cronolgica, todas as etapas que simbolizam o progresso do projecto: 12/03/2001: Incio do Projecto 15/03/2001: Publicao do site PD-77 Alinhamento de Imagens de Medicina Nuclear no seguinte URL: http://www.fe.up.pt/~nuclear, para satisfao parcial dos requisitos da disciplina de Projecto Seminrio Trabalho Fim de Curso. 22/03/2001: Concluso da primeira fase do projecto: pesquisa de informao acerca dos processos de obteno de imagens de radioistopos e aos mtodos passivos de aquisio de informao tridimensional. 31/03/2001: Compra e montagem do material necessrio elaborao do projecto. Incio do desenvolvimento, em paralelo, das rotinas de calibrao e de aquisio 6/04/2001: Implementao da rotina de simulao de calibrao.

10/04/2001: Implementao da rotina de determinao de parmetros extrnsecos e intrnsecos do modelo das cmaras. 16/04/2001: Implementao das rotinas de aquisio de imagens ou sequncias de imagens de uma ou duas cmaras. 20/04/2001: Implementao da rotina de deteco dos pontos de calibrao. 28/04/2001: Dimensionamento em paralelo dos alvos de calibrao e de aquisio de coordenadas 3D. 5/05/2001: Elaborao do relatrio de progresso para satisfao parcial dos requisitos das regras do Projecto Seminrio Trabalho Fim de Curso. 10/05/2001: Correco e optimizao das rotinas de calibrao e aquisio. 12/05/2001: Desenvolvimento das rotinas de deteco de pontos caractersticos em imagens. 15/05/2001: Concentrao numa s aplicao de todos os mdulos desenvolvidos at ao momento.

Capitulo I - Apresentao
20/05/2001: Implementao e concluso da rotina de deteco de pontos caractersticos numa imagem. 27/05/2001: Implementao da rotina de emparelhamento de pontos caractersticos em pares de imagens. 5/06/2001: 6/06/2001: Implementao da rotina de deteco e emparelhamento de pontos caractersticos em pares de imagens ao longo de uma sequncia de imagens. Criao do lao institucional entre o INEB e o Servio de Medicina Nuclear do Hospital S. Joo do Porto, com o objectivo de obtermos mais informaes acerca dos exames a que no propusemos a corrigir e ter um contacto directo com o ambiente clnico.

10/06/2001: Implementao da rotina que permite fazer a actualizao dos dados de calibrao a partir de ficheiro em disco. 15/06/2001: Dimensionamento do suporte para as cmaras e desenvolvimento das rotinas para o clculo de coordenadas 3D. 20/06/2001: Implementao da rotina para clculo de coordenadas 3D 22/06/2001: Ida ao servio de radiologia do Hospital Universitrio de Coimbra com o intuito de obter exames do tipo SPECT planar em formato de imagem .bmp e .img 28/06/2001: Implementao da rotina de clculo de coordenadas 3D numa sequncia de pares de imagem. Concluso da 2 fase do projecto. 2/07/2001: Desenvolvimento das rotinas de estimao e correco de Implementao fsica do sistema de duas cmaras atravs do suporte. movimento.

10/07/2001: Inicio da elaborao do relatrio. 15/07/2001: Finalizao das rotinas de estimao e correco de movimento. Concluso da 3 fase. 16/07/2001: Elaborao do poster de apresentao do projecto. 17/07/2001: Obteno de dados para anlise e concluses acerca da validade do projecto. Realizao de testes laboratoriais. 18/07/2001: Concluso da 4 fase do projecto. 19/07/2001: Finalizao do relatrio final do projecto. De referir tambm que houve sempre uma actualizao peridica da pgina do projecto, com novas imagens, software, vdeos, informao acerca de eventos, etc..

Capitulo I - Apresentao

Captulo II - Medicina Nuclear, SPECT e PET

Captulo II

Introduo:
Neste segundo captulo apresentada a recolha de informao efectuada sobre os temas de medicina nuclear e seus protocolos de aquisio: Single Photon Emission Computed Tomography (SPECT) e Positron Emission Tomography (PET). A recolha de informao foi dividida em duas fases: 1) a recolha propriamente dita da informao 2) organizao da informao. A recolha propriamente dita da informao teve incio 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 incio do segundo semestre desse ano lectivo. Nesse primeiro semestre lectivo foi nos dada a oportunidade de realizar um projecto de investigao no IBT (Institut fur Biomedzisniche Technik), sobre o tema da segmentao do trax 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 condies ptimas de acesso informao, tentamos retirar o mximo de informao possvel acerca da medicina nuclear e seus protocolos de aquisio. De salientar toda a disponibilidade das pessoas que trabalham nesse Instituto em nos tentar esclarecer todas as nossas dvidas que foram surgindo durante a recolha de dados, e de nos alertar para as dificuldades com nos iramos defrontar ao longo deste projecto, no s nos aspectos tcnicos relativos ao sistema que nos proponhamos a desenvolver, mas tambm para as dificuldades inerentes ao trabalho nesta rea (tais como, a falta de informao por parte dos fabricantes das mquinas de aquisio nuclear). Da fase de recolha de informao tambm faz parte uma visita MEDICA 2000 em Dusseldorf (maior exposio mundial sobre equipamentos de aquisio, tratamento e diagnstico mdico). A segunda fase j foi realizada no segundo semestre do referido ano lectivo e consistiu na compilao da informao adquirida, retirando para este relatrio apenas a informao que consideramos essencial percepo daquilo que se faz nesta rea e suas linhas mestras para o presente / futuro. De referir ainda que a informao que foi adquirida tanto no primeiro como no segundo semestre no se restringiu apenas medicina nuclear e seus protocolos, mas tambm foi adquirida informao que ir ser exposta nos captulos seguintes, informao essa que forma os pilares tericos do sistema que nos propusemos a desenvolver. Assim neste captulo ir ser feita uma breve descrio do que consiste a medicina nuclear como uma disciplina especfica da medicina geral, seus aspectos histricos, suas preocupaes, aplicaes e futuro. Em seguida feita uma descrio dos protocolos de aquisio existentes na medicina nuclear: SPECT e PET, sendo dado mais relevo ao SPECT, dado que esse o protocolo para o qual foi

Captulo II - Medicina Nuclear, SPECT e PET


desenvolvido o sistema deste projecto. Desta maneira, feita um pequeno sumrio do SPECT, seus aspectos histricos, teoria e instrumentao inerentes ao SPECT, seus constituintes, problemas e artefactos existentes nos diversos exames, avanos tecnolgicos e so feitas algumas concluses. Da mesma maneira feita uma pequena abordagem ao PET onde os itens expostos so semelhantes aos expostos no SPECT embora sem o mesmo nvel de detalhe. assim nosso objectivo que o leitor no final deste captulo seja capaz de entender esta rea especfica da medicina, a sua misso, suas condicionantes, os princpios fsicos e de funcionamento dos protocolos, seus constituintes e suas problemticas e tambm aquilo que se est a fazer para que este tipo de anlise chegue cada vez mais a um maior nmero de pessoas sem que isso implique um custo econmico (para os utentes e para as instituies que detm os equipamentos) incomportvel.

1 Medicina Nuclear
1.1 - Introduo Medicina Nuclear
Medicina Nuclear uma especialidade mdica que usa tcnicas seguras, indolores e com custo eficaz tanto para processamento e anlise de imagem de todo o corpo humano, assim como para o tratamento de doenas. O processamento e anlise de imagem em Medicina Nuclear, nico no facto de que documenta e estrutura funes dos orgos, em contraste com diagnsticos feitos em radiologia, diagnsticos estes que so baseados na anatomia dos orgos. uma maneira de adquirir informao mdica, que doutra forma seria provavelmente impossvel, ou ento, requerendo intervenes cirrgicas ou testes diagnsticos mais caros. O campo da medicina nuclear uma mistura de muitas reas da matemtica e cincia, tais como a fsica, qumica, matemtica, tecnologia de computadores e medicina. Como parte de um tratamento integral de um paciente, a medicina nuclear usada no diagnstico, gesto, tratamento e preveno de doenas graves. Os procedimentos utilizados na anlise de imagem em medicina nuclear frequentemente identificam anormalidades numa fase precoce no progresso de uma doena, muito antes do que os outros testes consigam detect-los. Esta deteco precoce permite o tratamento da doena numa fase em que o prognstico tem mais probabilidades de ter sucesso. Medicina nuclear usa uma pequena quantidade de material radioactivo ou rdiofarmaco para o diagnstico e tratamento de doenas. Rdiofarmacos so substncias que so atradas para orgos, ossos ou tecidos especficos. Os rdiofarmacos usados em medicina nuclear emitem raios gama que podem ser detectados externamente por tipos especiais de cmara: gama ou PET cmaras. Estas cmaras funcionam em conjuno com computadores que so usados para formar imagens que providenciam dados e informao acerca da rea do corpo que est sujeita a exame. O fsico pode ento visualizar a anatomia do paciente a partir do resultado da cmara. O rdioistopo tem que ter uma meia - durao de vida curta de modo a que no permanea no corpo, por um perodo de tempo muito prolongado. Meio-tempo de vida o tempo necessrio para que metade do material radioactivo presente deixe de emitir. Assim a medicina nuclear essencialmente a criao mapas anatmicos de orgos. O material radioactivo administrado oralmente, intra venosamente ou inter cavitalmente. O material radioactivo absorvido pela regio doente e pode ento destruir as clulas ou promover a cura dessa regio. A quantidade de radiao de um procedimento de medicina nuclear e comparvel com aquele que recebido durante um diagnstico raioX. As imagens de medicina nuclear tm mais definio e so capazes de mostrar mais partes da anatomia do que as mquinas de raio-x usuais. Fsicos licenciados so as nicas pessoas autorizadas a praticar medicina nuclear. De modo a algum estar certificado para tal, dever ter um curso mdico e pelo menos 1 ou mais anos de. Os fsicos tem assim 2 anos de treino em medicina nuclear para no final fazer um exame de certificao. Uma vez certificado o fsico ser ento assistido por outros fsicos e farmacologistas especialmente treinados. Hoje em dia, medicina nuclear oferece procedimentos que so de grande ajuda para uma vasta rea de especialidades mdicas, desde pediatria ate cardiologia passando pela psiquiatria. Existem quase cem tipos de processamento e anlise de imagem em medicina nuclear disponveis e no existe nenhum sistema do corpo humano que no seja adquirido por medicina nuclear. Hipertiroidismo, cancro da tiride, desequilbrios sanguneos, e alvio da dor de certos tipos de cancro de ossos so tratados atravs da medicina nuclear.

1.2 - Histria da Medicina Nuclear

Captulo II - Medicina Nuclear, SPECT e PET


De acordo com Hamilton a descoberta da radioactividade artificial foi um ponto fulcral na medicina nuclear. A histria 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 Rdio 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 tcnicas invasoras ao corpo. O uso de radionuclidos foi outro desenvolvimento inicial da medicina nuclear. Os radioistopos so pequenas quantidades de material radioactivo colocadas num corpo, sendo inicialmente usados com finalidade teraputica. Mais tarde viriam a constituir-se como instrumentos para diagnsticos. A primeira utilizao de radioistopos num humano com finalidade de diagnstico, foi o Pa (228) para estudar o tempo de circulao do sangue no corpo humano ( Colombetti 1979). A radioactividade artificial foi descoberta em 1934. O primeiro uso clnico foi em 1937 quando um material radioactivo foi usado, para tratar um paciente com leucemia na Universidade de Berkeley na Califrnia. O acontecimento que considerado como sendo o marco da medicina nuclear moderna foi o uso de iodo radioactivo para tratar doenas da tiride. O iodo radioactivo foi injectado no paciente e seguiu o trajecto normal que o iodo seguiria. Foi absorvido pela tiride onde era usado tanto para fins teraputicos como para obteno de imagens. Durante a segunda guerra mundial, foram recrutados biologistas para o campo do radar. Este trabalho preparou-os para o desenvolvimento da electrnica na medicina nos anos ps guerra. No entanto surgiram dois problemas. A gerao seguinte de biologistas no tiveram o benefcio desses conhecimentos e a tecnologia avanou to rapidamente que depressa ultrapassou at os conhecimentos da gerao da guerra. Obviamente uma ponte sobre a lacuna entre conhecimento tcnico e biologia era necessria. Assim mdicos e biologistas com interesse e 2.1 - Medicina Nuclear no passado compreenso da engenharia para alm de engenheiros electrotcnicos com interesse na biologia, transformaram-se assim nos primeiros bioengenheiros. Aqueles que se interessavam principalmente com medicina tornaram-se nos primeiros engenheiros biomdicos. Em 1946 foi relatado que aps um tratamento com iodo radioactivo o crescimento do cancro no paciente tinha completamente desaparecido. Na dcada de 1950 o uso da medicina nuclear alargou-se e na dcada de 60 tornou-se numa especialidade de estudos mdicos. Nos anos 70 era utilizada para visualizar o bao, fgado, crebro, e sistema gastrointestinal. Os rdiofarmacos comearam ento a ser usados para o diagnstico de doenas do corao nos anos 80. Avanos tecnolgicos tinham que ser feitos de modo a acompanhar os avanos na rea mdica. Cmaras tinham que ser desenvolvidas de modo a poder detectar material radioactivo e fazer imagens da anatomia que sustinha o material radioactivo. O primeiro exame rectilneo foi o engenho de Cassen. Um grande desenvolvimento nesta rea deveu-se ao aparecimento da cmara gama. Esta foi a primeira cmara estacionria que conseguiu ver um rgo por inteiro. Esta evoluo fez com que nos anos mais recentes protocolos de aquisio tais como PET, SPECT e MRI fossem desenvolvidos. Tanto o PET como o SPECT fornece uma viso tridimensional da regio de interesse. Hoje em dia existem mais de 100 procedimentos de medicina nuclear e a medicina nuclear pode ser aplicada a qualquer rgo do corpo humano. Se os avanos na medicina nuclear continuarem a avanar ao ratio actual a possibilidade de novos desenvolvimentos e interminvel.

1.3 - Factos acerca da Medicina Nuclear


Nos EUA 10 a 12 milhes de exames de medicina nuclear so efectuados anualmente Os procedimentos da medicina nuclear so dos procedimentos mais seguros, mais eficientes do ponto de vista de custos e nicos por si s. Informao acerca da funo e estrutura de qualquer rgo pode ser obtido pela medicina nuclear.

Captulo II - Medicina Nuclear, SPECT e PET


A quantidade de radiao recebida num procedimento de analise nuclear pode ser equiparada a quantidade de radiao recebida num exame de raio-x. Existem cerca de 2,700 fsicos de medicina nuclear a tempo inteiro e 14000 tcnicos em toda a nao (1997). Existem mais de 100 exames disponveis em medicina nuclear. Os exames de medicina nuclear esto catalogados como sendo dos mais seguros teste / diagnstico existentes.

1.4 - Computadores na Medicina Nuclear


1.4.1 - Introduo
Medicina nuclear conta com os computadores para adquirir, processar, transferir informao e imagens. A histria dos computadores na medicina nuclear e radiologia mesmo assim bastante curta. Nos anos 60 e princpios da dcada de 1970, CT (Tomografia Computorizada) e subtraco angiogrfica digital foram introduzidos na prtica clnica pela primeira vez. A subtraco angiogrfica digital usa computadores para digitalmente subtrair de uma angiografia padro os efeitos de tecidos moles e ossos circundantes, levando assim a uma melhoria das imagens disponveis para diagnstico. Tomografia Computorizada (CT) usa os computadores para reconstruir digitalmente informao seccionada usando vrios tipos de algoritmos de reconstruo de imagem tais como a projeco inversa filtrada. O pior elemento numa unidade CT era sem dvida nessa altura o computador, mas sem ele no era possvel executar um CT. SPECT e MRI foram desenvolvidas tecnologias alguns anos aps o CT e tambm necessitam de um computador para ser possvel a execuo de um exame. No caso do MRI o computador tem um papel de maior importncia, dado que controla o movimento da torre e todo o equipamento mecnico relacionado. No caso do SPECT, como no CT, a reconstruo da imagem tem que ser feita por computador. O uso de computadores em medicina nuclear tem tambm as suas razes na fsica das partculas de grande energia e tambm na fsica nuclear. Estas duas disciplinas usam anlises estatsticas de grandes nmeros de contagem de fotes, colectados e processados por um computador. primeiramente atravs dessa anlise e processamento que descobertas experimentais em medicina nuclear so feitas. O objectivo da medicina nuclear no a descoberta de novas leis da fsica ou de partculas, mas sim a de deteco e diagnstico de uma doena, mas como todos os outros mtodos, no se baseia na deteco de uma grande nmero de fotes para atingir uma concluso acerca do objecto em estudo. O problema de arquivar e transmitir essa larga quantidade de informao comeou a ser resolvida na dcada de 1970. Tentativas anteriores de transmitir imagens mdicas de um hospital para outro ou de uma clnica para outra para a visualizao e anlise foram encorajadas, mas a perda de qualidade de sinal, e em particular resoluo, degrada severamente a qualidade de imagem final. Ento 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 esperana de criar um departamento de radiologia digital totalmente controlado por computador.

1.4.2 - Imagens Digitais


De maneira a uma melhor compreenso dos requisitos na aquisio e transferncia de imagem em radiologia e em particular medicina nuclear, alguma terminologia bsica necessria. Para incio uma imagem digital essencialmente uma disposio ou coleco 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 trs dimenses constituda por valores inteiros que fazem um nmero varivel de bits. Dependendo do formato e do sistema computacional usado, uma imagem representada por uma matriz de nmeros num computador ter ligada a si informao na forma de um cabealho, informao esta que fornece detalhes sobre a imagem tais como: dia do exame, nome do paciente e nmero 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 nmero de bits para representar cada pixel e o nvel de rudo presente na imagem.

10

Captulo II - Medicina Nuclear, SPECT e PET


Se a matriz da imagem composta por apenas por poucos pixels e de grande dimenso, a resoluo resultante ser baixa. Se a matriz da imagem composta por muitos pixels de reduzida dimenso, e a falta de nitidez subjacente imagem no muito severa, a resoluo ser boa. Se o tamanho do pixel muito inferior a falta de nitidez da imagem subjacente, a imagem ir aparecer com algo parecido a borres. O nmero de bits usado para representar cada pixel dever idealmente depender da quantidade de rudo presente na imagem. Quanto maior for o nvel de rudo na imagem inicial, menor ser o nmero de bits necessrios para definir a informao que esta contm. 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 aquisio de imagem exige um processamento de imagem muito mais elevado, alm de maior capacidade de armazenamento e manipulao, 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 diagnstico (no caso de imagens mdicas). A maneira na qual uma imagem de medicina nuclear adquirida e o protocolo de aquisio 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 clnica.

1.4.3 - Aquisio de Imagem


Imagens de medicina nuclear podem ser adquiridas num formato digital usando, por exemplo, um scanner SPECT. A distribuio do radionucleido no corpo do paciente corresponde imagem analgica. Uma imagem analgica aquela que tem uma distribuio contnua da densidade representando a distribuio contnua de radionuclido acumulada num rgo particular. Um melhor exemplo de uma imagem digital ser uma fotografia tpica onde a distribuio contnua 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 so digitalizados e guardados no computador na forma de uma matriz de imagem. As matrizes tpicas usadas em aquisio de imagem SPECT so: 256x256, 128x128, 128x64, 64x64. A terceira dimenso corresponde ao numero de camadas transaxiais, frontais ou coronais usadas para definir o rgo que esta a ser pesquisado. Um exame tpico SPECT tem um limite de armazenamento de 16 bits por pixel. Quando um exame SPECT tiver sido completamente executado, a informao sem tratamento contida na matriz de imagem denominada de informao projectada e est pronta a ser reconstruda. O processo de reconstruo coloca a informao a sua forma final digital pronta a ser transmitida para outro computador ou sistema para posterior visualizao e anlise fsica.

1.4.4 - Concluso
O tratamento de imagens mdicas moderno no seria possvel sem os avanos que ocorreram no software e hardware nos ltimos 30 anos. A radiologia automatizada oferece potencialidades de grande poupana de custos e reduzido trabalho humano. No entanto devemos ter em mente que os computadores no so perfeitos e at instrumentos como digitalizadoras (de extrema importncia para a terapia de radiao) podem ter problemas. Sem os feitos tecnolgicos que se iniciaram a 100 anos no dia 8 de novembro de 1895 e continuando hoje em dia com a evoluo do hardware, software e equipamento, a radiologia como uma disciplina mdica no existiria.

1.5 - Segurana e Controlo da Qualidade


Os procedimentos de medicina nuclear so actualmente considerados dos mais seguros para diagnsticos por imagem disponveis aos pacientes actualmente. administrado aos pacientes apenas uma pequena quantidade de rdio frmaco. O procedimento de medicina nuclear expe o paciente a menos radiao que um raio-x. A maioria das pessoas esto expostas a quantidades de radiao muito mais superiores diariamente do que pensam. Radiao do solo, rochas espao e dos tomos de carbono e potssio nos seus prprios organismos perfazem 85 % da exposio anual de uma pessoa a radiaes. Televises a cores e detectores de fumo so alguns dos equipamentos do dia a dia que nos expe a radiao. O resto contribudo pelos materiais radioactivos e raio-x usados na medicina. Por isso em mdia os procedimentos da medicina nuclear contribuem como que com alguns meses de vida diria em termos de radiao. Os fsicos so especialmente treinados de modo a administrar as dosagens apropriadas de

11

Captulo II - Medicina Nuclear, SPECT e PET


rdio frmacos para expor os pacientes apenas ao estritamente necessrio protegendo-os de radiao desnecessria.

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 aplicaes esto a ser desenvolvidas todos os dias por todo o mundo. Uma das reas de maior avano a rea dos rdio frmacos. Actualmente o techtenium o rdiofarmaco mais usado de momento para imagem na medicina nuclear. Ate poucos anos tinha havido pouco esforo para tentar arranjar novos rdiofarmacos. Os cientistas aperceberam-se agora que certos procedimentos obteriam resultados mais satisfatrios se usassem rdiofarmacos 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 rdioistopo com perodo 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 rdiofarmacos e a rea das drogas orfs. So drogas que so desenvolvidas para o tratamento de doenas raras. estimado que 1 em cada 12 pessoas tem uma doena ou condio rara. estas condies raras no recebem tanta ateno por parte das empresas de investigao uma vez que estas se preocupam mais com as doenas dos pacientes da maior parte da populao e ignoram os pacientes raros ou pequenos. A medicina cardiovascular tambm uma rea de grande crescimento mas a nfase nesta rea vai para a instrumentao. Novos sistemas de cmaras esto a ser desenvolvidas de modo a obter imagens do corao muito mais pormenorizadas e precisas. As novas cmaras tm vrias cabeas ao contrrio das antigas que s tinham 2 cabeas. Estas cmaras so usadas nos sistemas SPECT. Cmaras digitais esto tambm a ser desenvolvidas. Com as cmaras antigas o sinal captado a partir da emisso de radiao por parte do radio farmacutico era um sinal 2.2 - Equipamento SPECT actual analgico. O sinal era ento convertido para um (Hospital Universitrio de Coimbra) sinal digital por um processador na cmara. O uso de sinais analgicos produz alguns erros nas leituras que poderiam ser evitadas se usasse um sistema apenas digital. A primeira cmara totalmente digital foi produzida pela Summit Nuclear. Neste sistema h um conversor analgico para digital dentro do circuito de modo que o sinal de sada do circuito digital. Estas cmaras permitem maior resoluo espacial, resoluo de energia e melhores capacidades de processamento. Com os avanos na medicina nuclear ir haver uma revoluo no campo da medicina. Passar-se de uma viso de ver a doena como o ataque de um agente externo ao corpo para uma viso de que a doena e uma disfuno de produtos gentico tais como substratos e enzimas. Os procedimentos mdicos actuais consistem na medida do contedo de fludos corporais ou bipsias de modo a determinar o tipo de doena. Com os avanos na medicina nuclear estes procedimentos iro ser substitudos por procedimentos que medem a qumica no interior do organismo. Os radioistopos sero utilizados para ver exactamente a constituio qumica de todo o corpo. Ser dado mais importncia ao lado molecular da medicina. A medicina nuclear permite estudar a biologia humana e a doena a um nvel gentico. O uso de rdiofarmacos para determinar o excesso ou falta de actividade qumica em determinadas regies do corpo. Assim os mdicos podero afirmar o que est errado a nvel gentico no paciente. Ao ser capaz de apontar especificamente a disfuno gentica ou desordem o mdico poder prescrever medicamentos que iro contrabalanar o problema e a fonte do problema. A nova perspectiva gentica ir tambm 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 doenas neuronais e de comportamento pelo estabelecimento da relao das doenas com desequilbrios qumicos. De modo a estes desenvolvimentos ocorrerem tem que haver desenvolvimento na rea de deteco de radiao, processamento de dados e sistemas de visualizao.

12

Captulo II - Medicina Nuclear, SPECT e PET


Um novo mtodo que est a ser desenvolvido a deteco dos nveis de oxignio em tecidos. Se uma rea tem um abastecimento deficiente de oxignio e sinal de que poder haver problemas a nvel vascular ou de tumores. Os rdiofarmacos que esto a ser usados so o iodo - 123 e o techtenium. Estes radioistopos agregam-se a reas de nveis de oxignio baixos e podem ento ser scannerizadas mostrando os tecidos que se encontram privados de oxignio. Este tipo de obteno de imagem denominado de hypoxia. A hypoxia indica-nos se encontram clulas viveis numa determinada rea. Isto pode ser til na determinao de que parte do crebro foi afectada em pacientes que tenham sofrido um enfarte ou quanto do tecido muscular do corao foi afectado aps um ataque cardaco. De acordo com testes feitos em animais a hypoxia ser extremamente til no diagnostico e tratamento do corao, crebro e extremidades. Tambm se concluiu que os rdiofarmacos tal como strontium-89 podem ser utilizadas em terapia radionuclida. administrado a pacientes que tenham dores de ossos intratveis. Os radionuclidos diminuem a dor sentida pelo paciente reduzindo ao mesmo tempo a quantidade de narcticos que este teria que tomar. Em 20% dos pacientes e mesmo eliminada a necessidade de uso de medicao. Quando a dor reaparece aps o tratamento geralmente no tem a mesma expresso que anteriormente. Estudos de sono esto tambm, a ser efectuados na rea de medicina nuclear. Os medicamentos actualmente no mercado para perturbaes a esse nvel induzem sono mas j se provou que este sono menos reabilitativo que o sono biolgico normal. Um estudo feito em gatos descobriu que existe uma molcula no corpo responsvel por induzir sono. Pensa-se que esta molcula viajara pelo fluido da espinal medula passando pela barreira sangue crebro agregandose a receptores no crebro. Pesquisadores de medicina nuclear esto a tentar etiquetar a molcula com carbono-11 ou nitrogenio-13. Uma vez a molcula etiquetada esta pode ento ser scannerizada no crebro para determinar quais os receptores no crebro responsveis por induzir sono. Esta investigao espera produzir uma droga 2.3 - Resultado de exame SPECT que interaja com os receptores do sono no crebro produzindo um sono verdadeiramente reabilitador tal como o sono fisiolgico normal. Com todos os avanos na medicina nuclear, possvel perder de vista o mais importante aspecto que a qualidade de cuidados a preos acessveis para todos os pacientes. Alguns fsicos debatem actualmente se todos os detalhes de procedimento dos exames e obteno de imagem so necessrios. Olhando para a maioria da populao, a maioria dos diagnsticos pode ser feita correctamente usando um mnimo de procedimentos. Por exemplo alguns mdicos defendem exames aos ossos para pessoas que tenham dores nas costas. Um scan de ossos d uma imagem muito detalhada mas tambm 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 coronrios. Estes pacientes tinham passado por procedimentos de obteno de imagens extensos de modo a determinar se a operao era necessria. Foi provado que muitos destes pacientes no necessitavam de estudos de imagem. A simples monitorizao dos sinais vitais expresso sangunea seriam suficientes. A medicina nuclear continuar a criar novas tcnicas e novos procedimentos, mas o paciente e no a tecnologia tero que ser a principal preocupao.

2 SPECT (Single Photon Emission Computed Tomography)


2.1 - Introduo ao Single Photon Emission Computed Tomography

13

Captulo II - Medicina Nuclear, SPECT e PET


Emisso (3-D) tridimensional da tomografia computorizada (ECT) fornece um olhar qualitativo e quantitativo na distribuio de um volume de radioistopo aps a sua injeco no corpo humano. O ECT junto com (a 2-D) imagem planar bidimensional so as tcnicas de aquisio de imagem principais, usadas em todos os departamentos de medicina nuclear. ECT tridimensional - um processo que envolve a rotao de at trs cmaras foto - sensveis (cmaras gama) em torno de um paciente - resulta numa imagem 3-D da distribuio de um rdioistopo injectado que apontado geralmente para um rgo em particular, como por exemplo o corao. A imagem 3-D obtida assim o resultado da reconstruo de uma srie de projeces 2 D, que de seguida " empilham-se " de modo a criar a terceira dimenso. SPECT corresponde a Single Photon Emission Computed Tomography. Em primeiro lugar SPECT uma forma de Tomografia Computorizada. Como o nome sugere, a emisso de raios gama constituem a fonte de informao, em vez de transmisses de raios - X tal como utilizado em Tomografia Computorizada. Ao contrrio do raio X Computed Tomography (CT) ou Magnetic Resonance Imaging (MRI) o Single Photon Emission Computed Tomography (SPECT) permite-nos a aquisio de informao funcional sobre o orgo de um paciente ou o sistema especfico do corpo. A radiao interna administrada por meio de um frmaco que etiquetado como um istopo radioactivo. Este rdiofarmaco, ou tracer, injectado, ingerido, ou inalado. Estes rdiofarmacos podem ser por exemplo o: Technetium-99m e Thallium-201. Um rdiofarmaco uma protena ou uma molcula orgnica que tem ligado a si um rdionuclido. As protenas e molculas orgnicas so seleccionadas com base nas suas propriedades de absoro dentro do corpo humano. Por exemplo alguns rdiofarmacos so colectados nos msculos do corao e so utilizados para aquisio de imagem SPECT cardaca. Outros so dimensionados para os pulmes e so usados para exames SPECT de perfuso. Muitos mais so utilizados de maneira a possibilitar a execuo de exames SPECT noutras reas do corpo. Depois o istopo radioactivo deteriora-se, tendo por resultado a emisso de raios gama. Estes raios gama do-nos um retracto de o que est a acontecer dentro do corpo do paciente. Assim, num modo geral, um rgo saudvel ir absorver uma determinada quantidade de rdiofarmaco, que ir aparecer como uma rea brilhante numa imagem SPECT. Uma absoro anormal de rdiofarmaco ir ter como consequncia um surgimento de uma rea mais clara ou mais escura do que o brilho padro na imagem SPECT, levando suspeita da presena de um estado de doena. Estes raios gama permitem-nos uma viso interna do corpo humano usando a ferramenta mais essencial na medicina nuclear, a cmara gama. A cmara gama pode ser usada no processamento latente planar de modo a adquirir imagens 2-D, ou em processamento latente SPECT para adquirir imagens 3dimensionais. A cmara gama adquire os raios gama que so emitidos de dentro do paciente, permitindonos assim a reconstruo de uma imagem de onde os raios gama so emitidos. A partir desta informao podemos determinar como um orgo ou um sistema particular est a funcionar. De salientar que existem vrios centros SPECT em Portugal com particular incidncia nos grandes centros urbanos (Lisboa e Porto). Mas como cada vez mais este tipo de exames se torna mais acessvel a todos e se revelam como exames de extrema importncia, mais pontos do pas tambm j possuem ou esto prestes a ter centros SPECT, tais como: Coimbra e Braga.

2.2 - Histria 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 fotes de NaI arranjados de uma forma rectangular em torno da cabea do paciente. O primeiro dispositivo comercial de Single Photon-ECT (SPECT) era similar no desenho ao projecto MARK IV mas tinha 32 detectores de fotes e foi chamado o Tomomatic-32. As primeiras aplicaes do ECT resultaram em imagens que do ponto de vista do diagnstico no eram usveis, e a tcnica no foi aceite de uma forma generalizada. s quando os mtodos evoluram durante a introduo do raio-x CT por Hounsfield e Cormack no ECT da medicina nuclear, que esta modalidade passou a ganhar a ateno da comunidade mdica que relacionada com anlise de imagem. Os algoritmos de reconstruo inventados para o CT de raio-x tiveram que ser reformulados para o ECT de modo a ter em ateno efeitos de atenuao de fotes e de espalhamento no corpo humano para alem das limitaes mecnicas e elctricas dos detectores. Quando se conseguiu tcnicas de reconstruo de imagem tais 2.4 - Exame de MRI como o FBP (projeco inversa filtrada) produziram-se imagens de ECT que pela primeira vez permitiram anlise qualitativa e que foram consideradas

14

Captulo II - Medicina Nuclear, SPECT e PET


quantitativamente vlidas para uso clnico. Ao contrrio de outras modalidades tais como MRI e raio-x, o ECT obtm imagens da funo do organismo e no da anatomia no sentido estrito. Isto devido, por exemplo, o SPECT envolve a deteco de radiao gama emitidos somente por tomos radioactivos, chamados radionuclidos, tais como o Techtenium -99m e Thalium-201. Um rdiofarmaco uma protena ou molcula orgnica com um radionuclido ligado a si. As protenas e molculas orgnicas so seleccionadas baseadas no seu uso ou nas suas propriedades de absoro por parte do corpo humano. Por exemplo alguns rdiofarmacos acumulam - se no msculo do corao e so por isso usadas para fazer SPECT cardacos. Assim no caso geral um corao, ou pulmes ou crebro saudveis iro absorver uma determinada quantidade do rdiofarmaco, que aparece como uma rea mais clara nas imagens obtidas por SPECT. Hoje em dia quase todos os pacientes cardacos recebem um ECT planar ou um SPECT como parte dos seus exames para detectar e avaliar o estado de desenvolvimento de uma doena coronria. Os exames SPECT ao fgado e crebro so tambm reas de grande utilizao do SPECT. O SPECT usado de uma forma rotineira para ajudar no diagnstico e avaliao de cancros, enfartes, doenas de fgado para alem de outras anormalidades funcionais.

2.3 - Teoria e Instrumentao


Assim como num exame raio-x CT, aquisio de imagem SPECT envolve a rotao de um detector de fotes em volta do corpo humano de maneira a adquirir informao de diversos ngulos. Usando esta tcnica procuramos as posies e concentraes da distribuio de radionuclidos. Por causa das fontes de emisso (radionuclidos injectados) se encontrarem dentro da cavidade corporal, esta tarefa de maior dificuldade de execuo do que para o raio-x CT, onde a posio e fora da fonte de emisso (exterior ao corpo humano) sempre conhecida. Isto , no raio-x CT a atenuao medida, no a fonte de transmisso. De maneira a compensar a atenuao ocorrida pela emisso de fotes pelos tracers injectados no corpo, o SPECT contemporneo usa algoritmos de reconstruo de maneira a aumentar a resoluo. A aquisio de imagem em SPECT inferior a do PET por causa da sensibilidade e resoluo alcanadas. Diferentes radionuclidos so usados em SPECT, sendo que todos eles emitem um foto apenas (usualmente a volta dos 140keV), em vez de emisso de positres (511 keV) como usado em PET. Como apenas um foto emitido pelos radionuclidos usados em SPECT, uma lente especial denominada de colimador usada para adquirir toda a informao resultante de vrios ngulos a volta do corpo. O uso de um colimador resulta numa tremenda diminuio da eficincia de deteco quando comparada com PET. Para tomografias de emisso de positres, a colimao alcanada de uma maneira natural pelo facto de que um par de fotes detectados (raios gama) podem ser localizados na sua origem desde que sigam uma trajectria ao longo da mesma linha de produo. Em PET existem pelos menos 500 detectores capazes de detectar um istopo PET a qualquer momento, enquanto que em SPECT existem apenas 1 a 3 colimadores. Resolues superiores requerem sensibilidade superior e a resoluo do SPECT muitas vezes inferior que a atingida em PET. A resoluo resultante que pode ser utilizada (cerca de 7mm) para SPECT inferior resoluo do PET num factor de 3 ou 4. Mesmo sendo a resoluo resultante da aquisio de imagem em SPECT no to boa como a obtida em PET, a disponibilidade de novos rdiofarmacos, particularmente para a cabea e crebro, e tendo em conta aspectos econmicos (um exame SPECT custa cerca de um tero de um exame PET) e prticos da instrumentao SPECT faz deste mtodo de emissao tomogrfica atractiva para estudos clnicos.

2.4 - Aquisio e Processamento de imagem


O SPECT tem como base a determinao da concentrao da quantidade de radionuclido num determinado e especfico orgo em funo do tempo. A introduo do rdioistopo Tc-99m por Harper que emite um s foto 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 foto facilmente detectado pelas cmaras gama. No entanto um problema tcnico de engenharia envolvendo a colimao destes raios gama, antes

15

Captulo II - Medicina Nuclear, SPECT e PET


de entrarem propriamente na cmara gama, teve que ser resolvido antes do SPECT se poder afirmar como uma modalidade de imagem vivel. Sendo assim essencial em SPECT, a colimao dos raios gama emitidos pela distribuio no corpo onde foram injectados os radionuclidos. Os colimadores para SPECT so 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 atravs dos quais e apenas atravs dos quais os raios gamas so 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 so colocados directamente por cima de um cristal muito delicado de NaI que existe em todas as cmaras gama. Qualquer cmara gama assim equipada com um colimador apelidada de cmara Anger, devido ao nome do seu inventor. Os raios gama que sejam emitidos numa direco que coincida com os canais do colimador passaro pelo colimador sem serem absorvidas, e interagiro com o cristal de NaI criando luz. Por detrs do cristal, uma rede de tubos fotomultiplicadores (sensveis a luz) recebero a luz para processamento, e a partir da anlise destes sinais de luz so constitudas as imagens SPECT. Dependendo do tamanho da cmara de Anger orgos inteiros tais como o corao ou fgado podem ser visualizados em imagens SPECT. Cmaras de Anger maiores so usadas para obter imagens de todo o corpo humano, como por exemplo para visualizao da estrutura ssea. Para os raios gama emitidos pelos rdiofarmacos tpicos de SPECT h duas importantes interaces com a matria. A primeira envolve o espalhamento dos raios gama resultante da interaco com as molculas e tomos (DNA) no corpo humano. Este espalhamento chamado como Compton Scattering. Alguns fotes que sofrem esta influncia so deflectidos para fora da cmara Anger e perdidos para o processo de deteco. A segunda interaco consiste na absoro por parte de um tomo do corpo do foto com a elevao do potencial energtico ou at mesmo com a libertao de um electro. Este processo chamado de efeito fotoelctrico e foi detectado por Einstein nos metais tendo recebido o prmio Nobel pela sua descoberta. Ambos os processos resultam em perdas ou degradao da informao acerca da distribuio do rdiofarmaco no corpo. O segundo processo cai no conceito geral de atenuao em termos de imagens mdicas e uma rea de investigao activa. A atenuao resulta na reduo do numero de fotes que chegam a cmara de Anger. A quantidade de atenuao sentida por cada foto depende no caminho que este percorre no corpo e da sua energia. Os fotes que experimentam o espalhamento so geralmente reflectidos, perdendo muitas vezes energia, acabando assim por ser absorvidas ou reflectidas para fora do ngulo de recepo da cmara de Anger. Em qualquer um dos casos, o foto e a informao que este transporta consigo acerca da distribuio do rdiofarmaco no corpo, no vai ser detectado e assim considerado perdido devido a atenuao. Aos 140KeV Compton Scattering a causa mais provvel de interaco de um foto de radiao gama com a gua ou tecidos do corpo. Uma percentagem mais pequena de fotes perdida devido a interaco fotoelctrica. possvel, que os fotes quando sujeitos ao efeito de Compton Scattering serem espalhados para o ngulo de viso da cmara de Anger. Estes fotes no entanto no transportam informao til acerca da distribuio do rdiofarmaco no corpo uma vez que no indicam de onde no corpo foram emitidos. Como resultado a deteco de fotes espalhados no SPECT levam a perdas de contraste na imagem bem como imagens tecnicamente imprecisas. A aquisio e processamento de uma imagem SPECT, quando correctamente efectuada, envolve compensaes e ajustes de muitos parmetros fsicos e de parmetros do sistema. Uma seleco destes inclui: atenuao, espalhamento, uniformidade e linearidade de resposta do detector, resoluo geomtrica espacial e sensibilidade do sistema, truncagem da imagem, shift mecnico da camera ou gantry, shift electrnico, eixo de rotao de calibrao, rudo de imagem, espessura das fatias de imagem, tamanho da matriz de reconstruo e filtros, intervalos angulares e lineares de amostragem, variaes estatsticas nas contagens de fotes detectados, mudanas no campo de viso da cmara de Anger com a distncia fonte e tempo morto do sistema. A calibrao e monitorizao de muitos destes parmetros caem na designao geral de Controlo de Qualidade e so usualmente efectuadas por um tcnico de medicina nuclear certificado ou mdico fsico. Nesta lista a colimao tem o maior efeito em termos de resoluo espacial e sensibilidade do sistema, sendo a sensibilidade relacionada com o nmero de fotes por segundo que so detectados. A resoluo e a sensibilidade do sistema so as medidas fsicas mais importantes na qualidade da performance de um sistema SPECT. A melhoria destes parmetros raramente conseguida simultaneamente na prtica apesar de ser o grande objectivo de qualquer investigador na rea SPECT. A distribuio do radionuclido no corpo do paciente corresponde imagem analgica (imagem que tem uma distribuio contnua de densidade) que representa a concentrao de um radionuclido num

16

Captulo II - Medicina Nuclear, SPECT e PET


determinado orgo. A radiao gama proveniente do paciente digitalizada e armazenada numa matriz ou vector de imagem. A 3 dimenso na matriz o nmero de fatias transaxiais, coronais ou sagitais usadas para representar o orgo. uma vez o scan SPECT terminado, a informao obtida na matriz de imagem e chamada de dados de projeco e esta pronto para ser reconstrudo. A reconstruo coloca essa informao no seu formato digital final de modo a poder ser analisada pelo fsico.

2.5 - Reconstruo de Imagem


2.5.1 - Projeco Inversa Filtrada
O algoritmo mais comum usado na reconstruo tomogrfica de informao clnica o mtodo da projeco inversa filtrada. Existem tambm outros mtodos, mas estes sero discutidos na seco sobre mtodos de reconstruo iterativos. Para a reconstruo da imagem final so necessrias cinco fases: projeco da informao, transformada de Fourier da informao, filtragem da informao e filtragem inversa. 1. Projeco da informao medida que a cmara SPECT gira em volta do paciente, cria uma srie de imagens planares chamadas projeces. Em cada paragem, apenas fotes movendo-se perpendicularmente face da cmara passam atravs do colimador. Como muitos desses fotes tem como origem vrias zonas diferentes em profundidade do paciente, o resultado uma sobreposio de todos os rgos, sujeitos a aco do rdioistopo, que se encontrem no mesmo caminho especfico, da mesma maneira que uma radiografia raio-x a sobreposio de todas as estruturas anatmicas de 3-D para 2-D. Um estudo SPECT consiste em muitas imagens planares retiradas desta forma e tendo em conta vrios ngulos diferentes. Aps a aquisio de todas as projeces, estas so sub divididas, tirando todas as projeces referentes a uma parte, a uma pequena fatia do paciente. Todas as projeces referentes a cada fatia so ordenadas e colocadas numa imagem chamada sinograma. 2. Transformada de Fourier da informao. Se a informao contida no sinograma fosse reconstruda neste ponto, artefactos iriam aparecer na imagem reconstruda devido a natureza da subsequente operao de projeco inversa. Adicionalmente, devido a natureza da radioactividade, existe um rudo inerente na informao que faz com que as imagens reconstrudas tendam a ter um aspecto pouco suave. De maneira a evitar estes dois factores necessrio fazer uma filtragem da informao. Quando se efectua a filtragem da informao, esta pode ser feita directamente no espao da projeco, que significa que temos de multiplicar a informao por um factor de suavizao (smoothing kernel). Este processo conhecido como convoluco. A convoluco uma tarefa muito intensiva do ponto de vista computacional e por isso til evit-la sempre que possvel. sabido que a convoluco no domnio do tempo corresponde a uma multiplicao do domnio das frequncias. Isto significa que qualquer filtragem feita por uma operao de convoluco do domnio dos tempos pode ser muito facilmente ser feita por uma multiplicao no domnio das frequncias. Em SPECT faz-se uma transformao similar da informao projectada para o domnio das frequncias, domnio este onde se pode fazer uma filtragem mais eficiente da informao. A transformada de que se faz uso para a passagem de domnio denominada de Transformada de Fourier Unidimensional. 3. Filtragem da informao. Uma vez que a informao tenha sido transformada para o domnio das frequncias, ento filtrada de maneira a suavizar a aco do rudo estatstico. Existem muitos filtros diferentes disponveis para efectuar esta operao e todos tem certas caractersticas diferentes. Por exemplo alguns filtros iro efectuar uma suavizao to forte que deixar de haver na imagem contornos afiados, e isso faz com que haja uma degradao na resoluo da imagem final. Ha tambm filtros que mantm uma resoluo final muito alta mas a suavizao efectuada muito ligeira.

17

Captulo II - Medicina Nuclear, SPECT e PET


Assim os filtros tipicamente utilizados so: filtro de Hanning, Butterworth, Cosseno passa baixo, Weiner, etc... . Independentemente do filtro utilizado, o resultado final ser uma imagem que relativamente sem rudo e agradvel a visualizao. 4. Transformada inversa da informao Como a informao filtrada encontra-se no domnio das frequncias temos que proceder a transformao inversa para colocar novamente a informao no domino espacial de maneira a obter a informao x,y,z da distribuio 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 informao resultante e similar a informao do sinograma original excepto no aspecto que a informao final se encontra suavizada e praticamente sem rudo. 5. Projeco inversa O passo mais importante na reconstruo envolve um processo conhecido como projeco inversa. Como a informao original foi adquirida deixando apenas que os fotes emitidos perpendicularmente a face da cmara entrem na cmara, a projeco inversa faz um esbatimento da informao binria da cmara no sinograma filtrado ao longo das mesmas linhas de onde o foto foi emitido. Regies onde as linhas de diversos ngulos da projeco inversa se intersectam representam reas que contm uma alta concentrao de rdioistopo.

2.5.2 - Mtodo dos parmetros directos


Tem sido mostrado atravs da aquisio de imagem planar dinmica que o metabolismo de tracers no miocrdio podem ser modelizados atravs de uma funo exponencial dual no tempo. Este modelo corresponde ao tracer ser levado at um particular compartimento do corao, ser metabolizado e expelido desse compartimento. A taxa qual o tracer metabolizado e expelido modelado por essa funo no tempo. Tem sido tambm sugerido que os parmetros desta funo so uma boa indicao da viabilidade geral do corao, isto , se o tracer for expelido com taxas elevadas que o corao se encontra num estado saudvel enquanto zonas no saudveis tm taxas baixas. Se ns soubermos o tempo total do comportamento do corao, podemos ir um passo adiante e supor que regies individuais do corao tm o mesmo comportamento funcional. Devido ao facto de que em SPECT, ns lidarmos com representaes por pixels de objectos, natural aplicar a nossa funo exponencial dual a cada pixel do corao. Desta maneira a nossa funo pode ser aplicada em ordem ao tempo a cada pixel, e assumir que cada pixel tem um comportamento especfico. Para tal necessrio que cada pixel siga esta equao: P(T) = A.e-l*t + B.e-m*t +C possvel determinar os parmetros atravs de optimizao computacional. O resultado desta reconstruo de imagem so cinco imagens representando as cinco variveis desconhecidas. A partir deste mtodo, os pixels com rpidas taxas cinticas, representam regies que podem ser facilmente diferenciadas de regies mais lentas.

2.5.3 - Mtodo dos mnimos quadrados com restrio linear


A desvantagem primria da aproximao dos parmetros directos o facto que ns termos que assumir uma determinada forma da funcionalidade do movimento do tracer. ainda desconhecido se fazer essa suposio para todas as circunstncias verdade e tambm pode no ser verdade que o tracer pode ser descrito por uma funo exponencial dual em todos os instantes de tempo. Por estas razes extremamente vantajoso desenvolver um mtodo de reconstruo totalmente dinmica, que no faa qualquer tipo de suposies acerca do comportamento do tracer. Assim uma aproximao possvel usar o mtodo dos mnimos quadrados com restries lineares (LLS). A LLS aproximao no faz qualquer tipo de suposio quanto forma funcional de alterao de actividade, mas supe minimamente que a actividade de cada pixel apenas decresce no tempo. Este suposio correcta no evento de que o tracer administrado antes do exame ter lugar e que a maior parte do tracer est presente no orgo de interesse no incio do exame.

18

Captulo II - Medicina Nuclear, SPECT e PET


Quando reconstrudo com LLS, o resultado uma srie de imagens, cada uma delas referindo a distribuio espacial do tracer a um dado instante de tempo. O problema referido como uma restrio linear dos mnimos quadrados porque ns assumimos que a diferena nas actividades num pixel entre imagens consecutivas apenas um valor positivo. Ento, isto assegura que a actividade do pixel continuamente decrescente ao longo tempo.

2.5.4 Reconstruo iterativa


De maneira a incorporar informao dos data sets morfolgicos para o processo de reconstruo, so feitas as seguintes consideraes: a radioactividade continua numa regio anatmica tende a ser homognea (isto , matria cinzenta), as fronteiras entre regies anatmicas so tambm fronteiras entre regies, nas quais, a absoro do tracer similar e finalmente as fronteiras de regies anatmicas podem ser extradas atravs de informao priori com um mtodo apropriado de segmentao. O algoritmo da reconstruo iterativa consiste em combinar um mtodo iterativo rpido com um mtodo de reconstruo com informao priori. Este ltimo baseado no mtodo de reconstruo que incorpora informao morfolgica para o modelo estatstico de Shepp e Vardi usando a regra estatstica de Bayes. A primeira considerao feita no pargrafo anterior pode ser substituda por uma restrio menos severa, onde os pixels dentro de uma regio extrada de informao priori, tendem a ter todos o mesmo valor. Isto pode ser modelado atravs de cadeias de Markov (que equivalente a uma descrio da distribuio de Gibbs). O mtodo de reconstruo HOSP (High-Overrelaxation Single Projection) pode ser derivado do mtodo anterior atravs de uma simplificao do modelo. As correces efectuadas em cada iterao so no simultneas, e assim, permitem o uso o uso de parmetros de grande relaxamento resultando num significativo aumento da velocidade do processo de reconstruo. Este mtodo de reconstruo consiste nos seguintes passos: reconstruo da informao SPECT sem informao morfolgica; emparelhamento destas imagens com imagens morfolgicas; segmentao da informao morfolgica; incorporao da informao morfolgica atravs de cadeias de Markov; validao dos resultados da reconstruo atravs da comparao de perfis e varincia nas regies de interesse.

2.6 - A Cmara Gama


Sendo o rdiofarmaco administrado, necessrio detectar as emisses de raios gama de maneira a obter informao funcional. O instrumento usado em medicina nuclear para a deteco de raios gama conhecido por cmara Gama. Os componentes que constituem a cmara gama so: colimador, detector de cristal, matriz de tubos fotomultiplicadores, circuitos lgicos de posio e um computador de anlise de dados.

2.6.1 Caractersticas da Gama Cmara


Quando a radiao ionizada interage com matria a energia absorvida geralmente convertida em calor. Algumas substncias emitem uma poro desta energia em excesso na forma de luz visvel ou luz ultravioleta e so conhecidos como cintiladores. O brilho de cada emisso proporcional energia depositada no cristal, que por sua vez proporcional energia do foto incidente. Por isso tanto o nmero e energia dos fotes incidentes podem ser registadas. Os detectores de cintilao consistem num cristal de cintilao e num tubo fotomultiplicador. O iodeto de sdio (NaI) o cristal de 2.5 - Equipamento de Medicina Nuclear cintilao mais utilizado. o que tem a maior eficincia de converso - cerca de 13 % da energia depositada no cristal emitida como luz visvel. A aco dos cristais de NaI maximizada pela adio de pequenas quantidades de thalium inico. - Resoluo espacial

19

Captulo II - Medicina Nuclear, SPECT e PET


A resoluo espacial denota a capacidade de um instrumento de reproduzir finos detalhes. A resoluo geralmente expressa como a amplitude "Full-Width-at-Half-Maximum". Quanto maior o valor de FWHM maior o aspecto confuso da imagem (borres). Assim menores valores de FWHM indicam melhor resoluo de deteco. A maioria das cmaras de cintilao de Anger tem resolues espaciais de 6 a 8 mm na superfcie de um colimador de orifcios paralelos de alta resoluo. Os colimadores geralmente melhoram a resoluo por excluso da difuso. - Sensibilidade A sensibilidade ou eficincia demonstra a fraco de fotes incidentes que um sistema de aquisio realmente regista. Fotes de alta energia so mais penetrantes e assim tem menos probabilidade de interagir que os de baixa energia. Cmaras gama modernas funcionam melhor quando trabalham com fotes no intervalo de 100 a 200 KeV. Cristais de maior espessura interceptam uma fraco de fotes mais elevada do que cristais menos espessos. No entanto, infelizmente, cristais de maior espessura degradam a resoluo pois a luz difunde-se num caminho mais longo antes de atingir os tubos foto multiplicadores. As cmaras de Anger localizam cintilaes por comparao dos pulsos de todos os tubos fotomultiplicadores de modo a determinar a posio do maior sinal. A melhor troca entre sensibilidade e resoluo para visualizar Technetium ou Thalium cerca de 0.6 cm de espessura para o cristal. Esta espessura no entanto ineficiente para maiores emisses gama tais como Gallium, Indium e Iodine. Como compromisso geralmente usado um cristal de espessura de 0.95 cm. - Resoluo temporal A resoluo temporal de um sistema tpico de deteco de cintilao de aproximadamente 1.5 a 3 microsegundos. Perdas por tempo morto (tempo entre processamento de sinal no qual no pode registar outros sinais) so de cerca de 10 a 30 % com uma taxa de contagem mxima de 300000 contagens por segundo. Cmaras de multi-cristal podem registar ate 50000 contagens em cada - cristal/tubo fotomultiplicador - resultando assim em contagens de 600000 a 1 milho de contagens por segundo. O cristal mais espesso usado em detectores de multi cristal (1cm) limita no entanto a resoluo espacial.

2.6.2 - Controlo da qualidade da Cmara


Cada cmara deveria ser optimizada diariamente e antes de mudar de radionuclido, de modo a que a sua janela de energia esteja sempre correcta. A uniformidade tambm deveria ser verificada numa base diria usando uma contagem de alto fluxo. Este fluxo pode ser extrnseco (com o colimador ligado) ou intrnseco (com o colimador desligado). Para um fluxo intrnseco o colimador removido e um ponto fonte colocado afastado pelo menos 5 vezes o dimetro do detector. A esta distncia essencialmente um fluxo uniforme de fotes atingir o detector. Um ponto fonte no pode ser usado para efectuar um fluxo extrnseco pois o colimador ira excluir radiao fora de eixos. O fluxo extrnseco deve ser efectuado com uma fonte em forma de disco ou um fantoma cheio de agua.. A vantagem de um fluxo extrnseco que se pode detectar a presena de um colimador defeituoso. A resoluo de cmara e a linearidade deveriam ser verificadas numa base semanal no mnimo. Imagens incorrigidas iro demonstrar geralmente uma ligeira heterogeneidade devido a desequilbrios dos tubos foto multiplicadores ou do prprio cristal. Circuitos de correco so utilizados para tornar a imagem uniforme. Uma variao em uniformidade ate 10 % pode ser tolerada para aquisio planar sem grandes perdas de detalhe. Para aquisio SPECT no entanto variaes 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 presso para efectuar todos os exames nucleares dento de um tempo aceitvel. Para o SPECT isto pode resultar em relativamente elevado rudo estatstico na imagem devido ao nmero limitado de fotes detectados num intervalo de tempo pelo scan.

20

Captulo II - Medicina Nuclear, SPECT e PET


Este facto no impede a capacidade clnica para prognosticar o estado da doena usando o SPECT mas levanta questes de investigao interessantes. Por exemplo uma cmara de Anger tpica equipada com um colimador de energia baixa detecta aproximadamente 1 em cada 10 000 fotes gama emitidos pela fonte na ausncia de atenuao. Este nmero depende do tipo de colimador usado. A resoluo espacial do sistema tambm depende do tipo de colimador e da resoluo intrnseca da cmara Anger utilizada. Uma cmara Anger moderna tem tipicamente uma resoluo de 3 a 9 milmetros. Independentemente do colimador a resoluo no consegue ficar melhor do que a resoluo intrnseca. A mesma ideia se pode aplicar a sensibilidade: a sensibilidade do sistema sempre pior ou igual na melhor das hipteses sensibilidade intrnseca. Os colimadores tm um papel fulcral na definio das caractersticas extrnsecas de imagem de um sistema. A taxa de energia de um colimador indica a mxima energia dos fotes que pode ser eficientemente tratada pelo colimador. Isto geralmente definido como sendo a energia a que menos de 5% dos fotes fora de eixos passam pelo colimador. Colimadores de baixa energia so desenhados para um mximo de energia de 140m a 200 KeV, enquanto colimadores de energia media so eficientes ate 300 a 400 KeV. A taxa de energia do colimador tambm denominada de espessura septal. Apesar do tungstnio absorver fotes mais eficazmente, a maioria dos colimadores so feitos de chumbo devido a estes serem mais baratos.

2.7.1 - Resoluo e Sensibilidade


A resoluo e a sensibilidade de um colimador esto inversamente relacionadas. A melhor resoluo espacial conseguida com um colimador com buracos compridos de pequeno dimetro pois o ngulo de aceitao menor e mais disperso rejeitada. A sensibilidade destes colimadores de alta resoluo no entanto menor, pois menos fotes atingem o cristal. Sensibilidade ou eficincia refere-se fraco de fotes 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 resoluo espacial no crtica e o fluxo de fotes ou o tempo de aquisio limitado, um colimador de alta sensibilidade pode ser usado. O colimador que sirva ambas as caractersticas um colimador que atinja um compromisso entre sensibilidade e resoluo espacial. Quando se usa qualquer colimador a resoluo espacial diminui com o aumento da distncia ao paciente. Genericamente a resoluo decresce de 1mm por cada centmetro adicional de distncia a que o paciente se coloque da face do colimador de buracos paralelos. Assim a resoluo melhora com a diminuio do dimetro dos buracos do colimador, aumento do comprimento efectivo dos buracos do colimador e diminuio da distncia do paciente ao colimador. A sensibilidade teve francas melhorias devido aos sistemas de SPECT de mltiplas cmaras. Um sistema SPECT de trs cmaras equipado com colimador parallel hole de resoluo ultra-elevada consegue obter uma resoluo (medida a full width half maximum -FWHM) de 4 a 7 mm.

2.7.2 - Tipos de colimadores:


A sensibilidade geomtrica no entanto est relacionada com a resoluo geomtrica de modo inverso, ou seja a melhoria de uma equivale a piorar a outra caracterstica. claro que ambas estas caractersticas so os objectivos principais do SPECT, por isso os investigadores de SPECT tm sempre que considerar ambas as caractersticas quando desenham novos colimadores. Tem havido vrios desenhos de colimadores nos passados 10 anos que optimizaram a relao inversa sensibilidade / resoluo pelos seus desenhos particulares. Existem 3 tipos de colimadores. Estes so: 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 parallelhole, e tem uma resoluo geomtrica (ou de colimador) que aumenta com a distncia da fonte de radiao gama. A resoluo geomtrica pode ser melhorada atravs do uso de canais mais pequenos. Os colimadores de buracos paralelos no introduzem distoro e fornecem um campo de vista constante. A resoluo melhor quando o objecto colocado contra o colimador, mas a sensibilidade independente da distncia ao colimador. 2.7.2.2 Convergncia e divergncia

21

Captulo II - Medicina Nuclear, SPECT e PET

Os colimadores de convergncia e divergncia so assim chamados devido a visionarem os buracos com a perspectiva dos detectores. Os colimadores de convergncia podem na realidade permitir a deteco de estruturas mais pequenas do que a resoluo intrnseca da cmara (aumentando a resoluo do sistema). Na prtica a ampliao limitada a cerca de 15%, no entanto colimadores convergentes introduzem distoro de imagem, uma vez que a ampliao varia de acordo com a profundidade do objecto. A sensibilidade (eficincia) aumenta com a distncia ao colimador mas isto ir diminuir a resoluo. Estes colimadores foram construdos para melhorar a relao entre resoluo e sensibilidade atravs do aumento da superfcie da cmara Anger que se encontra exposta a fonte de radionuclido. Isto vem aumentar o nmero de contagens, que provoca o aumento da sensibilidade. Colimadores de desenho mais moderno tal como half-cone beam e astigmtico, tambm foram concebidos. Um colimador divergente reduz a imagem e degrada tanto a sensibilidade como a resoluo, que iro piorar com o aumento da distncia ao colimador. Este tipo de colimador til somente quando necessrio 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 orgos ou extremidades humanas tais como o pulso ou a glndula tiride ou at para investigao em animais tais como os ratos. Um colimador pinhole pode tambm ser utilizado para ampliar a imagem. A ampliao mxima ocorre quando o pinhole esta mais prximo do objecto e diminui quando este se afasta do objecto. Uma vez que a magnificao determinada pela distncia abertura, um objecto espesso contem reas que iro ser visualizadas a diferentes ampliaes. Esta ampliao diferencial produz distoro da imagem que maior na ampliao mxima. Imagens de pinhole aumentam tambm a resoluo espacial do sistema de cmara. A resoluo est relacionada com o tamanho da abertura, no entanto pequenas aberturas que produzem melhores resolues limitam o nmero de contagens adquiridas. A resoluo tambm melhorada pelo aumento do comprimento da abertura. As imagens de pinhole so melhores para ampliaes de objectos pequenos e finos. A magnificao electrnica mais fcil de ser efectuada mas no aumenta a resoluo do sistema.

2.8 - Detectores de Cintilao


De maneira a detectar os fotes gama utiliza-se detectores de cintilao. Um detector de cristal constitudo por uma liga de Tallium activado, Sdio e Iodo, sendo esta uma soluo generalizada empregue nas Gama cmaras. Esta soluo devida deteco eficiente do cristal em relao a energia proveniente da emisso radionucleica dos raios gama comum na medicina nuclear. O detector de cristal circular tem tipicamente 9 mm de espessura e um dimetro de 30-50cm. Um foto de raios gama interage com o detector atravs do Efeito Fotoelctrico ou Compton Scattering com os ies de iodo do cristal. Esta interaco causa a libertao de electres que por sua vez interagem com a matriz do cristal resultam a produo de luz, num processo conhecido como cintilao.

2.9 - Tubos Fotomultiplicadores


Apenas uma pequena parte de luz extrada do detector de cintilao, por isso os tubos multiplicadores so colocados atrs do cristal. O topo do tubo foto multiplicador constitudo por um foto ctodo que quando estimulado por fotes luminosos, ejecta electres. O PMT (Photo Multiplicator Tube) um instrumento que detecta e amplifica os electres que so produzidos pelo foto ctodo. Por cada 7 a 10 fotes incidentes no foto ctodo apenas um electro gerado. Este electro proveniente do ctodo localizado num dnodo que absorve este electro e reemite muitos mais electres (usualmente 6-10). Estes novos electres so localizados no prximo dnodo e o processo volta a repetir se por toda a matriz de dnodos. A base do PMT constituda por um nodo que atrai o grande bloco final de electres e os converte em impulso elctrico. Cada cmara tem vrios PMTs colocados numa forma geomtrica conhecida. A cmara tpica contm 37 a 91 PMTs.

22

Captulo II - Medicina Nuclear, SPECT e PET

2.10 - Circuitos de posicionamento


Os circuitos lgicos de posicionamento seguem-se imediatamente aos PMTs e recebem os impulsos elctricos 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 cintilao ocorreu no detector de cristal.

2.11 - Computador de anlise de dados


Finalmente, para tratar da informao projectada 3 D que contm a distribuio espacial da actividade dentro do paciente, proveniente dos circuitos mencionados acima e consequentemente process-la para um formato legvel, usado um computador com grandes capacidades de processamento. O computador pode usar vrios tipos de mtodos de reconstruo de imagem, como projeco inversa filtrada ou reconstruo iterativa.

2.12 - Visualizao SPECT


O SPECT superior visualizao planar no que diz respeito a localizao da doena. A visualizao SPECT melhora o contraste do objecto por eliminao de tecidos sobrepostos. Com uma rbita circular o detector estar por vezes mais afastado do paciente o que resulta em perdas da resoluo espacial. rbitas elpticas ou de seguimento de contorno mantero o detector mais prximo do paciente e por isso no devero sofrer da mesma perda de resoluo espacial. Infelizmente, especialmente em SPECT cardaco, as rbitas elpticas resultam numa maior probabilidade de obteno de artefactos. Apesar do detector estar mais prximo do corao h no entanto uma maior variao na distncia do detector ao corao do que com rbitas circulares, pois com uma rbita circular apesar da distancia ser maior, esta mais uniforme ao longo do arco. Esta variao de resoluo espacial mais visvel em pacientes magros, e no visualizada se for utilizado uma rbita de 360 graus.

2.12.1 Artefactos que influenciam a visualizao SPECT


Em SPECT existem vrias condicionantes de vrios tipos que podem influenciar a imagem mdica final e consequentemente o diagnstico mdico. Estas condicionantes vo desde o tipo de paciente sujeito ao exame, condies fsicas onde realizado o exame e tambm caractersticas internas do prprio aparelho. Em seguida, feita uma caracterizao de cada um dos artefactos existentes neste tipo de exames. - Uniformidade do campo A uniformidade do campo do detector o parmetro mais crucial na performance do SPECT. Flutuaes aleatrias no fluxo de sensibilidade de campo (no 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 milhes para uma matriz de 64x64 (120 milhes de contagens seriam necessrias para uma matriz de 128x128). Geralmente estes fluxos so efectuados semanalmente com 3 milhes de contagens de fluxo dirias. O fluxo deve ser obtido com o colimador ligado. - Centro de rotao Os detectores de uma cmara SPECT rodam em torno de um eixo central. O computador assume conhecer a posio desse eixo durante a reconstruo da imagem. Se o verdadeiro eixo no corresponde ao eixo assumido sero criados artefactos durante a reconstruo da imagem. A maioria dos departamentos verifica a posio do eixo de rotao semanalmente. Quando o detector um detector de cabeas mltiplas fixos em gantry rotativos no necessrio fazer verificaes do eixo de rotao to frequentes. A aquisio do centro de rotao consiste de um ponto fonte colocado fora do centro do campo de vista. Este deve ser calculado com uma preciso de pelo menos 1 dcimo de pixel. Um

23

Captulo II - Medicina Nuclear, SPECT e PET


deslocamento de meio pixel no centro de rotao pode resultar numa aprecivel degradao da imagem final. Um erro de alinhamento no centro de rotao ir resultar na reconstruo de um ponto como um anel pelo que erros de alinhamento de centro de rotao resultam em artefactos do tipo cauda de cometa ou forma de anel. - Alinhamento de detectores A cabea da cmara deve ser nivelada antes de cada aquisio. Uma cabea no nivelada provocar um erro do tipo de erro de alinhamento do centro de rotao. Para avaliar o alinhamento do detector, o ponto fonte deve mover-se para trs e para a frente numa linha recta. Se oscilar para cima e para baixo na imagem final, a cabea da cmara no est nivelada ou o suporte da cmara no e realmente vertical. - Movimento do paciente Para a realizao de um exames do tipo planar ou SPECT, estritamente necessrio que o paciente se mantenha imvel durante todo o tempo de realizao do exame. O movimento do paciente pode ser verificado de variadas formas: sinograma, display cinemtico e imagem das projeces somadas. - O sinograma consiste em linhas correspondentes de cada vista planar (projeces equivalentes tais como as usadas para um plano topogrfico) so colocadas construtivamente numa matriz bidimensional. - O display cinemtico basicamente o hardware onde feita a visualizao das imagens adquiridas e onde so constatados os movimentos atravs de visualizao directa. - A imagem das projeces somadas consiste nas imagens de projeco mltiplas. Estas imagens de projeco mltipla so somadas de forma a compor uma imagem de projeco. Se no tiver ocorrido movimento o objecto constituir uma linha. Este tipo de artefactos habitual em exames SPECT, sendo uma constante se os pacientes forem crianas ou pessoas que no consigam manter-se imveis durante a durao dos exames. O movimento do paciente, deteriora de tal forma a imagem como a posterior anlise e diagnstico, que obriga repetio do exame na maior parte dos casos. - Reconstruo Tomogrfica Como regra, e de modo ao SPECT obter a mesma preciso estatstica como as imagens planares convencionais, so necessrias cerca de 5 vezes mais contagens. No entanto melhor ter uma contagem um pouco mais pobre mas mais ntida do que uma imagem com mais contagens mas mais esborratada. O uso de detectores mltiplos fornecem sensibilidade suficiente para se poder utilizar colimadores de alta resoluo, adquirindo ainda assim informao suficiente sobre a densidade. - Correco de Atenuao A atenuao dos fotes degrada significativamente a preciso quantitativa de uma imagem SPECT devido a introduo de artefactos e distores. O factor mais importante a degradar a resoluo da imagem SPECT a distncia da cmara ao paciente. O segundo factor mais importante a disperso devido a auto absoro dentro do paciente. O radionuclido Tc-99m tem um meio valor de camada (half value layer) de aproximadamente 4 cm em tecidos moles. Regies prximas do centro do corpo ou crebro esto pelo menos 2 meios valores de camada acima da cmara gama do que a maioria das estruturas superficiais. Esta profundidade extra resulta em significativas variaes de emisso, que chegam a cmara devido a auto absoro. Estas perdas por auto - absoro devem ser corrigidas durante a reconstruo uma vez que a verdadeira correco de atenuao para SPECT no existe ainda. Os dois mtodos mais usados para fazer a correco so o mtodo de pr - processamento de Sorenson e o mtodo de ps - processamento de Chang. Estes mtodos no funcionam bem no trax, uma vez que este se encontra rodeado de tecidos de densidade varivel, que possuem factores de atenuao diferentes. A correco ptima de atenuao requer o uso de um scan de transmisso para determinar correces apropriadas. O scan de transmisso pode ser alcanado pela

24

Captulo II - Medicina Nuclear, SPECT e PET


obteno de uma imagem SPECT de 10 min de uma fonte oposta ao paciente. A ento as imagens de emisso do paciente podem ser corrigidas adequadamente. Um estudo combinado emisso / transmisso pode ser efectuado usando uma cmara de 3 cabeas, usando 2 cabeas para adquirir dados de emisso e uma para receber informao de transmisso. Este sistema encontra-se presentemente em desenvolvimento. - Projeco inversa filtrada A projeco inversa filtrada usada para a reconstruo de imagem. A projeco inversa sem filtragem resulta em indesejvel esborratamento (image blur) de imagens e presena de artefactos em forma de estrela. O nvel a que os artefactos de projeco inversa podem ser removidos deve ser compensado pelo grau a que o rudo de imagem pode ser tolerado. A frequncia refere-se as mudanas do numero de contagens de pixel para pixel. Sinais de imagem reais decaem rapidamente com o aumento da frequncia enquanto o rudo contido se mantm constante. O rudo de background considerado de alta frequncia, pois encontra-se uma variabilidade demarcada no nmero de contagens de pixel para pixel. A nitidez da imagem (fino detalhe e deteco de orlas) tambm considerada de alta frequncia enquanto o alvo de baixa frequncia. Filtros RAMP (filtros de alta frequncia) impulsionam as altas frequncias de modo a tornar mais ntidos os detalhes da imagem, infelizmente tambm aumentam o rudo, devido a este ser tambm de alta frequncia. Assim apesar dos filtros RAMP produzirem os melhores detalhes na reconstruo as imagens so frequentemente interpretveis devido a propagao de rudo associada a baixas contagens estatsticas. Para limitar este efeito um segundo filtro (passa baixo) utilizado para reduzir rudo estatstico. Os filtros passa baixo aumenta a relao sinal rudo, mas s custas de perdas de contraste e resoluo de imagem. Alguns exemplos de filtros passa baixo comuns so: Butterworth , Hanning, SheppLogan e Parzen. Quando se selecciona um filtro para processamento h sempre um acordo entre contraste e uniformidade de imagem. A frequncia de corte a frequncia acima da qual toda a informao removida. Quanto mais baixa for a frequncia de corte mais suave ser a imagem reconstruda e maior a perda de contraste e resoluo devido a perda de nitidez (sharpness) contida nas altas frequncias. Altas contagens estatsticas so cruciais uma vez que quanto maior o nmero de contagens nos dados projectados maior poder ser a frequncia de corte. Um filtro com alta frequncia 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 variaes acentuadas que produzem imagens mais ntidas mas tambm com mais distores. A filtragem anterior reconstruo prefervel pois reduz a propagao de rudo num nvel precoce do processo de formao de imagem e promove a implementao de um filtro simtrico em 3 dimenses. Apesar de uma matriz de maiores dimenses (128x128) com pixels mais pequenos ter teoricamente mais resoluo espacial, cada pixel ter proporcionalmente menos contagens e a imagem ser degradada por rudo estatstico. A variao percentual em contagens de pixels devido a efeitos estatsticos ou ocasionais aproximadamente de (100 / N1/2 )%, onde N o numero de contagens por pixel. A variabilidade estatstica em exames SPECT e de 5 a 10 % para matrizes de (64x64). Duplicando o tamanho da matriz de modo a melhorar a resoluo espacial ir aproximadamente duplicar o erro estatstico em cada contagem estatstica por pixel. Este aumento em rudo estatstico ir diminuir tanto a resoluo, como o contraste e pode obscurecer detalhes da imagem.. - Correco do tamanho da imagem A resoluo tomogrfica para uma cmara com uma cabea de aproximadamente 16 - 18mm para o thalium e de 13 mm para o technetium. Para objectos mais pequenos que 2 elementos de resoluo do detector as contagens recuperadas dos tomogramas reconstrudos so muito dependentes do tamanho do objecto (o numero mximo de contagens proporcional a espessura do objecto).

2.13 - Protocolos de Aquisio


2.13.1 - Aquisio de imagem planar

25

Captulo II - Medicina Nuclear, SPECT e PET


O protocolo mais simples de aquisio o planar. Com aquisio de imagem planar, a matriz de deteco encontra-se estacionria sobre o paciente, e apenas adquire dados de um determinado ngulo. A imagem ento criada com este tipo de aquisio similar a uma radiografia raio-x. Exames a ossos so feitos primariamente desta maneira. 2.13.1.1 - Aquisio de imagem planar dinmica Seguindo a mesma filosofia do protocolo anterior temos a aquisio planar dinmica. Este protocolo basicamente consiste em adquirir imagens planares (2 D) acrescentando-lhes uma terceira dimenso que o tempo. Assim iro ser adquiridas vrias imagens planares ao longo de um determinado intervalo de tempo. Para isso basta que a cmara fique sempre numa determinada posio. Num estudo planar, possvel observar a deslocao de um rdioistopo ao longo do corpo atravs da aquisio de uma srie de imagens planares do paciente ao longo do tempo. Cada imagem o resultado da soma de informao durante um intervalo de tempo curto, tipicamente 1-10 segundos. Se varias projeces forem tiradas durante um intervalo de tempo mais longo, ento possvel fazer uma animao visual do trajecto percorrido pelo rdioistopo e uma anlise desta informao pode ser realizada. O exame planar dinmico mais comum tem a finalidade de medir o ratio de filtrao glomerular nos rins.

2.13.2 - Aquisio de imagem SPECT


Se rodarmos a cmara em volta do paciente, a cmara ir adquirir vistas da distribuio do rdioistopo numa grande variedade de ngulos. Aps a observao de todos os ngulos, possvel reconstruir uma visualizao 3D da distribuio do rdioistopo dentro do corpo. A reconstruo de imagem em 3 D est explicada em detalhe no ponto 2.5 deste captulo. 2.13.2.1 Aquisio de imagem SPECT dinmico Enquanto a aquisio de imagem planar funciona bem para determinados estudos, a falta de informao acerca da profundidade significa que tem uma aplicabilidade limitada. O mtodo baseado em imagem d-nos a requerida informao de terceira dimenso, mas o facto de requerer hardware especial e um complicado protocolo de aquisio impossibilita a sua aplicao clnica. O objectivo do SPECT dinmico ser capaz de usar cmaras SPECT de uma s cabea convencionais com um protocolo de aquisio tpico. Como o tempo requerido para uma aquisio convencional muito longo quando comparado com a cintica envolvida na maior parte dos processos, a projeco inversa filtrada no pode ser usada para a reconstruo da imagem final. Se a projeco inversa filtrada for usada, artefactos surgiro nas reconstrues como resultado de projeces inconsistentes e assim pode levar a diagnsticos errados. Por estas razes novos mtodos de reconstruo devem ser desenvolvidos, mtodos estes que devem ser capazes de ter em conta a alterao de actividade nas vrias projeces. Para efectuar a reconstruo de imagem so utilizados mtodos como o mtodo de parmetros directos e o mtodo dos mnimos quadrados com restrio linear. Estes mtodos encontram-se explicados no ponto 2.5 deste captulo.

2.13.3 - Aquisicao SPECT GATED


Como o corao um objecto em constante movimentao, ao fazermos um exame regular SPECT ao corao, a imagem final obtida ir representar a posio mdia ao longo do tempo que o exame foi feito. possvel visualizar o corao nas vrias etapas do ciclo de contraco, sendo isto conseguido ao subdividirmos cada vista projectada SPECT numa serie de sub - vistas, cada uma definindo os contornos do corao a uma etapa diferente do ciclo em estudo. Este protocolo exige que a cmara SPECT esteja ligada a uma maquina ECG, da maneira a poder extrair informao do electrocardiograma para a reconstruo de imagem.

2.14 - Aplicaes SPECT

26

Captulo II - Medicina Nuclear, SPECT e PET


Esta seco tem como objectivo mostrar quais os estudos que se podem fazer com SPECT. Estes sao: aquisio de imagem do corao, aquisio de imagem de crebro, aquisio de imagem renal, exames sseos e exames sobre o fgado. Em seguida fornecida uma breve descrio destes exames. Exames Renais O estudo mais usual em medicina nuclear SPECT o exame dinmico renal. No sistema renal, o sangue continuamente passado pelos rins, onde filtrado e purificado antes de passar pelo resto do corpo. Produtos indesejveis so ento extrados do sangue e expelidos do corpo como urina. Em condies normais de funcionamento, os rins so capazes de filtrar sangue rapidamente, e assim atravs de uma medio do ratio da filtrao sangunea, possvel obter uma medida quantitativa do funcionamento renal. Este tipo de medio denominado ratio de filtrao glomerular (GFR). Funcionamento do corao Considerando o caso de shunting cardaco entre ventrculo esquerdo e direito, quando um tracer injectado numa veia perifrica, passa atravs do trio direito e em seguida ventrculo direito onde bombeado para os pulmes. O sangue retorna novamente para o corao atravs da veia pulmonar para o trio esquerdo e ventrculo esquerdo. Por causa do shunting no ventrculo 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 corao atravs da artria pulmonar e outras veias. Este retorno til no sentido que possibilita a determinao da quantidade de shunting que est a acontecer de maneira a planear futuros tratamentos. A quantidade de shunting determinada atravs de modelizao. Metabolismo Cerebral Estudos dinmicos cerebrais so muito comuns em SPECT devido natureza do procedimento de aquisio de imagem. Com a introduo de um radionuclido que seja levado at ao crebro atravs das clulas e que seja concentrado pelas clulas do crebro ento possvel observar o seu funcionamento. As partes activas do crebro iro concentrar mais radionuclido do que aquelas que no estejam activas, e assim possvel observar como as diferentes partes do crebro reagem a estmulos locais. Como exemplo, se 2.6 - Exame SPECT cerebral um paciente que est a ser sujeito a um exame funcional ouvir msica em simultneo, as partes do crebro responsveis pelo processamento da informao proveniente da funo auditria, estaro mais activas e concentraro mais radionuclido que as outras clulas cerebrais. Exames sseos Os exames sseos podem ser realizados de duas formas: atravs de um exame planar ou atravs de um exame SPECT. Atravs da injeco de um radionuclido apropriado, este ser transportado pela corrente sangunea a toda a estrutura ssea do corpo humano. Nas reas onde houver qualquer anormalidade, haver uma maior concentrao de radionuclido, sendo assim possvel localizar a leso. Esta localizao com um exame planar uma localizao relativa, dado que, no temos a indicao de profundidade e assim impossvel aferir com exactido a localizao exacta da leso. Com um exame SPECT, como temos acesso a informao sagital, transversal e coronal, ento possvel aferir com preciso a localizao da leso. Esta filosofia de anlise tambm aplicvel aos exames pulmonares, onde uma concentrao elevada de radionuclido indica uma obstruo pulmonar, 2.7 - Exame SPECT sseo e que quanto maior for a concentrao de radionuclido maior ser o brilho na imagem final e maior ser a gravidade da leso (neste tipo de exames, maior ser a obstruo).

27

Captulo II - Medicina Nuclear, SPECT e PET

2.15 - Avanos Tcnicos do SPECT


A nvel de instrumentao os detectores de estado slido e a electrnica de semicondutores foram desenvolvidos para substituir os cristais de cintilao e os tubos fotomultiplicadores (PMTs). A emisso de um foto a partir de um determinado orgo atinge o cristal de estado slido, como o caso do teluride- cdmio de zinco (CZT), que um semicondutor que converte o foto directamente num sinal digital electrnico. 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 localizao no detector dista exactamente um pixel digital, e quando for atingido por um foto, providencia a posio da interaco com grande resoluo espacial e energtica. Isso significa uma deteco muito mais directa da posio da posio e energia do foto emitido em vez do processo tradicional em SPECT. O aumento da resoluo espacial e energtica destes detectores de estado slido provoca resolues superiores de contraste e deteco mais eficaz de anormalidades. A grande desvantagem desta soluo, como de esperar o seu elevado preo de manufactura. Outra aproximao aos detectores de estado slido 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 cintilao um fotododo de silicone. Embora esta soluo no seja um clssico detector de estado slido, como foi definido previamente, oferece a maior parte dos benefcios destes. Estes benefcios incluem uma resoluo intrnseca espacial fixa e alta a qualquer energia assim como um verdadeiro posicionamento digital. Como os PMTs no so 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 tambm ser feitos com um sdio iodide de cesium activado cristal (CsI(Na)) para diferentes propriedades. Existem fenmenos fsicos que degradam o grau com qual so detectadas as contagens que representam a actividade do tracer e consequentemente a preciso do diagnstico. Estes so: a) a atenuao varivel (absoro e espalhamento) pelo corpo dos fotes emitidos do orgo de interesse, b) a contagem incorrecta dos fotes provenientes do espalhamento para dentro do detector de cristal, e c) a limitada e varivel natureza da resoluo espacial atravs da distribuio do tracer no orgo. A correco destes fenmenos ir reduzir ou eliminar a atenuao presente em imagens de perfuso de pessoas com densos tecidos, e tambm a atenuao diafragmtica observada em vrios homens. Estas correces tambm corrigiro uma srie de artefactos mais subtis e permitiro para um uso mais previsvel o contorno do corpo humano. Os mtodos de correco da atenuao varivel esto a ser presentemente comercializados para compensar a atenuao varivel atravs do trax. O algoritmo de correco requer um mapa (uma imagem de transmisso) dos coeficientes de atenuao, que no nada mais do que uma imagem de baixa qualidade de um exame CT. Para gerar este exame de transmisso, uma fonte transmisso radioactiva montada no sistema SPECT, que emitir fotes que iro passar atravs do paciente antes de serem gravados no detector de cintilao. Numa nova aproximao, um tubo de raio-x foi montado no sistema SPECT de maneira a produzir imagens CT de qualidade superior. Idealmente, os estudos da transmisso e recepo so adquiridos simultaneamente de maneira a prevenir um acrscimo do tempo de aquisio e discrepncias entre exames. Esta aquisio simultnea requer correco para o espalhamento gerado adicionalmente pela fonte de emisso para a janela de energia da fonte de transmisso. Como no existem solues analticas para o problema da atenuao em SPECT, algoritmos de reconstruo iterativa so usados para progressivamente reduzir a degradao da imagem causada por este fenmeno fsico. Embora estes algoritmos sejam bastante conhecidos desde h vrios anos, o tempo computacional requerido para se atingir convergncia proibitivo e no pode ser implementado clinicamente. O advento de ter computadores rpidos a preos acessveis com memrias de grande capacidade permitiu a sua implementao de maneira que agora possvel que um estudo completo pode ser processado num espao de tempo de poucos minutos ou segundos, dependendo do tamanho da matriz e do nmero de projeces adquiridas. Em ordem a corrigir tanto a atenuao varivel e espalhamento, pelo menos trs janelas de energia independentes so requeridas pelo detector. Uma janela necessria para adquirir as contagens de emisso provenientes do pico de energia do tracer. Outra janela necessria para efectuar a contagem dos fotes de transmisso atravs do posicionamento da janela por cima do pico de energia da fonte de transmisso (como o Gd 153 com97 e 103 keV de pico). A terceira janela a janela de espalhamento, sendo necessrio que esta seja posicionada entre as duas janelas de maneira a corrigir os fotes espalhados do paciente tanto para os picos de transmisso como de emisso. Aproximaes que usam mais do que trs janelas esto a ser desenvolvidas para correces mais precisas. Experincias a nvel clnico revelam que a correco da atenuao teve um aumento significativo no diagnstico de certo tipo de doenas.

28

Captulo II - Medicina Nuclear, SPECT e PET

2.15.1 Cmara de Compton


A limitao primria em aquisio de imagem SPECT a sua fraca resoluo espacial e a grande dosagem a que o paciente submetido. Esta dosagem necessria de maneira a haver contagens suficientes detectadas pela cmara de maneira a providenciar uma imagem estatisticamente precisa. O colimador tpico de chumbo permite apenas que um foto em 10000 emitidos do corpo do paciente seja detectado. Assim, sem o colimador a performance do sistema dever melhorar substancialmente. Isto pode ser alcanado atravs do uso de uma cmara de Compton. Os ganhos potenciais que uma cmara de Compton oferece em relao cmara de Anger so devidos primariamente inexistncia do colimador de chumbo. Com este facto espera-se que existam ganhos substanciais na sensibilidade do sistema e permitir a aquisio da informao representando as vistas de mltiplos ngulos da fonte de distribuio de uma posio apenas e desta maneira reduzir o necessrio movimento da cmara. Ambos os efeitos podem reduzir a dose que empregue ao paciente para formar uma imagem final til. Primeiro, os sistemas com elevada sensibilidade iro permitir o uso de nveis de actividade mais baixos e/ou istopos com meias vidas mais curtas. Segundo, a reduzida moo angular da cmara ir resultar em menos tempo perdido entre paragens angulares. A complexidade mecnica do sistema ir tambm ser reduzida devido ausncia do colimador de chumbo macio.

2.16 - Concluso
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 rpidos e melhores o SPECT ir adaptar e incorporar esses avanos. Como exemplo, as propriedades estatsticas de Bayes foram recentemente aplicadas a reconstruo de imagem do SPECT criando imagens excepcionais custa de grandes tempos de processamento e memria de computador. Espera-se que um dia as melhorias no processamento paralelo e na arquitectura de computadores faro a reconstruo de Bayes mais rpida a custa de menor memria de computador tornando-a assim mais atractiva para o seu potencial uso em ambiente clnico. As tcnicas de fuso de imagem tm sido desenvolvidas nos casos de estudo cerebrais e de tumores para registar distribuies 3D SPECT com correspondncia a distribuies de outras modalidades tais como CT e MRI. O avano mais notvel ocorreu na aplicao de tcnicas computacionais ao electrocardiograma (ECG) associado ao estudo de perfuso do miocrdio gated SPECT.

3 Positron Emission Tomography (PET)


3.1 - Introduo ao PET
PET - positron emission tomography - uma tcnica usada para medir as concentraes de radioistopos positres emitidos dentro dos tecidos de sujeitos vivos. Estas medies so feitas fora do sujeito vivo. A maior parte dos istopos radioactivos decaiem por ibertao de um raio gama e electres, outros decaiem por libertao de um positro. Um positro pode ser pensado com um electro positivo. Uma grande motivao e interesse generalizado, aliado a uma grande acelerao na tecnologia PET, foram factores estimulados pelo desenvolvimento de algoritmos de reconstruo associados com o raio-x CT e melhorias nas tecnologias de deteco nuclear. Em meados da dcada de 80, PET tornou-se uma ferramenta para diagnstico mdico, estudos dinmicos do metabolismo humano e tambm utilizado para estudos de actividade cerebral. Assim o PET pode ser dividido em vrios passos: 1. etiquetar o composto escolhido com um rdioistopo com emisso de positres. 2. administrar este composto ao sujeito em estudo.

29

Captulo II - Medicina Nuclear, SPECT e PET


3. adquirir a imagem da distribuio da actividade dos positres como funo do tempo por emisso tomogrfica. 4. deduzir, atravs da aplicao do modelo adequado, da informao adquirida uma percepo do comportamento biolgico do composto. De salientar que ainda no existem centros PET em Portugal ao invs da vizinha Espanha que j possui 6 centros PET. Isto deve-se ao facto do ainda preo elevado de um centro PET, custos associados com pessoal e preos incomportveis para os pacientes. Todos estes factores tornam impossvel a rentabilizao deste tipo de centros e consecutivamente a sua implementao em ambiente clnico.

3.2 - Aspectos Histricos do PET


O interesse nos elementos Carbono 11, Nitrognio 13 e Flourine - 18 no existia nos anos 40 e incio da dcada de 50, talvez devido descoberta do carbono-14 em 1940 por Carmen e Ruben. O carbono-14 provou ser um istopo mais verstil e eficiente, pelo que este perodo parecia inconsequente em termos de investigao biomdica seguindo a linha de radionuclidos emissores de positres. Em meados dos anos 50 Ter-Pogossian promoveu a ideia de apesar das curtas meias - vidas destes radionuclidos emissores de positres, estes ofereciam um mtodo atractivo para o estudo regional do metabolismo, devido a serem comuns. Entre os meados dos anos 50 e inicio dos anos 70 a utilizao destes radionuclidos emissores de positres foi lenta. Estes radionuclidos passaram a ganhar alguma popularidade apenas quando alguns centros comearam a utilizar ciclotres. Trs factores contriburam 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 qumicos na etiquetagem rpida de molculas complexas com etiquetas fisiolgicas apesar das suas curtas meias vidas. 3. A concluso de que a radiao penetrante resultante da aniquilao dos positres tornara bvio que a localizao destes positres era possvel. Desde o inicio dos anos 70 PET tem sido usado como ferramenta de investigao, e nos anos mais recentes mostrou potencialidades na medicina clnica. Os primeiros scanners PET usavam fatias nicas quando efectuam tomografia. Estas tomografias eram produzidas no inicio dos anos 60 em vrios institutos de investigao usando sistemas com anis de 32 detectores NaI (Tl). A resoluo de cada fatia era maior que dois centmetros FWHM. A gerao de scanners seguinte reduziu a dimenso dos detectores e acrescentou anis adicionais para aquisio simultnea de varias fatias. A resoluo de fatia melhorou de mais de 2 centmetros FWHM para menos que 1 centmetro FWHM. A maioria destes sistemas complicados eram mquinas nicas. No final dos anos 70 o marketing comeou finalmente a disponibiliz-las comercialmente. A medida que o tempo foi passando mais detectores e PMTs foram adicionados a estas mquinas de modo a aumentar a sua sensibilidade e resoluo. Aps muitos anos de estudo uma mquina de nome PENN-PET foi desenvolvida na universidade da Pensilvnia. Esta mquina consistia numa matriz estacionaria de 6 detectores de positres distribudos de uma forma hexgono em torno de um dimetro de 50 cm a volta do paciente. Esta mquina oferecia alta sensibilidade e uma resoluo de 5.5 mm FWHM e era menos complexa e menos cara que os sistemas com detectores de anel. De salientar que esta mquina ainda se encontra comercialmente disponvel. Aps anos de avano feitos na investigao PET apenas pouco mais de cem centros existem em todo o mundo. A maioria destes centros dedicam-se a investigao e poucos dedicam-se ao seu uso clinico.

3.3 - Teoria e instrumentao


A aquisio de imagem PET comea com a injeco de um tracer metabolicamente activo de emisso (por exemplo, Carbono 11, Azoto 13, Oxignio 15 ou Flour 18). Em minutos, o istopo acumula numa rea do corpo para a qual a molcula tem uma afinidade. Como exemplo, glucose etiquetada com Carbono 11 (meia vida, 20 minutos), ou uma glucose anloga etiquetada com Flour 18 (meia-vida, 1.8 horas), acumula no crebro, onde a glucose usada como fonte primria de energia. O ncleo radioactivo decai por emisso de positro. O positro emitido colide com um electro livre, usualmente em menos de

30

Captulo II - Medicina Nuclear, SPECT e PET


um 1mm de distncia do ponto de emisso. A interaco das duas partculas sub atmicas resulta numa converso de matria para energia na forma de dois raios gama. Estes raios gama de alta energia emergem do ponto de coliso em direces opostas, e so detectados por uma matriz de detectores que rodeiam o paciente. Quando os dois fotes so gravados simultaneamente por um par de detectores, significa que a coliso que originou os dois fotes ocorreu algures ao longo da linha que liga os detectores. claro, se um dos fotes provem, no da coliso, mas sim do espalhamento a linha de coincidncia ser incorrecta. Aps 500,000 contagens, a distribuio do tracer emissor de positres calculada atravs de procedimentos de reconstruo tomogrfica. Assim o PET gera uma imagem de duas dimenses. Reconstrues a trs dimenses podem ser realizadas usando projeces 2-D de mltiplos ngulos.

3.4 - Radionuclidos
Os compostos utilizados em PET tm uma grande diversidade. Estes radionuclidos com emisso de positres tem meias vidas muito curtas e energias de radiao muito altas quando comparadas com outros radioisotopos usados em pesquisa biomdica. Os radionuclidos com emisso de positres mais usados em PET incluem Carbono-11, Nitrogenio-13, Oxignio - 15, e Flor-18, com meias vidas de 20, 10, 2 e 110 minutos respectivamente. Estes compostos so 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, seno todos, os compostos que so consumidos pelo corpo humano apenas faz sentido que o exame PET e uma tcnica obvia para o estudo do destino destes componentes in vivo. Estes compostos de rastreio so administrados por meios de injeco ou inalao, com o propsito de simplesmente aceder a corrente sangunea. a curta meia vida destes componentes que permite que se possa administrar grandes doses no paciente com uma exposio radioactiva mnima e tambm 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 produo destes radionuclidos necessrio que o centro esteja equipado com um acelerador de partculas, uma equipa de fsicos nucleares, especialistas em computadores, rdiofarmacos, especialistas de istopos e clnicos. Se um laboratrio no tiver meios de levar a cabo este processo sinttico os radionuclidos tem que ser transportados ate o sitio onde sero usados. Dos quatro radionuclidos mencionados acima mencionados o Flor-18 o ideal para transporte. Nestes anos passados, PET tem tido um desenvolvimento muito rpido, devido principalmente as novas substncias de rastreio disponveis para estudo em humanos.

3.5 - Metabolismo da glucose


Os estudos PET tm includo medies do metabolismo da glucose, fluxo de sangue cerebral, metabolismo do oxignio, assim como a aquisio de imagem de outros processos fisiolgicos. Correntemente o metabolismo da glucose medido atravs de [Flor-18], o fluxo cerebral atravs de do [Oxignio-15] em combinao com um seu istopos. Em condies normais, o crebro humano depende da glucose como sua nica fonte de energia. A maioria da glucose usada para manter os nveis de potencial das membranas e para restaurar gradientes inicos a nvel celular. Quando clinicamente se mede o metabolismo da glucose, o paciente fica numa posio imvel durante 40 minutos aps a injeco intravenosa de FDG (Flor Desoxi Glucose). Durante este espao de tempo, o FDG levado atravs das clulas e atingido um equilbrio.. A distribuio do Flor - 18 ento medida em vrias seces tomogrficas, e esta distribuio baseada na utilizao da glucose debaixo de condies especficas patolgicas de condio cerebral. Uma das maiores razes de medio de glucose, devido ao facto do grande ratio gluclico da maior parte das doenas. A aquisio PET tem a habilidade de detectar a presena de tecidos malignos e consegue quantificar alteraes na concentrao de glucose num tumor durante e aps tratamento. A tcnica Cerebral Blood Flow (CBF) utiliza as alteraes fisiolgicas e patolgicas em regies de fornecimento de sangue. assumido que aumentos no fluxo sanguneo so associados com o aumento da actividade funcional. Aps activao, a distribuio oxignio - 15 pode ser medida e atravs do uso de imagens coloridas codificadas de CBF, e ento possvel visualizar quais as reas do crebro esto activadas aquando sujeito a certas actividades. Por exemplo, quando uma pessoa l ou fala, o hemisfrio direito fica iluminado.

31

Captulo II - Medicina Nuclear, SPECT e PET

3.6 - Aquisio e processamento de imagem em PET


A aquisio de imagem em PET totalmente indirecta. Tal como no CT, MRI e SPECT, PET conta com a reconstruo computorizada para proceder a produo de imagens tomogrficas. executado com meios de deteco de emisso de positres atravs do uso de tomografia. Duas maneiras nas quais os radionuclidos decaem e que iro reduzir a carga positiva excessiva no ncleo, inclui a neutralizao de uma carga positiva com uma carga negativa de um electro ou a emisso de um positro do ncleo. Ento o positro ir combinar-se com um electro das redondezas e anular-se. Aps a aniquilao de tanto o positro como o electro so convertidos em radiao electromagntica. Esta radiao electromagntica est na forma de dois fotes de grande energia que so emitidos com um desfasamento de 180 graus um do outro. esta radiao de aniquilao que ser detectada externamente e ser usada para medir tanto a quantidade e a localizao do emissor de positres. A deteco simultnea de dois destes fotes por detectores em lados opostos do sujeito coloca o stio de aniquilao numa linha ligando os centros dos dois detectores. Neste ponto o mapeamento da distribuio da aniquilao por computador permitido. Se a aniquilao for originada fora do volume entre os dois detectores apenas um dos fotes pode ser detectado. Uma vez que a deteco de um nico foto no satisfaz a condio de incidncia o evento rejeitado. A deteco simultnea fornece um campo de viso preciso com sensibilidade uniforme. Isto acontece uma vez que quer a desintegrao tenha lugar entre os dois detectores, ou no, os fotes em soma tem que ter viajado a distncia total entre detectores de modo a que o evento seja gravado. A imagem geralmente obtida apresentada como uma imagem de nveis de cinzento de uma seco cruzada do objecto em que a intensidade de cada elemento de imagem proporcional a concentrao do istopos no objecto. Quando se obtm imagens no claras isto pode causado pela qualidade da medida da correco de atenuao ou por estatsticas de foto 2.8 - Doena de Parkinson Exame PET pobres. Um mtodo para corrigir imagens PET usa uma relao tabulada determinada empiricamente, entre profundidade de interaco e mais que provvel altura de pulsao para cada raio gama detectado.

3.7 - Funes do PET


A utilidade do PET que dentro de certos limites tem a capacidade de detectar mudanas bio qumicas dentro do corpo. Qualquer regio do corpo que esteja a experimentar mudanas bioqumicas anormais pode ser visto por PET. O PET teve um impacto enorme em aplicaes clnicas para doenas neurolgicas, incluindo doenas crebro - vasculares, epilepsia e tumores cerebrais. O PET importante na pesquisa e desenvolvimento de drogas e pode ser usado para estudar a distribuio de certas drogas, a farmacocintica e farmacodinmica. Para alm de tumores cerebrais o PET usado e localizar metastases linfogenticas bem como outros tumores. Uma das funes mais importantes do PET a sua capacidade para modelizar funes fisiolgicas e biolgicas do corpo, proteco e modelizao das concentraes de radioactividade regional num orgo particular. Actualmente possvel obter localizaes anatmicas melhoradas de actividade, adicionando a informao 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 radiao, sensores mltiplos e cmaras de cintilacao. Carbono-11, Carbono-13 e Flor-18 foram pela primeira reconhecidos como teis para estudos biolgicos logo aps a sua disponibilizao por irradiao ciclotron dos seus elementos estveis.

3.8 - Aplicaes e investigao associada ao PET


Mecanismos cerebrais em condicionamento clssico:

32

Captulo II - Medicina Nuclear, SPECT e PET

Aqui o PET tem sido usado para estudar o mecanismo cerebral que supervisiona o condicionamento humano clssico. Este estudo realizado atravs da medio da distribuio do fluxo sanguneo no crebro. A experincia consiste em trs fases, pr condicionamento, condicionamento, e ps - condicionamento. O scanning PET realizado na primeira e terceira fase. A fase de condicionamento usada para enviar ligeiros choques elctricos para os sujeitos. Aps visualizao da primeira e terceira fase ento constatado que a fase de condicionamento resultou numa fase de acrscimo de activao nas regies frontais e temporal do crebro especialmente na zona do hemisfrio direito cerebral. Receptores de estrogneo em cancro da mama: PET tem sido usado para estudar vrios aspectos de patofisiologia do cancro dos seios. FDG tem sido largamente utilizado em estudos PET de cancro devido s observaes que quase todos os tumores malignos exibem, sendo registado um aumento de concentrao de FDG, presumindo-se assim um aumento do ratio da glucose no tecido do tumor. FDG-PET mostrou em estudos clnicos ser um meio fivel para distinguir massas mamrias entre benigno e maligno e tambm para avaliar a extenso regional do tumor. Correco de atenuao em corpo inteiro PET Correco de atenuao um procedimento de rotina em PET atravs do uso de factores derivados de um scan de transmisso ou assumindo uma densidade de tecido constante. No entanto aquisio PET de corpo inteiro uma excepo a isto. Aquisio de corpo inteiro entende o campo axial de viso do scanner PET atravs da movimentao da cama em passos atravs do tomgrafo. A informao adquirida tipicamente em espaos de tempo entre 4 a 10 minutos em cada posio. Por causa disso, uma quantificao precisa no possvel e imagens reconstrudas incluem artefactos, tais como um aparente decrscimo na acumulao do tracer em direco ao centro do corpo. Aquisio PET em doenas Renais Os rins so distinguveis por altos nveis de metabolismo e fluxo sanguneo. Este estudo prova que excelentes imagens de rins podem ser obtidas com Carbono - 11 - acetato e aquisio PET. Devido ao alto fluxo sanguneo nos rins uma transio alta do tipo alvo - para - fundo muito esperado. Mesmo quando este fluxo sanguneo reduzido bastante devido doena renal, a correspondente reduo na acumulao do tracer no exclui a visualizao dos rins ou suficiente actividade do tracer para anlise da cintica do tracer. Mecanismos cerebrais para respostas de memria A resposta de informao da memria de uma pessoa envolve no s a resposta com sucesso da informao armazenada (cephory), mas tambm invoca todos os processos relativos tentativa de lembrar. Estudos recentes PET do retorno da memria humana mostram que o retorno da informao armazenada provoca o encadeamento de vrias zonas cerebrais. Estas regies incluem o crtex direito pr frontal assim como as regies corticais posteriores. Este estudo foi capaz de mostrar que a activao destas regies est associada com a tentativa de retorno de informao, no necessariamente com o sucesso desse retorno. Evoluo de redes metablicas anormais no crebro Para visualizar a informao complexa retornada por exame PET, combina-se o mtodo standard PET com modelizao estatsticas aproximadas e tcnicas de visualizao para melhor demonstrar os resultados das anlises. Perfis topogrficos representam funcionamento implcito de redes de regies metabolicamente covariantes, que no so perceptveis atravs dos processos convencionais de aquisio e processamento de imagem e tcnicas estatsticas devido sua pequena magnitude quando comparada com os efeitos globais. Atravs da quantificao, identificao e ilustrao da existncia dessas redes implcitas de funcionamento, marcadores independentes neuronais so providenciados para diferenciao

33

Captulo II - Medicina Nuclear, SPECT e PET


entre desordens neuro - generativas similares assim como uma viso profunda dos mecanismos fisiolgicos destas doenas.

34

Captulo III - Fundamentos Tericos

Captulo III

1 Introduo Viso por computador


1.1 - Introduo
O sistema de viso o elemento sensorial mais importante para a sobrevivncia de uma grande percentagem de seres vivos. A informao adquirida por este elemento sensorial de facto importante quer a nvel qualitativo quer a nvel quantitativo, fornecendo informao sobre o meio que condiciona e influencia toda a atitude e interaco da entidade que a possui. A importncia do sistema de viso tem assim vindo a ganhar uma importncia cada vez maior junto da comunidade cientifica de modo a criar sistemas automticos, computadorizados, que sejam capazes de executar funes do sistema de viso tal como se encontram nos seres vivos. Esta rea de desenvolvimento cientfico (viso por computador ou viso artificial) surge assim associada a outras reas tais como processamento de imagem, grficos computadorizados, reconhecimento de padres, inteligncia artificial e psicofsica.

1.2 - Viso por computador


O objectivo de um sistema de viso por computador criar um modelo do mundo real a partir de imagens. Um sistema de viso por computador adquire informao til de uma cena a partir das suas projeces bidimensionais. Uma vez que as imagens so projeces bidimensionais do mundo tridimensional, a informao no est directamente disponvel e tem que ser recuperada. Este facto implica a inverso de um mapeamento de muitos para um. Para recuperar a informao tridimensional necessrio termos conhecimentos acerca das caractersticas dos objectos envolvidos na cena bem como de geometria projectiva. Consideremos os seguintes exemplos: 1) No diagnstico de uma doena usando tomografia computadorizada a viso por computador permite ao fsico recuperar informao fazendo a melhoria das imagens adquiridas, medidas quantitativas em regies de interesse podem ser efectuadas facilmente. Estes sistemas tm vindo a ser desenvolvidos para todo o tipo de visionamento til na rea da sade. Sistemas de viso por computador tm 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 mvel cada par representa um par streo de um instante particular de imagem. Estas imagens so usadas para obter informao tridimensional do ambiente envolvente para a se movimentar autonomamente. A informao adquirida usada para mapear

35

Captulo III - Fundamentos Tericos


o ambiente envolvente de uma forma robusta e com a preciso suficiente para a funo desejada. Tais sistemas so teis para a navegao automtica de automveis, avies e robots entre outros. 3) A imagem obtida a partir de um satlite de uma regio pode fornecer informao importantssima para a previso da metrologia, anlise de mudanas globais e agricultura entre outros. Os sistemas de viso computadorizados assumem cada vez mais um papel importante na anlise e gesto de informao dos grandes volumes de dados adquiridos por satlite. A viso por computador produz medidas ou abstraces de caractersticas geomtricas, pelo que

Viso = Geometria + Medidas + Interpretao 1.3 - reas associadas viso por computador
De seguida referimos as reas que se encontram associadas viso por computador e que com ela tm evoludo.

1.3.1 - Processamento de imagem


um campo bem desenvolvido que transforma imagens noutras, onde se realam as caractersticas desejadas. Por outro lado os algoritmos de viso por computador usam imagens como base de partida mas produzem outros tipos de informao, tais como representaes do contorno de objectos numa imagem; ou seja na viso por computador o nfase dado na obteno de informao automaticamente com o mnimo de interaco humana. Assim os algoritmos de processamento de imagem tornam-se teis em estgios iniciais da viso por computador, para realar informao particular e suprimir rudo. O processamento de imagem envolve as seguintes reas entre outras: Melhoramento de imagens melhoramento e realce subjectivo de certas caractersticas de uma dada imagem. Restaurao de imagens restaurar imagens que tenham sido degradadas na sua qualidade por um qualquer processo (distoro geomtrica, movimento..) Compresso de imagens representao de imagens de forma a ocupar menos espao fsico, podendo ou no perder informao de acordo com o fim a que se prope a imagem.

1.3.2 - Grficos computadorizados


Criao de imagens a partir de primitivas geomtricas tais como linhas, crculos e outras superfcies de forma variada. Tm um papel importante nos campos da visualizao e da realidade virtual. A viso por computador tm no entanto uma funo inversa, ou seja estimao de primitivas geomtricas a partir da imagem. Ou seja os grficos computadorizados sintetizam imagens enquanto a viso por computador faz a anlise das mesmas. Estes campos tm-se aproximado mais nos ltimos anos graas em parte realidade virtual e aos avanos feitos na visualizao.

1.3.3 - Reconhecimento de padres


Classifica dados simblicos e numricos. Muitas tcnicas estatsticas e sintcticas tm sido desenvolvidas para a classificao de padres. Estas tcnicas de reconhecimento de padres tm um papel importante em viso por computador no reconhecimento de objectos.

1.3.4 - Inteligncia artificial


Preocupa-se com o projecto de sistemas que sejam inteligentes e que possuam aspectos de estudo computacional inteligente. usada para analisar cenas pelo clculo de representaes simblicas dos contedos das cenas aps o processamento das imagens de forma a obter tais caractersticas. Podemos encarar a inteligncia artificial, como sendo constituda por trs passos: percepo, cognio e aco. A percepo transforma os sinais do mundo exterior em smbolos, a cognio manipula esses

36

Captulo III - Fundamentos Tericos


mesmos smbolos e a aco transforma esses smbolos em sinais externos que influenciam o prprio mundo exterior. Muitas tcnicas de inteligncia artificial so usadas em viso por computador sendo que muitas vezes a viso por computador mesmo considerada um sub - campo da inteligncia artificial. Um caso de uma tcnica de inteligncia artificial que tem sido muito desenvolvidas nos ltimos anos so as redes neuronais que comeam agora a ser usadas em viso por computador.

1.3.5 - Psicofsica
A psicofsica junto com a cincia cognitiva tem vindo a estudar a viso humana h j algum tempo. Muitas das tcnicas usadas em viso por computador esto relacionadas com conhecimentos adquiridos da viso humana. Muitos investigadores preocupam-se mesmo mais em desenvolver modelos computacionais da viso humana do que sistemas de viso por computador.

1.4 - reas de aplicao


Actualmente surgem cada vez mais aplicaes associadas viso por computador, tais como: Inspeco industrial - o controle de qualidade cada vez mais importante nos dias que correm e uma vez que as funes de inspeco visual humana so bastante rotineiras, cansativas e morosas originando frequentemente erros e falhas surge a necessidade de as automatizar por meio de sistemas computadorizados que possuam viso. Assim a viso por computador usada no controlo dimensional de componentes, controle de qualidade superficial ou verificao de integridade dos componentes. Guiamento de veculos autnomos a substituio de operrios humanos por veculos, robots ou manipuladores no desempenho de funes fisicamente exigentes ou mesmo perigosas cada vez mais frequente, tornando-se essencial que estes equipamentos possuam viso de modo a poderem interagir com o meio que os rodeia de uma forma correcta e segura seguindo a melhor trajectria possvel e da forma mais rpida. Aplicaes mdicas A anlise de imagens mdicas no geralmente pretendida com um sentido perfeitamente autnomo mas como um auxiliar importante para o diagnstico clinico. Torna-se assim normal encontrar sistemas de viso por computador na rea da sade que auxiliam a anlise de exames de diagnstico e consequentes anlises clnicas. Meteorologia a anlise de imagens obtidas por satlite efectuada por sistemas de viso permitem efectuar previses de tempo. Sistemas de trfego automvel a incorporao de sistemas de viso por computador na gesto de trfego automvel permitem torn-los mais flexveis, eficientes e rpidos. Agricultura as imagens de deteco remota permitem efectuar anlise e controlo do crescimento e grau de maturao das plantaes.

2 - Tcnicas de aquisio de informao tridimensional


2.1 - Introduo
A necessidade de aquisio de informao tridimensional de uma cena levou ao desenvolvimento de vrias tcnicas que directa ou indirectamente determinam as coordenadas tridimensionais dos pontos das cenas, a distncia destes pontos a um determinado referencial ou a orientao local das superfcies que a constituem atravs de um sistema de medida de distncia. Um sistema de medida de distncia ou sensor de distncia em geral um sistema integrado que engloba equipamentos diversos: computadores, cmaras, fontes de luz, dispositivos de aquisio e processamento de sinais... Estes sensores de distncia podem ser caracterizados por diversos parmetros tais como a resoluo, preciso, exactido, velocidade de aquisio e campo de viso. Geralmente estes parmetros tero que estar associados a uma determinada distncia de referncia pois alguns deles podero depender dessa

37

Captulo III - Fundamentos Tericos


distncia. A definio de resoluo, preciso e exactido so bem conhecidos. A velocidade de aquisio avaliada pelo nmero de pontos calculados por segundo. O campo de viso deve ser especificado por uma medida linear ou gama de distncias e por uma medida angular ou ngulo de viso. Todos este parmetros so importantes para a avaliao de um sensor de distncia , no entanto nem sempre so especificados , ou ento so avaliados de formas diferentes pelo que se torna mais complicado avaliar um sensor de distncia comparativamente a outros. Podemos dividir de uma forma genrica as tcnicas de aquisio de informao tridimensional em duas categorias: Activas atravs da projeco controlada de energia sobre a cena obtemos a informao desejada. A energia reflectida detectada por sensores que directa ou indirectamente fornecem a informao tridimensional. Passivas usando a iluminao ambiente obtm-se a informao tridimensional. de uso mais geral mas no entanto tambm de utilizao mais difcil.

2.2 - Tcnicas activas de obteno de informao tridimensional


De um modo geral as tcnicas activas so adequadas em cenas onde no se encontrem pontos caractersticos e quando comparadas com as tcnicas passivas podemos afirmar que a extraco de pontos caractersticos e o estabelecimento de correspondncias vm simplificadas. Estas tcnicas apresentam problemas quando se usam padres no codificados ou a cena apresenta superfcies com descontinuidades, uma vez que tm dificuldades em estabelecer as correspondncias; quando utilizado um feixe ou plano de luz existe a necessidade de varrer a cena pelo que torna o processo moroso e passvel de pequenas falhas mecnicas; quando so utilizados vrios planos de luz o emparelhamento torna-se mais difcil principalmente em cenas com descontinuidades; surgem geralmente problemas na utilizao destas tcnicas nas partes ocultas da cena em questo. Como exemplo de tcnicas activas encontramos: Esteroscopia activa consiste na projeco de um padro de luz sobre a cena em questo e obteno de uma imagem de intensidades com a cmara afastada da fonte de luz utilizada. De seguida obtm-se a correspondncia entre os pontos do padro de luz projectado e os obtidos na imagem. Recorrendo ao principio da triangulao obtm-se a informao tridimensional desejada, ou seja fazendo uso das equaes de projeco do ponto tridimensional em questo para a fonte de luz e para a cmara utilizada obtemos um sistema de equaes sobredimensionado que pode ser resolvido de modo a obter a informao tridimensional do ponto. Interferometria consiste na projeco sobre a cena de riscas de sombra igualmente espaadas . De seguida deve-se adquirir uma imagem da cena com uma cmara deslocada lateralmente em relao ao projector e em frente da qual se encontra uma grelha idntica a usada para obter as riscas. A imagem obtida apresenta os contornos dos pontos que esto mesma distncia , mas no d indicao acerca do sinal de variao de distncia entre linhas de contornos adjacentes. A deslocao de objectos num sentido conhecido ou o uso de uma segunda grelha permitem-nos obter tal informao. Esta tcnica usada essencialmente para obter informao acerca de distncias relativas. Deteco de ecos consiste na projeco de energia sobre a cena e na medida do tempo que decorre entre a emisso dessa energia e a recepo da mesma aps reflexo na cena.

2.3 - Tcnicas passivas de obteno de informao tridimensional


As tcnicas passivas caracterizam-se por fazer uso apenas de luz ambiente para iluminar a cena. A informao de distncia obtida a partir de uma ou mais imagens de intensidade da cena. A principal vantagem que estas tcnicas apresentam deve-se ao facto de serem de aplicabilidade genrica , mesmo em ambientes naturais no controlados. As desvantagens apresentadas so as seguintes: dificuldade de aplicao em caso de cenas sem pontos caractersticos; dificuldade quando pontos so vistos numa imagem mas no em outra; lentido do processo na obteno de informao tridimensional ou quando se pretende informao mais densa. Como exemplo de tcnicas passivas encontramos:

38

Captulo III - Fundamentos Tericos


Esteroscopia passiva obteno de imagens em instantes simultneos por parte de duas cmaras que devero estar posicionadas de forma adequada. De seguida estabelece-se correspondncias entre pontos caractersticos das duas imagens e fazendo uso do principio da triangulao, a partir das equaes de projeco dos pontos caractersticos em questo e da geometria do sistema podemos assim obter a informao tridimensional desejada. Usando uma cmara semelhante ao exemplo anterior no entanto as duas imagens so obtidas pela mesma cmara em duas posies distintas. Forma com base em X procura-se extrair a informao de distncia a partir de uma ou mais imagens monoculares de intensidade, obtidas com uma cmara fixa. Estas tcnicas podem ser baseadas no brilho , na perspectiva, na textura, na ocultao ou noutras caractersticas que de forma indirecta traduzem a geometria da cena.

3 - Processamento e Anlise de Imagem


Nesta seco so fornecidos os princpios bsicos matemticos para os mtodos de processamento e anlise de imagem utilizados no sistema desenvolvido assim como alternativas implementao realizada. Assim sero explicadas diferentes transformaes, filtros e mtodos para extrair informao essencial das imagens iniciais. Esta informao essencial consiste em orlas de intensidade, linhas e forma de objectos detectados.

3.1 - Thresholding
Um mtodo simples para segmentao de imagem o thresholding, que faz com que uma imagem de cinzentos se torne numa imagem binria. Pode ser definido por

1 se f ( x, y ) > t z ( x, y ) = , 0 outros casos


onde f(x,y) representa a funo original, z(x,y) a funo binria e t o valor do threshold. O valor do threshold tem que ser determinado de acordo com cada imagem. Existem vrias possibilidades para atribuir valores a esta varivel. A maneira mais simples um valor esttico: 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 no transita o valor um para a imagem final, mas sim o valor de cinzento da imagem original. Outro mtodo para efectuar o thresholding usa os mtodos acima mencionados em intervalos incluindo os limites do intervalo em vez de usar a toda a gama de valores. Tambm usada informao de histograma para procurar o valor a aplicar de threshold (por exemplo, o valor de threshold a aplicar o mnimo valor presente no histograma da imagem). Se valores de cinzento pertencentes ao fundo da imagem aparecem tambm no prprio objecto, podem surgir alguns problemas quando usado o mtodo mais simples de threshold. Para resolver este tipo de problemas, os threshold dinmicos usam janelas de m x m centradas numa posio (x,y). Se a rea de fundo e a rea de objecto tm a mesma frequncia de ocorrncia, ento o valor mdio um bom valor de threshold:

t=

m -1 1 m -1 m -1 f ( x + k - i, y + k - j ) com k = 2 m i =0 j =0 2

Uma extenso possvel deste mtodo pode ser feita usando informao do histograma paralelamente com o uso das janelas acima mencionadas. Mtodos menos elegantes no calculam um novo valor de threshold para cada pixel e assim conseguem ser muito mais rpidos.

39

Captulo III - Fundamentos Tericos

3.2 - Filtragem de imagem


Ainda na fase de pr processamento, operaes em imagens com filtros so adoptadas para suprimir o rudo e artefactos e ainda para extrair a informao necessria.

3.2.1 - Filtros de suavizao e realce


Todos os filtros passa - baixo tem um efeito de suavizao. Estes filtros so especialmente desenhados para eliminar rudo ou estruturas subtis e provocam nas imagens uma perda de preciso. Estes filtros tambm so usados como filtros fundamentais na construo de filtros mais complexos. Para propsitos de estimao da qualidade do filtro, a sua funo de transferncia (a resposta impulsional da transformada de Fourier) analisada nos seguintes pontos: um filtro de suavizao preenche todos os seus propsitos, se a funo de transferncia tem um mximo global a partir do qual a funo decresce monotonamente e torna-se zero a partir de uma determinada frequncia, denominada de frequncia de corte. As caractersticas do filtro so perfeitas, se a funo de transferncia tem tambm caractersticas isotrpicas (ou sem caractersticas sobrepostas).

a)

b)

c)

Figura 3.1: Imagem corrompida com rudo. a) Imagem original. b) Imagem com rudo Gaussiano. c) Imagem com rudo impulsivo

3.2.1.1 - Filtro de mdia Um dos mais simples filtros lineares implementado atravs de uma operao local de mdia onde o valor de cada pixel substitudo pela mdia de todos os valores na sua vizinhana local:

h[i, j ] =

1 M

( k , l ) N

f [k , l ]

onde M o nmero total de pixels numa vizinhana N. Por exemplo, tomando uma vizinhana de 3x3 em [i,j] resulta:

h[i, j ] =

1 i +1 j +1 f [k , l ]. 9 k = i -1 k = j -1

Este filtro de mdia tambm pode ser implementado como um filtro de convoluo, sendo que os pesos dos coeficientes da mscara de convoluo tm que ser obrigatoriamente todos idnticos. O tamanho da vizinhana N controla a quantidade de filtragem. Uma vizinhana mais alargada, correspondendo a uma mscara de convoluo mais alargada, ir resultar num grau de filtragem superior. claro que, quanto maior for o grau de filtragem e consequentemente maior a quantidade de reduo de rudo, maior ser a perda de detalhes na imagem. Os resultados de filtros de mdia de vrios tamanhos so mostrados na figura 3.2.

40

Captulo III - Fundamentos Tericos

a)

b)

c)

Figura 3.2: Resultados da aplicao de mscaras de, 3x3 a), 5x5 b) e 7x7 c) na imagem (b) da figura 3.1.

Quando se desenham filtros de suavizao, os pesos dos coeficientes devem ser escolhidos de maneira que o filtro tenha apenas um pico nico, denominado lbulo principal, e simtrico nas direces verticais e horizontais. Um padro tpico de coeficientes para um filtro de suavizao 3x3 : 1/16 1/8 1/16 1/8 1/4 1/8 1/16 1/8 1/16

Filtros de suavizao lineares removem as componentes de alta frequncia, e assim a preciso de alguns detalhes da imagem so perdidos. Por exemplo, transies do tipo degrau, so transformadas em transies graduais, e a capacidade de localizar com preciso uma transio ser sacrificada. Um filtro variando espacialmente ajusta os pesos dos coeficientes de modo a que a suavizao seja feita numa rea relativamente uniforme da imagem, e que pouca suavizao seja feita em reas com transies bruscas na imagem. 3.2.1.2 - Filtro de mediana O problema principal com operaes de mdia locais, o facto de que estas tendem a esborratar orlas bem demarcadas e estreitas. Uma aproximao alternativa substituir todos os valores dos pixels com o valor da mediana de todos os valores de cinzento da sua vizinhana local. Os filtros que usam esta tcnica so denominados de filtros de mediana. Os filtros de mediana so muitos eficazes a remover rudo impulsivo enquanto mantm todos os detalhes da imagem devido ao facto de no dependerem de valores que so muito diferentes dos valores presentes na sua vizinhana 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. 2. Ordenar os pixels de uma forma ascendente por nvel de cinzento. Escolher o valor do pixel do meio como novo valor para o pixel [i,j].

Geralmente, uma vizinhana com tamanho mpar escolhida para calcular a mediana. Se no entanto, for uma escolhida uma vizinhana com tamanho par, a mediana tomada como a mdia dos valores dos pixels do meio aps ordenao ascendente. Os resultados da aplicao de vrias mscaras de filtros de mediana so apresentados na figura 3.3.

41

Captulo III - Fundamentos Tericos

a)

b)

c)

Figura 3.3: Resultados das aplicao do filtro de mediana de vrias mscaras imagem (c) da figura 3.1. a) Mscara de 3x3, b) Mscara de 5x5 e c) Mscara de 7x7

3.2.1.3 - Filtro Gaussiano Uma das classes de filtros de suavizao o filtro Gaussiano. A funo Gaussiana de uma dimenso dada pela seguinte frmula:

g (x) =

1 2 e 2s 2 .p s

x2

Esta frmula define o filtro e possvel verificar que a forma deste controlada pelo parmetro s. A anlise da imagem digital usa a forma discreta de duas dimenses desta frmula:
(x2 + y2 ) 2s 2

1 g [x , y ] = e 2.p s

A funo Gaussiana tem caractersticas que fazem com que seja extremamente til o seu uso como filtro de suavizao, mas tambm como a base de outros filtros mais complexos. Essas caractersticas so: 1. Mesma forma nos domnios espacial e das frequncias: A funo Gaussiana mantm a mesma forma em ambos os domnios. A transformada de Fourier computada atravs de

F{g ( x)} =

g ( x).e

- jwx

dx
x2

1 = 2.p s 1 = 2.p s 1 = 2.p s

2s 2

e - jwx dx

x2

2s 2

(cos wx + j sin wx)dx 1 . cos wxdx + 2.p s


x2

x2

2s 2

2s 2

j.sin wxdx

42

Captulo III - Fundamentos Tericos

O segundo integral zero, devido funo seno e assim o integrando anti-simtrico. Assim a transformada de Fourier simplifica para:

F{g ( x)} =

1 2.p s

x2

2s 2

. cos wxdx

=e
2. 3. 4.

w2

2v 2

, v2 =

1 . s2

Simetria na rotao: A isotropia da rotao garante uma suavizao uniforme em todas as direces. Factor de escala: Atravs do escalonamento do parmetro s, possvel variar a largura da funo assim como o nvel de suavizao. Separabilidade: Uma implementao eficaz (mesmo para filtros com bandas maiores) pode ser realizada atravs da diviso da funo em 2D para duas de 1D. A aplicao de um filtro Gaussiano mostrada na figura 3.4.

a)

b)

c)

Figura 3.4: Resultado da aplicao de filtros Gaussainos. (a) Imagem original. (b) Filtro Gaussiano com uma mscara 5x5. (c) Filtro Gaussiano com uma mscara 9x9

3.2.2 - Filtros Derivativos


3.2.2.1 - Operadores de gradiente Para detectar estruturas em imagens, tais como orlas e linhas, filtros so usados de maneira a extrair as derivadas da imagem. Os operadores de Roberts, Prewitt e Sobel so exemplos de tipos de filtros que fornecem o valor absoluto de um gradiente de vrias formas. A aplicao de um filtro de gradiente mostrada na figura 3.5. A sensibilidade perante o rudo pode ser decrementada de uma maneira bastante significativa atravs da construo da derivada de uma imagem suavizada (imagem que foi sujeita a um filtro passabaixo). Assim em vez de se obter as derivadas da imagem directamente, a imagem inicialmente sujeita a um filtro do tipo Gaussiano, e s depois so extradas as suas derivadas. Este mtodo feito tendo em considerao o teorema da convoluo:

f ( x, y ) ( g ( x, y ) * f ( x, y )) = f ( x, y ) * g ( x, y )
com

43

Captulo III - Fundamentos Tericos


1 g ( x, y ) = e 2.p s (x2 + y 2 ) 2s 2

A primeira equao mostra que se pode chegar ao mesmo resultado de duas formas distintas: 1. 2. Fazer a convoluo da imagem com o filtro Gaussiano e em seguida obter a sua derivada, ou Derivar a funo Gaussiana e em seguida fazer a convoluo da imagem com a funo resultante.

A derivao da funo de Gauss pode ser calculada analiticamente e assim pode ser implementada de uma forma prtica nos sistemas computacionais. Na utilizao dos operadores acima referidos surgem algumas dificuldades: 1. A seleco do nvel de amplitude a partir do qual se marcam as orlas pode dar origem ao aparecimento de traos largos em vez de orlas bem demarcadas e estreitas; nesse caso necessria uma operao de adelgaamento aplicada imagem resultante da convoluo. Esta operao consiste em eliminar todos os pontos que no sejam mximos locais, de preferncia segundo a direco da orla a que possam pertencer. Outro efeito indesejvel que surge na aplicao dos operadores de gradiente a descontinuidade dos contornos detectados, inerente ao carcter discreto das mscaras de convoluo. As orlas que apresentam uma amplitude elevada segundo uma direco tero certamente variaes fracas na direco perpendicular e, como tal, um contorno curvilneo poder ser detectado como vrias pequenas linhas descontnuas. Para evitar essas quebras podem-se utilizar mtodos de limiarizao especficos, como por exemplo, limiarizao a dois nveis com histerese ou com base em histogramas locais.

2.

3.2.2.2 - Operadores Laplacianos Outra alternativa para a deteco de orlas consiste em determinar as passagens por zero da segunda derivada da funo imagem, mas apenas segundo a direco de variao mxima em cada ponto. Embora numa primeira anlise seja uma operao idntica anterior, apresenta a vantagem de se poder usar um operador independente da orientao o Laplaciano cuja expresso num espao bidimensional tem a forma:

2 I ( x, y ) 2 I ( x, y ) I ( x, y ) = (I ( x, y )) = + x 2 y 2
2

Tambm neste caso, podemos passar ao domnio discreto e aproximar o Laplaciano por equaes s diferenas, mas agora de segunda ordem, obtendo-se mscaras de convoluo idnticas s que se ilustram na fig. 5. Estas mscaras resultam tambm de se considerarem aproximaes diferentes; contudo, ao contrrio das anteriores, tm um carcter no-direccional. O Laplaciano duma imagem obtm-se por uma nica convoluo I(x,y)*h(x,y), sendo h(x,y) uma mscara da qual se pode verificar o seu efeito na fig.5, da qual resultam as orlas presentes qualquer que seja a sua orientao. A mscara h14 na fig.5, no entanto, pouco sensvel s variaes nas diagonais. A maior desvantagem das operaes de diferenciao a sua grande sensibilidade ao rudo 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 prvia para remoo do rudo que, no entanto, tem tambm efeitos sobre a prpria localizao das orlas.

44

Captulo III - Fundamentos Tericos

a)

b)

c)

Figura 3.5: Exemplo de aplicao de filtros de gradiente e Laplaciano. a) imagem original. b) Aplicao de um filtro Laplaciano e c) Aplicao de um filtro de Sobel.

3.3 - Deteco de orlas de intensidade


3.3.1 Deteco de orlas de intensidade Canny
A deteco de orlas em conjunto com mtodos como o region growing ou modelos deformveis tornam possvel descobrir regies inter-relacionadas. A deteco de orlas melhora a robustez destes mtodos, isto , o conhecimento acerca das orlas permite uma melhor formulao do critrio de truncagem. A ideia bsica quando se procuram as orlas descobrir regies na imagem com um alto gradiente. Como mostrado na seco de filtragem de imagem algumas pr-consideraes tm que ser tomadas de maneira a ser possvel extrair gradientes realizveis. Um operador derivativo para a deteco de orlas tem que satisfazer dois requisitos principais: 1. 2. 3. Reduo de rudo: A probabilidade do rudo ser detectado como uma orla tem que ser a mais baixa possvel. Localizao exacta: A orla tem que ser encontrada numa posio o mais exacta possvel a partir dos gradientes calculados Unicidade de resposta: Deve existir uma relao unvoca entre orlas reais e orlas assinaladas ou, por outras palavras, uma orla real deve ser assinalada uma nica vez. A satisfao simultnea de todos os requisitos difcil de obter, porque quanto mais efectiva a suavizao da imagem, menor a possibilidade de se poder se determinar a posio da orla. A preposio que Canny faz para resolver este problema, subdivide este processo em trs etapas:
Clculo de Gradientes Locais Supresso de No Mximos Threshold por Histerese

Estas etapas sero explicadas na seco de operaes complementares

3.3.2 - Deteco de orlas de intensidade Deriche


Deriche em 1987, props um filtro idealizado com vista deteco ptima de variaes de intensidade em degrau. Assim modifica as condies de fronteira do filtro de Canny para as de um filtro de resposta impulsional infinita, o que conduz equao:

f D = -c.e

-a x

sin( wx)

Deste modo, este filtro fica totalmente definido por apenas dois parmetros a e w, sendo o valor de c determinado pela condio de ganho que, normalmente, se pretende unitrio. Este filtro de Deriche, para deteco de orlas de intensidade, o mais recomendado devido a factores como:

45

Captulo III - Fundamentos Tericos


1. 2. 3. A sua implementao ser recursiva, sendo assim eficiente; O tempo de execuo depender apenas das dimenses da imagem na qual se pretende empregar; A afinao conseguida para diferentes tipos de imagem, pela utilizao dos parmetros a e w.

A afinao conseguida neste filtro responsvel pela preferncia atribuda ao filtro de Deriche em detrimento do filtro de Shen e Castan: neste filtro apenas existe um parmetro de ajuste, e por isso, a mesma afinao mais difcil quando se utiliza este tipo de filtro. Na figura 6 apresenta-se o resultado da deteco de orlas em imagens pelo filtro de Deriche. de notar a diferena entre a imagem obtida e as resultantes da aplicao dos operadores de Sobel e do Laplaciano apresentadas na imagem 5, nas quais, manifestamente mais elevada a amplitude do rudo em toda a imagem. De notar tambm, na figura 6, que apesar de nos resultados finais, em termos de imagem, no haver grandes diferenas entre as imagens resultantes da deteco de Canny e de Deriche, o esforo computacional extremamente elevado da deteco de Canny torna-se numa grande desvantagem deste mtodo, quando comparada com o mtodo de Deriche.

3.3.3 - Operaes complementares


A imagem resultante da filtragem est longe de ser uma representao fidedigna e precisa das orlas de intensidade na imagem original, em particular, os problemas que surgem na diferenciao de imagens subsistem, embora em menor escala, nas imagens resultantes da aplicao de qualquer um dos filtros para deteco de orlas de intensidade, quer seja numa configurao de deteco por mximos (como o caso do filtro de Deriche), quer seja numa configurao de deteco por passagens por zero. O tipo de filtragem utilizada deteco por mximos ou deteco por passagens por zero determina as operaes aplicveis. Nomeadamente, as operaes de supresso de no mximos e de limiarizao s so aplicveis a imagens resultantes de uma filtragem por detector de mximos de amplitude do gradiente, enquanto que a operao de validao de passagens por zero, como o nome indica, aplicvel a imagens de orlas detectadas por derivaes 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 necessrios para preencher os critrios de qualidade acima referidos. Deriche estendeu tambm o mtodo de Canny para o caso de trs dimenses.

a)

b)

c)

Figura 3.6: Aplicao de filtros de deteco de orlas de intensidade. (a) Imagem original. (b) Deteco de orlas Canny. (c) Deteco de orlas Deriche.

Supresso de no - mximos Esta operao tem por objectivo remover todos os pontos que, no sendo mximos de amplitude na resposta do filtro imagem original, se situam nas suas imediaes e apresentam ainda um nvel elevado que poder conduzir a uma localizao imprecisa da orla correspondente. O que se pretende realizar uma espcie de adelgaamento direccionado segundo o gradiente de intensidade em cada ponto da imagem. A implementao que est feita do filtro de Deriche usada neste trabalho inclui a supresso de no-mximos.

46

Captulo III - Fundamentos Tericos

Limiarizao A limiarizao de uma imagem de orlas de intensidade destina-se a tranform-la numa representao grfica ou mapa das orlas mais significativas presentes na imagem original, removendo-se todas aquelas que correspondem a pequenas transies de intensidade, vulgarmente associadas a rudo nos processos de aquisio e digitalizao de imagens. Esta operao no est, todavia, isenta de dificuldades. O rudo na imagem de amplitudes de orlas, aps as operaes de filtragem, d origem a flutuaes 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 rudo. Validao das passagens por zero No que diz respeito deteco de orlas pelas passagens por zero de um operador de derivao de segunda ordem, h que ter em conta que surgem com frequncia deteces falsas. Estas no tm nenhuma correspondncia directa com variaes nos sinais originais e as suas causas so principalmente duas: 1. 2. O rudo nos sinais ou imagens originais, introduzido possivelmente pelos dispositivos de captao, e que do origem a desvios na resposta do operador; As variaes no sinal ou imagem serem tais que, devido suas interferncias, surjam mnimos locais na amplitude da primeira derivada.

Torna-se assim necessrio validar as passagens por zero que correspondem efectivamente s variaes existentes e remover as passagens por zero que surgiram indevidamente.

3.4 - Transformao de Hough


A transformao de Hough define uma transformao de um domnio da informao para um outro domnio. Cada ponto sob uma determinada curva vota sobre determinados parmetros; os parmetros que ganham a maioria dos votos so declarados vencedores. Em seguida so apresentadas trs transformaes de trs curvas distintas: rectas, crculos e elipses.

3.4.1 - Deteco 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 parmetros. Se os valores dos parmetros, a relao entre as coordenadas de um dado ponto claramente especificada. Se rescrevermos a equao dada em cima por: b= -m.x+y. Agora, na equao de cima, vamos assumir que m e c so variveis de interesse, e que x e y so constantes. A equao acima representa uma linha recta no espao m-b. O declive e a interseco com o eixo vertical so determinados atravs de x e y. Um ponto (x,y) corresponde a uma linha recta no espao m-b. Este mapeamento mostrado na figura 7. Deve ser mencionado aqui que a forma da curva no espao dos parmetros depende da funo original usada para representar a curva. Na prtica, a equao polar de uma linha:

x. cos(a ) + y. sin(a ) - r = 0 ,
mais usada que a forma explcita para evitar problemas com linhas que so praticamente verticais. Pontos situados na fronteira (x,y) so mapeados para o espao dos parmetros (r,a).

47

Captulo III - Fundamentos Tericos


No caso de uma linha recta, tal como representado em cima, se existirem n pontos que esto situados sobre essa mesma linha, ento estes pontos iro corresponder a uma famlia de linhas rectas no espao dos parmetros, como ilustrado na figura 3.7. Todas estas linhas iro passar pelo ponto (a,b) no espao dos parmetros. Este ponto d os parmetros da linha recta original. Se estamos interessados em encontrar a linha recta que melhor se adapta a n pontos numa imagem, ento ns podemos utilizar o mapeamento mencionado em cima do espao de imagem para o espao dos parmetros. Nesta aproximao, denominada de transformada de Hough, ns representamos o espao dos parmetros como um vector de acumuladores, representando valores paramtricos discretos. Cada ponto na imagem vota em vrios parmetros, de acordo com a equao de transformao. De maneira a encontrar parmetros que caracterizam a linha, devemos detectar picos de acumulao no espao dos parmetros. A transformao de Hough no requer agrupamento priori dos pontos situados em orlas, e tambm que esses pontos que ficam situados sobre a curva de interesse constituam uma fraco pequena de todas as orlas presentes na imagem. Em particular, o nmero de orlas que se situam ao longo da curva de interesse podem ser menos do que metade o nmero de orlas presentes na cena, facto este, que inviabiliza a utilizao da maior parte dos algoritmos de regresso. O pressuposto por detrs da transformada de Hough que na presena de grandes quantidades de rudo, o melhor que pode ser feito encontrar o ponto no espao dos parmetros que satisfaa um maior nmero de orlas na imagem. Se o pico no espao dos parmetros cobre a mais do que um acumulador, o centride da regio providencia uma estimativa dos parmetros. Se existem vrias tipos de curvas na imagem que so encontradas pelo modelo, haver vrios picos no espao dos parmetros. possvel detectar cada pico, remover as orlas associadas com a instncia da curva correspondendo ao pico, e continuar a deteco das curvas restantes, at que os picos serem no significativos. De qualquer forma, pode ser difcil de detectar se um pico significativo.

Figura 3.7: Exemplo de uma tranformao de Hough. Estas imagens mostram a deteco de uma linha dos domnios espacial e de Hough. (a) Linha do domnio espacial. (b) Transformao de Hough de uma linha.

3.4.2 - Deteco de crculos


Outro problema com a transformada de Hough que o tamanho do espao dos parmetros discretos aumenta muito rapidamente medida que o nmero de parmetros aumenta. Para um arco circular, o espao dos parmetros tem trs dimenses; para outras curvas estas dimenses podem ser muito superiores. Como o nmero de acumuladores aumenta exponencialmente com a dimenso do espao, a transformada de Hough pode ser computacionalmente muito ineficiente para modelos complexos. Vrios mtodos tem sido sugeridos de maneira a melhorar a performance da transformada de Hough. Um mtodo usa a informao do gradiente para regies de fronteira de maneira a reduzir o trabalho no espao dos parmetros. Supondo que o modelo de curva um crculo. Este modelo tem trs parmetros: dois parmetros para o centro do crculo e um parmetro para o raio do crculo. Se o ngulo do gradiente para as orlas de intensidade est disponvel, ento este modelo providencia uma condicionante que reduz o nmero de graus de liberdade e consecutivamente o tamanho requerido para o espao dos parmetros. A direco do vector que vai desde o centro do crculo para cada orla determinado atravs do ngulo do gradiente, deixando o valor do raio como o nico parmetro desconhecido. Existem outros mtodos que podem ser usados para reduzir o tamanho do espao dos parmetros. Os crculos so descritos atravs da seguinte frmula genrica:

( x - a ) 2 + ( y - b) 2 = r 2 b = y r 2 - ( x - a ) 2 ,

48

Captulo III - Fundamentos Tericos


onde a e b referem a posio do centro e r o raio do crculo. De modo a evitar os requisitos computacionais de uma transformao 3D de Hough, o problema organizado de uma forma heurstica em duas fases distintas e ento simplificado para uma transformao de Hough de duas dimenses. Essas fases so: 1) Encontrar todos os centros dos crculos. 2) Determinar o raio de cada crculo. O correspondente centro do crculo encontra-se na recta normal tangente de um determinado ponto do crculo. Assim, as normais de vrios pixels do mesmo crculo iro intersectar-se no centro do crculo. Para cada pixel a sua tangente estimada como a linha que melhor se adapta a todos os pixels dentro de uma vizinhana pequena. Este mtodo permite a computao da recta normal que gravada no histograma. O mximo do histograma d-nos a localizao dos vrios candidatos a centros do crculo processado. O prximo passo encontrar o correspondente raio para cada centro atravs da computao de um histograma radial para cada centro. Para cada pixel na imagem a sua distncia do centro computada e guardada num histograma de uma dimenso. O mximo desse histograma corresponde ao raio dos crculos.

Figura 3.8: Deteco de um crculo usando a transformao de Hough.

3.4.3 - Deteco de elipses


Uma elipse definida por uma equao do tipo

a( x - p) 2 + 2.b( x - p)( y - q) + c( y - q) 2 = 1

a.c - b 2 > 0

Aqui encontramos cinco parmetros (a, b, c, p, q). Uma transformao de Hough de cinco parmetros ir exigir muito esforo computacional. Assim, uma alternativa heurstica reside no facto de simplificar o problema atravs da separao desta tarefa em duas fases: 1) Todos os centros das elipses so identificados. 2) Os restantes trs parmetros so determinados atravs da utilizao de uma implementao focal da transformada de Hough. As tangentes de trs pontos (x1, y1), (x2, y2) e (x3, y3) na elipse determinam o ponto de centro 0. O ponto de interseco t1 e o meio de dois pontos (x1, y1) e (x2, y2) so calculados. O centro 0 encontra-se num raio dado por t1 e m1. O segundo e terceiro ponto formam t2 e m2.A interseco 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 transformao de Hough de dois parmetros acumula esses raios, com a interseco desses raios a corresponder ao mximo do histograma. Para calcular os parmetros restantes a,b,c a elipse transformada para o centro do sistema de coordenadas. A equao da elipse simplifica para

ax 2 + 2.b.x. y + c. y 2 = 1 .
Substituindo estes trs pontos na elipse o seguinte sistema linear de equaes

49

Captulo III - Fundamentos Tericos


x12 2 x2 2 x3 2 x1 y1 2 x2 y 2 2 x3 y3 y12 a 1 2 y2 b = 1 2 y3 c 1

pode ser resolvido em ordem a a, b e c. A equao ac-b2>0 tem que ser verificada tambm. Se este critrio no for observado, os trs pontos escolhidos no pertencem elipse ou os clculos das tangentes no foram precisos. Neste caso, os clculos tero que ser refeitos. Finalmente, os parmetros a,b,c so convertidos para r1, r2 e F, onde r1 representa o raio principal, r2 o raio secundrio e F o ngulo entre r1 e o eixo dos xx.

(x1,y1) 0 m2 (x3,y3) t2
a)

m1

t1 (x2,y2)

y r2 0
f r1

b)

Figura 3.9: Transformao de Hough Deteco de uma elipse. (a) Deteco do centro da elipse. (b) Determinao dos parmetros restantes.

3.5 Transformaes e coordenadas homogneas


Adicionando um quarto componente a um vector de trs dimenses leva s denominadas coordenadas homogneas. 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 homogneo p= (kx, ky, kz, k)T. A transformao do sistema de coordenadas homogneo para o sistema de coordenadas cartesianas alcanada atravs da diviso das primeiras trs coordenadas homogneas pela quarta coordenada homognea. Matrizes homogneas tm como vantagem a facilidade de representao de transformaes por multiplicaes de matrizes. Uma das maiores vantagens a possibilidade de fazer o escalonamento da perspectiva.

Figura 3.10: A matriz homognea combina as formas de transformao rotao, translao, perspectiva e escalonamento numa s matriz.

3.6 - Modelos Deformveis


Os modelos deformveis so multidimensionais, baseados em modelos geomtricos e capazes de deformaes elsticas dependendo nos seus graus de liberdade de maneira a corresponder a uma dada quantidade de informao que se pretende avaliar. As foras elsticas provm da sua energia interna de

50

Captulo III - Fundamentos Tericos


deformao, enquanto que as foras externas formam o modelo. Uma energia potencial dependendo da informao do modelo formam as foras externas. Os modelos deformveis possuem a capacidade de segmentar estruturas anatmicas e segui-las em sequncias de imagens atravs da combinao de informao derivativa da informao da imagem com um conhecimento priori acerca da posio, tamanho e forma da estrutura. Muitos mtodos seguem esta filosofia, sendo diferentes entre si nas seguintes caractersticas: comportamento e eficincia dos modelos, sua dimenso e equaes de movimento. Muitas extenses e adaptaes so reportadas desde a primeira publicao de Terzopoulos et al. Dois exemplos so explicados em seguida.

3.6.1 - Snakes
A clssica aproximao aos modelos deformveis a denominada snake, que consiste num contorno parametrizvel movendo-se num plano (x,y) 2 com a finalidade de minimizar uma dada energia funcional. As funes de coordenada x(s) e y(s) constrem a descrio do parmetro v(s)=(x(s),y(s))T do contorno. Estas funes tem o domnio de imagem (x,Y) D2 como o domnio de valor e s [0,1] como domnio de definio. A energia funcional

E ( v ) = S (v ) + P ( v )
descreve a forma do contorno. A forma final do contorno resulta da minimizao desta energia. O termo de primeira energia corresponde energia para a deformao elstica interna e a soma da energia de tenso SD(v) e da energia de curvatura SK(v):

S (v ) = S D ( v ) + S K (v )
v S D (v) = wD ds s 0
1 2

2v S K = wK 2 ds s 0

O parmetro wD define a tenso e consequentemente a eficincia de tenso, e o parmetro wK regula a rigidez e consequentemente a suavizao do contorno. Em

P(v) = P(v( s ))ds


0

o escalar da funo potencial P (v ( s )) escolhido de forma, a que os seus mnimos coincidam com a posies das caractersticas da imagem. Estas caractersticas necessitam de ser encontradas. As orlas presentes na imagem so um bom exemplo das caractersticas da imagem. Assim o gradiente de uma imagem suavizada I(x,y):

P(v) = - wB Gs * I ( x, y ) ,
forma a funo potencial, com Gs a ser o filtro de suavizao, cuja largura de banda influencia a expanso dos mnimos locais. A funo v(s) tem que preencher os requisitos da equao de Euler-Lagrange:

v 2 2v ( wD ) + 2 ( wK 2 ) + P(v( s)) = 0 s s s s

51

Captulo III - Fundamentos Tericos

sendo a condio necessria para a existncia de uma soluo para a equao. ento possvel resolver esta equao numericamente, atravs do mtodos das diferenas finitas e do mtodo dos elementos finitos.

3.6.2 - Balloons
Em contraste com uma segmentao por nveis morosa com modelos deformveis planares, o uso de modelos de superfcie tri-dimensionais podem acelerar o processo. Simultaneamente, a intensidade do rudo e a suavizao entre nveis distintos aumenta. Especialmente, os modelos de trs dimenses podem ser usados de uma maneira eficaz e precisa para segmentar volumes de imagens dependentes do tempo. O comportamento fsico de um modelo deformvel de trs dimenses ou balloon equivalente (dependendo da variao dos parmetros) a uma placa fina ou a uma membrana sob tenso que se deforma igualmente por toda a sua superfcie. O contorno activo de trs dimenses dado por

[0,1]2

u, v x(u, v) = ( x(u, v), y (u, v), z (u, v))T

A energia funcional

x x 2x 2x 2x + a 01 + b 20 2 + b11 + b02 2 E p ( x) = a10 u v u uv v 0 0

1 1

dudv

(5)

descreve a deformao energtica do contorno e corresponde ao termo S(v) na equao 4. Os factores no negativos aij(u,v) e bij(u,v) determinam a tenso e a rigidez da superfcie. Um aumento de aij(u,v) normalmente reduz a superfcie, onde valores altos de bij(u,v) restringem a flexibilidade do contorno. O factor b11 especfico para o modelo de contorno de trs dimenses e classifica a toro da superfcie.

52

Captulo IV - Sistema Desenvolvido

Captulo IV

1 Introduo ao Sistema Desenvolvido


1.1 Problemtica do projecto
O objectivo principal deste projecto a correco 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 realizao da correco das referidas imagens. Esta deteco de movimento ser realizada atravs de um sistema de inspeco visual estereoscpico passivo externo sistema de aquisio de imagem mdica. De acordo com esta problemtica, o factor com mais relevo o clculo da distncia, atravs da determinao de coordenadas 3D dos pontos caractersticos presentes numa cena em relao a um determinado ponto de origem. Um mtodo comum para obter tal informao de profundidade a partir de imagens obtidas por cmaras a aquisio de uma par de imagens atravs de duas cmaras que se encontrem em localizaes diferentes e que adquiram o par de imagens da cena em instantes simultneos de modo a ser possvel a aquisio de informao 3D dinmica, medida que o exame clnico vai decorrendo. O princpio usado para o clculo de coordenadas 3D o da triangulao. Assim dentro da problemtica global, acima mencionada, podem ser definidas vrias fases do projecto. Estas fases esto relacionadas com: adquirir imagens digitais simultaneamente atravs do frame grabber, conhecer os parmetros internos e externos das cmaras para inferir com preciso coordenadas 3D, dimensionamento de alvos de calibrao e de deteco, deteco de entidades presentes nas imagens, emparelhamento das imagens, clculo de coordenadas 3D de pontos caractersticos, estimao do movimento e correco de imagens conforme o movimento estimado. Foi tambm objectivo do projecto o dimensionamento de um sistema de aquisio de custo reduzido e de fcil acesso, ou seja, de modo a que se possa replicar o sistema de raiz sem que os custos econmicos, por si s inviabilizassem a montagem deste sistema.

1.2 - Mtodo
O mtodo para o dimensionamento da aplicao de aquisio e correco seguiu uma filosofia modular, isto , tentou-se desenvolver a aplicao por mdulos de maneira a que possam ser independentes por si s e assim ser reutilizados em outras aplicaes. Assim a aplicao encontra-se

53

Captulo IV - Sistema Desenvolvido


dividida nos seguintes mdulos: aquisio, calibrao, deteco e estimao de coordenadas 3D, estimao e correco do movimento. Na figura 4.1 est representado o diagrama geral da abordagem global adoptada.

Mundo 3D

Calibrao das cmaras

Imagem Esq.

Imagem Dir.

Aquisio

Determinao das entidades

Determinao das entidades

Emparelhamento

Determinao das coordenadas 3D dos pontos

Deteco e Obteno de Informao 3D

Estimao e Correco de movimento

Estimao e Correco de movimento

Figura 4.1 Diagrama geral da abordagem adoptada

54

Captulo IV - Sistema Desenvolvido

1.3 - Conceitos Bsicos


Nesta seco sero introduzidas algumas definies e conceitos globais que permitem visualizar o sistema de viso por computador desenvolvido de uma forma mais completa.

1.3.1 - Estereoscopia passiva


A tcnica para obteno de informao tridimensional utilizada neste projecto foi a estereoscopia passiva. Recorre-se assim a duas imagens de uma cena, tomadas de posies diferentes, para obter a informao de distncia. A aquisio desta informao dividida nos seguintes passos: 1 Aquisio Aquisio de duas imagens da cena, tomadas de pontos diferentes e de modo a que exista alguma sobreposio entre elas. 2 Deteco e obteno de informao 3D Estabelecer correspondncias entre pontos das duas imagens, isto encontrar pares de pontos que sejam a projeco do mesmo ponto na cena. Para cada par de pontos correspondentes determinar o ponto de interseco das rectas por eles determinados no espao, obtendo assim as coordenadas do ponto da cena (triangulao).

1.3.2 - Triangulao
A triangulao o principio bsico usado nas tcnicas esteroscopicas para a obteno de informao tridimensional. Qualquer tcnica que faa uso de um sistema de duas cmaras, que se encontrem em posies diferentes e obtenham um par de imagens da cena em cada instante, pode fazer uso deste princpio. Princpio este que tambm aplicvel na situao em que substitumos uma das cmaras por uma projeco de um padro de luz sobre a cena. O padro projectado pode assim ser encarado como uma imagem do padro que a projeco gera na cena. Um ponto de uma imagem determina, juntamente com o centro ptico da lente da cmara utilizada na sua aquisio, uma recta no espao que passa pelo ponto da cena que lhe deu origem. A equao de recta correspondente calculada a partir das coordenadas do ponto na imagem e dos parmetros geomtricos da cmara. Conhecendo dois pontos nas duas imagens que correspondam ao mesmo ponto na cena, possvel determinar as equaes de duas rectas que se interseccionam num ponto ao qual correspondem as coordenadas tridimensionais do ponto da cena. Em geral as duas rectas no se intersectam pelo que geralmente o ponto soluo ser o ponto que minimiza a distncia s duas rectas no sentido dos mnimos quadrados. Geralmente as tcnicas baseadas em triangulao requerem o estabelecimento de correspondncias entre pontos de duas imagens constituindo-se como uma das suas principais limitaes, devido ao seguintes factores:

Figura 4.2 Geometria de um sistema stereo

- O custo computacional do estabelecimento das correspondncias em regra geral elevado. - Nem sempre possvel determinar o ponto correspondente na outra imagem, ou porque no foi captado nessa imagem (parte oculta) ou porque no foi possvel identific-lo. - Podem ser estabelecidas falsas correspondncias, o que origina valores de distncia errados. A determinao das equaes das rectas obriga a uma calibrao geomtrica prvia das cmaras com o objectivo de determinar as equaes que relacionam as coordenadas dos pontos da cena com as respectivas coordenadas imagem.

55

Captulo IV - Sistema Desenvolvido

1.3.3 - ptica
O sistema de viso por computador baseia-se no modelo de cmara pin-hole, que modela a geometria da projeco perspectiva mas omite o efeito da profundidade de campo, uma vez que apenas os pontos dentro de um certo intervalo de distncia se encontram focadas no plano da imagem. A projeco perspectiva assume que o volume a visionar uma pirmide infinita limitada apenas, pelo topo, fundo e lados do rectngulo de viso do plano da imagem. Efeitos pticos tais como a profundidade de campo e atenuao de luz limitam o volume visvel devido, introduo de limites distncia qual um objecto visvel. Objectos podem no ser visualizados de uma forma clara se estiverem muito prximos ou muito afastados. O modelo pin-hole da cmara assume que os raios perspectivos passam por uma abertura infinitesimal na frente da cmara. Na realidade a abertura da cmara tem que ser maior para possibilitar a entrada de luz. So 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 projeco perspectiva.. A lente adquire assim mais luz, possibilitando um ambiente de funcionamento para a cmara com menor iluminao ou com uma velocidade de shutter superior, tendo como desvantagem a limitao da profundidade de campo. excepo da limitao da profundidade de campo e da calibrao da cmara as lentes no introduzem efeitos que violem as ideias base da projeco perspectiva, e a maioria dos algoritmos de viso por computador no dependem do desenho do sistema ptico para a formao de imagem. Pode ser necessrio calcular a profundidade de campo de modo a seleccionar a lente para a cmara que melhor se adapte a uma aplicao especifica de viso por computador. 1.3.3.1 - Equao da lente A equao de lente relaciona a distncia do plano da imagem ao centro da lente ( Z), a distncia do ponto na cena (Z) e a distncia focal da lente ( f ).

1 1 1 - = Z' Z f
Quando Z tende para infinito a distncia Z do plano da imagem origem ptica igual distncia focal. A distncia focal a distncia do plano da imagem origem do centro ptico quando raios paralelos esto focados num ponto nico no plano da imagem. Quando a lente se encontra focada em pontos que no se encontram no infinito (Z < f) o uso de f para aproximar Z sobrestima a constante da cmara. A distncia Z do plano da imagem origem ptica aproxima melhor f medida que a focagem da cmara alterada para pontos mais distantes na cena. 1.3.3.2 - Resoluo da imagem A resoluo espacial da imagem determinada pelo espaamento entre pixels, aberraes da lente, difraco e profundidade de campo. Para a maioria das aplicaes de viso por computador a distoro da lente e a difraco no so factores limitantes. A resoluo espacial determinada pela conjuno do espaamento entre pixels e profundidade de campo. Supondo que o espaamento entre pixels no plano da imagem de D, o limite de resoluo de 2D, uma vez que esta a separao entre elementos que permite consider-los diferentes. Ou seja necessrio pelo menos uma unidade de imagem para que dois elementos distintos possam ser distinguidos como tal. Em cmaras electrnicas usando fotododos, a resoluo de imagem limitada pelo espaamento entre pixels na carga acoplada do sistema de aquisio da cmara. Filme fotogrfico contm cristais de hlide prateado suspenso em gelatina clara. Quando um raio de luz atinge um gro de hlide prateado este muda para prateado metlico. Os gros que no tiverem sido expostos luz so eliminados durante o processo de revelao das fotografias. A resoluo nas fotografias depende da distncia mnima entre gros de hlide prateado (geralmente 5 mm). No sistema de viso humano a resoluo espacial determinado por caractersticas internas ao globo ocular. O limite de resoluo tpico para o olho humano de 0.3x10-3 radianos. Assim a distncia ao olho pode ser multiplicada pelo limite de resoluo em

56

Captulo IV - Sistema Desenvolvido


radianos para determinarmos o limite de resoluo espacial do olho humano. Por exemplo distncia de 40 cm teremos 0.3x10-3 x 40 cm = 120 mm. O espaamento entre pontos impressos numa pgina por uma impressora laser de 85 mm. A viso humana consegue aperceber-se de separaes abaixo do limite de resoluo para o sistema de viso humano, por interpolao das zonas onde se encontram os diferentes elementos obtendo assim uma resoluo sub pixel.

1.3.3.3 Profundidade de campo A funo de uma lente possibilitar o uso de uma maior abertura na construo da cmara de modo a que possa entrar mais luz na cmara, possibilitando o funcionamento da cmara com condies de luz ambiente mais fracas ou com velocidades de shutter mais rpidas. No entanto uma maior abertura leva a menores profundidades de campo. H assim um equilbrio a manter entre o tamanho da abertura e a profundidade de campo. Na prtica a profundidade de campo determinada pela resoluo espacial do aparelho de visionamento utilizado. Algum desfoque pode ser tolerado abaixo do limite de resoluo do aparelho. H um intervalo de distncias ao plano de imagem (Z) com um nvel de desfoque aceitvel e da mesma maneira um intervalo de distncias 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 dimetro deste crculo se encontrar abaixo da resoluo do aparelho de aquisio da imagem, ento o desfoque pode ser considerado irrelevante.

2 - Sistema Desenvolvido
2.1 Material utilizado
Para o dimensionamento do sistema referido no ponto 1.1 deste captulo foi utilizado o seguinte material: - Duas cmaras e duas lentes. - Um suporte para as cmaras. - Um frame grabber. - Um PC com o software e carta de aquisio (frame grabber). - Um alvo com pontos caractersticos para extraco informao tridimensional. - Um alvo de calibrao para o clculo dos parmetros intrnsecos e extrnsecos das cmaras. - Transformadores e cabos de ligao

2.1.1 Cmaras e lentes


As cmaras utilizadas so cmaras CCD preto e branco, ilustradas na figura 5.3, uma vez que a cor no viria trazer nenhum acrescento em termos de aquisio de informao tridimensional, de um modelo genrico e fcil de adquirir no mercado.

Figura 4.3 -Cmara CCD preto e branco

57

Captulo IV - Sistema Desenvolvido

As caractersticas tcnicas de algum relevo da cmara so as seguintes: Caracteristicas Dimenses Peso Elemento sensor Nmero de pixels Tamanho da clula Sistema de scan Resoluo Corrente Valores 39 (W) x 43 (H) x 72 (L) mm 150 g Sensor CCD de 1/3 de polegada CCIR 500(H) x 582 (V) CCIR 9.8 mm(H) x 6.3 mm(V) 2:1 entrelaado 420 linhas horizontais de TV 120 mA

Verifica se pelos dados que se trata de uma cmara de pequenas dimenses e peso, o que facilita o seu manuseamento, sendo que as lentes escolhidas foram as de 2.1 mm. As outras caractersticas foram escolhidas seguindo critrios tendo em conta parmetros econmicos e funcionais de maneira satisfazer os requisitos necessrios para o desenvolvimento da aplicao em causa para a aplicao em causa.

2.1.2 - Suporte para cmaras


O suporte para as cmaras (figura 4.4.a) foi dimensionado de modo a obterse um sistema configurvel, flexvel e que possa deste modo adaptar-se a diferentes situaes e modos de operao. O suporte possui trs posies regulveis para cada cmara (figura 5.4.b), de modo a que fosse possvel realizar testes para verificar a exequibilidade da calibrao para diferentes posies e orientaes.

Figura 4.4 - Suporte dimensionado (a) para as cmaras CCD, que inclui trs posies regulveis (b).

2.1.3 - Frame grabber


O frame grabber escolhido foi a Matrox Meteor I, devido ao facto de ser uma placa de aquisio que j se encontrava nas instalaes onde decorreu o desenvolvimento do projecto. As caractersticas desta placa esto sumarizadas no seguinte quadro: Caractersticas Nmero de canais Caractersticas programveis Aquisio Formatos de aquisio Transferncias em Real-Time Valores 4 Saturao, Contraste, Brilho, Tonalidade Cor standard, Video monocromtico NTSC/PAL/SECAM, CCIR/RS-170, Composto ou Y/C At 45 MB/seg (Depende do sistema ou placa VGA utilizada)

58

Captulo IV - Sistema Desenvolvido 2.1.4 - PC


O PC utilizado no tem uma importncia de relevo no desenvolvimento do projecto, bastando a este ter uma slot livre para colocar a placa de aquisio de imagem (frame grabber), e que tenha memria RAM suficiente para um processamento e anlise mais rpido das imagens adquiridas.

2.1.5 - Alvo a colocar no paciente para deteco e clculo de informao 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 deteco dos pontos caractersticos da mesma, sendo que este alvo com este tipo de figuras geomtricas se configura como sendo uma boa base para o algoritmo Figura 4.5 - Alvo a detectar. de deteco de pontos desenvolvido. O dimensionamento deste alvo feito no ponto... deste captulo.

2.1.6 - Alvo para calibrao dos parmetros das cmaras


A imagem de calibrao foi escolhida de acordo como o apresentado em [Tsai] uma vez que todo o modelo de cmara utilizado foi o modelo terico desenvolvido por este. O alvo de calibrao foi desenvolvido de forma a que seja possvel calibrar as duas cmaras sem ter que alterar a posio do alvo, e de modo que as condies do algoritmo de calibrao sejam satisfeitas. Este alvo de calibrao foi dimensionado de forma a cobrir o volume onde se ir encontrar o alvo do paciente de forma a minimizar erros de clculos de localizao 3D de pontos que se afastam do volume de calibrao.

2.1.7 - Transformadores e cabos de ligao

Figura 4.6 Alvo para calibrao de cmaras

Foram escolhidos transformadores que permitissem fornecer a alimentao necessria para as cmaras (12V DC). Os cabos foram escolhidos tendo em ateno o seu comprimento de modo a poderemos maior liberdade de colocao das cmaras. Assim foram utilizados dois cabos RCA, e quatro adaptadores BNC RCA, dado que a conexo dos cabos tanto s cmaras como ao frame grabber feita atravs de conexes BNC.

(a)

(b)

(c)

Figura 4.7 Sistema de interface: (a) transformador para alimentao da cmara (b) cabo de ligao da cmara ao computador (c) adaptadores para os terminais da cmara e computador.

59

Captulo IV - Sistema Desenvolvido

2.1.8 Interruptor de porta srie


O interruptor de porta srie foi implementado para poder fornecer ao software um evento que assinala um momento de aquisio. A sua construo bsica fazendo uso de um filtro passa-baixo RC de modo a evitar jitters de sinal e possveis falsas activaes de evento. O filtro apresenta a configurao de ligao porta srie apresentada na figura 4.8 (a) .Fazendo uso dos pinos RTS(Pino 7) e DTR(Pino 4) da porta srie, injectado um sinal no CTS (Pino 8) , sinal este no qual so detectados as variaes de sinal que originam, os eventos de trigger.

(a)

(b)

Figura 4.8 - Interruptor de porta srie: circuito elctrico (a) e forma fsica (b).

2.2 - Aquisio de imagens estereoscpicas


2.2.1 - Introduo
A aquisio das imagens fazendo uso de duas cmaras afastadas uma da outra, e de um modo simultneo, constitui o que se designa de aquisio de imagens estereoscpicas. Todo o sistema de aquisio foi desenvolvido e pensado de modo a que esta aquisio possa ser feita da melhor forma possvel, isto de modo que o alvo que se encontra ligado ao paciente seja perfeitamente visvel nas duas cmaras de modo a evitar problemas na deteco dos pontos caractersticos do alvo que permitir estabelecer a correspondncia em termos de instante temporal de aquisio da imagem de exame clnico e movimento do paciente.

2.2.2 - Software desenvolvido


O mdulo de aquisio permite obter imagens a partir de uma ou duas cmaras e seguindo diferentes esquemas de aquisio. O desenvolvimento do software para este mdulo baseou-se quase exclusivamente na livraria Mil Lite que um subset da Mil - Matrox Imaging Library - que nos permite realizar aquisio, manipulao de dados, grficos e controle de visualizao fazendo uso de todas as potencialidades do frame grabber. 2.2.2.1 Opes de aquisio A aquisio a partir de uma cmara ligada ao frame grabber envolve necessariamente a configurao de parmetros de aquisio de modo que a cmara tenha as suas caractersticas adaptadas ao sistema usado. Estes parmetros podem ser configurados na aplicao antes de se realizar a aquisio, atravs do menu apresentado na figura 4.9, entre os quais: 1) Nmero de cmaras a utilizar pelo sistema. 2) Canal de aquisio associado a cada cmara. 3) Tipo de sinal a captar em ambas as cmaras. 4) Formato de imagem a captar. 5) Modo de display.

60

Captulo IV - Sistema Desenvolvido


6) Escala de imagem a utilizar na aquisio. 7) Formato de gravao da sequncia e taxa de compresso da mesma. 8) Formato de gravao das imagens adquiridas. 9) Informao texto adicional a acrescentar s imagens adquiridas do tipo .BMP .

Figura 4.9 - Menu de configurao dos parmetros de aquisio.

1) Nmero de cmaras a utilizar pelo sistema. A especificao do nmero de cmaras a utilizar permite a aquisio a partir de uma ou duas cmaras, possibilitando assim a aquisio stereo utilizada no projecto ou a aquisio simples a partir de uma cmara de modo a que este mdulo possa ser utilizado independentemente, e com outras funcionalidades que no as necessrias ao projecto. 2) Canal de aquisio associado a cada cmara. Indicao do canal do frame grabber a partir do qual feita a aquisio do sinal vdeo das cmaras, potenciando assim a seleco de qualquer um dos quatro canais disponibilizado pelo frame grabber. 3) Tipo de sinal a captar em ambas as cmaras. Indicao do formato do sinal a captar pelo frame grabber dependendo to tipo de sinal vdeo fornecido pela cmara. Opes: Em caso de formato RGB - Aquisio a cor PAL SECAM NTSC Em caso de formato Gray - Aquisio em tons de cinzento CCIR RS-170 4) Formato de imagem a captar. Indicao 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. Opes: RGB Cinzento 5) Modo de display. Indicao do tipo de display a utilizar durante a visualizao. Opes:

61

Captulo IV - Sistema Desenvolvido


Modo Bsico - este modo no h optimizao de velocidade em imagens a cores, o que pode resultar numa performance mais lenta. Modo Bsico optimizado - este modo faz uso de um algoritmo que permite aumentar a velocidade de visualizao 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 aquisio. A escala a utilizar permite definir qual o tamanho da imagem a utilizar para a aquisio. Opes: 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 gravao da sequncia e taxa de compresso 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 gravao das imagens adquiridas. O formato em que gravado o ficheiro de imagem de modo a terem um formato apropriado sua utilizao neste projecto - .BMP - ou de uma forma independente em outras aplicaes. 9) Informao texto adicional a acrescentar s imagens adquiridas do tipo .BMP . Este parmetro foi disponibilizado de forma a podermos referenciar, se desejado as imagens do tipo .BMP adquiridas com informao 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 oferea a possibilidade de visualizar as imagens adquiridas com o maior tamanho disponibilizado pelo frame grabber, usando o formato .BMP com um modo de aquisio a duas cmaras em formato CCIR em formato de tons de cinzento uma vez que estas so as caractersticas das cmaras utilizadas.

2.2.2.2 Esquemas de aquisio Foram implementados vrios esquemas de aquisio que permitem adquirir imagens de um modo sequencial de acordo com vrios parmetros ajustveis: Sequncia - Este modo foi implementado apenas para potenciar o uso do software com outras finalidades que no a do projecto desenvolvido. Multi-Shot - permite adquirir as imagens de um modo sequencial, podendo os instantes de aquisio serem activados de dois modos distintos: Temporalmente - Fazendo uso do temporizador da placa de aquisio - 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 aquisio 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 srie activado o momento de aquisio. Este modo foi pensado de forma a utilizar um possvel sinal de trigger da prpria mquina de exames mdicos, no caso da mquina possuir um sinal ao qual seja possvel aceder externamente e que nos desse indicao dos instantes de aquisio das imagens SPECT planares da mquina em questo. Para o projecto desenvolvido o esquema de aquisio multi-shot em modo temporal o escolhido, uma vez que geralmente difcil aceder a sinais da mquina que nos possibilitem saber quais os instantes de aquisio. Essa informao difcil ou praticamente impossvel de obter uma vez que tal

62

Captulo IV - Sistema Desenvolvido


informao no disponibilizada pelo fabricante das mquinas de exames mdicos SPECT. No entanto e conhecendo os protocolos de aquisio em exames SPECT o modo temporal a alternativa segura uma vez que faz uso dos mesmos parmetros utilizados nos protocolos de exame SPECT, podendo assim acompanhar o exame desde que no haja um desfasamento temporal significativo entre os relgios dos dois equipamentos: relgio do temporizador do frame grabber, relgio do temporizador da mquina de exames mdicos SPECT. Na figura 4.10 feita uma ilustrao da interface com o utilizador, onde podem ser visualizadas os esquema de utilizao que o utilizador tem ao seu dispor.

Figura 4.10 Esquemas de utilizao

2.2.2.3 Configurao de nveis de referncia da aquisio de imagem Uma vez que as condies em termos de luminosidade podem variar dependendo do local e das condies circunstanciais onde se encontra a mquina desenvolvemos um mdulo que nos permite alterar as referncias da placa de aquisio no que concerne ao brilho, contraste, saturao e tonalidade das imagens adquiridas. Assim, ao variar esses parmetros de acordo com as condies locais onde se encontra a cmara, adaptando assim o processo de aquisio e obtendo melhores resultados. tambm possvel retirar imagens instantneas e aumentar / diminuir o zoom das imagens, atravs do interface utilizador / implementao ilustrado na figura 4.11. 2.2.2.4 Anlise do software desenvolvido
Figura 4.11 Configurao de nveis de referncia

As imagens adquiridas pelo frame grabber apresentam faixas negras nas regies superior e lateral direita da imagem que influenciam os algoritmos de calibrao e deteco. Estas faixas so exteriores imagem adquirida e tm que ser ignoradas pelas implementaes de calibrao e de deteco de modo a que tais problemas no se verifiquem. Em termos de implementao todo o mdulo foi desenvolvido de modo a obtermos um mdulo multifuncional e adaptvel a situaes que no s as encontradas no desenvolvimento do projecto de forma a ser utilizvel com outros fins que no os inerentes a este projecto.

2.3 - Calibrao das cmaras


2.3.1 - Introduo
O processo de calibrao um pr - requisito importante para a maioria das aplicaes de viso por computador. Geralmente um sistema calibrado por duas razes: Retroprojeco Inferir informao 3D a partir das coordenadas da memria frame. A calibrao fornece a partir das coordenadas imagem na memria frame, a equao de recta de projeco no espao 3D que passa pelo ponto. Obtendo duas imagens de posies diferentes podemos calcular a posio 3D do ponto atravs do clculo do ponto que mais se aproxima da interseco das duas rectas equacionadas a partir das duas imagens - triangulao estereoscpica.

63

Captulo IV - Sistema Desenvolvido


Projeco Inferir as coordenadas 2D imagem na memria frame a partir da informao 3D. Nas aplicaes baseadas em modelos e utilizando viso por computador, uma hiptese do estado do mundo pode ou no ser confirmada pela verificao de que as coordenadas imagem do objecto esto de acordo com a hiptese. A projeco utilizada essencialmente em grficos por computador onde geralmente usado um modelo de cmara ideal. Por outro lado o principal objectivo da retroprojeco principalmente fazer medies de posio para aplicaes 3D incluindo inspeco dimensional e manipulao robtica. Quando as cmaras so usadas na retroprojeco necessria elevada preciso na calibrao. A maioria das tcnicas de calibrao inicialmente criadas empregavam o modelo de cmara pinhole e os processo eram simples e rpidos quando aplicados. No entanto devido simplificao, que no considerava as no linearidades inerentes ao processo de aquisio, era difcil obter resultados precisos. Assim assistiu-se ao desenvolvimento de modelos de cmaras mais precisos envolvendo correco da distoro da lente, que identificada como sendo a maior fonte de introduo de no linearidade no sistema. Tsai props uma tcnica eficiente que faz uso de uma srie de equaes para determinar os parmetros da cmara com um modelo simplificado da distoro radial da lente.

2.3.2 - Fundamentos tericos - Modelo de Tsai


Aqui se encontram reunidas as caractersticas mais importantes do modelo de Tsai: - O modelo de cmara de Tsai baseado no modelo pin-hole de projeco de perspectiva 3D2D com distoro radial de lente de primeira ordem. O modelo possui onze parmetros, cinco internos ou intrnsecos e seis externos ou extrnsecos que so: Parmetros intrnsecos f - distancia focal efectiva do modelo de cmara pin-hole k - coeficiente de distoro radial de primeira ordem Cx,Cy - coordenadas do centro de distoro radial da lente e ponto de perfurao do eixo dos Zs do sistema de coordenadas de frame com o plano do sensor da cmara. sx - factor de escala que compensa incertezas no escalamento efectuado pelo frame grabber na linha de scan horizontal. Parmetros extrnsecos Rx, Ry, Rz - ngulos de rotao para a transformao entre o sistema de coordenadas mundo e os sistema de coordenadas da cmara. Tx,Tzy,Tz - componentes de translao para a transformao entre o sistema de coordenadas mundo e os sistema de coordenadas da cmara. Para alm deste onze parmetros o modelo de Tsai possui ainda 6 constantes intrnsecas cmara que so : Ncx Nfx dx dy dpx dpy - nmero de elementos sensores na direco dos xx da cmara - nmero de pixels na direco dos xx da cmara - a dimenso dos elementos sensores segundo a direco dos xx - a dimenso dos elementos sensores segundo a direco dos yy - dimenso real segundo a direco dos xx dos pixels no frame grabber - dimenso real segundo a direco dos yy dos pixels no frame grabber

- As constantes intrnsecas Ncx, dx e dy podem ser encontradas na ficha tcnica do equipamento. No realmente essencial conhecer os valores das constantes intrnsecas para calibrar um modelo preciso de cmara. Para a maioria das aplicaes a preciso requerida limita-se a prever, com a preciso adequada, a partir das coordenadas 3D do ponto na cena as coordenadas do ponto no frame buffer. Neste caso os verdadeiros valores das constantes intrnsecas no so necessrios. Para fazer com que o modelo convirja para uma soluo apenas necessrio o ratio cmara / frame grabber ou seja o ratio entre dpx e dpy. possvel obter uma boa estimativa para esse ratio a partir de uma imagem de um rectngulo simples. Medindo o rectngulo, o ratio

64

Captulo 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 calibrao convirja. Dado este ratio basta escolher para dpy um valor e faz-se uso desse valor para calcular os outros parmetros 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 parmetros extrnsecos, Cx ,Cy e sx se mantm constantes bem como o erro de calibrao. - Mesmo que se use o valor da distncia focal fornecida pelo fabricante o valor exacto deste parmetro no ser o mesmo uma vez que o valor fornecido pelo fabricante o de um modelo de cmara de lente espessa e no o correspondente ao modelo pin-hole utilizado. Apesar destes valores terem efeitos similares na imagem so quantitativamente bem diferentes. - Os dados de calibrao para o modelo so constitudos pelas coordenadas 3D mundo de um ponto em (mm) e as correspondentes coordenadas frame 2D em pixels. As coordenadas 3D tm que ser especificadas num sistema de coordenadas que siga a regra da mo direita. Aps a primeira calibrao o processo de calibrao para diferentes posies pode ser acelerado fazendo uso dos valores dos parmetros intrnsecos obtidos na primeira calibrao. - O algoritmo de Tsai tem duas variantes: o coplanar e o no coplanar. Para os dados coplanares a componente segundo a direco dos zz das coordenadas 3D dos pontos ter de ser igual para todos. A calibrao coplanar bsica requer pelo menos cinco pontos e a no coplanar pelo menos sete. A calibrao completamente optimizada requer pelo menos onze pontos quer para o mtodo coplanar quer para o mtodo no coplanar. Nas rotinas de calibrao seguindo o mtodo coplanar o valor de sx mantm-se inalterado. - De modo a estimar com preciso a distoro radial da lente e o centro da imagem, os dados de calibrao devem ser distribudos uniformemente no campo de viso da cmara. Devendo tambm tentar cobrir o volume onde nos interessa efectuar as medidas. - O algoritmo de Tsai falha se a origem do sistema de coordenadas mundo estiver prximo do centro do campo de vista ou prxima do eixo dos yy do sistema de coordenadas da cmara, 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 calibrao no verificarem a condio anterior muito simples de criar um novo sistema de coordenadas artificial com um offset em relao ao sistema de coordenadas mundo de modo a que as condies 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 distoro perspectiva nos dados de calibrao. Para obtermos uma distoro que possa ser usada a distncia entre os pontos de calibrao mais prximos e os mais afastados da cmara devem estar na mesma escala que a distncia entre os pontos de calibrao e a cmara. Para a calibrao coplanar o pior caso aquele em que os pontos se encontram num plano paralelo ao plano da imagem da cmara ( Ou seja todos os pontos mesma distncia). Nesse caso no conseguimos separar os efeitos de f e tz. Um ngulo relativo de 30 ou mais recomendado para obtermos uma certa profundidade aos pontos de calibrao. No caso no coplanar o pior caso aquele em que os pontos se encontram num volume que relativamente pequeno em comparao com o volume de distncia cmara. - Para obter dados de calibrao precisos necessitamos de medir a localizao dos pontos caractersticos no plano da imagem com preciso sub pixel.

2.3.3 - Abordagem seguida no projecto

65

Captulo IV - Sistema Desenvolvido

2.3.3.1 - Introduo O mtodo utilizado neste projecto para efectuar a calibrao das cmaras foi o mtodo de calibrao considerando projeco perspectiva, distoro radial da lente de primeira ordem e utilizando pontos coplanares, proposto em [Tsai,1987]. Neste mtodo considerado em termos de modelo terico da cmara, projeco perspectiva e distoro radial de primeira ordem da lente. A aproximao seguida baseia-se na procura de uma restrio ou equao que seja apenas funo de um subconjunto dos parmetros de calibrao de modo a reduzir de uma dimenso o espao dos parmetros desconhecidos. Pode-se verificar que essa restrio existe e designada de restrio de alinhamento radial. Esta restrio (ou equaes que resultam de tal restrio fsica) funo da rotao e translao relativa excepo da componente em z entre os pontos de calibrao e a cmara. Apesar da restrio ser uma funo no linear dos parmetros de calibrao anteriormente referidos, existe um modo simples e eficiente de os calcular. Os outros parmetros de calibrao so calculados com equaes de projeco normais. Uma boa aproximao destes parmetros pode ser obtida ignorando a distoro da lente e usando simples equaes lineares com duas incgnitas. Os valores precisos desses parmetros podem ento ser calculados com uma ou duas iteraes que minimizem o erro da equao de projeco perspectiva. 2.3.3.2 - Modelo de cmara Considerando quatro os passos que nos permitem transformar as coordenadas 3D mundo para coordenadas de cmara e tendo em ateno a geometria do modelo de cmara ilustrado na figura 4.12 vem:

O y Y f o

X Pu ( Xu,Yu) Pd ( Xd,Yd)

zw ow xw yw P(xw,yw,z w) P(x,y,z )
Figura 4.12 Geometria do modelo de cmara.

Nesta figura possvel definir: (xw,yw,z w) (x,y,z ) (X,Y) f (Xu,Yu) (Xd,Yd) coordenadas 3D do ponto P no sistema mundo coordenadas 3D do ponto P no sistema de coordenadas cmara 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 cmara. distncia focal efectiva representa as coordenadas imagem de P se for utilizado um modelo pin-hole perfeito para a cmara( coordenadas imagem sem distoro) representa as coordenadas da imagem real , ou seja com distoro.

66

Captulo IV - Sistema Desenvolvido


No entanto uma vez que as unidades utilizadas para definir as coordenadas (Xf,Yf) a unidade pixel, necessrio especificar e calibrar outros parmetros que relacionam o sistema de coordenadas imagem com o sistema de coordenadas na memria frame. Esquematizando a transformao das coordenadas (xw,yw,z w) em (Xf,Yf) obtemos o seguinte diagrama:

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

Transformao corpo rgido de ( xw,yw,z w ) para ( x,y,z ) Parmetros a calibrar : R, T ( x, y, z) Sistema de coordenadas 3D cmara

Projeco perspectiva com modelo pin-hole. Parmetros a calibrar : f ( Xu, Yu ) Coordenadas imagem ideal, no distorcida

Distoro radial da lente Parmetros a calibrar : k ( Xd, Yd ) Coordenadas imagem no ideal, distorcida

Varrimento TV, amostragem, aquisio Parmetros a calibrar : sx, ( Cx, Cy )

( Xf, Yf ) Coordenadas imagem no frame buffer

O quarto passo especifico para aplicaes industriais onde so utilizadas cmaras de TV (CCD ou CID). 1) Transformao corpo rgido das coordenadas 3D do sistema de coordenadas mundo ( xw,yw,z w) para o sistema de coordenadas cmara ( x,y,z )

xw x y = R y + T w zw z

r1 r2 r3 Onde R a matriz de rotao (3x3 ) R = r4 r5 r6 r7 r8 r9

67

Captulo IV - Sistema Desenvolvido


ou

R=

cosy cosq seny cosq -senq -seny cosf+ cosy senq cosf cosy cosf+seny senq senf cosq senf seny senf+ cosy senq cosf -cosy senf+seny senq cosf cosq cosf

t x e T o vector translao: T = t y t z
Os parmetros a calibrar so a matriz de rotao 3D R e o vector de translao 3D T. Devemos reparar que a transformao de corpo rgido de um sistema de coordenadas cartesiano rgido para outro nico se a transformao for definida como sendo uma rotao 3D em torno da origem seguida de uma translao 3D. 2) Transformao das coordenadas 3D do referencial cmara ( x, y, z ) para as coordenadas ideais de imagem ( Xu, Yu ) usando projeco perspectiva com geometria de cmara pin-hole.

Xu = f

x z

Yu = f

y z

O parmetro a calibrar a distncia focal efectiva f 3) A distoro radial da lente : Xd + Dx = Xu , Yd + Dy = Yu Onde ( Xd, Yd ) so as coordenadas da imagem real ou distorcida no plano da imagem e Dx = Xd (k1r2+k2r4+...) Dy = Yd (k1r2+k2r4+...)

r=

X 2d + Y 2d

Os parmetros a serem calibrados so o factor de distoro k . Existem dois tipos de distoro: radial e tangente. Para cada tipo de distoro necessrio uma srie infinita. No entanto opinio generalizada que para aplicaes industriais de viso por computador basta considerar a distoro radial e com apenas um termo. Se tomarmos em conta modelos mais elaborados no s ser desnecessrio como causa instabilidade numrica. 4) Transformao das coordenadas reais imagem ( Xd, Yd ) para coordenadas imagem da memria frame ( Xf, Yf ). Xf = sx dx-1 Xd + Cx Yf = dy-1 Yd+ Cy Onde ( Xf,Yf ) - So as coordenadas discretas do ponto na memria frame. ( Cx,Cy ) - So as coordenadas discretas do centro ptico na memria frame.

68

Captulo IV - Sistema Desenvolvido

d' x = d x

N cx N cy

dx - a distncia entre centros dos elementos sensores vizinhos segundo a direco x. dy - a distncia entre centros dos sensores CCD vizinhos segundo a direco y. Ncx nmero de elementos sensores na direco x. Nfx - nmero de pixels numa linha tal como amostrada pelo computador. Normalmente os fabricantes das cmaras CCD fornecem na ficha tcnica do equipamento os parmetros dx e dy com preciso de sub mcron. Contudo necessrio utilizar um parmetro de incerteza horizontal sx devido a diversos factores tais como m sincronizao temporal entre o frame grabber e a velocidade de varrimento da cmara ou imprecises no sincronismo de varrimento TV. O parmetro a ser calibrado assim o factor de incerteza horizontal de escala sx. 2.3.3.3 Calibrao de uma cmara Verificar pela figura 4.6 que o setup para a calibrao de uma cmara utilizando um conjunto de pontos coplanares. O plano de calibrao, cuja forma foi discutida na seco anterior consiste num conjunto de quadrados negros igualmente espaados quer na vertical quer na horizontal cujos vrtices so os pontos de calibrao. Uma vez que os pontos de calibrao ( 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 no muito prxima do centro de viso ou do eixo dos yy do sistema de coordenadas da cmara de modo a que ty no seja nulo. Uma vez que o sistema de coordenadas definido pelo utilizador de uma forma arbitrria no difcil satisfazer essas condies. Neste mtodo a calibrao para determinao dos parmetros pode ser dividida em dois estgios, o primeiro para determinao dos trs ngulos de rotao e das componentes segundo x e y de translao 3D e o segundo para determinao da translao segundo z, do factor de distoro radial da lente k e a distncia focal efectiva f. 1 Clculo da rotao 3D e das translaes segundo os eixos x e y. Clculo de sx factor de incerteza horizontal Clculo das coordenadas da imagem distorcida (Xd, Yd) Clculo das cinco incgnitas ty-1r1, ty-1r2,ty-1tx, ty-1r4, ty-1r5 Clculo 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 Clculo de sx factor de incerteza horizontal No foi possvel implementar o clculo do factor de incerteza horizontal pelo processo de calibrao, definindo-se assim sx como sendo

sx =

N cx N fx

Clculo das coordenadas da imagem distorcida (Xd, Yd) 1) Deteco de cada ponto de calibrao i na memria frame, designado as respectivas coordenadas por ( Xfi, Yfi ) 2) Obter dx e dy , utilizando os dados respectivos fornecidos pelo fabricante da cmara e a dx=sxdx com sx definido anteriormente. 3) Fazer ( Cx, Cy ) igual s coordenadas do centro da memria frame. 4) Calcular ( Xdi, Ydi ) utilizando Xdi=dx( Xfi+Cx ) e Ydi=dyYi+Cy com i a variar entre 1 e N , em que N o nmero total de pontos de calibrao. Clculo das cinco incgnitas ty-1r1, ty-1r2,ty-1tx, ty-1r4, ty-1r5

69

Captulo IV - Sistema Desenvolvido


Para cada ponto de calibrao 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 equaes lineares com ty-1r1, ty-1r2,ty-1tx, ty-1r4, ty-1r5 como incgnitas:

t y -1 r1 -1 t y r2 -1 [ Ydixwi Ydiywi -Xdixwi -Xdiywi] t y rx = Xdi -1 t y r4 -1 t y r5


Se N nmero de pontos de calibrao for maior que cinco ento teremos um sistema sobre determinado que poder ser resolvido em ordem s incgnitas utilizando por exemplo o mtodo de regresso dos mnimos quadrados. Nota: A equao ter uma soluo 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. Clculo 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 rotao 3D R

Por exemplo C =
ento
2

r1 ty r4 ty

r2 ty r5 ty

Se o determinante de C diferente de zero

ty2 = e ri =

S r - S r - 4(r '1 r '5 - r4 ' r ' 2 ) 2 2(r '1 r '5 - r4 ' r ' 2 ) ri ty
2

, com Sr = r12 +r22 + r42+r52

Ou ento calcula-se ty por ty2= ( ri2+ rj2 )-1 com ri e rj sendo os elementos da linha ou coluna da matriz C que no apresenta nenhum elemento igual a zero, sendo que no entanto esta situao raramente se verifica. 2) Determinao do sinal de ty Escolhe-se um ponto i no sistema de coordenadas mundo ( xw,yw,z w ) cujas coordenadas imagem na memria frame ( Xf, Yf ) so afastadas das coordenadas imagem do centro ptico, na mesma memria, ( 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

Captulo IV - Sistema Desenvolvido


Se xi e Xdi tm o mesmo sinal assim como yi e Ydi ento o sinal de ty positivo, caso contrrio negativo. 3) Clculo da matriz de rotao 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 equao:

r1 r2 1 - r1 - r2 2 2 R = r4 r5 s 1 - r4 - r5 r7 r8 r9

Onde s = - sinal(r1r4+ r2r5). A funo sinal() significa o sinal do seu argumento. Os elementos da matriz de rotao 3D R: r7, r8, r9 so determinados usando o produto vectorial das duas primeiras linhas, utilizando a propriedade ortonormal da matriz R. Calcular uma aproximao para a distncia focal efectiva f utilizando: [yi -Ydi]

f t = wiYdi , onde yi = r4xwi + r5ywi + ty e wi = r7xwi + r8ywi z

Se esta aproximao for menor que que zero ento:

r1 r2 - 1 - r1 - r2 2 2 R = r4 r5 - s 1 - r4 - r5 - r7 - r8 r9

2 Calcular a distncia focal efectiva f, coeficiente de distoro radial k e a translao segundo o eixo z, tz. Calcular uma aproximao para f e para tz ignorando a distoro da lente. Clculo da soluo exacta para f, tz e k Calcular uma aproximao para f e para tz ignorando a distoro da lente. Para cada ponto de calibrao i, estabelecer a seguinte equao linear com f e tz como i ncgnitas:

[yi -Ydi]

f t = wiYdi , onde yi = r4xwi + r5ywi + ty e wi = r7xwi + r8ywi z

Com vrios pontos de calibrao, obtm-se um sistema de equaes lineares sobredeterminado que pode ser resolvido para a determinao das incgnitas f e tz. O plano de calibrao no pode ser exactamente paralelo ao plano da imagem pois seno a equao acima referida tornar-se-ia linearmente dependente. Clculo da soluo exacta para f, tz e k

71

Captulo IV - Sistema Desenvolvido

Resolver a equao: Yd(1+k1r2) = f

r4 x w + r5 y w + r6 z w + t y r7 x w + r8 y w + r9 z w + t z

fazendo f, tz e k como incgnitas por um mtodo de optimizao standard como por exemplo o mtodo Levenberg-Marquardt. Utilizar como soluo inicial a aproximao para f e tz encontrada pela resoluo do sistema de equaes lineares anterior e igualando k a zero.

2.3.3.4 - Consideraes sobre o modelo utilizado e alteraes ao mesmo Este mtodo tem como grandes vantagens a incluso no modelamento da cmara da distoro radial da lente e um factor de incerteza radial, a utilizao de equaes lineares e no lineares de pequena dimenso e de pontos coplanares. No entanto como desvantagens devemos referir que as coordenadas da imagem do centro ptico na memria frame coincidem com as coordenadas do centro desta e a impossibilidade do factor de incerteza ser calculado pelo processo de calibrao e a necessidade do plano de calibrao no ser paralelo ao plano da cmara, que podem constituir dificuldades em certas aplicaes. O desenvolvimento do sistema de calibrao tem no entanto algumas alteraes em relao ao proposto por [Tsai]. Tendo como principal vantagem o facto da determinao das coordenadas do centro da imagem na memria frame serem calculadas pelo prprio processo de calibrao [Lens]. O mtodo utilizado tem assim como grandes vantagens, tal como referido em [Tavares]: Incluso da distoro radial da lente e projeco perspectiva. Utilizao de pontos coplanares. No necessidade de estimativas iniciais para qualquer parmetro Possibilidade de determinao das coordenadas do centro da imagem na memria frame conjuntamente com os restantes parmetros, excepo do factor de incerteza horizontal.

Apresentando como desvantagens: Necessidade do plano de calibrao no ser paralelo ao plano da cmara, o que em certas aplicaes pode ser desvantajoso. No considerao da possibilidade dos eixos segundo a direco x e y do referencial de coordenadas na memria frame, no 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 necessrio efectuar uma vez para um determinado sistema cmara / lente pode ser difcil ou mesmo impossvel.

2.3.3.5 - Influncia de uma determinao incorrecta do centro da imagem O centro da imagem definido pelas coordenadas (Cx, Cy ) na memria frame do ponto de interseco do eixo ptico com o plano imagem. Geralmente utilizado como ponto de origem do processo de formao de uma imagem e pertence aos parmetros presentes nas equaes de projeco perspectiva. Em vrias aplicaes utilizam-se estas coordenadas como sendo as do centro da imagem frame, no entanto existem desvios que levam a que seja necessrio calcul-los em aplicaes de maior preciso como os de viso tridimensional por computador. Pode facilmente ser calculado o erro residual devido a uma determinao incorrecta do centro da imagem obtendo-se a seguinte equao: ERRO =

k1 ( K x LC x + K y LC y ) Em que Kx e Ky dependem do setup experimental que

est a ser utilizado [Tsai].

72

Captulo IV - Sistema Desenvolvido


Uma maneira de estimar o centro da imagem baseia-se em minimizar o erro residual. Apesar de ser uma optimizao no linear com duas incgnitas, uma abordagem que se demonstra ser eficaz uma vez que com poucas iteraes se pode chegar soluo final., devido dependncia sistemtica do erro residual com LC x e LC y . A equao acima indicada d-nos indicao que este mtodo apenas resulta na presena de distoro radial da lente e quando o erro residual devido extraco das coordenadas imagem na memria frame dos pontos de calibrao for pequeno em comparao com ERRO. 2.3.3.6 - Determinao das coordenadas dos pontos de calibrao Para se efectuar a calibrao necessrio determinar as coordenadas dos pontos de calibrao na memria frame. Todo o processo de calibrao se inicia aqui , sendo que a preciso dos valores tem um peso importante na qualidade dos resultados a obter. A tcnica utilizada para a deteco dos pontos de calibrao baseado em [Tsai] considera um conjunto de quadrados igualmente distribudos, sendo os vrtices dos quadrados os pontos de calibrao a considerar. A deteco dos pontos efectuada do seguinte modo: 1) Realizar a aquisio da imagem de cinzentos 2) Binarizao da imagem por threshold sendo que o valor do limiar no critico uma vez que pode ser obtido manualmente pela observao do histograma da imagem de calibrao. 3) Efectuar a ligao entre os pontos fronteira dos quadrados de modo a obter o conjunto dos lados aproximados dos quadrados. 4) Percorrer a imagem inicial nas direces perpendiculares s dos lados aproximados dos quadrados anteriormente determinados de modo a obter os verdadeiros pontos dos lados dos quadrados utilizando para o efeito interpolao 5) Ajuste de linhas rectas aos verdadeiros pontos dos lados dos quadrados. 6) Determinao da interseco entre linhas rectas de ajuste de modo a obter-se a localizao dos pontos de calibrao com preciso ao nvel de a 1/3 de pixel O mtodo utilizado neste projecto seguiu o mtodo concebido em [Tavares] e que consiste no seguinte: 1) Realizar a aquisio da imagem de cinzentos. 2) Sujeitar a imagem de calibrao a um detector de orlas de intensidade, para classificar os pixels da imagem inicial Figura 4.6 Alvo para calibrao de em termos de amplitude e de direco q. cmaras 3) Determinar as duas direces principais q1 e q2 que sejam diferentes de pelo menos um valor qd , isto |q1-q2| qd considerando nesta determinao apenas os pixels cujo valor de amplitude Ai seja superior a um determinado valor de modo a desprezar-se pontos de rudo. 4) Classificao dos pixels resultantes da deteco das orlas de intensidade na imagem de calibrao em duas classes C1 e C2 Uma constituda pelos pixels que apresentam, um valor de amplitude Ai igual ou superior ao limiar e uma direco qi aproximadamente igual a q1 e outra constituda pelos pixels que apresentem um valor de amplitude Ai igual ou superior a um dado limiar e cuja direco qi seja aproximadamente igual a q2. 5) Determinar as linhas rectas constitudas pelos lados das figuras geomtricas na classe C1 sendo esta determinao efectuada do seguinte modo: i) Determinar o primeiro elemento da classe C1 no considerado e classific-lo como considerado. ii) Definir a recta que passa pelo ponto anteriormente determinado e que tem direco igual a q1 . iii) Determinar o prximo ponto na classe C1 ainda no considerado que pertence linha recta determinada no passo anterior , tendo por base que a distncia 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

Captulo IV - Sistema Desenvolvido


v) Realizar a regresso linear dos pontos classificados como pertencentes a uma determinada linha, se o nmero destes for superior a um dado limiar, de modo a eliminar falsas linhas. vi) determinar uma nova, linha voltando ao ponto i) at no existirem mais elementos na classe C1 ainda no considerados. 6) Determinar as linhas rectas constitudas pelos lados das figuras geomtricas na classe C2 do mesmo modo como foi efectuado para a classe C1 considerando no entanto q2 em vez de q1 . 7) Determinar a interseco das linhas obtidas para C1 e C2. 8) definir os pontos de interseco, determinados no passo anterior como os pontos de calibrao pretendidos.

2.3.4 - Software desenvolvido


Nesta parte do relatrio sero apresentadas as implementaes desenvolvidas no domnio de calibrao de cmaras. Estas aplicaes foram desenvolvidas em linguagem Microsoft Visual C ++. Assim sero apresentadas as seguintes aplicaes: Uma implementao para a calibrao de todos os parmetros intrnsecos e extrnsecos de uma cmara, exceptuando a factor de incerteza horizontal : sx. Uma implementao para a determinao das coordenadas imagem na memria frame de pontos de calibrao utilizados. Uma implementao para simulao de uma cmara de geometria interna conhecida. Uma implementao para a formatao dos pontos de calibrao provenientes da rotina de deteco dos referidos pontos, para ser possvel efectuar a calibrao da cmara que efectuou a aquisio da imagem. O desenvolvimento de uma rotina de simulao de dados de calibrao deveu-se ao facto de se obter resultados simulados de forma a testar convenientemente a implementao da rotina de calibrao de todos os parmetros da cmara. Com esta implementao torna-se possvel obter, de forma automtica, as coordenadas 3D e as coordenadas na memria frame dos pontos de calibrao coplanares, para uma dada geometria interna e posio e orientao da cmara relativamente ao plano de calibrao. 2.3.4.1 Calibrao de uma cmara Neste ponto apresentada, de uma forma sucinta, uma implementao para calibrao de uma dada cmara segundo o mtodo descrito no ponto 2.3.3. Com esta implementao, possvel a calibrao de todos os parmetros de uma cmara excepto o factor de incerteza horizontal sx. A referida implementao responsvel por: Interface utilizador / implementao.

Figura 4.13 Interface utilizador / implementao onde so especificados todos parmetros necessrios realizao da rotina de calibrao.

Leitura dos argumentos opcionais:

74

Captulo IV - Sistema Desenvolvido


nome do ficheiro para escrita dos resultados obtidos, nomeadamente, as condies de realizao da calibrao. O valor da tolerncia de erro para as solues exactas da distncia focal efectiva f, da componente tz do vector de translao T e do factor de distoro radial da lente k1, determinadas pela resoluo do sistema de equaes no lineares respectivo e utilizando o mtodo Levenberg Marquardt. Por defeito, igual a 0.0000001. Sx, factor de incerteza horizontal. Por defeito, igual a 0.710935. Find Image Center, quando esta opo accionada pelo utilizador, a implementao determina as coordenadas exactas do centro da imagem na memria frame (Cx, Cy). Por defeito, esta opo encontra-se no accionada.

Leitura dos argumentos no opcionais: dx, distncia entre centros dos elementos sensores vizinhos na direco x. Dy, distncia entre centros dos sensores CCD vizinhos na direco y. Cx, coordenada do centro da imagem na memria frame segundo a direco x. Quando Cx no conhecido exactamente, o utilizador deve especificar Cx igual a metade da dimenso da memria frame segundo a direco x e especificar implementao que pretende que esta determine a coordenada correcta. Deste modo, o valor especificado para Cx apenas a soluo inicial sendo a implementao responsvel pela determinao da soluo exacta. Cy, coordenada do centro da imagem na memria frame segundo a direco y. Quando Cy no conhecido exactamente, o utilizador deve especificar Cy igual a metade da dimenso da memria frame segundo a direco x e especificar implementao que pretende que esta determine a coordenada correcta. Deste modo, o valor especificado para Cy apenas a soluo inicial sendo a implementao responsvel pela determinao da soluo exacta. Nome do ficheiro de entrada que contm as coordenadas 3D mundo (xW, yW, zW) e as coordenadas 2D imagem na memria frame (Xf1, Yf1) para todos os pontos de calibrao i.

Determinao das coordenadas do centro da imagem na memria na memria frame (Cx, Cy) quando pretendido pelo utilizador; para tal, utilizada outra funo. Essa funo responsvel pela determinao das coordenadas do centro da imagem na memria frame (Cx, Cy), utiliza o mtodo iterativo apresentado. Durante a determinao, todos os parmetros so tambm determinados novamente at o mdulo atingir uma soluo global ptima. Calibrao de todos os parmetros restantes da cmara, excepto o factor de incerteza horizontal sx; para tal, so utilizadas outras funes. A funo responsvel pela resoluo de um sistema sobre determinado de equaes lineares, z[m][n] x a[n]=y[m] utiliza o mtodo dos mnimos quadrados, com resoluo do respectivo sistema de equaes normais. Para tal, utilizamos a decomposio de Cholesky da matriz [z[m][n] Tz[m][n], com posterior substituio para a frente e para trs. Esta decomposio das mais eficientes em termos de memria consumida; no entanto, a sua utilizao s possvel em matrizes [z[m][n] Tz[m][n] definidas positivamente. A funo responsvel pela resoluo de um sistema de equaes lineares alfa[NMAX1][NMAX1] x delta[NMAX1]=beta[NMAX1] utiliza a decomposio de Cholesky da matriz alfa[NMAX1][NMAX1], com posterior substituio para a frente e para trs. Apresentao dos resultados obtidos. Comunicao da existncia da existncia de erros em argumentos de entrada ou ao longo do decurso da execuo. Como restries na utilizao deste mtodo tm-se: O nmero de pontos de calibrao deve ser maior que cinco; O sistema de coordenadas 3D mundo deve ser escolhido de forma que todos os pontos de calibrao tenham a coordenada 3D mundo z igual a zero e a componente ty do vector de translao T no seja exactamente igual a zero. O factor de incerteza horizontal sx, deve ser diferente de zero.

75

Captulo IV - Sistema Desenvolvido


Esta rotina s aceita ficheiros de texto criados pelas rotinas de simulao de uma cmara descrito no ponto 2.3.4.4 ou pela rotina de determinao das coordenadas dos pontos de calibrao na memria frame.

2.3.4.2 - Determinao das coordenadas na memria frame dos pontos de calibrao Neste ponto apresentada, de forma sumria, a implementao do mtodo para determinao das coordenadas imagem na memria frame (Xf, Yf) dos pontos de calibrao considerados. O resultado desta aplicao podem ser at cinco imagens, dependendo das opes de visualizao seleccionadas, e um ficheiro de texto. Supondo que todas as opes de visualizao foram seleccionadas os resultados sero constitudos por: Uma imagem contm o resultado da aplicao de uma operao de filtragem de realce ou suavizao da imagem inicial. Duas imagens contendo o resultado da aplicao do filtro de deteco de orlas de intensidade, a primeira, contm todos os pixels identificados com amplitude superior a um dado limiar especificado pelo utilizador e direco aproximadamente igual a uma direco principal; a segunda, contm todos os pixels identificados com amplitude superior ao mesmo limiar e direco aproximadamente igual outra direco principal. Duas imagens que contm as linhas de interseco segundo as direces principais. Uma quinta imagem, onde so identificados os pontos de calibrao e assinalados por intermdio de uma cruz; Um ficheiro de texto com a escrita dos resultados obtidos, nomeadamente as coordenadas imagem na memria frame (Xf, Yf) dos pontos de calibrao determinados.

A referida implementao responsvel pela interface implementao / utilizador. Leitura dos parmetros opcionais: o Tolerncia do erro na classificao de um dado pixel quanto sua direco. o Diferena mnima entre as duas direces principais.

Figura 4.14 Interface utilizador / implementao onde o utilizador especifica todos os parmetros de deteco dos pontos de calibrao.

o o o o o

Mxima distncia que um pixel a uma dada recta para ser classificado como pertencente a esta. Valor mnimo de amplitude que um dado pixel deve apresentar para no ser classificado como rudo. Possibilitar o realce ou suavizao da imagem de entrada. Filtro de realce ou suavizao da imagem de entrada Filtro de deteco de orlas de intensidade

76

Captulo IV - Sistema Desenvolvido


o o Opes de visualizao Nome do ficheiro de texto onde ser feita a escrita dos resultados obtidos, nomeadamente as coordenadas imagem na memria frame (Xf, Yf) dos pontos de calibrao determinados.

Chamada de outras funes. Determinao das duas direces principais presentes na imagem de entrada; Classificao dos pixels, na segunda imagem de sada, que tm amplitude superior a um dado limiar e que tm uma direco prxima de uma das direces principais; Classificao dos pixels, na terceira imagem de sada, que tm amplitude superior a um dado limiar e que tm uma direco prxima da outra direco principal; determinao das rectas que existem em cada uma das imagens referenciadas anteriormente; para tal faz a chamada a outra funo; durante a execuo, a funo responsvel por essa determinao opta automaticamente pela melhor regresso linear, isto , para rectas com declives entre 45 e 45 a regresso linear (utilizando a regresso linear pelo mtodo dos mnimos quadrados) do tipo y=m.x+b e, para os restantes declives, a regresso linear do tipo x=m.y+b. Para determinar se um pixel pertence a uma dada recta, a sua distncia a esta calculada e comparada com a mxima distncia admissvel especificada pelo utilizador. Para eliminao de falsas linhas, o mdulo s considera uma dada recta se o nmero de pixels que esta contm maior que um determinado especificado pelo utilizador. Registo das rectas de interseco nas terceira e quarta imagem, imagens estas que contm apenas uma das direces das rectas de interseco. Determinao das coordenadas dos pontos de calibrao atravs da interseco entre vrias rectas definidas analiticamente. Registo dos pontos de calibrao no ficheiro de texto e na ltima imagem de sada, usando para tal uma funo que faz o desenho na imagem de sada respectiva, de uma cruz de dimenses 9x9 centrada num determinado pixel. Visualizao das imagens seleccionadas pelo utilizador. Comunicao da existncia de erros de argumentos ao longo do decurso da execuo.

Como restries na utilizao tm-se: A imagem de entrada deve conter figuras geomtricas de quatro lados paralelos dois a dois, perfeitamente iguais e paralelas entre si. A imagem de entrada deve ser do tipo DIB, com a extenso .bmp, sendo uma imagem constituda por nveis de cinzento.

2.3.4.3 Formatao dos pontos de calibrao determinados Neste ponto apresentado, de forma sumria, a implementao responsvel pela formatao dos pontos de calibrao determinados atravs do mtodo descrito no ponto anterior. Como os pontos de calibrao determinados anteriormente so pontos 2D, isto , so pontos que so descritos relativamente ao plano da memria frame, necessitam de ser formatados de maneira a ser possvel utilizar a rotina de clculo dos parmetros internos e externos de uma cmara (descrita no ponto 2.3.4.1). Esta rotina exige a par da coordenada 2D na memria frame a coordenada desse mesmo ponto no sistema de coordenadas mundo, isto , a sua coordenada 3D.

Figura 4.15 Interface utilizador / implementao onde este especifica o ficheiro de texto proveniente da implementao de deteco dos pontos de calibrao e o nome do ficheiro do resultado da formatao desses pontos.

Assim, com esta implementao obtm-se:

77

Captulo IV - Sistema Desenvolvido


Um ficheiro de texto contendo todos os pontos de calibrao referidos nas suas coordenadas 2D e 3D. Leitura dos argumentos opcionais: o Nome do ficheiro de texto que contm todos os pontos de calibrao encontrados pela rotina descrita no ponto 2.3.4.2. o Nome do ficheiro de texto que ir conter todos os pontos de calibrao definidos atravs das suas coordenadas 3D e 2D. Formatao dos pontos de calibrao, atravs da leitura do ficheiro de texto referido em cima e consecutivamente das coordenadas 2D desses pontos. A formatao permite escolher qual o ponto que se pretende introduzir a sua coordenada 3D, no sendo obrigatrio formatar todos os pontos presentes no primeiro ficheiro de texto, possibilitando vrios testes ao algoritmo de calibrao (por exemplo, qual o resultado da rotina de calibrao quando se utiliza apenas ponto colineares). Quando todos os pontos de calibrao pretendidos pelo utilizador se encontram formatados, esta informao guardada no ficheiro de texto indicado pelo utilizador. tambm dada a informao de quantos pontos de calibrao foram determinados pela rotina anterior.

Figura 4.16 Interface responsvel pela indicao do valor do pixel a formatar e leitura das coordenadas 3D desse ponto.

Restries a esta implementao: O algoritmo de formatao apenas aceita ficheiros de textos produzidos pela rotina de determinao das coordenadas na memria frame dos pontos de calibrao.

2.3.4.4 Simulador de uma cmara Neste ponto apresentada uma implementao de um simulador de uma cmara para um dado conjunto de pontos coplanares. A partir dos respectivos parmetros de entrada, a prpria implementao determina automaticamente as coordenadas 3D mundo (xw, yw, zw) e as coordenadas na memria frame (Xf, Yf), para cada ponto de calibrao, do seguinte modo: I) Determinao da projeco inversa, sobre o plano de calibrao considerado, dos quatro vrtices que definem as dimenses da memria frame. Esta projeco inversa possvel pois conhece-se a geometria interna da cmara, a posio e orientao desta relativamente ao plano de calibrao considerado, a coordenada 3D mundo z do plano de calibrao e as coordenadas 2D na memria frame dos pontos pretendidos (1,1), (1, Dimfy), (Dimfx, x) e (Dimfx, Dimfy) onde Dimfx a dimenso da memria frame segundo a direco x e Dimfy a dimenso segundo a direco y. II) Considerar este paralelogramo definido pelas projeces sobre o plano de calibrao 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 nmero de pontos de calibrao pretendidos linhas rectas distribudas uniformemente entre dois lados mais ou menos paralelos. IV) Definir o conjunto de n linhas rectas distribudas uniformemente entre os restantes dois lados do paralelogramo.

78

Captulo IV - Sistema Desenvolvido


V) Definir os pontos de calibrao como situados sobre o plano de calibrao e coincidentes com as interseces, sobre este plano, das linhas rectas definidas em III) com as linhas rectas definidas em IV). VI) Determinar para cada ponto de calibrao, cujas coordenadas 3D foram determinadas anteriormente, as coordenadas respectivas na memria frame.

Figura 4.17 Interface utilizador / implementao responsvel pela caracterizao de todos os parmetros necessrios simulao de uma cmara de geometria interna conhecida.

Esta implementao ento responsvel por: Leitura dos argumentos opcionais: o Numero de pontos de calibrao pretendidos. o Coordenada 3D mundo z para o plano de calibrao. o Coordenada Cx do centro da imagem na memria frame, segundo a direco x. Por defeito, igual a metade da dimenso da referida memria segundo a mesma direco. o Coordenada Cy do centro da imagem na memria frame, segundo a direco y. Por defeito, igual a metade da dimenso da referida memria segundo a mesma direco. o Dimenso da memria frame segundo a direco x. o Dimenso da memria frame segundo a direco y. o Valor em graus da rotao segundo o eixo x. o Valor em graus da rotao segundo o eixo y. o Valor em graus da rotao segundo o eixo z. o Componente tx do vector translao, isto a translao segundo o eixo x. o Componente ty do vector translao, isto a translao segundo o eixo y. o Componente tz do vector translao, isto a translao segundo o eixo z. o Distncia focal efectiva f. o Distncia entre centros dos elementos sensores vizinhos na direco x, dx. o Distncia entre centros dos elementos sensores vizinhos na direco y, dy. o Factor de incerteza horizontal, sx. o Factor de distoro 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 memria frame determinadas para cada ponto de calibrao. Apresentao das componentes determinadas da matriz de rotao 3D R do sistema de coordenadas mundo para o sistema cmara. Execuo da simulao da cmara propriamente dita.

79

Captulo IV - Sistema Desenvolvido


Escrita no ficheiro de sada das coordenadas 3D mundo (xw, yw, zw) e das coordenadas 2D (Xf, Yf) imagem na memria frame determinadas para todos os pontos de calibrao. Comunicao da existncia de erros em argumentos de entrada ou ao longo do decurso da execuo da rotina.

Como restries a esta rotina temos: O valor especificado para o nmero de pontos de calibrao pretendidos deve ter raz quadrada inteira, por exemplo 16. Os valores especificados para as rotaes segundo os trs eixos principais devero estar definidos em graus e compreendidos entre 360 e 360.

2.3.5 Resultados experimentais


Nesta seco so apresentados alguns resultados experimentais obtidos pelas vrias implementaes descritas anteriormente. Estes resultados tem apenas um carcter demonstrativo, deixando a maior parte da anlise e concluses de diversos cenrios para no Captulo V. Assim sero apresentados: a) Resultados experimentais obtidos na utilizao da implementao responsvel pela determinao das coordenadas na memria frame dos pontos de calibrao considerados; b) Resultados experimentais obtidos na utilizao da implementao responsvel pela simulao de cmaras de geometria interna conhecida. c) Resultados experimentais obtidos pela implementao responsvel pela calibrao de cmaras. d) Resultados experimentais obtidos pela utilizao da implementao responsvel pela formatao das coordenadas dos pontos de calibrao considerados. 2.3.5.1 Implementao para a determinao das coordenadas dos pontos de calibrao considerados Para realizar o teste da implementao desenvolvida foi capturada uma imagem, em tons de cinzento, formato .bmp, de dimenses 768x586, de 8 bits e contendo 12 quadrados, que est representada na figura 4.18 a). Sendo assim esta imagem contm 48 possveis pontos de calibrao. Na figura 4.18 b) so visveis os parmetros de entrada implementao. Na figura 4.19 podemos observar os resultados do filtro de realce do tipo Gaussiano a) e de deteco de orlas Deriche b) e c) sobre a imagem da figura 4.18 a). As duas imagens resultado da aplicao deste filtro de deteco de orlas foram previamente negadas de maneira a facilitar a sua visualizao.

a)

b)

Fig. 4.18 Imagem de teste usada para testar o algoritmo de deteco a) e parmetros utilizados pela implementao para efectuar essa deteco

80

Captulo IV - Sistema Desenvolvido

Como resultado da implementao obtiveram-se trs imagens, que so apresentadas na figura 4.20. Na figura 4.20 a) est representada a imagem que contm todos os pixels que tm um valor de amplitude superior a 50 e direco aproximadamente igual a uma das direces principais. Na figura 4.20 b), est representada a imagem que contm todos os pixels que tm uma valor de amplitude superior a 50 e direco aproximadamente igual segunda das direces principais. Na figura 4.20 c), est representada a imagem que contm todas as localizaes dos pontos de calibrao existentes na imagem de teste, isto , os vrtices dos quadrados localizados. A localizao destes pontos na imagem feita atravs de uma cruz.

a)

b)

c)

Figura 4.19 Resultados das operaes de filtragem sobre a imagem original. a) filtro Gaussiano 5x5 b) e c) filtro de deteco de orlas de intensidade Deriche.

De maneira a determinar a qualidade dos resultados obtidos, executou-se a soma lgica da imagem de teste representada na figura 4.18 a), com a imagem contendo todos os pontos de calibrao encontrados, representados na figura 4.21 b). Com o mesmo objectivo procedeu-se tambm soma lgica desta ltima imagem com a imagem obtida pelo detector de orlas de intensidade de Deriche, sendo esta soma representada na figura4.21 a).

a)

b)

c)

Figura 4.20 Resultado da deteco de linhas a) numa das direces principais e b) na segunda direco principal e c) resultado da interseco das linhas detectadas, assinaladas por intermdio de uma cruz.

possvel observar que esta implementao apresenta resultados de boa qualidade, com resoluo ao nvel do sub pixel. Nas duas imagens da figura 4.22 essa resoluo bem visvel atravs da ampliao 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 visualizao.

81

Captulo IV - Sistema Desenvolvido

a)

b)

Figura 4.21 Soma lgica da imagem contendo os pontos de calibrao com a) a primeira imagem de sada do filtro de Deriche e b) com a imagem original previamente negada.

Figura 4.22 Ampliao de zonas escolhidas aleatoriamente das imagens da figura 4.21.

Finalmente, na tabela 1 ilustrado o contedo do ficheiro de texto de sada da implementao, nomeadamente as coordenadas 2D na memria frame (Xf, Yf) de todos os pontos de calibrao 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 Contedo do ficheiro de texto de sada de resultados obtidos pela implementao desenvolvida para a imagem original apresentada na figura 4.18 a).

82

Captulo IV - Sistema Desenvolvido


2.3.5.2 Implementao da rotina de simulao de cmaras de geometria interna conhecida Neste ponto sero apresentados alguns resultados de simulaes de cmaras de geometria interna conhecida utilizando a implementao apresentada no ponto 2.3.4.4. Para a executar a simulao de uma calibrao de uma cmara de geometria interna conhecida foram usados os seguintes parmetros de entrada:

Figura 4.23 Parmetros de entrada para a implementao de simulao de calibrao.

Como pode no ser muito visvel a distncia utilizada entre sensores na distncia x e y so aqueles que foram apresentados aquando da descrio do material utilizado, que so 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 implementao de simulao de uma calibrao de uma cmara de geometria interna conhecida.

Estes resultados podem ser comprovados utilizando o ficheiro de texto apresentado na tabela 2, na rotina de calibrao de cmaras. Esta verificao faz-se atravs da comparao dos valores obtidos para a matriz de rotao e de translao, distncia focal e distoro radial obtidos pela rotina de calibrao com os valores introduzidos como parmetros iniciais da rotina de simulao de calibrao.
-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

83

Captulo 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 calibrao coplanares obtidos pela rotina de simulao

possvel constatar na tabela 2 que os pontos obtidos pela rotina de simulao so todos coplanares (coordenada z igual a zero) formando 3 linhas e 3 colunas de quadrados perfeitamente paralelos entre si, perfazendo assim 36 pontos de calibrao coplanares. Submetendo estes pontos de calibrao rotina de obteno dos parmetros extrnsecos e intrnsecos de uma dada cmaras, os resultados so os seguintes:

Figura 4.25 Parmetros intrnsecos e extrnsecos obtidos pela rotina de calibrao de uma dada cmara.

Estes resultados tambm podem ser observados atravs do ficheiro de texto onde so gravados os resultados da calibrao.
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 sada da rotina de calibrao onde so referenciados tanto os parmetros de entrada como os parmetros de sada da rotina que so os parmetros intrnsecos e extrnsecos da cmara

84

Captulo IV - Sistema Desenvolvido


Na observao dos resultados produzidos pela rotina de calibrao possvel constatar que estes so idnticos aos parmetros introduzidos para a rotina de simulao, levando nos a concluir que a rotina de simulao de calibrao retorna uma distribuio de pontos de calibrao no plano de calibrao sempre regular, dado que, essa a sua filosofia de implementao; a forma do conjunto dos pontos de calibrao depende dos valores utilizados para as rotaes nos trs eixos principais x, y e z. Sendo assim, concluiu se que se pode utilizar esta implementao para realizar diversos testes de calibrao e analisar os seus resultados sem ter que recorrer a experincias laboratoriais. 2.3.5.3 Implementao da rotina de formatao de pontos de calibrao na memria frame. Esta implementao tem como objectivo executar a formatao dos pontos de calibrao obtidos pela implementao de deteco desses mesmos pontos. Esta formatao necessria dado que, a implementao de calibrao dos parmetros intrnsecos e extrnsecos de uma cmara tem que ter como ficheiro de dados os pontos de calibrao coplanares nas suas coordenadas mundo (3D) e na memria frame (2D). Como apenas dispomos das coordenadas na memria frame temos ento que introduzir as coordenadas mundo desses pontos. Assim como parmetro de entrada a esta implementao o ficheiro de dados apresentado na tabela asdasd.

a)

b)

Figura 4.26 a) Parmetros de entrada implementao de formatao dos pontos de calibrao e b) formatao de um ponto escolhido aleatoriamente.

A formatao, 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 calibrao. Esta formatao permite-nos escolher quais os pontos de calibrao detectados que sero utilizados para a determinao dos parmetros extrnsecos e intrnsecos da cmara. Desta maneira, possvel realizar vrios testes sobre a influncia da distribuio dos pontos no plano de calibrao nos resultados apresentados pela implementao responsvel pela determinao dos parmetros da cmara. Como resultado desta implementao o ficheiro de dados de sada tem o contedo apresentado na tabela 4. De salientar que apenas foram formatados 24 pontos dos 48 detectados pela implementao de deteco dos pontos de calibrao na memria 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 implementao de formatao onde a informao 2D das coordenadas da memria frame combinada com a informao 3D das coordenadas mundo.

85

Captulo IV - Sistema Desenvolvido


2.5.3.4 Implementao de calibrao de cmaras Neste ponto sero apresentados os resultados da calibrao de uma cmara usando para tal um conjunto de pontos coplanares, previamente detectados e formatados respectivamente pelas implementaes de deteco de pontos na memria frame e de formatao de pontos de calibrao. Assim este ponto no tentar demonstar o algoritmo, pois essa verificao j foi realizada no ponto 2.5.3.2 deste captulo. Assim apresentaremos os resultados de uma calibrao usando imagens e dados reais capturados atravs das cmaras usadas no mbito deste projecto. A anlise desses valores, com base tambm em outras calibraes com outros valores e parmetros de entrada, ser feita nos captulos seguintes. Assim tendo como ficheiro de dados de entrada o ficheiro apresentado na tabela 4, temos os seguintes resultados:

Figura 4.27 - Resultado da calibrao de uma cmara para o alvo de calibrao Ilustrado na figura 4.19 a).

visvel na figura 4.27 que quando se efectua uma calibrao podemos colocar os resultados dessa calibrao como valores por defeito de uma das cmaras, facilitando assim o processo de obteno de coordenadas 3D, dado que estes valores se encontram em memria, evitando assim que sejam sempre colocados pelo utilizador quando se pretender calcular coordenadas 3D. Os resultados obtidos na verificao desta implementao leva-nos a concluir que se obtm em mdia bons resultados. No entanto esta qualidade afectada por algumas caractersticas prticas tais como: a translao segundo o principal y no dever ser nula; o factor de incerteza horizontal dever ser o mais correcto possvel, pois uma pequena variao no seu valor implica grandes variaes nos parmetros determinados; as coordenadas 3D dos pontos dever ser a mais precisa possvel, pois uma pequena variao no seu valor implica grandes variaes nos parmetros determinados e o nmero de pontos de calibrao dever ser razovel (na ordem de algumas dezenas).

2.4 - Deteco de pontos caractersticos de um alvo e obteno de informao 3D dos mesmos


2.4.1 - Introduo
A deteco de pontos caractersticos de imagens de um alvo colocado sobre um paciente, obtidas por um sistema stereo de aquisio de imagens e o respectivo emparelhamento para posterior obteno de informao tridimensional acerca desses mesmos pontos sero discutidos neste capitulo. A obteno da informao tridimensional associada a cada par de imagens a base de todo o processo a apresentar ponto 2.5 para estimao de movimento. Ou seja aps possuirmos um sistema stereo de aquisio de imagem posicionado e calibrado, da maneira que foi apresentada no ponto 2.3, podemos obter, fazendo uso do mdulo de aquisio de imagem apresentado no ponto 2.3, em sequncia temporal, pares de imagem a partir das quais obteremos informao tridimensional. A informao tridimensional obtida ir assim permitir-nos realizar a estimao de movimento desejada.

86

Captulo IV - Sistema Desenvolvido


No mtodo desenvolvido a obteno de informao tridimensional conseguida pela resoluo do respectivo sistema de projeco stereo aps a determinao da localizao e emparelhamento de pontos caractersticos de um alvo num par de imagens adquirido por um sistema stereo calibrado de aquisio de imagem. A determinao da informao tridimensional obtida fazendo uso de linhas epipolares e fazendo o clculo da posio do ponto que minimiza os erros associados a disparidades de posio 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 aquisio de imagem stereo calibrado, e que resulta na obteno de informao tridimensional acerca de pontos caractersticos que se encontram nesses mesmos pares de imagens, adquiridas em sequncia temporal, um processo que se pode afirmar como sendo constitudo por trs fases: Deteco dos pontos caractersticos em cada imagem, pontos estes que so os vrtices de slidos geomtricos que se encontram num alvo dimensionado para tal. Emparelhamento dos pontos caractersticos em cada par de imagem por meio de etiquetagem. Obteno de informao tridimensional a partir da projeco estereo dos pontos anteriormente emparelhados.

2.4.2 - Deteco de pontos caractersticos


2.4.2.1 Dimensionamento do alvo A abordagem seguida para o dimensionamento do alvo foi que os pontos caractersticos que seriam determinados deveriam ser o resultado da interseco de linhas pertencentes a figuras geomtricas. Assim surgem como possveis candidatos as seguintes figuras geomtricas: tringulos, quadrados, losngulos, rectngulos e cruzes (esta forma pode no ser convencionalmente considerada como uma forma geomtrica mas resulta da sobreposio de duas figuras geomtricas, que so os rectngulos). A filosofia seguida para o dimensionamento deste alvo foi que deveria ser constitudo por um conjunto de formas geomtricas o mais diverso possvel, de maneira que a eficcia e preciso dessas formas geomtricas fosse a mais elevada possvel, e assim permitir um emparelhemto dos pontos caractersticos detectados mais simples e eficaz. O nmero de figuras geomtricas a incluir no alvo deve ser no mnimo 3 figuras, de maneira a produzir pelo menos uma dezena de pontos detectados. Esta quantidade de pontos necessria para a anlise dos resultados dos valores 3D calculados pela rotina responsvel, e tambm para se fazer anlise e estimao do movimento sofrido nos diversos instantes de aquisio. Olhando melhor para as figuras geomtricas candidatas verificamos desde logo, que algumas delas apresentam caractersticas intrnsecas que por si s podem ser vantajosas para a sua deteco. Em seguida feita uma descrio dessas caractersticas internas de cada uma das figuras geomtricas candidatas: Quadrado: possui duas linhas de direco que o definem completamente (vertical e horizontal), todos os seus pontos resultantes da interseco dessas linhas encontram-se nas prprias linhas, forma geomtrica simples, entre dois lados consecutivos existe sempre um desfasamento de 90 e tm comprimentos iguais. Estes aspectos so ilustrados na figura 4.28 a). Rectngulo: tem todas as caractersticas do quadrado, excepto no comprimento igual de todos os lados, que no caso do rectngulo, os lados so iguais em comprimento dois a dois. Da mesma forma podemos caracterizar o losngulo. Tringulo: ao contrrio das formas geomtricas anteriores, o tringulo constitudo por trs linhas de direco diferentes: duas oblquas e uma horizontal, tal como ilustrado na figura 4.28 c). Cruz: no sendo uma forma geomtrica genuna, pode ser construda custa de dois rectngulos. Desta maneira, tambm fica completamente definida custa de duas linhas de direco, embora todos os pontos resultantes da interseco dessas duas linhas no pertenam a essa forma geomtrica, isto , a interseco dessas duas linhas vai originar pontos de interseco exteriores forma geomtrica, formando assim uma interseco falsa, como ilustrado na figura 4.28 b).

87

Captulo IV - Sistema Desenvolvido

a)

b)

c)

Figura 4.28 Interseco das linhas de direco que constituem as figuras geomtricas. A vermelho so assinaladas as interseces falsas e a verde as que pertencem figura geomtrica. a) Quadrado, b) Cruz e c) Tringulo

A partir da observao da figura 4.28 possvel concluir vrios aspectos tais como: Se juntarmos qualquer uma das figuras geomtricas com um / vrios tringulos, os pontos de interseco do tringulo sero resultantes da interseco das linhas com direces oblquas. Desta maneira para sabermos quais so os pontos de interseco pertencentes ao tringulo, basta saber quais so as rectas com direco oblqua e quais os pontos que resultaram da interseco das duas linhas oblquas e destas com a linha de direco horizontal. Na cruz, o facto de haver falsas interseces, pode ser uma vantagem muito grande, dado que, dentro do permetro formado pelas falsas interseces, vo-se encontrar todos os pontos de interseco verdadeiros, pertencentes cruz. Desta maneira para sabermos quais os pontos de interseco pertencentes cruz, faz-se a deteco de falsas interseces, constri se uma caixa imaginria volta desses pontos, e assim todos os pontos contidos nessa caixa (excepto aqueles que a formam) so considerados pontos pertencentes cruz. Quanto ao quadrado, rectngulo ou losngulo, a nica caracterstica que os diferencia em relao s formas geomtricas descritas anteriormente o comprimento entre pontos consecutivos de interseco ser constante e superior a todos os outros comprimentos detectados nessa direco. Se o nosso alvo for constitudo apenas por tringulos, cruzes e quadrados existe outra forma de detectar estes pontos de interseco, que consiste basicamente em detectar primariamente os pontos de interseco dos tringulos e cruzes e s depois classificar os pontos restantes como pontos pertencentes aos quadrados.

Assim o alvo dever ser constitudo principalmente por cruzes e tringulos, dado que, para estes a classificao dos seus pontos de interseco faz-se de uma maneira clara e inequvoca. Tendo tambm em conta que o facto de se incluir uma (ou mais) cruz faz com que os pontos de interseco sejam muitos mais dado que a existncia de mais duas linhas na direco horizontal vai provocar mais cruzamentos nas outras figuras geomtricas tal como ilustrado na figura 4.29.

Figura 4.29 Pontos de interseco resultantes do cruzamento das linhas nas quatro direces mencionadas na caixa com cor verde. Os pontos assinalados a vermelho so interseces falsas. A azul assinalada a caixa imaginria de classificao dos pontos pertencentes cruz.

88

Captulo IV - Sistema Desenvolvido

O nmero de pontos resultantes devido ao facto de haver quatro linhas na direco 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 presena de pelo menos uma cruz pode ser um factor de erro nos clculos, dado que os pontos resultantes da interseco das linhas horizontais da cruz, originam pontos que no caractersticos das outras figuras geomtricas. Outro pormenor a ter em conta a dimenso do alvo. Se este for muito pequeno, mais sensvel influncia do rudo (que tem como uma das consequncias a no deteco de certas linhas ou provocar a deteco de linhas inexistentes) e dificultar a anlise de pequenos movimentos. Pelo contrrio se o alvo for muito grande, alm das dificuldades relacionadas com a implementao fsica, corre-se o risco de no detectar o alvo na sua totalidade e assim perder informao preciosa sobre o movimento efectuado. Assim, tendo em conta as condicionantes referidas, o melhor compromisso ser a incluso de quatro figuras geomtricas. Como a filosofia desta implementao requer a maior diversidade possvel destas figuras, apenas a quarta figura pode ser uma repetio de uma das outras trs. Assim as configuraes possveis seriam: Tringulo <> Quadrado <> Cruz <> Tringulo Quadrado <> Quadrado <> Cruz <> Tringulo Cruz <> Quadrado <> Cruz <> Tringulo

Tendo em conta as caractersticas internas de cada uma destas figuras geomtricas concluiu se que aquela em a deteco e classificao dos pontos de interseco mais eficaz e precisa o tringulo. Assim a configurao do alvo implementado est representada na figura 4.30. Embora sejam marcados na figura 4.30 os pontos de interseco falsos na cruz no usados para o processamento nem so gravados nos ficheiros de texto de sada das implementaes.

Figura 4.30 Alvo dimensionado para deteco, clculo de coordenadas 3D e estimao de movimento. Na figura so visveis a azul os pontos de interseco do tringulo, a amarelo os do quadrado, a verde os pontos considerados como pertencentes cruz e a vermelho os pontos de interseco no pertencentes cruz

2.4.2.2 Deteco do alvo Para se efectuar o emparelhamento e posteriormente clculos das coordenadas 3D necessrio determinar as coordenadas dos pontos de interseco das figuras caractersticas do alvo na memria frame. Todo o processo de clculo de coordenadas 3D se inicia aqui, sendo que a preciso dos valores tem um peso importante na qualidade dos resultados a obter. A tcnica utilizada para a deteco dos pontos caractersticos do alvo baseado no mtodo apresentado no ponto 2.3.3.6, mtodo este que considera um conjunto de quadrados igualmente distribudos, sendo os vrtices dos quadrados os pontos de calibrao a considerar. Neste caso, o conjunto de figuras a considerar est ilustrado na figura 4.30, e os pontos a considerar so, alm dos vrtices, todos os pontos resultantes da interseco entre as linhas nas quatro direces principais. Assim a determinao dos pontos de interseco das figuras geomtricas na memria frame feita da seguinte forma: 1) Realizar a aquisio da imagem de cinzentos. 2) Sujeitar a imagem de calibrao a um detector de orlas de intensidade, para classificar os pixels da imagem inicial em termos de amplitude e de direco q.

89

Captulo IV - Sistema Desenvolvido


3) Determinar as quatro direces principais q1 e q2 que sejam diferentes de pelo menos um valor qd , isto |q1-q2| qd, |q1-q3| qd, |q1-q4| qd, |q3-q2| qd, |q4-q2| qd e |q4-q3| qd considerando nesta determinao apenas os pixels cujo valor de amplitude Ai seja superior a um determinado valor de modo a desprezar-se pontos de rudo. 4) Classificao dos pixels resultantes da deteco das orlas de intensidade na imagem de calibrao em quatro classes C1, C2, C3 e C4, uma vez que temos quatro direces principais possveis, tal como ilustrado na figura asdasd. Uma constituda pelos pixels que apresentam, um valor de amplitude Ai igual ou superior ao limiar e uma direco qi aproximadamente igual a q1, outra constituda pelos pixels que apresentem um valor de amplitude Ai igual ou superior a um dado limiar e cuja direco qi seja aproximadamente igual a q2, outra constituda pelos pixels que apresentem um valor de amplitude Ai igual ou superior a um dado limiar e cuja direco qi seja aproximadamente igual a q3 e outra constituda pelos pixels que apresentem um valor de amplitude Ai igual ou superior a um dado limiar e cuja direco qi seja aproximadamente igual a q4. 5) Determinar as linhas rectas constitudas pelos lados das figuras geomtricas na classe C1 sendo esta determinao efectuada do seguinte modo: a) Determinar o primeiro elemento da classe C1 no considerado e classific-lo como considerado. b) Definir a recta que passa pelo ponto anteriormente determinado e que tem direco igual a q1 . c) Determinar o prximo ponto na classe C1 ainda no considerado que pertence linha recta determinada no passo anterior , tendo por base que a distncia 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 regresso linear dos pontos classificados como pertencentes a uma determinada linha, se o nmero destes for superior a um dado limiar, de modo a eliminar falsas linhas. f) determinar uma nova, linha voltando ao ponto i) at no existirem mais elementos na classe C1 ainda no considerados. 6) Determinar as linhas rectas constitudas pelos lados das figuras geomtricas na classe C2 do mesmo modo como foi efectuado para a classe C1 considerando no entanto q2 em vez de q1 . 7) Determinar as linhas rectas constitudas pelos lados das figuras geomtricas na classe C3 do mesmo modo como foi efectuado para a classe C1 considerando no entanto q3 em vez de q1 . 8) Determinar as linhas rectas constitudas pelos lados das figuras geomtricas na classe C4 do mesmo modo como foi efectuado para a classe C1 considerando no entanto q4 em vez de q1 . 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 oblquas do tringulo, tal como pode ser constatado na figura dasd. Desta maneira so duas as classes que contm este valor mnimo. Por excluso a classe com um valor mdio de linhas rectas contm as linhas rectas na direco horizontal. 10) Determinar a interseco das linhas obtidas entre as classes que contm os valores mnimos de linhas rectas (esta interseco ir resultar nos vrtices dos tringulos). 11) Definir os pontos de interseco, determinados no passo anterior como pontos pertencentes a um tringulo (sendo colocados na imagem final a uma intensidade pr definida exclusiva do tringulo). 12) Determinar a interseco das linhas obtidas entre as classes que contm os valores mnimos e a classe que contm o valor mdio de linhas rectas (esta interseco ir resultar nas bases dos tringulos). 13) Definir os pontos de interseco, determinados no passo anterior como pontos pertencentes a um tringulo. 14) Determinar a interseco das linhas obtidas entre a classe que contm o valor mximo e a classe que contm o valor mdio de linhas rectas (esta interseco ir resultar nos restantes pontos de interseco). 15) Determinar os pontos que correspondem a falsas interseces. 16) Definir os pontos de interseco, contidos num rectngulo imaginrio definido pelos pontos resultante das falsas interseces, como pontos pertencentes cruz (sendo colocados na imagem final a uma intensidade pr definida exclusiva do cruz).

90

Captulo IV - Sistema Desenvolvido


17) Definir os restantes pontos de interseco, excepo dos pontos resultante das falsas interseces, como pontos pertencentes ao quadrado (sendo colocados na imagem final a uma intensidade pr definida exclusiva do quadrado).

2.4.3 - Emparelhamento de pontos caractersticos


O emparelhamento dos pontos caractersticos consiste basicamente na classificao unvoca 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 geomtricas, translaes e rotaes a que sejam sujeitos. Assim qualquer imagem, contendo o alvo dimensionado, que seja submetida implementao de emparelhamento o resultado desta implementao ser sempre um vector de pontos devidamente ordenado por figuras geomtricas, sendo tambm feita uma etiquetagem dos pontos, identificando a posio que estes ocupam dentro da figura geomtrica. Assim a etiquetagem que realizada ilustrada na figura 4.31.

Figura 4.31 Etiquetagem realizadas no alvo dimensionado para a deteco. A amarelo encontra-se a etiquetagem realizada no quadrado, a azul nos tringulos e a verde na cruz.

Conforme visvel na figura 4.31 a etiquetagem realizada por figura geomtrica detectada. O processo de etiquetagem feito da seguinte forma: 1) Procurar todos os pontos identificados como pertencente aos tringulos. 2) Identificar os vrtices dos tringulos. 3) Classificar como T1 aquele que se encontrar mais perto da falsa deteco da cruz do canto superior direito. 4) Classificar T2, T3 e T4 os pontos pertencentes linha recta que vai desde o vrtice T1 at ao vrtice do lado esquerdo da base. 5) Classificar T5, T6 e T7 os pontos pertencentes linha recta que vai desde o vrtice T1 at ao vrtice direito da base. 6) Classificar como T8 o vrtice do segundo tringulo 7) Classificar T9, T10 e T11 os pontos pertencentes linha recta que vai desde o vrtice T8 at ao vrtice do lado esquerdo da base. 8) Classificar T12, T13 e T14 os pontos pertencentes linha recta que vai desde o vrtice T8 at ao vrtice 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 distncia a este inferior do que a distncia do outro ponto do quadrado pertencente tambm 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 distncia a este inferior do que a distncia do outro ponto da cruz pertencente tambm linha recta de T4.

91

Captulo 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 distncias ao ponto T3 e tambm condio 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 distncias ao ponto T2 e tambm condio 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 Obteno de informao tridimensional


2.4.4.1 Principio da triangulao estereoscpica A obteno de informao tridimensional de uma cena essencial para a estimao de movimento a que este projecto se prope. Assim a soluo escolhida para o fazer foi o uso de duas cmaras que obtm imagens distintas de uma cena, conhecendo-se os parmetros intrnsecos e extrnsecos das cmaras utilizadas para a aquisio de imagem possvel obter informao tridimensional a partir da resoluo do sistema de projeco estereo para os pontos caractersticos previamente detectados e emparelhados (ver 2.4.2 e 2.4.3). Nesta seco apresentado o mtodo que foi utilizado para obter a informao tridimensional a partir do conhecimento das coordenadas de pontos caractersticos previamente detectados e emparelhados. Quando se pretende obter informao tridimensional de uma cena a partir de imagens distintas da mesma , necessrio o conhecimento prvio do modelo da cmara utilizada. Assim necessrio do modo comos os pontos tridimensionais so transformados em pontos no plano da imagem. O conhecimento destes parmetros resulta do processo de calibrao da cmara. A calibrao norma geral efectuada uma vez e independentemente, devendo ser efectuada de novo apenas se o posicionamento das cmaras 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 transformao global determinada atravs da calibrao da cmara,. A equao global que traduz esta transformao global para um ponto P em coordenadas homogneas, para um dada cmara para a posio e orientao k, :

xw wX u L y L wYu = M PPL w em que MPPL= zw w 1

a11 a21 a31

a12 a22 a32

a13 a23 a33

a14 a24 a34

(wXuL, wYuL, w) - so as coordenadas homogneas no distorcidas do ponto P no sistema 2D do plano imagem da cmara para a posio e orientao L. (xu, yu, zu, 1) - so as coordenadas homogneas do ponto P no sistema 3D mundo. MPPL - a matriz no invertvel da transformao global da mesma cmara para a posio e orientao L. Analisando os dados anteriores facilmente se pode verificar que no possvel 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 incgnitas - xu, yu, zu, e w - para trs equaes. Assim necessitamos das coordenadas do mesmo ponto no sistema 2D do plano da imagem para outra posio e orientao. Ou seja com o sistema de equaes anterior e o seguinte, obtido com a segunda cmara conseguimos obter as coordenadas 3D do sistema mundo do ponto P pois passamos a ter um sistema de equaes sobre determinado.

92

Captulo IV - Sistema Desenvolvido


xw wX u R y R w wYu = M PPR z em que MPPR= w w 1

b11 b12 b21 b22 b31 b32

b13 b23 b33

b14 b24 b34

(wXuR, wYuR, w) - so as coordenadas homogneas no distorcidas do ponto P no sistema 2D do plano imagem da cmara para a posio e orientao R. (xu, yu, zu, 1) - so as coordenadas homogneas do ponto P no sistema 3D mundo. MPPR - a matriz no invertvel da transformao global da mesma cmara para a posio e orientao R. Fazendo uso das equaes obtidas para R e L obtemos ento um sistema de equaes lineares sobre determinado (sistema de projeco stereo) :

a11 - a31 X u a21 - a31Yu b11 - b31 X u b21 - b31Yu

a12 - a32 X u a22 - a32Yu b12 - b32 X u b22 - b32Yu

a13 - a33 X u a23 - a33Yu b13 - b33 X u b23 - b33Yu

L R

L R

L R

a34 X u L - a14 xw a Y L - a y w = 34 u R 24 z b34 X u - b14 w R b34Yu - b24

Trata-se de um sistema com quatro equaes lineares para trs incgnitas onde intervm apenas as coordenadas 2D no distorcidas do ponto P no plano imagem e as matrizes de transformao global da cmara para as posies L e R. Este sistema pode ser resolvido em ordem s trs incgnitas utilizando por exemplo o mtodo dos mnimos quadrados com decomposio em valor nico ou de Cholesky. De notar que as duas posies e orientaes devem fazer entre si uma disparidade estereoscpica aceitvel de modo a que a resoluo do sistema anterior corresponda a solues o mais precisas possveis. 2.4.4.2 Implementao desenvolvida A extraco de coordenadas 3D de pontos, seguindo o principio da triangulao estereoscopica, cujas coordenadas 2D do frame buffer so conhecidas, foi a funcionalidade. Ou seja a partir dos pontos obtidos e emparelhados por meio de etiquetagem na deteco e emparelhamento dos pontos caractersticos explicado nos captulos 2.4.2 e 2.4.3 podemos obter as respectivas coordenadas 3D. Assim o algoritmo desenvolvido para a obteno da informao tridimensional efectua dois passos: Determinao das coordenadas imagem no distorcidas para cada ponto caracterstico emparelhado, a partir das suas coordenadas na memria frame, para a primeira e segunda posio e orientao da cmara. Determinao das coordenadas 3D para o respectivo ponto.

2.4.5 Software desenvolvido


2.4.5.1 Comprovao dos algoritmos desenvolvidos Nesta seco demonstra-se que os algoritmos desenvolvidos funcionam correctamente, pelo seu uso em condies onde partida sabemos a soluo verificando se de facto o algoritmo nos fornece a soluo esperada. 1) Deteco dos pontos caractersticos Neste ponto ser demonstrada que a deteco do alvo dimensionado no ponto 2.4.3 unvoca, sendo imune a translaes, rotaes e tamanhos diferentes dos objectos, diferenciando assim todas as

93

Captulo IV - Sistema Desenvolvido


figuras geomtricas, sendo cada classe de figuras representadas com uma cor diferente e exclusiva dessa classe. Desta maneira esta implementao ser testada atravs da deteco destas entidades presentes nas imagens ilustradas na figura 4.32. De notar que as duas imagens apenas tm em comum o facto de possurem as mesmas figuras geomtricas.

a)

b)

Figura 4.32 Imagens de teste criadas para testar o algoritmo de deteco das entidades presentes em cada imagem.

Aplicando estas imagens implementao de deteco com os parmetros indicados na figura 4.18 b), o resultado foi o ilustrado na figura 4.33. De notar que os parmetros iniciais so submetidos implementao atravs do mesmo interface utilizado aquando da deteco dos pontos de calibrao na memria frame, dado que, as filosofias de deteco das duas implementaes so idnticas. Atravs da anlise da figura 4.33, constata se que o resultado da implementao de deteco de entidades caractersticas presentes numa imagem foi idntico para as duas imagens ilustradas na figura 4.32. De notar que cada uma das classes de figuras geomtricas representada com um valor diferente de todas as outras classes, facilitando assim o posterior processamento destas imagens assim como uma melhoria em termos de visualizao. Desta maneira concluiu se que a implementao de deteco bastante robusta e flexvel.

a)

b)

Figura 4.33 Resultado da implementao de deteco de entidades caractersticas 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

Captulo IV - Sistema Desenvolvido

Neste ponto ir ser feita a demonstrao do algoritmo de emparelhamento definido no ponto 2.4.3. Este emparelhamento, como j foi referido, de extrema importncia para o clculo de coordenadas 3D devido ao facto de que neste clculos 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 necessrio executar o emparelhamento descrito. De notar que as duas figuras apenas tm em comum as mesmas figuras geomtricas, sendo que estas imagens tm orientaes diferentes e translaes diferentes. Desta maneira ser provado a flexibilidade, robustez e eficcia da implementao desenvolvidas. Assim submetendo as imagens de teste ilustradas na figura 4.35 implementao de emparelhamento obtiveramse os resultados apresentados na tabela 5.

[a]

[b]

Figura 4.35 Imagens de teste criadas para teste do algoritmo de emparelhamento. Xf:
682 703 725 746 650 619 588 143 164 186 207 111 80 49 509 456 567 514 461 408 572 519 466 413 524 471 338 233 343 238 348 243 352 248

Yf:
149 207 266 325 203 256 311 102 161 219 278 156 210 264 304 299 252 247 243 238 196 191 187 182 136 131 289 280 232 223 177 167 121 112

Object:
T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8

Xf:
698 729 761 792 676 655 633 172 203 234 266 150 129 107 541 488 589 536 483 431 584 531 478 426 526 473 396 292 391 287 387 282 382 277

Yf:
148 202 255 310 207 265 324 194 248 301 355 252 311 369 332 336 270 275 280 284 215 219 224 228 163 168 344 353 288 297 232 241 176 185

Object:
T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8

[a]

[b]

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

Captulo IV - Sistema Desenvolvido


Atravs da observao dos valores apresentados na tabela 5, conclui se queo algoritmo classifica os pontos caractrsticos da cada imagem sempre da mesma maneira, independentemente da direco, translao e tamanho que as formas geomtricas possam apresentar. A classificao destes pontos idntica descrita no ponto 2.4.3. 3) Obteno das coordenadas 3D Usando como parmetros de referncia: dx= 0.00837766 dy= 0.0080756 Cx= 256 Cy= 256 sx = 0.710935 Para a cmara na posio 1( Left ou L ) usamos a seguinte matriz de transformao

- 55 0 1 0 MPPL= 0 1 - 15 0 0 0 0.02 - 0.6

e com o ponto a ter as coordenadas de buffer (195, 301)

Para a cmara na posio 2 ( Right ou R ) usamos a seguinte matriz de transformao

- 55 0 1 0 MPPR= 0 1 - 55 e com o ponto a ter as coordenadas de buffer (193, 179) 0 0 0 0.02 - 2


E para ambas as cmaras f = 50 (Distncia focal) k = 0.001 (Distoro 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 so bons com uma preciso bastante aceitvel. 2.4.5.2 - Implementao do software Neste captulo ser referida a implementao do mdulo que nos permite efectuar as seguintes funes: Deteco dos pontos caractersticos do alvo a colocar sobre o paciente. Emparelhamento dos pontos do alvo a colocar sobre o paciente detectados, obtidos a partir de duas cmaras em locais diferentes (sistema stereo de aquisio) Obteno das coordenadas 3D dos pontos do alvo a partir das suas coordenadas imagem 2D

As trs funes referidas anteriormente so 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

Captulo IV - Sistema Desenvolvido


coordenadas dos pontos 3D do alvo que se encontra nesses mesmos pares de imagens. Fornecendo assim a informao necessria para a posterior deteco e correco do movimento efectuado. Este mdulo tem como parmetros de entrada dados que foram adquiridos e calculados em mdulos anteriores do software desenvolvido tais como a calibrao e a aquisio. As matrizes de transformao de cada cmara. A distncia focal e distoro radial da lente para cada cmara. Os parmetros dx, dy, cx, cy, sx do sistema. Nmero de pares de imagem a considerar para deteco de alvo. E posteriormente aps introduo dos parmetros da aquisio as imagens: O conjunto de pares de imagem nas quais se pretende fazer a deteco dos pontos caractersticos de um modo ordenado.

Introduo dos parmetros da aquisio Assim quando iniciado o mdulo deteco e clculo de coordenadas 3D necessrio introduzir os parmetros de configurao, do sistema que foi utilizado para a aquisio das imagens do alvo a considerar, para a deteco dos pontos caractersticos do alvo nas imagens de ambas as cmaras utilizadas. A introduo dos parmetros pode ser efectuada de 3 modos: i) Manualmente - Os parmetros so introduzidos pelo utilizador um a um de acordo com os valores pretendidos pelo mesmo. ii) Usando os valores de default - Os parmetros so todos automaticamente introduzidos de acordo com os valores que se encontram configurados como sendo os de pr-definio ou se o processo de calibrao tiver sido efectuado anteriormente os parmetros de pr-definio sero automaticamente actualizados com os valores determinados nesse processo. iii) Por leitura do ficheiro obtido na calibrao do sistema , ficheiro este onde se encontra toda a informao necessria para a cmara em questo. Os parmetros introduzidos so: 1 - A matriz de transformao de cada cmara ( Com a designao genrica de Cmara esquerda/Cmara direita) 2 - Os parmetros dx- Distncia entre centro dos elementos sensores vizinhos na direco x. dy- distncia entre centro dos sensores CD vizinhos na direco y. cx- Coordenada do centro da imagem na memria frame segundo a direco Figura 4.36 Interface utilizador / implementao de x. aquisio de informao 3D cy- Coordenada do centro da imagem na memria frame segundo a direco y. sx- Factor de escala que compensa incertezas no escalamento efectuado pelo frame grabber na linha de scan horizontal. Todos estes parmetros so essenciais de modo a referenciar os pontos a um referencial comum tendo em ateno as caractersticas das cmaras utilizadas no processo bem como as suas posies 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 prximo passo permite-nos organizar as imagens obtidas anteriormente da forma que desejarmos de modo a detectar posteriormente os movimentos efectuados em relao a uma posio inicial, para o nmero de pares de imagens desejado. Assim encontrando-se as imagens em processo de visualizao na aplicao seleccionando a imagem desejada e posteriormente a referncia com a qual a queremos corresponder, iremos activar o

97

Captulo IV - Sistema Desenvolvido


processo de deteco e emparelhamento dos pontos caractersticos do alvo que se encontram localizados na imagem seleccionada. Utilizando o interface ilustrado na figura 4.17 procede se deteco dos pontos caractersticos. Tal procedimento dever ser efectuado para cada imagem de cada par, indicando qual a cmara utilizada para a sua aquisio e o nmero associado ao par de imagem. Ser dada uma indicao 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. Aps o processo de deteco e emparelhamento para cada par de imagens dever ser seleccionada a opo para obteno de coordenadas 3D. Aps ter efectuado o processo de deteco e emparelhamento e o processo de obteno de coordenadas Figura 4.37 Deteco, 3D para cada par de imagens dever ser seleccionado qual o par de Emparelhamento e determinao de imagens a funcionar de referncia para as outras imagens, de modo ao coordenadas 3D prximo mdulo poder referir a estimao de movimento a um par de imagens referncia, a partir do qual o processo de estimao de movimento se desenrola. Aps todo este procedimento ser pedido ao utilizador o nome e local do ficheiro para gravao em disco, da informao 3D dos pontos caractersticos para cada par de imagens considerado. Alguns resultados experimentais Nesta seco apresentada uma demonstrao processo de deteco, emparelhamento e obteno de coordenadas 3D.Para tal calibrando o sistema de cmaras para aquisio das imagens do alvo obtivemos as seguintes caractersticas: Cmara 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 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 calibrao dos parmetros intrnsecos e extrnsecos das duas cmaras

Cmara 2 (Right)

De seguida foram capturadas as imagens do alvo a partir das duas cmaras, obtendo as seguintes imagens:

98

Captulo IV - Sistema Desenvolvido

Figura 4.38 Aquisio simultnea das duas cmaras do alvo a detectar.

Tendo os dados necessrios ao processo pudemos inici-lo obtendo os seguintes resultados em termos de deteco e emparelhamento de pontos caractersticos das imagens alvo:

Figura 4.39 Deteco 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 informao:
Results for the 3D coordinates algorithm. ... Number of Image Pairs: . 1 1 98.9584 83.1823 67.3396 51.4554 98.7647 83.507 67.6676 51.5209 83.563 67.7109 36.0072 3.83225 36.0801 3.89533 36.1337 3.95507 36.1891 4.02333 -16.9301 0.187258 -17.2021 0.92416 -17.1955 0.974594 -17.1812 1.08141 -34.1955 0.57735 -33.9303 1.2291 -33.932 1.2602 -33.9391 1.31269 -51.1969 1.54532 -50.9323 0.813521 -0.39406 2.34608 -0.344682 4.15349 -17.4369 1.87608 -17.3945 2.23403 -33.9255 1.37334 -33.6268 2.41878 -50.9494 0.842789 -50.9323 1.13632 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 3D Coordinates for Image Pair number: X coord Y coord Z coord 138.351 -50.9643 3.20956 137.561 -34.3583 0.703536 136.685 -16.7062 -2.01538 135.536 -0.737885 -4.91216 139.016 -34.5084 2.27125 139.642 -16.9075 1.28916 140.251 -0.367107 0.158014 -35.6267 -51.2443 1.37772 -35.1206 -33.846 2.6109 -34.8579 -17.7769 1.59176 -34.352 -0.615183 3.22706 -36.577 -33.5109 5.40251 -36.6713 -17.6647 5.57182 -37.8389 0.362267 8.54108 83.1033 -0.47082 0.542053 67.2671 -0.178348 1.36295 TAG T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 C1 C2

Tabela 7 Coordenadas 3D dos pontos caractersticos dos alvos da figura 4.38.

99

Captulo IV - Sistema Desenvolvido


A anlise e discusso dos resultados obtidos bem como a sua adequao realidade sero tratados no Capitulo V.

2.5 Estimao do movimento e correco das imagens de medicina nuclear


2.5.1 - Introduo
A estimao de movimento do paciente durante o exame baseia-se nas coordenadas mundo dos pontos caractersticos do alvo a colocar sobre o paciente. Partimos do pressuposto de que o paciente efectua apenas movimento simples de translao e rotao no plano paralelo ao plano de calibrao. Ignoramos assim a componente de profundidade das coordenadas (z) projectando os pontos no plano que paralelo ao plano de calibrao que por sua vez ser colocado paralelamente mesa sobre a qual se encontra o paciente. A componente de profundidade das coordenadas dos pontos caractersticos do alvo ter interesse para a aplicao em trabalhos futuros. A correco das imagens resultantes dos exames SPECT usar a informao obtida pela estimao de movimento para corrigir a posio das imagens de exame efectuando a respectiva translao e rotao calculados para as imagens do alvo colocado sobre o paciente, obtidas pelo sistema estereo de aquisio de imagem. Partimos assim do pressuposto que existe um movimento rgido do rgo que se pretende visualizar e que este movimento o mesmo que o efectuado pelo alvo colocado sobre o paciente.

2.5.2 - Mtodo
O mtodo utilizado faz uso das coordenadas em x e em y dos pontos caractersticos para calcular o centro geomtrico de cada slido identificado no alvo a colocar sobre o paciente. ignorada a componente em profundidade uma vez que a projeco dos pontos caractersticos sobre um plano paralelo ao plano de calibrao corresponde simplesmente a ignorar a profundidade, uma vez que o sistema de coordenadas tem o seu plano x-origem-y paralelo ao plano de calibrao. Assim so calculadas as coordenadas dos pontos P1, P2, P3, P4 que so os centros geomtricos dos slidos, que teoricamente se encontram sobre a mesma recta no espao 3D, e consequentemente tambm no espao 2D.

P1

P2

P3

P4

Figura 4.40 Localizao dos centros geomtricos das figuras.

As coordenadas dos pontos so calculadas da seguinte forma: P1 Fazendo uso das coordenadas dos pontos T8,T9,T10,T11,T12,T13,T14: 1) Calculamos as coordenadas do ponto mdio do segmento de recta definido por T12 e T9 e tambm as coordenadas do ponto mdio do segmento de recta definido por T13 e T10, para de seguida calcular as coordenadas do ponto mdio do segmento de recta definido pelos dois pontos

100

Captulo IV - Sistema Desenvolvido


anteriormente calculados. Assim obtemos uma primeira estimativa das coordenadas do ponto central do tringulo.
1 ___ 2 ___

2) Calculamos as coordenadas do ponto mdio do segmento de recta definido pelos pontos T14 e T11, calculando de seguida as coordenadas do ponto mdio do segmento de recta definido pelos pontos T8 e pelo ponto calculado anteriormente. Assim obtemos uma segunda estimativa das coordenadas do ponto central do tringulo. 3) Minimiza-se o erro associado ao clculo das coordenadas do ponto central da figura fazendo a mdia das coordenadas das duas estimativas calculadas anteriormente, obtendo assim as coordenadas para o ponto P1.

Figura 4.41 Centro geomtrico P1

P2 Fazendo uso das coordenadas dos pontos Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8: 1) Calculamos as coordenadas do ponto mdio do segmento de recta definido por Q6, e Q5, e tambm as coordenadas do ponto mdio do segmento de recta definido por Q4 e Q3, para de seguida calcular as coordenadas do ponto mdio do segmento de recta definido pelos dois pontos anteriormente calculados. Assim obtemos 1 ___ uma primeira estimativa das coordenadas do ponto central 2 ___ do quadrado. 2) Calculamos as coordenadas do ponto mdio do segmento de recta definido pelos pontos Q8 e Q2, calculando de seguida as coordenadas do ponto mdio do segmento de recta definido pelos pontos Q7 e Q1. , para finalmente calcular as coordenadas do ponto mdio do segmento de recta definido pelos dois pontos anteriormente calculados. Assim obtemos uma segunda estimativa das coordenadas do Figura 4.42 Centro ponto central do quadrado. geomtrico P2 3) Minimiza-se o erro associado ao clculo das coordenadas do ponto central da figura fazendo a mdia das coordenadas das duas estimativas calculadas anteriormente, obtendo assim as coordenadas para o ponto P2. de notar que a direco dos segmentos de recta utilizados para calcular os pontos mdios no 1 e 2 passo so propositadamente diferentes de modo a minimizar erros que possam existir associados a uma das direces. 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 mdio do segmento de recta definido por C12, e C11, e tambm as coordenadas do ponto mdio do segmento de recta definido por C1 e C2, para de seguida calcular as coordenadas do ponto mdio 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 mdio do segmento de recta definido pelos pontos C10 e C6, calculando de seguida as coordenadas do ponto mdio do segmento de recta definido pelos pontos C7 e C3. , para finalmente calcular as coordenadas do ponto mdio 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 mdio do segmento de recta definido pelos pontos C9 e C8, calculando de seguida as coordenadas do ponto mdio do segmento de recta definido pelos pontos C5 e C4. , para de seguida calcular as coordenadas do ponto mdio do segmento de recta

101

Captulo IV - Sistema Desenvolvido


definido pelos dois pontos anteriormente calculados. Assim obtemos uma terceira estimativa das coordenadas do ponto central da cruz. 4) Minimiza-se o erro associado ao clculo das coordenadas do ponto central da figura fazendo a mdia das coordenadas das trs estimativas calculadas anteriormente, obtendo assim as coordenadas para o ponto P3. de notar que a direco dos segmentos de recta utilizados para calcular os pontos mdios no 1,2 e 3 passo so propositadamente diferentes de modo a minimizar erros que possam existir associados a uma das direces. Neste caso a preciso obtida ainda maior uma vez que este ponto ser o ponto que servir de base para calcular a translao associada ao alvo, tal como explicado a seguir.

1 ___ 2 ___ 3 ___ Figura 4.43 Centro geomtrico 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 correspondncia entre os pontos caractersticos do primeiro com o segundo tringulo.

Este processo de clculo de coordenadas 3D efectuado para o conjunto de pontos caractersticos de referncia, ou seja o conjunto de pontos caractersticos da imagem adquirida inicialmente pelo sistema stereo de aquisio, e de seguida efectuado para o conjunto de pontos caractersticos associados a outro instante desejado que no o inicial. Ao movimento do alvo associado um movimento composto de translao e de rotao. Neste algoritmo primeiro calculado a translao correspondente ao ponto P3 , que o ponto cujas coordenadas possuem a maior preciso de clculo, tal como explicado anteriormente. De seguida calculamos a rotao 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 clculo das coordenadas dos pontos P1, P2, P3 e P4 (no plano 2D) para os dois conjuntos de pontos. calculado a translao em x e em y da imagem tendo como referncia a diferena 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 possveis erros associados ao clculo das coordenadas desses mesmos pontos. Fazendo uso dos dois declives calculados respectivamente para cada conjunto de pontos, verificamos a diferena angular existente entre ambas, sendo esse o valor da rotao a efectuar.

A correco das imagens finais efectuada tendo em ateno os parmetros que resultam da deteco de movimento. As funes utilizadas para a translao e rotao das imagens so simples funes de translao de imagens seguindo o mtodo do nearest-neighbour para efectuar a interpolao de valores, e preenchendo o background com a cor preta medida que efectua as operaes. A translao segundo o eixo dos x, a translao segundo o eixo dos y e o ngulo de rotao em torno do ponto calculado. As coordenadas do eixo de rotao so introduzidas pelo utilizador uma vez que foi impossvel efectuar um exame clnico analisando a correspondncia entre o sistema de coordenadas utilizado como referencial mundo e a aquisio dos exames SPECT. Este assunto ser debatido nos capitulo posteriores.

102

Captulo IV - Sistema Desenvolvido

2.5.3 Software desenvolvido


2.5.3.1 Comprovao 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 rotao do alvo de 45 e por translao do mesmo de modo ao vrtice do quadrado se localizar na origem do sistema de coordenadas, resultando numa translao de 1.535 cm segundo o eixo dos x e de -6.363 cm segundo o eixo dos. Assim foi feito o clculo das coordenadas dos pontos caractersticos, ilustrado na tabela 8.

x T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 C1 C2 C3 7 7.5 8.5 9 6.5 5.5 5 -8 -7.5 -6.5 -6 -8.5 -9.5 -10 3 1 4

y -2 -1 1 2 -1 1 2 -2 -1 1 2 -1 1 2 2 2 1 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 C1 C2 C3

x 5.656 6.7165 8.8375 9.898 6.0095 6.7165 7.07 -4.949 -3.8885 -1.7675 -0.707 -4.5955 -3.8885 -3.535 5.656 4.242 5.656

y -11.312 -10.9585 -10.2515 -9.898 -10.2515 -8.1305 -7.07 -0.707 -0.3535 0.3535 0.707 0.3535 2.4745 3.535 -5.656 -4.242 -7.07

x C4 C5 C6 C7 C8 C9 C10 C11 C12 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 3 1 0 4 3 1 0 3 1 -1 -5 -1 -5 -1 -5 -1 -5

y 1 1 1 -1 -1 -1 -1 -2 -2 2 2 1 1 -1 -1 -2 -2 C4 C5 C6 C7 C8 C9 C10 C11 C12 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8

x 4.242 2.828 2.828 4.242 2.828 1.414 1.414 2.828 1.414 2.828 0 2.121 -0.707 0.707 -2.121 0 -2.828

y -6.363 -4.949 -4.242 -8.484 -7.777 -6.363 -5.656 -8.484 -7.07 -2.828 0 -3.535 -0.707 -4.949 -2.121 -5.656 -2.828

Tabela 8 Clculo das coordenadas dos pontos caractersticos

Tendo como resultados: Translao segundo o eixo dos x: Translao segundo o eixo dos y: Rotao em ngulos:

1.535 -6.363 49.9999

Os resultados obtidos confirmaram assim o que era esperado, devemos no entanto notar que estes clculos so exactos como seria de esperar uma vez que foram utilizados coordenadas de pontos caractersticos exactas.

103

Captulo IV - Sistema Desenvolvido


De seguida apresentamos o resultado utilizando coordenadas para os pontos caractersticos com alguns erros, na ordem de alguns milmetros aleatoriamente distribudos: 1 Teste Translao segundo o eixo dos x: Translao segundo o eixo dos y: Rotao em ngulos: 1.447 (5%) -6.451 (1%) 46.23 (2.7%)

2 Teste - Introduzindo ainda mais erros aleatoriamente Translao segundo o eixo dos x: Translao segundo o eixo dos y: Rotao em ngulos: 1.606 (4,6%) -6.452 (1%) 46.47 (3%)

Verificamos que mesmo assim os erros obtidos so aceitveis, provando a robustez do algoritmo e que os erros cancelam-se parcialmente devido filosofia do mtodo desenvolvido. 2.5.3.2 - Implementao da estimao de movimento e correco A estimao e correco surgem no seguimento do processo de deteco e obteno de informao tridimensional. Os valores obtidos pelo processo de deteco e obteno de informao tridimensional ficam em memria sendo utilizados pelo processo de estimao e correco de movimento. Neste processo possvel indicar o nmero de referncia do conjunto de pontos cujo movimento em relao ao conjunto de pontos de referncia pretendemos, surgindo a indicao dos valores de translao segundo os eixos dos x e dos y e a rotao em ordem ao eixo, determinado teoricamente como sendo o centro geomtrico da cruz que se encontra desenhada no alvo colocado sobre o paciente, de imediato nos campos apropriados. A correco do movimento determinado na imagem do exame SPECT pode ser efectuada usando os valores calculados pelo processo de estimao de movimento ou por valores introduzidos pelo utilizador. dada ao utilizador uma indicao das imagens mdicas 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 associao entre as coordenadas do conjunto de Figura 4.44 Interface pontos de referncia, obtidos no processo de deteco, e as imagens de estimao e correco de movimento resultantes dos exames mdicos no foi estabelecida por motivos discutidos no captulo VI. assegurada uma opo ao utilizador para indicao do eixo de rotao na imagem do exame SPECT.

104

Capitulo V - Anlise de Resultados

Captulo V

1. - Introduo
Neste captulo ser demonstrada a funcionalidade do software , bem como efectuar a anlise do sistema. Esta anlise tentar ser uma anlise critica sobre todas as condicionantes do sistema, ou seja, tudo o que possa influenciar a preciso das medidas. Para alm disso tentaremos caracterizar qual o melhor modo de operao do sistema desenvolvido. Ao fazermos o setup do sistema devemos efectuar a calibrao das cmaras de modo a podermos inferir informao 3D a partir dos pares de imagens stereo obtidos pelo sistema de aquisio. No entanto antes da calibrao necessrio escolher a posio das cmaras. Este posicionamento deve ter em conta os seguintes factores: problema das partes ocultas, resoluo e preciso da medida de distncia, e o volume de medida pretendido. O volume de medida depende no s da posio relativa das cmaras mas tambm do campo de viso de cada cmara que funo da respectiva distncia focal. Alm disso quando o ngulo formado pelos eixos pticos das cmaras aumenta, aumenta tambm a impossibilidade de calcular a distncia de certos pontos da cena. Por outro lado a diminuio deste ngulo tem como consequncia a diminuio da preciso da medida de distncia.

Volume de medida

d - ngulo de incerteza da linha de viso

Figura 5.1 - Volume de medida definido pela interseco dos ngulos de viso das cmaras

105

Capitulo V - Anlise de Resultados


O uso de duas cmaras leva a que o seu posicionamento tenha que ser pensado de modo a que a distncia entre elas resulte do compromisso entre o agravamento do problema das partes ocultas e a diminuio da preciso da medida. Para um determinado ngulo de incerteza na determinao da linha de viso associada a cada ponto de uma imagem, a incerteza na determinao do ponto do espao

Incerteza de posio j - ngulo de incerteza da linha de viso j j

Figura 5.2 - Efeito da aproximao das cmaras na preciso da medida de distncia. A incerteza na determinao aumenta medida que estas se aproximam.

correspondente aumenta com a aproximao das cmaras.

2. - Estimao do ngulo de viso das cmaras


O ngulo de viso das cmaras foi determinado medindo, com a ajuda de uma rgua colocada a

Aproximadamente 41,2 cm

Figura 5.3 - Campo de viso das cmaras

uma distncia bem definida da cmara ( 70 cm ) , a largura de viso, em centimetros, da imagem captada. Recorrendo trigonometria podemos determinar o ngulo de viso como sendo de:

d = 2 x arctan (

41,2cm/2 70cm

41,2 cm

) 32.8

70 cm

Uma vez determinado o ngulo de viso podemos agora determinar a distncia entre cmaras a utilizar de modo a obter a melhor configurao possvel, ou seja tendo em ateno o compromisso entre volume de viso e preciso de medio. Atravs do ngulo de viso verificamos que, usando clculos simplificados de modo ao alvo ocupar mais de 50 % da largura de viso da cmara e no ocupar mais de 100 %, obtemos como distncia ao alvo um valor que dever encontrar-se entre 42,5 cm e 85 cm tendo em ateno que a dimenso do alvo em largura de 25 cm aproximados.

Figura 5.4 - ngulo de viso

106

Capitulo V - Anlise de Resultados


Atendendo ao ngulo ptimo (q = 60 ) de calibrao chegamos aos seguintes valores de
R (cm) 50 55 60 65 70 75 80 85 90 95 100 105 110 115 120 125 130 135 140 145 150 D (cm) 57.80347 63.58382 69.36416 75.14451 80.92486 86.7052 92.48555 98.2659 104.0462 109.8266 115.6069 121.3873 127.1676 132.948 138.7283 144.5087 150.289 156.0694 161.8497 167.6301 173.4104

ALVO

R
q

SUPORTE
Esquerda Direita

Figura 5.5 - Relao raio - distncia

distncia ao alvo, e de distncia entre cmaras Uma vez que estes valores no se adaptam s dimenses inicialmente consideradas como aceitveis para a construo do suporte, de modo a no termos um suporte de elevadas dimenses, no iremos usar um ngulo ( q ) preciso de 60 . Analisando as dimenses necessrias para realizao aproximada dessa condio realizamos vrios testes para distncias variveis de forma a podermos analisar qual a distncia que nos permite visualizar o alvo com as dimenses consideradas adequadas para o algoritmo de calibrao e posteriormente para a deteco do alvo, com erros associados baixos. De seguida apresentamos o resultado de testes efectuados para verificao da executabilidade do modelo e verificao da melhor distncia ao alvo, bem como a melhor distncia entre cmaras.

3. - Testes efectuados
Iniciamos os testes de laboratrio para verificar a executibilidade do modelo. O suporte foi posicionado a uma distncia de aproximadamente 55 cm do alvo e com um espaamento entre cmaras de 60 cm o que corresponde a q 61, o que no deixa de ser um ngulo bastante aproximado dos 60 pretendidos.

Figura 5.6 - Alvo de calibrao

A deteco dos pontos caracteristicos dos alvos foi conseguida de uma forma ptima recorrendo apenas a pequenas alteraes nos parmetros do algoritmo de deteco dos pontos caracteristicos do alvo.

107

Capitulo V - Anlise de Resultados


Verificamos que o software implementado consegue assim adaptar-se s condies de aquisio de imagem adaptando-se s caracteristicas especificas de cada cmara e do prprio ambiente, tal como a iluminao e as diferenas que se notam na aquisio efectuada por cada cmara.

Figura 5.7 - Pontos de calibrao

De seguida efectuamos a formatao 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 calibrao

Assim resultaram os pontos cuja descrio encontramos no tabela 1 para a cmara da posio da esquerda e 2 para a cmara da posio da direita.

108

Capitulo V - Anlise de Resultados


-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 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

Tabela 1 - Pontos de calibrao em coordenadas 3D e 2D.

Fazendo uso deste pontos formatados podemos finalmente calcular os parmetros de calibrao para cada cmara. Para tal configuramos os parmetros sx, Cx , Cy, dx e dy para cada cmara e obtivemos os resultados indicados na tabela 3 e 4, para a cmara da esquerda e da direita respectivamente.
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 - Calibrao da cmara da esquerda 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 Tabela 3 - Calibrao da cmara da esquerda

109

Capitulo V - Anlise de Resultados

Como podemos verificar as cmaras apresentam valores de distoro radial e de distncia focal ligeiramentee diferentes o que levar a erros na estimao das coordenadas 3D devido no uniformidade destes parmetros em duas cmaras que partida se pretendiam semelhantes. Foi utilizada a opo de determinao do centro ptico das cmaras O valor de sx foi aproximado pela simplificao demonstrada no Capitulo IV em 2.3.3.3

Aps o processo de calibrao efectuamos o processo de deteco de um alvo para apenas uma posio do alvo de modo a verificarmos a preciso das medidas tridimensionais do mesmo, confirmando se assim ou no se o processo de calibrao efectuado nos permitiu chegar aos valores mais correctos.

Figura 5.9 - Alvo para clculo de coordenadas 3D

Verificamos que o processo de deteco dos pontos caracteristicos se apresenta como sendo robusto e adaptvel, sendo que facilmente com pequenas alteraes dos parmetros de deteco dos pontos caracteristicos do alvo conseguimos detectar e emparelhar os pontos caracteristicos de uma forma precisa, sem erros.

Figura 5.10 - Deteco dos pontos de interseco do alvo

Obtivemos do processo de deteco as coordenadas para os pontos detectados e emparelhados apresentados na tabela 4, associados respectivamente s cmaras da esquerda e da direita.

110

Capitulo V - Anlise de Resultados


possvel verificar que os pontos foram todos correctamente emparelhados.
Points: Xf: 540 553 562 575 529 522 511 203 221 231 247 187 178 162 450 432 475 449 431 402 475 448 430 402 446 428 366 288 365 286 364 286 362 285 Yf: 225 254 274 303 255 275 305 225 260 281 313 261 282 315 306 307 276 276 277 277 256 256 257 257 226 226 309 312 278 280 258 259 226 226 Object: T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Points: Xf: 515 531 542 557 500 489 474 191 203 211 223 178 171 159 406 388 435 407 388 361 435 407 389 361 408 389 324 256 325 256 325 257 326 257 Yf: 257 289 311 343 289 311 342 264 293 311 340 293 311 339 342 341 311 311 311 311 290 290 290 291 259 259 341 340 311 311 291 292 261 262 Object: T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8

Tabela 4 - Classificao dos pontos de interseco detectados

Figura 5.11 - Mtodo de emparelhamento dos pares de figuras

O processo de clculo de coordenadas 3D resultou nos valores apresentados na tabela 7, do qual podemos fazer as seguintes verificaes: A coordenada em profundidade dos pontos apresenta alguns erros,essencialmente ao nvel da coordenada em Z dos pontos do tringulos verificando-se que para os outros pontos esta coordenada apresenta valores muito satisfatrios. Verificando as distncias 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 so satisfatrios. No entanto podemos enumerar alguns problemas que podem interferir com a preciso das coordenadas dos pontos calculados: - O alvo de calibrao impresso numa impressora a laser no tem preciso suficiente, notando-se desde logo que o alvo impresso possui os quadrados no completamente alinhados, demonstrando-se esta soluo como alvo de calibrao uma soluo pobre.

111

Capitulo V - Anlise de Resultados


Seg. Recta T14 e T8 T14 e T11 T8 e T11 Q1 e Q2 Q2 e Q8 Q8 e Q7 Q7 e Q1 C1 e C2 C2 e C12 C12 e C11 C11 e C1 T1 e T4 T4 e T7 T7 e T1 Erro 0.6% 0.1% 1.4% 1.1% 0.5% 0.8% 0.7% 1.1% 0.8% 1.8% 0.7% 0.1% 1.7% 0.5% Valor medido (mm) 44.71537234 39.96804832 44.38558873 39.57536674 39.79466031 39.66047612 39.70930609 9.892354365 39.66766089 10.18340339 39.71641147 44.96231961 40.68788063 44.7842249 Valor esperado (mm) 45 40 45 40 40 40 40 10 40 10 40 45 40 45

Tabela 7 - Coordenadas 3D dos pontos detectados e emparelhados

- O suporte no possui estabilidade nem suficientemente preciso, de modo a podermos alinhar as cmaras, denotando-se que as imagens obtidas, devido ao encaixe das cmaras no suporte, no se encontram alinhadas horizontalmente. - As cmaras tm uma elevada distoro no linear. A distoro to elevada que se nota claramente nas prprias imagens adquiridas, sendo o aumento a distoro do centro da imagem para a periferia. 3D Coordinates ....
X coord 102.315 109.689 114.795 121.91 94.4599 89.0088 81.2336 -78.2201 -70.6646 -66.2103 -59.2111 -86.5445 -91.1594 -99.1745 45.6982 35.8276 61.1426 Y coord -29.4948 -14.4937 -4.13703 10.9543 -14.687 -4.59058 10.003 -32.5149 -16.8247 -7.34219 7.57878 -16.9819 -7.63413 6.9729 9.1766 8.86312 -5.20437 Z coord TAG -3.20021 T1 -2.30059 T2 -1.88616 T3 -1.96876 T4 -2.20169 T5 -2.49656 T6 -2.13947 T7 -1.45711 T8 -1.59232 T9 -0.827526 T10 -0.345701 T11 -1.13471 T12 -0.898206 T13 -0.412459 T14 -1.58676 C1 -1.01086 C2 -1.73739 C3 46.2808 36.1105 20.7692 61.5452 46.4221 36.5299 21.1603 46.8199 36.6403 0.292171 -39.2785 0.83038 -39.3197 0.937984 -38.7045 1.26848 -38.3805 -5.64238 -5.68239 -6.2008 -15.1026 -15.6036 -15.6874 -15.8681 -30.5208 -30.7962 8.35522 7.80425 -6.46212 -7.00591 -16.1864 -16.7078 -31.3356 -31.9795 -1.47188 C4 -1.43658 C5 -0.148284 C6 -2.50836 C7 -1.60963 C8 -0.989955 C9 -0.823248 C10 -1.0852 C11 -1.04516 C12 -0.660441 Q1 -0.399517 Q2 -0.444182 Q3 -0.223889 Q4 -0.502565 Q5 -0.191399 Q6 0.0569284 Q7 -0.648156 Q8

Tabela 6 - Erros das distncias detectadas

- As cmaras apresentam diferenas visiveis entre si o que afecta a aquisio de imagem, denotando-se que uma apresenta uma distoro superior outra. - As condies de iluminao do local onde se realizaram os testes introduziram pequenos artefactos que dificultam as condies de execua dos algoritmos de calibrao e deteco dos pontos caracteristicos do alvo. - A distncia e posio das cmaras em relao ao alvo podero ter influncia nos resultados obtidos. De seguida realizamos os seguintes testes para verificao de que o ngulo ptimo de calibrao seria de facto aquele que mais se aproxima de q = 60 . Para diferentes distncias entre cmaras, e a uma distncia de 55 cm do alvo verificamos a validade da calibrao, pela anlise da preciso na medio das coordenadas 3D do alvo colocada no plano Z = 0.

112

Capitulo V - Anlise de Resultados

1 Teste: D = 30 cm ( q 75)
Seg. Recta T14 e T8 T14 e T11 T8 e T11 Q1 e Q2 Q2 e Q8 Q8 e Q7 Q7 e Q1 C1 e C2 C2 e C12 C12 e C11 C11 e C1 T1 e T4 T4 e T7 T7 e T1 Erro 3.7% 2.6% 5.0% 3.5% 4.4% 3.8% 4.4% 3.5% 4.7% 3.3% 5.6% 4.9% 2.4% 5.4% Valor medido (mm) 43.33469605 38.96045698 42.77007148 38.61072823 38.2432386 38.47524391 38.24136172 9.649495558 38.1138722 9.668915514 37.7730901 42.81055431 39.02689787 42.56906571 Valor esperado (mm) 45 40 45 40 40 40 40 10 40 10 40 45 40 45

Tabela 8 - Erros das ditncias detectadas. 3D Coordinates X coord Y coord 87.8247 -31.3646 95.5259 -16.8541 100.101 -7.07243 107.092 6.79472 80.2712 -17.1383 75.5467 -7.78517 68.3379 5.86087 -86.3103 -33.5902 -79.3599 -19.0772 -74.4849 -9.49677 -67.5424 4.83161 -94.34 -19.4444 -99.1653 -10.1053 -106.483 4.7033 34.0755 5.22629 24.4375 5.24737

Z coord -32.331 -30.4716 -30.4739 -30.0113 -29.8447 -28.4422 -25.5006 -26.4033 -25.9541 -25.9069 -25.5036 -23.8485 -22.8638 -24.2665 -24.0493 -24.5197

TAG T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 C1 C2

....
48.8421 34.4628 24.6448 10.1497 49.0779 34.5523 24.9852 10.2364 34.794 25.2333 -9.6517 -48.2603 -9.46191 -48.1005 -9.14784 -47.8709 -9.12953 -47.6015 -8.48822 -8.75665 -8.85763 -9.10261 -17.9319 -18.1712 -18.4077 -18.7278 -32.3656 -32.8164 5.13642 4.73438 -9.38994 -9.4744 -18.9182 -19.0178 -33.0984 -33.494 -25.0451 -25.8277 -25.2751 -24.4482 -26.8326 -26.1951 -24.6627 -24.9353 -27.6742 -26.3039 -25.149 -25.097 -24.1467 -25.2109 -25.3335 -24.6966 -25.6261 -25.935 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8

...

Tabela 9 - Erros das distncias detectadas

Podemos verificar que os erros aumentaram tal como seria de esperar uma vez que o ngulo entre as cmaras se afasta dos 60 referenciados anteriormente como sendo o ngulo ptimo. As coordenadas em z apresentam valores pouco correctos o que prova que a triangulao esteroscpica apresenta erros elevados devido falta de preciso na estimao das matrizes de calibrao.

2 Teste: D = 40 cm ( q 70)
Seg. Recta T14 e T8 T14 e T11 T8 e T11 Q1 e Q2 Q2 e Q8 Q8 e Q7 Q7 e Q1 C1 e C2 C2 e C12 C12 e C11 C11 e C1 T1 e T4 T4 e T7 T7 e T1 Erro 0.0% 0.1% 1.0% 0.3% 0.2% 0.4% 0.1% 2.1% 0.6% 0.1% 1.4% 0.2% 1.5% 1.1% Valor medido (mm) 44.99494008 40.02301165 44.56358326 39.88693402 40.07564728 39.84667475 39.97450997 10.20762498 39.75853547 10.00798827 39.45281292 44.90838664 40.60222444 44.51052056 Valor esperado (mm) 45 40 45 40 40 40 40 10 40 10 40 45 40 45

Tabela 10 - Erros das distncias detectadas.

113

Capitulo V - Anlise de Resultados

A melhoria na estimao das coordenadas visvel tal como seria de esperar uma vez que nos aproximamos um pouco mais do ngulo ptimo de calibrao, o que permite calcular matrizes de calibrao 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 contrrio do anterior onde denotamos a existncia de coordenadas em z com erros de 3,2 cm
3D X coord 100.309 108.446 113.723 121.685 93.1268 88.3387 81.2096 -80.1438 -72.1443 -67.0786 -59.359 -87.6037 -92.2585 -99.3462 45.6264 35.4288 .... Y coord Z coord TAG -41.4568 -5.01586 T1 -26.3123 -5.32037 T2 -16.6129 -4.87173 T3 -1.96309 -5.29278 T4 -26.2704 -3.42531 T5 -16.1749 -2.81114 T6 -1.35501 -2.14431 T7 -37.1776 -2.36657 T8 -22.189 -2.02449 T9 -12.2252 -2.51164 T10 2.23953 -1.92509 T11 -21.6389 -1.42335 T12 -11.7424 -0.693453 T13 3.483 -0.776578 T14 -0.777116 -1.59088 C1 -0.382266 -1.3703 C2

...
60.5051 -15.6693 45.6525 -15.406 35.4466 -15.2244 20.4146 -14.8812 60.3581 -25.6111 45.2886 -25.4512 35.0776 -25.2724 20.0318 -24.8575 45.1131 -40.2131 35.1546 -40.139 0.382794 0.574201 -39.4872 1.72516 0.125996 -14.2052 -39.7645 -13.0378 -0.0365562 -24.2921 -39.9928 -23.1492 -0.484947 -39.3907 -40.3112 -38.3349 -1.72259 C3 -1.42177 C4 -1.29009 C5 -1.6622 C6 -2.77478 C7 -1.65047 C8 -1.48194 C9 -0.424805 C10 -2.62245 C11 -1.63118 C12 -1.52076 Q1 -1.68317 Q2 -1.99217 Q3 -2.23782 Q4 -1.5623 Q5 -1.62912 Q6 -1.64389 Q7 -0.928106 Q8

Tabela 11 - Coordenadas 3D dos pontos detectados e emparelhados

3 Teste: D = 50 cm ( q 66)
Seg. Recta T14 e T8 T14 e T11 T8 e T11 Q1 e Q2 Q2 e Q8 Q8 e Q7 Q7 e Q1 C1 e C2 C2 e C12 C12 e C11 C11 e C1 T1 e T4 T4 e T7 T7 e T1 Erro 1.0% 0.3% 0.7% 0.1% 0.1% 0.4% 0.3% 0.1% 0.1% 0.0% 0.2% 0.4% 0.3% 0.3% Valor medido (mm) 44.53994296 40.10566538 44.6754495 39.96430236 39.95275878 40.14807382 39.89417869 9.99487153 40.03488767 9.997670567 39.93049672 44.84240859 40.12367892 44.86931613 Valor esperado (mm) 45 40 45 40 40 40 40 10 40 10 40 45 40 45

Tabela 12 - Coordenadas 3D dos pontos detectados e emparelhados 3D Coordinates X coord Y coord 103.965 -38.7922 111.972 -23.7058 117.562 -13.9009 125.337 0.629599 96.8717 -23.2896 92.0153 -12.991 85.2366 1.98092 -76.2146 -33.0485 -68.1853 -18.3419 -62.7699 -8.32353 -54.8787 6.1923 -83.3936 -17.9752 -88.1693 -7.50151 -94.9472 7.35902 50.108 2.97163 40.1256 3.25236

Z coord -1.39817 -1.5184 -1.58424 -1.4296 -1.73664 -1.59052 -1.63322 -2.63641 -2.31888 -2.71648 -3.55007 -2.11572 -1.87286 -2.27788 -2.92752 -3.34024

TAG T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 C1 C2

...
64.5492 49.6971 39.7477 24.6323 64.5527 49.462 39.4617 24.3724 49.0567 39.0968 4.88442 -35.0648 4.45802 -35.5782 4.1721 -35.6221 3.99596 -36.1291 -12.066 -11.8702 -11.4047 -10.966 -22.2177 -21.8247 -21.5257 -21.1497 -36.9445 -36.7426 4.41981 5.44927 -10.3996 -9.14118 -20.5689 -19.2792 -35.4584 -34.4403 -2.73171 -3.16517 -2.28635 -3.15265 -2.67968 -2.47327 -2.90633 -2.48644 -2.72282 -1.8784 -3.58639 -3.96783 -3.89286 - 2.98408 -3.23161 -2.9494 -2.89033 -1.98985 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8

....

Tabela 13 - Erros das distncias detectadas

114

Capitulo V - Anlise de Resultados


Neste teste verificamos que os erros so baixos tal como seria de esperar. De modo a termos uma viso mais ampla da reduo de erro de acordo com o aproximar do ngulo ao ngulo ptimo, construimos o grfico 1 e 2. Podemos verificar pela observao de ambos os grficos que os erros aumentaram de acordo com o esperado a no ser na posio para a qual espervamos menores erros. Isto deve-se ao facto de para esta posio tal como pode ser verificado nas imagens adquiridas, devido posio afastada das cmaras as imagens dos alvos aproximam-se mais da periferia o que leva a que possivelmente exista uma maior distoro na deteco desses pontos e consequentemente maiores erros na estimao de coordenadas 3D. No no entanto de eliminar a possibilidade de esses erros terem origem no algoritmo de deteco de pontos caracteristicos, que no se revelou to robusto como o esperado.

Erro Observado nas Medies 3D


6.00% 5.00% Erro (%) 4.00% 3.00% 2.00% 1.00% 0.00% 60 50 (cm)
Grfico 1 - Comparao de erros

T14 a T8 T14 a T11 T8 a T11 Q1 a Q2 Q2 a Q8 Q8 a Q7 Q7 a Q1 C1 a C2 C12 a C11 C11 a C1 T1 a T4

40

30

T4 a T7 T7 a T1

Mdia dos Erros Observados


4.50% 4.00% 3.50% Erro (%) 3.00% 2.50% 2.00% 1.50% 1.00% 0.50% 0.00% 60 50 (cm)
Grfico 2 - Comparao de erros em mdia

Mdia

40

30

A anlise destes dois grfico dos erros observados, comprovam que a ngulo ideal a que as cmaras devem encontrarem-se uma da outra 50 cm (para o suporte utilizado). A distncia exacta a que

115

Capitulo V - Anlise de Resultados


as cmaras deveriam estar afastadas uma da outres no foi possvel de ser determinada, devido ao facto do suporte no permitir uma maior flexibilidade em termos de distaciamentto entre cmaras.

4. - Influncia dos parmetros de calibrao


Verificamos que os valores de Cx e Cy apresentaram variaes considerveis para cada um dos testes efectuados o que pode ser parcialmente justificado pela fragilidade apresentada pelas cmaras em termos de capacidade de aquisio de imagens precisas e sem distoro. Para verficar qual a importncia do clculo correcto dos valores de Cx e Cy nos resultados das medies 3D finais, realizou-se um teste para a posio das cmaras que produz menos erros em mdia, com valores de Cx e Cy iguais ao centro de uma imagem adquirida na memria frame. Resultados obtidos na calibrao das duas cmaras:
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 calibrao das duas cmaras, na coluna da esquerda a calibrao referente a cmara da esquerda e na coluna da direita respectivamente a calibrao da outra cmara.

Atravs da anlise da tabela 14, verficamos que as matrizes de calibrao so diferentes do que aquelas obtidas utilizando um Cx e Cy correcto, sendo ainda de salientar que a distoro com estes valores cerca de dez vezes superior. Na tabela 15, so ilustradas as coordenadas 3D dos pontos de interseco caractersticos.
X coord 49.4372 57.4907 63.1788 71.2152 41.621 36.416 29.1086 -112.228 -107.095 -103.559 -98.0648 -117.43 -120.853 -125.899 -6.47495 -16.2607 8.15 Y coord -28.7403 -14.0337 -4.14289 10.3394 -13.4883 -3.61252 11.2199 -19.8334 -7.99389 0.575928 13.1299 -7.5214 1.14161 13.4359 11.3831 11.6363 -2.81267 Z coord -27.2825 -26.7645 -26.5515 -26.3891 -26.472 -26.0316 -25.4681 -69.4974 -64.9004 -62.2426 -58.9445 -72.0406 -73.7316 -76.3246 -28.8779 -30.5241 -27.7876 TAG T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 C1 C2 C3 ... -6.62114 -15.9161 -30.4494 8.39964 -6.3813 -16.1623 -30.2076 -6.49506 -15.7843 -48.9051 -82.8055 -49.0294 -82.474 -48.7868 -82.2401 -48.4287 -81.8822 -2.62256 -29.7171 -2.3257 -31.2922 -2.1005 -34.3713 -12.7674 -28.3051 -12.097 -30.2123 -11.7838 -31.8799 -11.5074 -34.8667 -26.5326 -31.0103 -26.1772 -32.597 12.3325 -38.4971 12.5571 -51.3826 -1.46443 -39.4237 -0.280756 -52.1245 -10.7978 -39.9181 -9.23362 -52.604 -24.1253 -40.5765 -22.2972 -53.2434 C4 C5 C6 C7 C8 C9 C10 C11 C12 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8

Tabela 15 - Coordenadas 3D obtidas para as interseces dos pontos caractersticos.

Analisando a tabela 15, verificam -se erros de em mdia 3,5 cm nas coordenadas 3D, em vez dos 1,3 mm obtidos em mdia 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 preciso, fundamental o clculo dos valores verdadeiros de Cx e Cy. De forma a determinar a influncia do valor do factor de incerteza horizontal sx,, nos resultados das medies 3D finais, realizou-se um teste para a posio das cmaras que produz menos erros em mdia, com um valores de sx igual a 1, isto , supondo que no h incerteza horizontal.

116

Capitulo V - Anlise 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 calibrao das duas cmaras, na coluna da esquerda a calibrao referente a cmara da esquerda e na coluna da direita respectivamente a calibrao da outra cmara. De notar que no resultado das calibraes a distncia focal alterou-se bastante relativamente aos valores obtidos quando se utiiza o valor aproximado relativamente s cmaras e frame grabber utilizado. 156.495 144.415 133.918 124.139 166.27 175.485 184.421 -4.54997 -11.8473 -18.8963 -26.2977 2.4412 8.80346 15.2426 94.7337 81.1929 109.874 -103.252 -79.3897 -58.8142 -39.5282 -95.3104 -83.2981 -69.4618 -79.4234 -67.7212 -53.9268 -42.5962 -63.6283 -50.134 -35.8954 -32.3678 -30.6742 -50.7963 108.806 77.196 56.1849 36.9941 131.636 146.159 154.129 22.2477 29.6909 31.2223 38.4669 17.1158 19.2958 16.0702 8.03116 0.356269 26.5209 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 C1 C2 C3 .... 94.9615 81.8987 68.2467 110.19 95.8543 82.1007 68.5585 96.1653 82.3148 54.7753 28.7599 55.4458 28.7951 55.554 29.4369 55.8762 29.4889

-45.737 -44.7797 -45.0953 -63.6035 -60.5239 -58.1205 -57.4127 -72.5464 -71.2791 -31.9086 -34.8657 -44.6268 -47.2818 -57.8012 -60.5736 -69.7757 -73.7645

7.13351 C4 3.60039 C5 3.6036 C6 22.2472 C7 10.7718 C8 2.49748 C9 -0.959401 C10 6.43343 C11 1.41275 C12 3.63526 Q1 12.419 Q2 1.77374 Q3 9.91794 Q4 0.222014 Q5 8.32518 Q6 -4.54825 Q7 6.14213 Q8

Tabela 17 - Coordenadas 3D obtidas para as interseces dos pontos caractersticos.

Como possvel observar atravs da tabela 17 as coordenadas 3D obtidas para os pontos de interseco caractersticos so altamente impresisos, chegando a haver erros na ordem dos 13 centmetros. Assim comprova-se que o clculo preciso tanto do sx como do Cx e Cy so fundamentais para se obter bons resultados na preciso do clculo de coordenadas 3D.

117

Captulo VI - Concluses e Trabalho Futuro

Captulo VI

Neste captulo feita uma discusso em termos de concluses gerais do que poder ser feito em termos de desenvolvimento do projecto e trabalho futuro, de modo a possibilitar a evoluo do projecto, atingindo melhores resultados (precises mais elevadas no clculo das coordenadas 3D dos pontos caractersticos), e aperfeioando tcnicas e algoritmos de modo a generalizar a utilizao do sistema e a torn-lo mais fivel e robusto. efectuada uma anlise critica do que poderia ser alterado em termos gerais de modo a optimizar o projecto desenvolvido.

1 - Pesquisa de Informao
A obteno de informao noutros centros de investigao, tal como o que foi efectuada no instituto de engenharia biomdica de Karlsruhe demonstrou ser de extrema importncia para definir rumos e estratgias de abordagem ao problema considerado. Essa importncia, deveu-se ao facto da experincia de trabalho em reas similares efectuado nos centros de investigao permitirem a definio de estratgias mais seguras, aprendendo com os trabalhos j efectuados nessa rea. Como trabalho futuro, poder ser implementada uma plataforma de disponibilizao da informao obtida sobre medicina nuclear e seus protocolos de aquisio, atravs de um portal Internet, que permitisse o acesso a esta informao a qualquer pessoa com interesse nesta rea, dando um passo para a concentrao de informao acerca deste tema num s local.

2 Etapas do projecto
O projecto desenvolvido atingiu os objectivos propostos excepo da realizao de exames em ambiente clnico uma vez que tal no foi possvel por questes de ordem de disponibilidade e condies de instalaes. A falta de realizao de exames clnicos e o recurso a fantomas para efectuar uma anlise em termos de funcionamento do sistema projectado em conjunto com a mquina SPECT, levaram a que o projecto no tomasse um carcter to prtico como poderia ter. As imagens resultantes da utilizao de fantomas poderiam fornecer informaes muito precisas acerca dos mtodos e algoritmos a implementar, para correco da degradao registada das imagens mdicas finais. Tal facto condicionou um pouco o projecto, uma vez que a falta de feedback em termos de utilizao por parte dos mdicos envolvidos no processo de aquisio SPECT levou a uma falta de sensibilidade em termos de aplicao, podendo esta no se encontrar (tal como est desenvolvida), completamente adaptada s necessidades inerentes ao objectivo fundamental do projecto, objectivo esse, a utilizao da fuso sensorial para corrigir artefactos introduzidos nos exames mdicos.

119

Captulo VI - Concluses e Trabalho Futuro


Ou seja o uso de informao de diferentes tipos no caso deste projecto a informao obtida pela mquina SPECT e a informao obtida pelo sistema de aquisio de imagem - pode trazer de facto grandes vantagens em termos de reduo de erros no diagnstico mdico bem como trazer vantagens tambm 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 aperfeioamento dos sistemas de aquisio de informao.

3 Abordagem Seguida
Verificamos que o pressuposto inerente aquisio simultnea de duas cmaras, em que os instantes de aquisio seriam sequenciais temporalmente, em intervalos bem definidos no tempo, poder no servir como mtodo directo de medio fivel. Isto acontece pois, pela anlise do modo como os exames so efectuados, constatamos que a aquisio da imagem realizada pela mquina SPECT efectuada por acumulao de contagens e no por aquisio instantnea, nem to pouco por acumulao em intervalos pequenos de tempo o que poderia ainda assim ser conveniente. No entanto a estimao de movimento poder ser efectuada se considerarmos a aquisio de vrias imagens do paciente por intervalo de tempo, efectuando-se uma medida estatstica do movimento a partir desse conjunto de imagens para cada intervalo de tempo. Assim usando modelos estatsticos podemos inferir o movimento efectuado adequando essa estimao ao nmero de contagens efectuadas por instante de tempo e obtendo assim um modelo mais complexo de estimao de movimento do que o considerado neste projecto. O desenvolvimento do sistema foi direccionado para cumprir objectivos de deteco de um alvo rgido colocado sobre o paciente detectando movimentos simples de rotao e translao no plano paralelo ao da aquisio por parte da mquina SPECT, no entanto esta abordagem poder ser generalizada de forma a fazer medio 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 informao do movimento do rgo em estudo. O uso de modelos deformveis afigura-se como forte oportunidade de servir os nossos propsitos de forma a obtermos um modelo do corpo, podendo mais facilmente inferir a posio de determinados rgos nesse modelo e consequentemente adaptar de uma forma mais precisa a estimao de movimento ao rgo em questo.

4 Equipamento Utilizado
As cmaras adquiridas demonstraram ter uma elevada distoro no linear apresentando tambm grandes diferenas entre si.

Como trabalho futuro poderemos fazer uso de cmaras que nos garantam maior preciso e menores distores e/ou tambm fazer uso de lentes mais precisas uma vez que poderamos assim obter uma maior preciso na aquisio de imagem, aumentando assim a preciso dos pontos detectados, quer no alvo de calibrao quer no alvo a colocar no o paciente, e consequentemente aumentando tambm a preciso do clculo das coordenadas 3D dos pontos caractersticos do alvo. Quando se efectua a aquisio em simultneo de imagens das duas cmaras verificamos que existe um tempo morto de cerca de 200 ms, que impossibilita que a aquisio seja perfeitamente simultnea.

Para evitar esta condicionante do sistema, as cmaras deveriam estar sincronizadas de forma a minimizar os tempos mortos entre aquisies simultneas ou deveramos usar um frame grabber que nos possibilitasse fazer a aquisio a partir de dois canais. O suporte das cmaras apresenta deficincias ao nvel de preciso de posicionamento entre cmaras, flexibilidade de alterao da posio das cmaras e medio dos ngulos formados entre cmaras. Devido a estes factores os testes realizados para

120

Captulo VI - Concluses e Trabalho Futuro


dimensionamento, das posies e ngulos das cmaras (factores determinantes nos clculos de preciso), foram fortemente condicionados. Como trabalho futuro, o suporte poder ser redimensionado e estruturado de forma a apresentarse como uma soluo flexvel para realizar testes laboratoriais que nos permitam identificar as fontes de erro de uma forma mais precisa. Assim o suporte dever permitir a medio dos ngulos entre as cmaras e o eixo que as une, variar as distncias entre cmaras de uma forma flexvel mas precisa e que possua uma base mais estvel de modo a no ser to susceptvel de alteraes de posio devido a movimentaes junto do suporte. O frame grabber utilizado introduz fitas negras nas imagens adquiridas, devido adaptao das dimenses das imagens e do buffer do frame grabber o que degrada a implementao dos algoritmos de deteco de pontos quer para o alvo de calibrao quer para o alvo a colocar sobre o paciente.

O uso de um frame grabber mais evoludo poder eliminar estas lacuna evitando os tempos mortos entre mudanas de canais e uma maior despreocupao com factores externos s imagens no desenvolvimento dos algoritmos. O alvo de calibrao demonstrou ter imperfeies no alinhamento e tamanho dos quadrados impressos, demonstrando que a qualidade de impresso no foi a melhor.

O alvo de calibrao dever ser manufacturado e impresso num material que nos garanta preciso, de modo a que os resultados da calibrao no sejam afectadas priori por erros do prprio alvo de calibrao.

5 - Algoritmos desenvolvidos
O algoritmo de deteco de pontos do alvo a colocar sobre o paciente para deteco de pontos caractersticos, apresenta algumas lacunas importantes em termos de preciso. Para alm disso existe a necessidade de alterar parmetros de deteco frequentemente, de acordo com os diferentes datasets de imagem. O algoritmo implementado est limitado deteco de alvos com um nmero pr-determinado de figuras geomtricas a detectar.

A reviso do algoritmo utilizado ou alterao da abordagem para deteco dos pontos poderia trazer melhorias na deteco do pontos aumentando assim a preciso com que se efectuam os clculos das coordenadas 3D desses mesmos pontos. Uma maior automatizao do algoritmo traria benefcios para o utilizador. O algoritmo dever ser alterado de forma a ser capaz de detectar e emparelhar as figuras geomtricas em duas imagens distintas, independentemente da ordem pela qual as figuras geomtricas se apresentem nas duas imagens. O algoritmo deveria ser capaz de identificar zonas correspondentes nas duas imagens, e de seguida identificar as figuras geomtricas e seus pontos caractersticos nas duas imagens. Com isto, seria possvel fazer-se um dimensionamento de um alvo de deteco que se adapta a toda a superfcie 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 aquisio stereo apresenta-se como responsvel pela presena de pequenos artefactos nas imagens podendo deteriorar a determinao dos parmetros de calibrao e das coordenadas dos pontos tridimensionais do alvo a colocar sobre o paciente.

Poderia ser efectuada uma anlise mais profunda da influncia de factores externos nos parmetros de configurao do sistema de aquisio, de forma a poder aferir se esta influncia afecta, e de que forma, a preciso dos clculos efectuados.

121

Captulo VI - Concluses e Trabalho Futuro


A deteco do sinal de trigger para activao do evento de aquisio de imagens efectuada atravs da porta srie tendo sido usado um boto de presso para simulao de evento. No foi no entanto comprovado a executabilidade deste mecanismo em exame clnico.

A verificao da executabilidade de tal aco torna - se assim indispensvel, atravs do conhecimento mais detalhado acerca das mquinas utilizadas para efectuar os exames SPECT planar, junto dos fabricantes se possvel, de forma a verificar se no seria possvel extrair um sinal de trigger da prpria mquina SPECT planar. A verificao da funcionalidade do mdulo de estimao de movimento foi verificada para o algoritmo com valores simulados e no ser validada em ambiente laboratorial uma vez que no existiam condies para a medio com o mnimo de preciso dos valores de translao e de rotao. Tambm no foi possvel a realizao da correco de imagens mdicas, devido ao facto de nao se ter realizado nenhuma aquisio de imagens estereoscopicas simultaneamente com um exame do tipo SPECT planar.

Dever ser feito uso de esquemas de medio das alteraes em termos de posio efectuadas sobre o alvo de forma a possuirmos uma ferramenta que nos permitisse verificar a funcionalidade do mdulo de calibrao de uma forma prtica. Dever ser feita uma aquisio simultnea destes dois tipos de sistemas.

122

Bibliografia

Publicaes
[Alves, 1994] - Jorge Silva Aquisio e Processamento de Informao 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. Dssel 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] - Franois 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

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 Cincias de Computao

124

[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] - Joo Tavares Obteno de Estrutura Tridimensional a Partir de Movimento de Cmara Faculdade de Engenharia da Universidade do Porto [Tavares2, 1995] - Joo Tavares Algumas Ferramentas para Viso 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 Offthe-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

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

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

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 fr 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

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

ANEXO

Manual do Utilizador

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

ANEXO

Caractersticas das Cmaras

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos


Caracteristicas Tipo Elemento sensor Nmero de pixels Tamanho da clula Sistema de cinsronizao Sistema de scan Resoluo S/N ratio Caracteristica gama Minimo de iluminao IRIS Electrnico Sada video Tenso de alimentao Corrente Dimenses Peso Valores TC-5011 Sensor CCD de 1/3 de polegada CCIR 500(H) x 582 (V) CCIR 9.8 mm(H) x 6.3 mm(V) Interno 2:1 entrelaado 420 linhas horizontais de TV Mais de 46 dB (AGC off) GAMMA = 0.45 0.2 Lux F1.4 IRIS CCD 1Vp~p 75 W DC 12 V 120 mA 39 (W) x 43 (H) x 72 (L) mm 150 g

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

ANEXO

Caractersticas do Frame Grabber

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos


MATROX METEOR I Esquema bsico:

Entrada Composta

Composto 1 / R Composto 2 / G Composto 3 / B Composto 4 / Sync Entrada S-Video ouTrigger

Software: Matrox imaging library(MIL-Lite) - uma biblioteca de alto nvel em c com comandos para aquisio, transferncia e display de imagem. Especificaes: Entrada video seleccionvel por software.(4 canais) Luminosidade, contraste,tonalidade e saturao programveis. Video cor standard ou monocromtico: NTSC/PAL/SECAM, RS-170/CCIR, Composto ou Y/C Jitter de pixel: 3ns (tipicamente)

Capacidade de transferncia 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).

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos


Conectores: DB-9 fmea. S-VHS. Phono. Caracteristicas: Consumo < 7.5 Watts Tamanho da placa: 23.55 cm x 10.55 cm Temperatura de operao de 0 a 55 C Humidade relativa: at 95% (no condensvel)

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

ANEXO

Transformaes Geomtricas em 2D e 3D

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Transformaes Geomtricas em 2D
Translao
A translao de pontos que se encontrem no plano (x, y) efectuada atravs da soma de quantidades de translao s suas coordenadas. x' = x + tx , y' = y + ty ou

x' x t x y ' = y + t y

Rotao
A rotao dos pontos de um objecto de um ngulo q consiste em alterar as coordenadas de cada ponto do objecto substituindo-as por uma funo pesada das coordenadas anteriores, em que o peso depende de q. x' = x*cosq - y*senq, y' = x*sen q + y*cosq ou

x' cos y ' = sen


Nota:

- sen x * cos y

ngulos de rotao positivos so medidos segundo o sentido contrrio dos ponteiros do relgio, para ngulos negativos o sentido o dos ponteiros do relgio. A rotao efectuada em torno da origem do referencial podendo no entanto ser efectuada em torno de um ponto arbitrrio.

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

x' sx y ' = 0

0 x * sy y

Nota: Se sx e sy forem diferentes obteremos um objecto com propores alteradas. O escalonamento feito em relao origem do referencial, fazendo com que o ponto se afaste ou aproxime do referencial, podendo no entanto ser efectuado em relao a um ponto arbitrrio.

Distoro

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos


A distoro consiste na alterao das coordenadas de cada ponto do objecto substituindo-as por uma funo pesada das coordenadas anteriores. x' = x*d1 + y*d2 , y' = x*d3 + y*d4 ou

x' d1 y ' = d 3

d2 x * d4 y

Nota: Pode-se transladar, escalonar, rodar ou efectuar outras operaes a um objecto efectuando a operao nos pontos extremos de cada segmento de recta que o compe de forma a no ter que efectuar a operao no objecto ponto por ponto, minimizando o tempo de processamento.

Equaes homogneas
Uma vez que a translao envolve a operao adio enquanto as restantes envolvem a operao multiplicao torna-se impossvel representar um conjunto de operaes numa s matriz. Assim de modo a podermos representar todas as transformaes pelo mesmo tipo de operao representamos os pontos nas suas coordenadas homogneas. Assim em coordenadas homogneas 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 homogneas representam o mesmo ponto se umas so mltiplas das outras, ou seja cada ponto tem em coordenadas homogneas vrias representaes possveis. Pelo menos uma das coordenadas homogneas do ponto tem de ser diferente de zero. Dividindo as coordenadas x e y pela terceira coordenada homognea obtemos as coordenadas cartesianas do ponto homogneo. Os pontos que possuam w = 0 so apelidados de pontos no infinito. Todas as representaes de um ponto homogneo formam uma recta no espao 3D que passa na origem , para cada w=c ,"c encontramos um plano de definio do espao 2D As operaes anteriormente demonstradas passam a ser representadas em coordenadas homogneas do seguinte modo: ____________________________________________________________________

Translao
x' 1 0 t x y ' = 0 1 t y 1 0 0 1
Nota: A translao tem a propriedade aditiva, isto : Se

x * y 1

x' 1 0 t x y ' = 0 1 t y 1 0 0 1

x * y 1

e ento

x' ' 1 0 t 'x y ' ' = 0 1 t ' y 1 0 0 1

x' * y ' 1

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

x' ' 1 0 t 'x y ' ' = 0 1 t ' y 1 0 0 1

____________________________________________________________________

1 0 tx 0 1 t y 0 0 1

x * y 1

x' 1 0 t x + t 'x y ' = 0 1 t + t ' y y 1 0 0 1

x * y 1

Rotao
x' cos y ' = sen 1 0 x' cos y ' = sen 1 0 - sen 0 x cos 0 * y 0 1 1 - sen 0 x cos 0 * y 0 1 1 x' ' cos - sen 0 x' y ' ' = sen cos 0 * y ' 1 0 0 1 1

A rotao tem a propriedade aditiva, isto : Se e ento

____________________________________________________________________ Escalonamento

x' ' cos - sen 0 cos - sen 0 x y ' ' = sen cos 0 sen cos 0 * y 1 0 0 1 0 0 1 1 x' cos ( + ) - sen( + ) 0 x y ' = sen( + ) cos ( + ) 0 * y 1 0 0 1 1

x' sx y ' = 0 1 0
Nota:

0 sy 0

0 x 0 * y 1 1

O escalonamento tem a propriedade multiplicativa, isto : Se

x' sx y ' = 0 1 0 0 s' y 0 0 0 1

0 sy 0 sx 0 0

0 x 0 * y 1 1 0 sy 0

e Ento

x' ' s'x y ' ' = 0 1 0

0 s' y 0

0 x' 0 * y ' 1 1 0 s ' y .s y 0 0 x 0 * y 1 1

x' ' s'x y ' ' = 0 1 0

0 x 0 * y 1 1

x' s 'x .s x y ' = 0 1 0

____________________________________________________________________

Distoro

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

x' d1 y ' = d 3 1 0

d2 d4 0

0 x 0 * y 1 1

Composio de transformaes geomtricas


A combinao das matrizes representativas das transformaes fundamentais pode ser efectuada aumentando assim a eficincia pela aplicao de uma transformao composta a um ponto, em vez da aplicao de uma srie de transformaes uma aps a outra. Exemplo: Rotao de um objecto em torno de um ponto arbitrrio. 1) Translao de modo que o ponto arbitrrio se localize na origem. 2) Rotao. 3) Translao de modo que o ponto arbitrrio retorne sua posio original. Sendo P(x1, y1)

x' 1 0 y ' = 0 1 1 0 0 x' y ' = 1


Nota:

cos - sen 0 sen cos 0 0 0 1 cos - sen x1 .(1 - cos ) + x1 y1 1 sen 0 cos 0

1 0 - x1 x 0 1 - y1 * y 0 0 1 1

y1 .sen x y1 .(1 - cos ) - x1 .sen * y 1 1

Para o escalonamento possvel faz-lo em relao a um ponto arbitrrio seguindo o mesmo procedimento adaptado ao escalonamento. No geral a multiplicao de matrizes de transformaes geomtricas no comutativa.

Transformaes geomtricas em 3D
Em coordenadas homogneas tal como em 2D podemos representar as transformaes por uma matriz de 3x3 em 3D podemos representlas numa matriz de 4x4. Os pontos so representados por um qudruplo em vez de um triplo. (x, y, z) (x, y, z, w) Dois conjuntos de pontos em coordenadas homogneas representam o mesmo ponto se umas so mltiplas das outras, ou seja cada ponto tem em coordenadas homogneas vrias representaes possveis. Pelo menos uma das coordenadas homogneas do ponto tem de ser diferente de zero. Dividindo as coordenadas x, y ez pela quarta coordenada homognea obtemos as coordenadas cartesianas do ponto homogneo. Os pontos que possuam w = 0 so apelidados de pontos no infinito. Todas as representaes de um ponto homogneo formam uma recta no espao 4D que passa na origem , para cada w =c ,"c encontramos um subespao de definio do espao 3D.

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos


Utilizamos o sistema de coordenadas da mo direita. Podemos verificar o sentido positivo das rotaes pela figura

x z

A transformao de coordenadas efectuada assim da seguinte forma:

x' x y ' = M. y z' z

Em que M a matriz representativa das transformaes bsicas em 3D , que so:

Translao

1 0 0 0

0 1 0 0

0 tx 0 ty 1 tz 0 1

Rotao
Em torno do eixo dos z Em torno do eixo dos y

cos sen 0 0 cos 0 - sen 0

- sen 0 0 cos 0 0 0 1 0 0 0 1 0 sen 0 1 0 0 0 cos 0 0 0 1

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos Em torno do eixo dos x


Escalonamento

1 0 0 cos 0 sen 0 0 0 0 sz 0 d3 d6 d9 0 0 0 0 1 0 0 0 1

0 - sen cos 0

0 0 0 1

Distoro

sx 0 0 0 d1 d4 d7 0

0 sy 0 0 d2 d5 d8 0

O resultado da multiplicao destes 3 tipos de matrizes ter a forma:

r11 r21 r31 0

r12 r22 r32 0

r13 r23 r33 0

tx ty tz 1

De modo a aumentar a eficincia computacional podemos fazer os clculos usando a seguinte notao:

x' x r11 y ' = R* y + T , onde R = r 21 z' z r31

r12 r22 r32

Nota: A composio de transformaes em 3D segue a mesma perspectiva que em 2D, ou seja divide-se o problema original em sub - problemas nos quais se utilizam as transformaes primitivas .

t x r13 r23 e T = t y t r33 z

Outras transformaes geomtricas em 3D


Transformao projeco

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos


Tudo se passa como se o observador projectasse a cena ou o objecto segundo uma direco paralela direco de projeco sobre um plano que perpendicular respectiva direco de projeco. Neste caso o centro de projeco localiza-se no infinito. Projeco segundo direco x

0 0 0 0

0 1 0 0

0 0 1 0

0 0 0 1

P (x, y, z)

Projeco segundo direco y

1 0 0 0

0 0 0 0

0 0 1 0

0 0 0 1

P (x, y, z)

Projeco segundo direco z

1 0 0 0

0 1 0 0

0 0 0 0

0 0 0 1

P (x, y, z)

Transformao projeco perspectiva


No caso de transformao perspectiva o centro de projeco no se localiza no infinito mas sim a uma distncia d do plano de projeco. Uma vez que este tipo de projeco no tem interesse directo para o projecto limitamo-nos a referir a sua existncia.

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

ANEXO

Exemplo de um Exame SPECT Planar

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Exemplo de imagens obtidas por exame SPECT Planar ( Rins)


Imagens numeradas em sequncia

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

ANEXO

Radionuclidos

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

1 - Radionuclidos
A qualidade de controlo dos rdiofarmacos feita atravs da anlise destes quatro itens: esterilidade, pureza qumica, pureza do radionuclido e pureza radioquimica.

1.1- Esterilidade
O gerador e o kit do produto so testados para esterilidade e pirognios pelo fabricante durante a produo. Os pirognios so endotoxinas bacteriais que produzem um estado febril. O teste de limulus utilizado para detectar a presena de pirognios. Os testes usam um agente derivado do sangue dos cravos de ferradura (limulus polyphemus). O limulus extrado forma um gel quando misturado com endotoxinas.

1.2- Pureza quimica


O alumnio (Al+3) um contaminante qumico que pode ser encontrado na soluo de Technetium, mas isso muito raramente um problema nos geradores actuais. O alumnio pode interferir com algumas reaces etiquetveis. A USP (United States Pharmacopeia) limita a quantidade de alumnio 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 emisses beta resultam numa dose muito elevada de radiao 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 so de menos importncia clnica incluem Nb-92 , Nb-95 e Zr-95. No Mo-99 produzido por irradiao de neutres, sendo que as impurezas mais comuns so Cs134,Co-60, Rb-86 e Sb-124.

1.4-Pureza radioquimica
As impurezas radioqumicas so os compostos de Tc-99m que no os desejados para uso radiofarmacutico. Existem sempre alguns no etiquetados Tc-pertechnate bem como technetium colloids no solveis.

1.5 - Tabela com radioistopos e aplicaes correntes

Rdioisotopo

Meia-Vida (Half-Life) 10.0d

Aplicaes

Ac-225

Acessrio monoclonal do anticorpo usado para o tratamento do cancro (RIT), tambm parente de Bi-213. Parente de Ra-223 (Acessrio monoclonal do anticorpo usado para o tratamento do cancro (RIT) ). Deteco de osteoporose, visionamento do corao

Ac-227

21.8a

Am-241

432a

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

As-72 As-74 At-211

26.0h 17.8d 7.21h

Visualizao planar, SPECT ou PET. Istopo emissor de positres com aplicaes biomdicas. Acessrio monoclonal do anticorpo (emissor alfa) usado para o tratamento do (RIT), usado com F-18 para estudos in vivo. Tratamento do cancro usando mini-gun (B), tratamento de cancro dos ovrios, prostata, ecrebro. Tratamento de melanoma e tumor de crebro. Usado no estudo da berylliosis. Acessrio monoclonal do anticorpo (emissor alfa) usado para o tratamento do (RIT), estudo de dosimetria celular. Acessrio monoclonal do anticorpo (emissor alfa) usado para o tratamento do (RIT), Visualizao planar , SPECT ou PET (C). Etiqueta radiosentizers para a quantizao de Te da hypoxia em tumores, e etiquetagem monoclonal do anticorpo. Radioistopo em PET para estudar funes cerebrais normais ou anormais. Etiquetagem isotpica para deteco de tumores (breast, et al.).

Au-198

2.69d

B-11 Be-7 Bi-212

Estvel 53.2d 1.10h

Bi-213

45.6m

Br-75 Br-77

98m 57h

C-11

20.3m

C-14 Ca-48 Cd-109 Ce-139 Ce-141

5730y Estvel 462d 138d 32.5d

Deteco de cancro, visualizao peditrica Calibra detectores de germnio de elevada. Diagnstico de tracto gastrointestinal, medio de fluxo sanguineo do miocrdio. Tratamento de cancro cervical, melanoma e crebro . Visualizao planar SPECT ou PET. Usado em PET para visualizao de tecidos cerebrais danificados aps . Calibrao de cmara gama, deve ser dada alta prioridade,

Cf-252 Co-55

2.64a 17.5h

Co-57

272d

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

para raio-X . Co-60 5.27a Teleterapia(destri clulas cancerosas), desinfeco de equipamento cirurgico e mdico, terapia externa por raiao para o cancro . Mdica, dosimetria, etiquetagem de clulas Agente localizador miocrdico Implantes intercavitais para radioterapia. Irradiadores de sangue, visualizao PET, tratamento de tumores. Visualizao planar, SPECT ou PET Radionuclido emissor de positro, usado como radioistopo em conjuno com Cu 64 em fluxo sanguineo do miocrdio e crebro Visualizao PET, visualizao planar, visualizao SPECT, estudos de dosimetria, fluxo sanguneo de crebro e miocrdio, usado com Cu 62 tratamento de cancro colorectal. Tratamento/diagnstico de cancro, monoclonal de anticorpos, radioimunoterapia, visualizao planar, SPECT ou PET. Sinovectomia de radiao, tratamento de artrite reumatoidal. Mdica. Deteco de osteoporose. Radioistopo para o crebro, estudos PET. Fonte de aquecimento. Mdica. Tratamento de doenas pulmonares (fibrose dos pulmes). Visualizao de infeces abdominais, deteco de linfoma de Hodgkins, usado com In-111 para infec~oes de tecidos moles e deteco de osteomelite, avaliao de doenas granulosas tais como a sarcoidiodis e outros, particularmente pulmes e mediastiusim .

Cr-51 Cs-130 Cs-131 Cs-137

27.7d 29.2m 9.69d 30.2a

Cu-61 Cu-62

3.35h 4.7m

Cu-64

12.7h

Cu-67

61.9h

Dy-165 Eu-152 Eu-155 F-18 Fe-55 Fe-59 Ga-64 Ga-67

2.33h 13.4a 4.73a 110m 2.73a 44.5d 2.63m 78.3h

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Ga-68

68.1m

Estudo de tromboses e artereoesclerose, visualizao PET, deteco de cancro pancretico correco de atenuao. Fonte dual de fotes, deteco de osteoporose, visualizao SPECT. Visualizao PET. Visualizao PET, etiquetagem. Estudo de fluxo sanguneo cerebral Visualizao de crebro, tiride, rim e miocrdio, fluxo sanguneo cerebral, doenas neurolgicas. Radioistopo usado para criar imagens da tiride humana, visualizao PET. Deteco da osteoporose, visualizao diagnstica, localizador para drogas, anticorpos monoclonais, tratamento de cancro cerebral(substituto de I-131),visualizao SPECT,etiquetagem com radiao, visualizao de tumores, mapeamento de receptores cerebrais, terapia de radiao intersticial para tratamento do cancro da prstata. Tratamento de tumor /hipertiroidismo de tecidos linfticos, etiquetagem de anticorpos, bioquimica cerebral em doenas mentais, agente renal, problemas da tiride, alternativa ao Tl-201 para radioimunoterapia , visualizao, dosimetria celular, cintilografia, , tratamento da doena de Graves, tratamento de goiters, visualizao SPECT, tratamento do cancro da prstata, tratamento de melanoma, localizao de infeces de osteomyelitis, etiquetagem radioactiva, localizao de tumores para remoo, tratemnto de tumores espinais, localizaao de leses metastticas , terapia de radiao interna, trataemnto do carcinoma da tiride. Mapeamento preciso de regio do tumor cerebral antes de operao. Deteco de rejeio de transplante do corao, visualizao de infeces abdominais, etiquetagem de anticorpos, , imunologia celular, usado com Ga-67 para deteco de infeces de tecidos moles e ostemyelitis , concentrao no figado, rins,alta actividade especifica, visualizao de clulas brancas sanguineas, dosimetria celular, visualizao do miocrdio, tratamento da leucemia, visualizao de tumores Etiquetagem de elementos sanguineos para avaliao da doena inflamatria de Bowel.

Gd-153

242d

Ge-68 H-3 I-122 I-123

271d 12.3a 3.6m 13.1h

I-124

4.17d

I-125

59.9d

I-131

8.04d

I-132

2.28h

In-111

2.81d

In-115m

4.49h

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Ir-191m Ir-192

6s 73.8d

Angiografia cardiovascular. Implante de sementes para o tratamento do cancro da prstata, crebro, mama, e ginecolgico. Visualizao pulmonar. Tratamento de doena do corao, terapia de cancro. Agente localizador do miocrdio. Visualizao PET Parente de gerador Tc-99m usado para crebro, pulmes, fgado e visualizao do corao. Visualizao PET, perfuso do miocrdio. Estudos do efeito de radioactividade em grvidas e fetos, localizador do miocrdio, visualizao PET. gua usada para medies tomogrficas do fluxo sanguneo cerebral, visualizao PET e SPECT. Parente do gerador Ir-191m para angiografia cardiovascular. Acessrio monoclonal do anticorpo (emissor alfa) usado para o tratamento do (RIT Polycythaemia Rubra Vera (doena de clulas sanguneas) e leucemia, tratamento / diagnstico de doenas dos ossos, visualizao SPECT de tumores, tratamento do cancro do pncreas etiquetagem radioactiva. Etiquetagem Visualizao planar, SPECT ou PET (usado com Bi-212), imunoterapia de anticorpos monoclonais, dosimetria celular. Etiquetagem radioactiva para terapia usando anticorpos, dosimetria celular. Tratamento do cancro da prstata. Agente radioterapeutico potencial.

Kr-81m Lu-177 Mn-51 Mn-52 Mo-99

13.3s 6.68d 46.2m 5.59d 65.9h

N-13 Nb-95

9.97m 35d

O-15

122s

Os-191 Os-194

15.4d 6.00a

P-32

14.3d

P-33 Pb-203

25d 2.16d

Pb-212

10.6h

Pd-103 Pd-109

17d 13.4h

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Pu-238 Ra-223

2.3a 11.4d

Pacemaker (sem contaminantes Pu-236). Acessrio monoclonal do anticorpo (emissor alfa) usado para o tratamento do (RIT), estudo de dosimetria celular. Istopo alvo para fazer Ac-227, Th-228, Th-229 (Parentes deemissores alfa usado para o RIT). Agente de visualizao do miocrdio, deteco precoce de doenas da artria coronria , visualizao PET, localizadores de fluxo sanguineo. Tratamento/ diagnstico de cancro, anticorpos monoclonais, alivio de dor de cancro dos ossos, tratamento de artrite reumatoidal, tratamento do cancro da prstata, tratamento da dor de ossos. Tratamento de cancro , anticorpos monoclonais. Aplicaes terapeuticas potenciais: etiquetagem de molculas e anticorpos monoclonais. Etiquetaghem de anticorpos monoclonais, visualizao planar, SPECT ou PET, visualizao por cmara gama. Fluxo sanguneo do miocrdio, etiquetagem radioactiva de microesferas, visualizao PET. Etiquetagem de cidos nucleicos,substituoto de P-32, dosimetria celular. Estudos de fluxo sanguneos locais, visualizao PET. Tratamento / diagnstico do cancro, anticorpos monoclonais, radioimunoterapia. Visualizao do crebro, sistema gerador com As-72, anticorpo monoclonal. Localizador radioactivo usado em estudos cerebrais, visualizao por cintilografia. Terapia por radiao do cancro. Tratamento do cancro do crebro usando I-127 (D).

Ra-226

1.60e3a

Rb-82

1.27m

Re-186

3.9d

Re-188 Rh-105

17h 35.4h

Ru-97

2.89d

Ru-103

39d

S-35

87.2d

Sc-46 Sc-47

84d 3.34d

Se-72

8.4d

Se-75

120d

Si-28 Sm-145 Sm-153

Estvel 340d 2.00d

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

alivio de dor de cancro dos ossos, tratamento de leucemia. Sn-117m Sr-85 Sr-89 13.6d 65.0d 50d Alivio de dor do cancro dos ossos. Visualizao cerebral, deteco de leses cerebrais focais. Paliao da dor do cancro dos ossos, dosimetria celular, myeloma ,tratamento do cancro da prstata,, tratamento de myeloma multipla, terapia osteoblastica , agente potencial para tratamento de metstases do cancro da prstata e mamas. Sistema gerador com Y-90 , imunoterapia com anticorpos monoclonais. Radionuclido injectado nos pacientes para permitir a visualizao das veias e do corao. Fonte fluorescente de raio-X. Tratamento do cancro da bexiga, implantes internos. Acessrio monoclonal do anticorpo usado para o tratamento do cancro (RIT), tambm parente de Bi-213. Estudos em animais com Tc-99m. Visualizao do crebro, corao, fgado, pulmes, ossos, tiride, e rins, fluxo sanguneo cerebral local, anticorpos, clulas sanguneas vermelhas, substituto de Tl-201. Tratamento do cancro, anticorpos monoclonais, parente de Bi212. Parente para emissor alfa (Bi-213) usado para tyratamento de cancro (RIT), parente de Ac-225. Radiologia clnica, visualizao do corao, caracteristicas nucleares menos desejveis que Tc-99m opara SPECT e SPECT planar, perfuso do miocrdio, dosimetria celular. Irradiaes sanguneas portveis para leucemia, tratamento de linfoma, fonte de potncia. Mdica. Tratamento de cancro, anticorpos monoclonais, parente para gerador de Re-188.

Sr-90

29.1a

Ta-178

9.3m

Ta-179 Ta-182 Tb-149

1.8a 115d 4.13h

Tc-96 Tc-99m

4.3d 6.01h

Th-228

720d

Th-229

7300a

Tl-201

73.1h

Tm-170

129d

Tm-171 W-188

1.9a 69.4d

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Xe-127

36.4d

Visualizao neuronal para alteraes cerebrais, investigao para alteraes neuropsiquiatricas, especialmente esquizofrenia e demncia, resolues SPECT superiores com menores doses para o paciente, visualizao de pulmes. Visualizao de pulmes, fluxo sanguneo cerebral local ,visualizao de fgado, visualizao SPECT do crebro, visualizao dos pulmes, deteco de leses. Substituto para Y-90 no desenvolvimento de terapia para tumores cancergenos. Terapia radioactiva interna de cancro do fgado, anticorpos monoclonais, doena de Hodgkins e hepatoma, dosimetria celular, tratamento de artrite reumatoidal,, tratamento de cancro da mama, tratamento de adenocarcinomas gastrointestinal . Tratamento do cancro (RIT), dosimetria celular.. Diagnstico do trato gastro intestinal Parente de Cu-62, um emissor de positres, usado para o estudo de fluxo sanguineo cerebral e miocardial. Mdica. Mdica.

Xe-133

5.25d

Y-88

107d

Y-90

64h

Y-91 Yb-169 Zn-62

58.5d 32d 9.22h

Zn-65 Zr-95

244d 64.0d

Anexo A Manual do Utilizador Anexo B - Caractersticas da cmara Anexo C - Caractersticas do frame grabber Anexo D - Transformaes geomtricas em 2D e 3D Anexo E - Exemplo de imagens obtidas por exame SPECT planar Anexo F - Radionuclidos Anexo G - Cdigo implementado

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

ANEXO

VPA - Vision Processing Application

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Introduo
Este manual destina-se a servir como base de suporte utilizao da aplicao desenvolvida no mbito do projecto final de curso - PD77 Alinhamento de imagens de medicina nuclear do curso de Engenharia Electrotcnica e de Computadores da Faculdade de Engenharia da Universidade do Porto. Este manual no fornece as bases tericas adjacentes s funcionalidades implementadas, tentando apenas fornecer uma viso dos mdulos existentes e das capacidades de cada mdulo no que concerne a resolver o tipo de situaes que esto na origem da sua criao. Assim se restarem dvidas acerca do modo de funcionamento de algum mdulo ser necessrio consultar o relatrio final do projecto PD 77.

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

ndice Mdulo I - Aquisio


1.1 - Opes de aquisio 1.2 - Grab 1.3 - Aquisio 1.4 - Progresso 1.5 - Informao

Mdulo II - Calibrao
2.1 - Simulao de uma Cmara de Geometria Interna Conhecida 2.2 - Deteco de Pontos de Calibrao na Memria frame. 2.3 - Formatao dos Pontos de Calibrao Considerados 2.4 - Calibrao de uma Cmara

Mdulo III - Deteco de Entidades e clculo de coordenadas 3D


3.1 - Inicializao 3.2 - Deteco de Pontos Caractersticos e Emparelhamento 3.3 - Obteno de Informao Tridimensional

Mdulo IV - Estimao e correco de movimento


4.1 - Estimao e Correco

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Mdulo I - Aquisio
1.1 - Opes de aquisio
A aquisio a partir de uma cmara ligada ao frame grabber envolve uma quantidade de parmetros de configurao considerveis. Parmetros estes que podem ser configurados na aplicao antes de se realizar a aquisio, de modo a que esta tenha as caractersticas adaptadas ao sistema usado. 1) Nmero de cmaras 2) Canal associado a cada cmara 3) Tipo de sinal vdeo a captar 4) Tipo de imagem a captar 5) Modo de display 6)Escala a utilizar na aquisio 7) Comentrios a anexar aos ficheiros do tipo .BMP 8) Formato de gravao de sequncia de imagens 9) Taxa de compresso de sequncia de imagens, em formato AVI-MPEG 10) Formato de gravao das imagens

1) Nmero de cmaras Define o nmero de cmaras a utilizar quando for efectuada a aquisio. Opes: 1 - Aquisio usando uma cmara. 2 - Aquisio usando duas cmaras. 2) Canal associado a cada cmara Define o canal da placa de aquisio a utilizar para ca da cmara utilizada. Opes: CH1 - Canal 1 da placa de aquisio. CH2 - Canal 2 da placa de aquisio. CH3 - Canal 3 da placa de aquisio. CH4 - Canal 4 da placa de aquisio. 3) Tipo de sinal vdeo a captar Define o tipo de sinal vdeo a captar pela cmara ou cmaras escolhidas. Quando seleccionada aquisio com duas cmaras em 1) - ambas as cmaras tero que ter o mesmo tipo de sinal vdeo. O tipo de sinal vdeo depende da escolha em 4) se esta for RGB teremos tipos de sinal vdeo diferentes dos que encontramos com a opo GRAY. Opes: Se 4) em RGB NTSC PAL

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos


SECAM Se 4) em GRAY CCIR RS-170 4) Tipo de imagem a captar Define o tipo de imagem a captar, o que por sua vez depende tambm do tipo de cmara utilizada, a cores ou monocromtica. Opes: RGB - Aquisio de imagem a cores. GRAY - Aquisio de imagem monocromtica. 5) Modo de display Define o tipo de display a utilizar, variando com o tipo de display a velocidade de refrescamento da imagem e a qualidade da mesma para aquisio a cores. Opes: BASIC - este modo no h otimizao de velocidade em imagens a cores, o que pode resultar numa performance mais lenta. BASIC OPTIMIZED - este modo faz uso de um algoritmo que permite aumentar a velocidade de visualizao em imagens a cores. ENHANCED - este modo faz uso de dithering melhorando particularmente o display de imagens a cores. 6) Escala a utilizar na aquisio Define a escala da imagem a adquirir. Opes: NORMAL - imagem adquirida em formato 768 x 576 pixels. HALF - imagem adquirida em formato 384 x 288 pixels . QUARTER - imagem adquirida em formato 192 x 144 pixels . 7) Comentrios a anexar aos ficheiros do tipo .BMP Define comentrio a anexar s imagens adquiridas, de modo a referenciar as mesmas. Esta opo s se encontra activa para aquisio de imagem em formato .BMP. 8) Formato de gravao de sequncia de imagens Define o formato da imagem adquirida para gravao da mesma em disco. Opes: AVI-DIB - formato de sequncia de imagens .avi no comprimido. AVI-MJPG - formato de sequncia de imagens .avi comprimido. 9) Taxa de compresso de sequncia de imagens, em formato AVI-MPEG Define a taxa de compresso , que pode variar entre 1 e 99, utilizada na gravao da sequncia de imagens do tipo .avi comprimido encontrando-se activo apenas no caso da opo AVI-MJPG se encontrar seleccionada em 8).

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

10) Formato de gravao das imagens Define o formato da imagem adquirida para gravao da mesma em disco. Opes: BMP - formato TIFF - formato MIL - formato

1.2 - Grab
Este mdulo permite alterar as referncias da placa de aquisio no que concerne ao brilho, contraste, saturao e tonalidade das imagens adquiridas. E adquirir e visualizar imagens em qualquer dos canais do fram grabber. 1) Zoom in 2) Zoom out 3) Aquisio de imagem 4) Visualizao 5) Canal 6) Selectores de propriedades de imagem

1) Zoom in Cada vez que pressionado efectua um zoom imagem duplicando o seu tamanho. 2) Zoom out Cada vez que pressionado efectua um zoom imagem diminuindo o seu tamanho para metade do tamanho actual. 3) Aquisio de imagem Efectua a aquisio da imagem que se encontrar activa na janela de aquisio gravando de imediato a imagem para um ficheiro em disco com o formato de imagem seleccionado em 9) do Mdulo de aquisio- Opes de aquisio. As dimenses da imagem adquirida so as da imagem que se encontrar em visualizao. As opes de zoom no interferem com as dimenses da imagem a adquirir. 4) Visualizao Se esta opo se encontrar activa, aps a gravao para disco, o ficheiro ser aberto e visualizado. Esta opo s se encontrar activa se o formato de imagem seleccionado em 9) do Mdulo de aquisioOpes de aquisio for o formato BMP .

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

5) Canal Permite alterar o canal da placa de aquisio seleccionado (canal este que fornece o sinal vdeo) a partir do 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 cmaras ligadas ao sistema. 6) Selectores de propriedades de imagem Permite alterar os valores de luminosidade, contraste, tonalidade e saturao que a placa de aquisio usa para efectuar a aquisio de imagem verificando os seus efeitos imediatamente na janela de aquisio.

1.3 - Aquisio
Foram implementados vrios esquemas de aquisio que nos permitem adquirir imagens de um modo sequencial de acordo com vrios parmetros ajustveis. 1) Tipo de aquisio 2) Tipo de aquisio Multiple shot 3) Nmero de imagens a adquirir 4) Tempo inicial de aquisio em modo Multiple shot / Temporal 5) Tempo entre aquisies em modo Multiple shot / Temporal 6) Tipo de trigger a utilizar 7) Localizao, em disco, da gravao das imagens adquiridas 8) Visualizao 9) Tempo entre aquisies em modo Sequence 10) Nmero de imagens a adquirir para a sequncia 11) Localizao, em disco, da gravao da sequncia adquirida 12) Opes de aquisio

1) Tipo de aquisio A aquisio pode ser feita em dois modos. Opes: Sequncia - adquirida uma sequncia de n imagens, com n definido em 10), a uma cadncia de uma imagem por cada intervalo especificado em 9) para o path indicado em 11) com as caracteristicas de ficheiro definidas em 7) e 8) do Mdulo de aquisio - Opes de aquisio Multiple Shot - Permite adquirir as imagens de um modo sequencial, podendo os instantes de aquisio serem activados de dois modos distintos. 2) Tipo de aquisio Multiple shot

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Aquisio em modo sequencial de n imagens, com n definido em 3) . Opes: Temporal- So adquiridas n imagens em intervalos de tempo definidos em 5) aps um perodo de espera inicial definido em 4) Trigger - So adquiridas n imagens a uma cadncia dependente dos instantes de trigger. Trigger este que do tipo definido em 6). 3) Nmero de imagens a adquirir Nmero de imagens a adquirir em modo Multiple Shot , aps o qual se d por terminado o processo de captura de imagem. 4) Tempo inicial de aquisio em modo Multiple shot-Temporal Tempo inicial a partir do qual iniciado o processo de captura em modo Multiple Shot / Temporal. Pode ser especificado em minutos ou segundos. 5) Tempo entre aquisies em modo Multiple shot-Temporal Tempo entre aquisies de imagem em modo Multipler Shot / Temporal . Pode ser especificado em minutos ou segundos. 6) Tipo de trigger a utilizar Tipo de Trigger que despoleta a aquisio de imagem para o modo Multiple Shot / Trigger. Podem ser seleccionados ambos ou apenas um dos dois, actuando o que primeiro for despoletado. Opes: Tecla - Evento de trigger a partir do teclado, com o pressionar das teclas C e SPACE a servirem de eventos de trigger. Trigger Externo - Evento de trigger a partir da porta srie efectuado por presso do boto de porta srie fornecido. 7) Localizao, em disco, da gravao das imagens adquiridas Localizao em disco da gravao das imagens adquiridas em modo Multiple Shot. O nome do ficheiro escolhido ser a base de formao dos nomes de todas as imagens adquiridas, sendo adicionados ao nome o ndice de imagem e um ndice da cmara utilizada se a aquisio for feita com duas cmaras , escolhidas em 1) do Mdulo de aquisio - Opes de aquisio. 8) Visualizao Opo de visualizao das imagens adquiridas em modo Multiple Shot se adquiridas com a opo .BMP em 9) do Mdulo de aquisio- Opes de aquisio. 9) Tempo entre aquisies em modo Sequence Tempo entre aquisies de imagem em modo Sequence . Pode ser especificado em minutos ou segundos. 10) Nmero de imagens a adquirir para a sequncia

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos


Nmero de imagens a adquirir em modo Sequence , aps o qual se d por terminado o processo de captura de imagem.

11) Localizao, em disco, da gravao da sequncia adquirida Localizao em disco da gravao das imagens adquiridas em modo Sequence. O nome do ficheiro escolhido ser a base de formao do nome das sequncias de imagens adquiridas, se a aquisio for feita com duas cmaras (escolhidas em 1) do Mdulo de aquisio - Opes de aquisio) sendo adicionados ao nome o indice da cmara utilizada. 12) Opes de aquisio Acesso ao Mdulo de aquisio - Opes de aquisio, para configurar todos os elementos de configurao do processo de aquisio.

1.4 - Progresso
Permite-nos iniciar e obter informao acerca do progresso do processo em qualquer um dos modos de aquisio utilizado em em 1) do Mdulo de aquisio - Grab.

1) Informao 2) Start 3) Close

1) Informao Informao acerca do estado do processo de aquisio actualizada de modo a dar um certo feedback ao utilizador. 2) Start D inicio ao processo de aquisio de imagens. 3) Close No fim do processo de aquisio torna-se activo de modo a poder fechar a caixa com a informao acerca do processo de aquisio de imagens.

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

1.5 - Informao
Permite-nos aceder a toda a informao acerca dos ficheiros de imagem adquiridos em formato .BMP em 9) do Mdulo de aquisio - Opes de aquisio . Este mdulo j se encontrava implementado pelo que nos limitamos a fazer uma breve referncia. Fazendo uso desta funcionalidade podemos visualizar a informao anexada a cada ficheiro de imagem em 10) do Mdulo de aquisio Opes de aquisio

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Captulo II - Calibrao
2.1 - Simulao de uma Cmara de Geometria Interna Conhecida
Esta parte da aplicao consiste na execuo de simulaes de cmaras de geometria interna conhecida, de maneira a serem analisados os efeitos de certos parmetros nos resultados finais de calibrao sem recorrer a testes laboratoriais. So tambm gerados um conjunto de pontos coplanares. Assim na interface utilizador / implementao o utilizador tem as seguintes opes:

1) Parmetros globais 2) Parmetros extrnsecos - rotao 3) Parmetros extrnsecos - translao 4) Parmetros intrnsecos 5) Parmetros de visualizao dos resultados 6) Efectuar a simulao de uma cmara

1) Parmetros globais Aqui o utilizador introduz os valores globais que sero utilizados no clculo dos parmetros de calibrao e na formulao do conjunto de pontos coplanares. Os parmetros que podem ser optimizados pelo utilizador so respectivamente (seguindo uma ordenao de cima para baixo): - Nmero de pontos de calibrao pretendidos. Por defeito, igual a 16. - Coordenada 3D mundo z para o plano de calibrao. Por defeito, igual a 0.0. - Dimenso da memria frame segundo a direco x. - Dimenso da memria frame segundo a direco y. - Distncia entre centros dos elementos sensores vizinhos na direco x, dx. - Distncia entre centros dos elementos sensores vizinhos na direco y, dy. 2) Parmetros extrnsecos rotao Aqui o utilizador especifica os valores dos graus de rotao segundo os eixos x, y e z, respectivamente. Por defeito, os valores so de 30, -30 e 30 respectivamente. 3) Parmetros extrnsecos translao Nesta seco so especificadas pelo utilizador as componentes do vector de translao segundo os eixos x, y e z, respectivamente. Por defeito, os valores so de 100, 100 e 2000 respectivamente. 4) Parmetros intrnsecos

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Aqui o utilizador pode especificar os parmetros intrnsecos que a cmara a simular tenha, tais como: - Distncia focal efectiva f. - Factor de distoro da lente, k1. - Factor de incerteza horizontal, sx. - Coordenada Cx do centro da imagem na memria frame, segundo a direco x. Por defeito, igual a metade da dimenso da referida memria segundo a mesma direco. - Coordenada Cy do centro da imagem na memria frame, segundo a direco y. Por defeito, igual a metade da dimenso da referida memria segundo a mesma direco. 5) Parmetros de visualizao dos resultados O utilizador pode inibir / desinibir as opes de visualizao dos resultados da simulao e tambm pode guardar o conjunto de pontos de calibrao coplanares gerados pela simulao num ficheiro de texto, sendo possvel especificar o nome e a localizao da gravao deste ficheiro. 6) Efectuar a simulao de uma cmara Este boto tem como funo iniciar a implementao da simulao de uma cmara de geometria interna conhecida introduzidos por defeito ou pelo utilizador na interface ilustrada.

2.2 - Deteco de Pontos de Calibrao na Memria frame.


Esta parte da aplicao consiste em determinar os pontos de calibrao na memria frame de uma imagem contendo o alvo de calibrao previamente dimensionado para o efeito. Assim na interface utilizador / implementao o utilizador tem as seguintes opes:

1) Inibir / desinibir a suavizao da imagem atravs da aplicao de filtros. 2) Escolher o filtro de deteco de orlas de intensidade. 3) Alterar os parmetros de deteco iniciais. 4) Escolher as opes de visualizao dos resultados e destino dos resultado. 5) Efectuar a deteco dos pontos.

1) Inibir /desinibir a suavizao da imagem atravs da aplicao de filtros Quando seleccionada esta opo de suavizao, o utilizador pode escolher filtros que actuaro sob a imagem de entrada contendo os pontos de calibrao a detectar. O resultado ser a suavizao da

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos


imagem se forem escolhidos os filtros Gaussianos ou a extraco de rudo se forem seleccionados os filtros de mediana ou mdia.

2) Escolher o filtro de deteco de orlas de intensidade. Nesta caixa o utilizador pode seleccionar o filtro de deteco de orlas de intensidade mais conviniente a aplicar sob a imagem contendo os pontos de calibrao. Aqui sero encontrados filtros como o de Deriche, Canny, Spacek e Shen and Castan. 3) Parmetros de deteco iniciais Aqui o utilizador introduz os valores que melhor se adaptam imagem a detectar. Os parmetros que podem ser optimizados pelo utilizador so respectivamente (seguindo uma ordenao de cima para baixo): - Valor mnimo de amplitude que um dado pixel dever apresentar para no ser classificado como rudo. Por defeito, igual a 50. - Tolerncia de erro na classificao de uma dado pixel quanto sua direco. Por defeito igual a 2. - Diferena mnima entre duas direces principais. Por defeito , igual a 32. - Mxima distncia de um dado pixel a uma determinada recta para ser classificado como pertencente a esta . Por defeito igual a 10. - Mnimo nmero de pontos que deve ser constituda uma linha para ser considerada como tal. Por defeito igual a 15. 4) Opes de visualizao dos resultados: Aqui o utilizador pode inibir / desinibir por ordem descente: - A visualizao do resultado da suavizao da imagem. - A visualizao do resultado do filtro de deteco de orlas de intensidade. - A visualizao do resultado da deteco das linhas nas duas direces principais. - A visualizao do resultado da interseco das linhas detectadas, que resultam nos pontos de calibrao considerados na memria frame. O utilizador tambm pode accionar a opo de gravao dos resultados da deteco num ficheiro de texto, sendo tambm possvel especificar o nome a localizao de gravao do ficheiro de texto. 5) Efectuar a deteco dos pontos de calibrao Este boto tem como funo iniciar a implementao de deteco dos pontos de calibrao com os parmetros introduzidos por defeito ou pelo utilizador na interface ilustrada.

2.3 - Formatao dos Pontos de Calibrao Considerados


Aps a determinao dos pontos de calibrao coplanares na memria frame necessrio fazer a sua formatao, isto , necessrio incluir no conjunto de pontos determinados as correspondentes coordenadas 3D de cada ponto determinado. A primeira interface tem como objectivo:

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

1) Especificao da localizao do ficheiro de texto com o conjunto de pontos coplanares na memria frame. 2) Especificao do nome do ficheiro de texto com os pontos formatados, sendo tambm possvel especificar o nome e a localizao do ficheiro. A segunda interface tem como objectivo:

1) Nmero total de pontos 2) Apresentao de valores 3) Insero de coordenadas 3D 4) Formatao dos pontos 5) Limpa ponto j formatado

1) Nmero total de pontos Indicao do nmero total de pontos a formatar. 2) Apresentao de valores Nesta parte da interface disponibilizado o nmero total de pontos de calibrao detectados na memria frame, assim como os valores de cada ponto nas suas coordenadas 3D. 3) Insero de coordenadas 3D Para cada ponto de calibrao detectado possvel inserir as suas coordenadas 3D correspondentes. 4) Formatao dos pontos Para cada ponto formatado possvel inseri-lo no ficheiro de sada da implementao ou removlo desse mesmo ficheiro. Desta maneira os pontos que iro formar o conjunto de pontos para o clculo da calibrao da cmara, sero apenas aqueles que o utilizador formatar, permitindo assim uma srie de testes de calibrao. 5) Concluso da formatao Este boto tem como funo concluir o processo de formatao.

2.4 - Calibrao de uma Cmara


A calibrao de uma cmara consiste na determinao dos seus parmetros intrnsecos e extrnsecos. Para executar a

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos


calibrao de uma cmara o utilizador tm sua disposio as seguintes opes: 1) Especificao dos valores gerais da implementao 2) Especificao do ficheiro contendo o conjunto de pontos de calibrao coplanares. 3) Optimizao dos valores por defeito. 4) Opes de sada da implementao. 5) Efectuar a calibrao. 1) Especificao dos valores gerais da implementao Aqui o utilizador pode especificar vrios parmetros globais necessrios ao clculo dos parmetros intrnsecos e extrnsecos da cmara. Estes so: a 0.0098. igual 256. a 0.0063. igual 256. - Distncia entre centros dos elementos sensores vizinhos na direco x, dx. Por defeito igual - Coordenada Cx do centro da imagem na memria frame, segundo a direco x. Por defeito - Distncia entre centros dos elementos sensores vizinhos na direco y, dy. Por defeito igual - Coordenada Cy do centro da imagem na memria frame, segundo a direco y. Por defeito

2) Especificao do ficheiro contendo o conjunto de pontos de calibrao coplanares. O utilizador aqui necessita de especificar a localizao do ficheiro contendo o conjunto de pontos coplanares detectados ou simulados pelas rotinas, respectivamente pelas implementaes de deteco e simulao. 3) Optimizao dos valores por defeito. O utilizador ao inibir a optimizao total dos parmetros de entrada na implementao de calibrao pode optimizar os seguintes parmetros: - O factor de incerteza horizontal, sx, por defeito igual a 0.710935. - A tolerncia do erro no clculo das solues exactas da distncia focal efectiva f, da componente tz do vector de translao T e do factor de distoro k1, determinadas pela resoluo do sistema de equaes no linear respectivo e utilizando o mtodo Levenberg Marquardt. Por defeito, igual a 0.0000001. - Inibir / desinibir a determinao exacta das coordenadas do centro da imagem (Cx,Cy) na memria frame. 4) Opes de sada da implementao. O utilizador pode inibir /desinibir a salva guarda dos resultados para um ficheiro de texto, sendo tambm possvel especificar o nome e a localizao do ficheiro a gravar. 5) Efectuar a calibrao Este boto tem como funo efectuar a calibrao de uma cmara com os parmetros especificados pelo utilizador na interface.

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Mdulo III - Deteco de Entidades e clculo de coordenadas 3D


3.1 - Inicializao
Permite-nos introduzir os parmetros de calibrao de um sistema stereo ou monocular obtido em 2.4 . Para posterior obteno de informao tridimensional por deteco e emparelhamento de pontos caractersticos e posterior triangulao estereoscpica para obteno de coordenadas 3D. 1) Matrizes de transformao 2) Distncia Focal e distoro radial da cmara 3) Parmetros de calibrao : dx, dy, Cx, Cy, sx 4) Nmero de pares de imagens 5) Uso de valores pr-definidos de calibrao 6) Uso de valores guardados em ficheiro para definir matriz de transformao, distncia focal e distoro radial 7) Uso de valores pr-definidos para definir matriz de transformao, distncia focal e distoro radial 8) Tipo de sistema

1) Matrizes de transformao Permite a introduo dos valores da matriz de transformao da respectiva cmara calibrada. 2) Distncia Focal e distoro radial da cmara Permite a introduo dos valores de distncia focal f e de distoro radial k. 3) Parmetros de calibrao : dx, dy, Cx, Cy, sx Permite a introduo dos seguintes parmetros: dx- Distncia entre centro dos elementos sensores vizinhos na direco x. dy- distncia entre centro dos sensores CD vizinhos na direco y. cx- Coordenada do centro da imagem na memria frame segundo a direco x. cy- Coordenada do centro da imagem na memria frame segundo a direco y. sx- Factor de escala que compensa incertezas no escalamento efectuado pelo framegrabber na linha de scan horizontal.

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

4) Nmero de pares de imagens Permite introduzir o nmero de pares de imagens a utilizar na deteco e posterior obteno de informao tridimensional. 5) Uso de valores pr-definidos de calibrao Permite fazer uso de valores pr-definidos de calibrao ( dx, dy, Cx, Cy, sx ) , no caso da calibrao ter sido efectuada imediatamente antes deste passo, os valores de calibrao obtidos anteriormente constituem os valortes pr-definidos. 6) Uso de valores guardados em ficheiro para definir matriz de transformao, distncia focal e distoro radial Permite fazer uso de valores contidos em ficheiro para determinar os valores da matriz de transformao 1) . 7) Uso de valores pr-definidos para definir matriz de transformao, distncia focal e distoro radial Permite fazer uso de valores pr-definidos de calibrao (matriz de transformao, distncia focal e distoro radial ) , no caso da calibrao ter sido efectuada imediatamente antes deste passo, os valores de calibrao obtidos anteriormente constituem os valortes pr-definidos. 8) Tipo de sistema Define o tipo de sistema. Stereo - Sistema que usa duas cmaras para obteno de informao tridimensional. Mono - Sistema que usa uma cmara para obteno de informao bidimensional. Ao aceitar todos os parmetros introduzidos, premindo em OK, seguir-se- o mdulo Deteco e 3D -

3.2 - Deteco de Pontos Caractersticos e Emparelhamento


A deteco dos pontos caractersticos e emparelhamento utiliza o mesmo interface utilizador / interface que o ponto 2.2 - Deteco de Pontos de Calibrao na Memria frame, uma vez que a filisiofia da deteco dos pontos caractersticos idntica da deteco dos pontos de calibrao.

3.3 - Obteno de Informao Tridimensional


Este mdulo activado imediatamente aps o mdulo Deteco e 3D- Inicializao e permite organizar as imagens obtidas em sequncia temporal associando-as a um nmero de par 1) possibilitando a deteco e obteno de informao 3D para cada par de imagens. Fazendo uso de imagens determina as coordenadas 3D de pontos caractersticos de um alvo tpico.

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

1) Nmero do par de imagem 2) Deteco dos pontos caractersticos de cada imagem pertencente ao par 3) Obteno das coordenadas tridimensionais dos pontos caractersticos 4) Marcao de pares de imagens como sendo a referncia

1) Nmero do par de imagem Indicao do ndice associado ao par de imagens do qual queremos detectar e emparelhar os pontos caractersticos. 2) Deteco dos pontos caractersticos de cada imagem pertencente ao par Permite a deteco e emparelhamento dos pontos caractersticos da imagem correspondente posio esquerda ou direita (1 ou 2 ) do sistema stereo de aquisio de imagem. Ao activar automaticamente executa mdulo Deteco e 3D - Deteco de pontos caractersticos e Emparelhamento. 3) Obteno das coordenadas tridimensionais dos pontos caractersticos Permite o clculo de coordenadas 3D dos pontos caractersticos, emparelhados, identificados em 2) colocando-as em memria. 4) Marcao de pares de imagens como sendo a referncia Estabelece qual dos pares de imagem ser a referncia em termos de estimao de movimento. A deteco e obteno de coordenadas 3D tm uma indicao que permite ao utilizador saber a cada passo o que j foi feito e o que falta fazer para terminar o processo. Estes indicadores permitem ao utilizador organizar do modo que lhe entender todo o processo.

PD 77 - Alinhamento de Imagens de Medicina Nuclear - Anexos

Mdulo IV - Estimao e correco de movimento


4.1 - Estimao e Correco

1) Nmero do conjunto de pontos 2) Correco do movimento 3) Indicao dos valores estimados de movimento 4) Coordenadas do centro de rotao 5) Estimao de movimento

1) Nmero do conjunto de pontos D-nos a indicao do nmero de conjuntos de pontos detectados obtidos no processo de obteno de informao tridimensional, bem como a indicao de ter sido efectuado ou no a estimao de movimento para esse conjunto de pontos em comparao com o conjunto de pontos de referncia. 2) Correco do movimento Permite efectuar a correco de uma imagem aps o clculo da translao segundo o eixo dos x e dos y e da rotao pelo boto de estimao de movimento 5). 3) Indicao dos valores estimados de movimento Aqui encontram-se os valores estimados da translao segundo o eixo dos x e dos y e da rotao para o conjunto de pontos escolhido em 1) em ordem ao conjunto de pontos referncia. Este campos so automaticamente preenchidos pelo processo de estimao de movimento 5) podendo no entanto ser alteradas pelo utilizador. 4) Coordenadas do centro de rotao As coordenadas do centro de rotao devem ser indicadas de forma a ser efectuada a rotao em torno do eixo de rotao certo. 5) Estimao de movimento O processo de estimao de movimento efectuado pressionando este boto o que ir desencadear o processo de estimao de movimento e respectivo preenchimento dos campos contidos em 3) .

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);

#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 */ 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 /*F:lregression* ________________________________________________________________ lregression ________________________________________________________________ Name: lregression - make the linear regression by least-squares fit of a straight 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. | 0 => Ok. | 1 => Can't make the linear regression.

/************************************************************************* ******************** 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"

Syntax: | int lregression(point *linepoint,int nline,int n,line

Return value:

/*******************************************************************/ Restrictions: (n*sum(x^2)-(sum(x))^2) must be different of zero. Author: Based On: Sergio Barros; Nuno S Couto; Joao Tavares Code By Joo Tavares /*F:mark* ________________________________________________________________ mark ________________________________________________________________ Name: Syntax: Description: 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); } Return value: mark - mark one cross | int mark(LPBITMAPINFOHEADER lp_in, int y, int x, int color) '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. | 0 => Ok.

version: 1.0 1/05/2001 Visual C++ Implementation ________________________________________________________________ */ int lregression(point *linepoint,int nline,int n,line *calline) {

Restrictions: None. Author: Based On: Nuno Sa Couto; Sergio Barros; Joao Tavares Code By Joo 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);

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);

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); Name: Syntax: findlines - find all the parallel lines in an input DIB | 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. | The number of lines. LPBITMAPINFOHEADER lp_in GlobalLock((HGLOBAL) bin1); int xsize = lp_in -> biWidth; int ysize = lp_in -> biHeight; = (LPBITMAPINFOHEADER)

/*________________________________________________________________ F: FINDLINES __________________________________________________________________

/**********/ 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);

Return value:

Restrictions: None. Author: Based On: Nuno Sa Couto; Sergio Barros; Joao Tavares Code By Joo Tavares

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; }

} 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; }

// 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); 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; } } } } }

} Restrictions: None. ::GlobalUnlock((HGLOBAL) bin1); Author: return(nline); Based On: } /*******************************************************************/ /*F:findpoints* ________________________________________________________________ findpoints ________________________________________________________________ Name: findpoints - find the corners's points of parallel squares or rectangles with same dimension | int findpoints(HDIB bin1, HDIB bin2, HDIB bout1, HDIB bout2, HDIB bout3, int error, int dang, double maxdist, int t, BOOL save) 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 | The number of points found. Id: 1.1 1/05/2001 VC++ Implementation Optimization ___________________________________________________________________ */ and Code By Joo Tavares Sergio Barros; Nuno Sa Couto; Joao Tavares

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 GlobalLock((HGLOBAL) bin1); LPBITMAPINFOHEADER lp_in2 GlobalLock((HGLOBAL) bin2); LPBITMAPINFOHEADER lp_out1 GlobalLock((HGLOBAL) bout1); LPBITMAPINFOHEADER lp_out2 GlobalLock((HGLOBAL) bout2); int xsize = lp_in1 -> biWidth; int ysize = lp_in1 -> biHeight; = = = = (LPBITMAPINFOHEADER) (LPBITMAPINFOHEADER) (LPBITMAPINFOHEADER) (LPBITMAPINFOHEADER)

Syntax:

Description:

Return value:

//************// 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){

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 direction // lpB2 = DIBGotoPoint ((BYTE *)lpDIB2, *lp_in2, (LONG) out1 *lp_out1, (LONG) i, (LONG) j); aux= DIBGetPoint(lpB2, lp_in2->biBitCount, (LONG) i); (LONG) i, (DWORD) BLACK); ang[(UINT) aux] += 1; } m1 += aux3; n1 += 1; } else if ( aux3 > ((DWORD) (max1+dang)) || aux3 < ((DWORD) (max1-dang))){ aux = aux3; ang[(UINT) aux] += 1; } } } } DIBChangePoint(out1, lp_out1->biBitCount, = DIBGotoPoint ((BYTE *)lpout1, and compute the average

i, (LONG) j);

} } /* angle threshold */ aux = ang[0]; max1 = 0; for (i = 1; i <= 255; ++i) { if ((UINT)aux<ang[i]) { aux = ang[i]; max1 = i; } }

for (i = -4; i <= 4 ; ++i) { if (aux = max1-(i) > 0) {

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]) { ((DWORD) (max2-dang))){ 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)){ } i, (LONG) j);

lpB2 = DIBGotoPoint ((BYTE *)lpDIB2, *lp_in2, (LONG) 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 *lp_out2, (LONG) i, (LONG) j); DIBChangePoint(out2, (LONG) i, (DWORD) BLACK); m2 += aux4; n2 += 1; } else if ( aux4 > ((DWORD) (max2+dang)) || aux4 < aux = aux4; ang[(UINT) aux] += 1; } lp_out2->biBitCount, = DIBGotoPoint ((BYTE *)lpout2,

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;

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);

yintreal = ((calline1[i].m*calline2[j].b+calline1[i].b)/(1.0calline1[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.0calline1[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); }

// find the intersection points // } LPBITMAPINFOHEADER lp_out3 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); ::GlobalUnlock((HGLOBAL) bout3); } else { return(npoint); = (LPBITMAPINFOHEADER) // 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);

} { /*******************************************************************/ /*P:cal_point* ________________________________________________________________ cal_point ________________________________________________________________ Name: cal_point - find the corners of parallel squares or rectangles with same dimension in an image | int cal_point(HDIB hDIB) '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. | 0 => OK. LPTSTR name; CDCalib_get_points list; HDIB in1DIB=NULL, out3DIB=NULL; int t, error, dang, npoint; double maxdist; // read arguments // if (list.DoModal()==IDOK) { in2DIB=NULL, out1DIB=NULL, out2DIB=NULL,

Syntax: Description:

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);

Return value:

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)

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 GlobalLock((HGLOBAL) in1DIB); LPBITMAPINFOHEADER lp_in2 GlobalLock((HGLOBAL) in2DIB); double alpha=1.0, omega=0.0001; int angles=1, width = 8; = = (LPBITMAPINFOHEADER) (LPBITMAPINFOHEADER)

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;

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 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);

not

open

input

file",

"Calibration

Error",

CMainFrame* pAppFrame4 = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame4->IsKindOf(RUNTIME_CLASS( CMainFrame ))); CString titulo4 = "Calibration Lines"; pAppFrame4->OpenNewDocument( out2DIB , TRUE, (const char*) titulo4);

} 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); }

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 */

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 {

#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 */ /*******************************************************************/

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;

/*******************************************************************/ /*F:linleastsquar* ________________________________________________________________ linleastsquar ________________________________________________________________

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[]);

Name: Syntax:

linleastsquar - make the linear least-squares regression by Cholesky's method |int linleastsquar(int m, int n, double z[][NMAX],

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. | 0 => Ok. /* cholesky decomposition - aux1[][]=l[][]*(l[][]transposed) */ Restrictions: The matrix [(z[[][]transposed)*z[][]] must be positive definite. Author: Based On: Sergio Barros; Nuno Sa Couto; Joao Tavares Code By Joo Tavares 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 decomposition!","Calibration error", MB_ICONERROR | MB_OK); return(1); } aux1[k][i] = (aux1[k][i]-sum)/aux1[i][i]; for (k = 0; k < n; ++k) { for (i = 0; i < k; ++i) { /* 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]; }

Return value:

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]; }

CHOLESKY

} 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];

Based On: }

Code By Joo Tavares

Id: 1.1 1/05/2001 VC++ Implementation ________________________________________________________________ /* 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); for (i = 0; i < k; ++i) { } /*******************************************************************/ /*F:solve* ________________________________________________________________ solve ________________________________________________________________ Name: Syntax: Description: solve - solve a system of linear algebraic equations by Cholesky's decomposition | int solve(double alfa[][NMAX1], double delta[] , double beta[]) 'alfa[][]' is the 'NMAX1'-by-'NMAX1' square matrix of coefficient. 'delta[]' is the vector of unknowns. 'beta[]' is the vector of constants. | 0 => Ok. 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 "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 "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; 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) {

CHOLESKY

decomposition.",

CHOLESKY

decomposition.",

Return value:

Restrictions: The matrix 'alfa[][]' must be positive definite. Author: Sergio Barros; Nuno Sa Couto; Joao Tavares

for (j = 0; j < i; ++j) sum += alfa[i][j]*aux[j]; aux[i] = (beta[i]-sum)/alfa[i][i]; } /* backward substitution */ Return value: 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*

'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. | 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: Based On: Sergio Barros; Nuno Sa Couto; Joao Tavares Code By Joo Tavares

Id: 1.1 1/05/2001 VC++ Implementation ________________________________________________________________

int findcenter(UINT n,calpoint point[], double dxl,double dy, double *cx, double *cy) ________________________________________________________________ findcenter ________________________________________________________________ Name: findcenter - compute the image center in the frame buffer using the radial alignment constraint | findcenter(UINT n,calpoint point[], double dxl pass = 0; Description: 'n' is the number of calibration points. do { '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. /* 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); } { 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;

Syntax:

/* 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) {

do { 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; } 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; 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) { 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) {

________________________________________________________________ } if (quinew >= quiold) { lambda *= 10.0; quiold = quinew; } else { Syntax: 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* 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 calibrate ________________________________________________________________ Name: calcamera - performs a camera calibration in the context of 3D machine vision using a coplanar set of calibration points | void calibrate(BOOL grava, double sx, BOOL find, double cx, double cy, double dx,

calibration points. Return value: | 0 => OK

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 */

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: Based On: Sergio Barros; Nuno Sa Couto; Joao Tavares Code By Joo 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 (sx == 0.0) { MessageBox(0,"The horizontal scale factor (sx) must be different of zero!", "Calibration Error", MB_ICONERROR | MB_OK);

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 MB_ICONERROR | MB_OK); return 0; } } not find image center!", "Calibration Error",

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;

/* 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){

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[][] */

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; }

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; }

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 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;

} 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;

equation!!",

"Calibration

Error",

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); } }

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 fprintf(outfpt, arg5); fprintf(outfpt, arg); fprintf(outfpt, arg1); fprintf(outfpt, arg2); fprintf(outfpt, arg3); fprintf(outfpt, arg4); #include "stdafx.h" #include "mainfrm.h" #include <math.h> #include "stdlib.h" #include "calib_sim3.h" #include "DCalibration.h"

#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 TSAIs model and a coplanar set of points. | int simcam3(double npoint, double zw, double tx, double ty, double tz, double 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 Return value: Restrictions: | 0 => OK.

(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.

Syntax: rotx,

The sqrt of <npoint> must be integer. The values for <rotx>, <roty> and <rotz> must be smaller than 360 and greater than -360 degree. Sergio Barros; Nuno S Couto; Joao Tavares Code By Joo Tavares

Author: Based On:

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)

{ } 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 arent 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!", dxl = sx*dx; aux1 = MPI/180.0; rotx = rotx*aux1; roty = roty*aux1; rotz = rotz*aux1; char arg[200];

"Simulation of Calibration error", MB_ICONERROR | MB_OK);

// 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); } }

/* 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;

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;

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;

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);

list->CenterWindow(); list->ShowWindow(SW_SHOWNORMAL); } } Description: } /* close file */ if (save) fclose(fpt); Return value: return(0); } /*******************************************************************/ Restrictions: Author: Based On: 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 LPTSTR name1,name2; CDCalib_input_frm list; 1.0 93/12/18 1.1 1/05/2001 Implementation None. | 0 => OK. Syntax:

points | input <inputfile> <outputfile> '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.

Sergio Barros; Nuno S Couto; Joao Tavares Code By Joo Tavares Joao Tavares NSC & SVB VC++

________________________________________________________________

int format(CString inputfile, CString outputfile) { int n; float xf, yf; FILE *infpt, *outfpt; char valid[500], *pdest; int ch = 'A',result=0;

CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); /* open input file */

name1= inputfile.GetBuffer(30); infpt=fopen(name1, "r"); if (infpt==NULL){ MessageBox(0,"Unable to open 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;

char arg[200]; /* open ouput file */ input file!", "Formating input 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);

if( list.DoModal() != IDOK) { fclose(infpt); return 0; }

/*******************************************************************/

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()

///////////////////////////////////////////////////////////////////////////// // 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:

// 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:

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 //}}AFX_DATA

m_default;

// 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

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";

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()

{ 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 }

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

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 ;

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; } }

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;

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);

void CDCalib_input_frm::OnCancel() { // TODO: Add extra cleanup here

CDialog::OnCancel(); 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; } ///////////////////////////////////////////////////////////////////////////// // 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)

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);

{ 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(); if (m_cksave == TRUE) { GetDlgItem(IDC_EFILE)->EnableWindow(TRUE); GetDlgItem(IDC_BROWSE)->EnableWindow(TRUE); } // 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);

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(); }

//{{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)

///////////////////////////////////////////////////////////////////////////// // CDCalib_simul_res dialog CDCalib_simul_res::CDCalib_simul_res(CWnd* pParent /*=NULL*/) : CDialog(CDCalib_simul_res::IDD, pParent) { EnableAutomation();

//{{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

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();

///////////////////////////////////////////////////////////////////////////// // 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;

// 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);

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() {

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 {

// 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); }

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

///////////////////////////////////////////////////////////////////////////// // 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;

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 Biomdica (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{

public: CVariaveisNuclear(); acquire.cpp /* ________________________________________________________________ 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; }; #ifdef _MAC #define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x)) #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)) acquire.cpp @(#)acquire.cpp 10/09/2000, Copyright 2000 Instituto de Engenharia Biomdica (INEB) Faculdade de Engenharia da Universidade do Porto (FEUP) Autor: Sergio Barros & Nuno Sa Couto ________________________________________________________________ */ #include "stdafx.h" #include "dib_func.h" #include "MainFrm.h" #include <afxmt.h> #include "ChildFrm.h" 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> // functions for DIBs // permite sincronizao por eventos CEvent // para definir CChildFrame para conseguir aceder

#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 //

MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame>m_VarNuclear.m_lChannel1 ); MdigGrabContinuous(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame>m_VarNuclear.MilImage[0]);

//1 or 2 cameras// if (pAppFrame->m_VarNuclear.m_CameraNum1 >m_VarNuclear.m_CameraNum2 ) { && pAppFrame-

//Comments// CEdit* >GetDlgItem(IDC_EDIT1); CButton* >GetDlgItem(IDC_BUTTON1); CButton* >GetDlgItem(IDC_BUTTON2); edit=(CEdit*) button=(CButton*) button2=(CButton*) pAppFrame->m_VarNuclear.dlgpAppFrame->m_VarNuclear.dlgpAppFrame->m_VarNuclear.dlg//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]); |

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; } ////////////////////

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]); }

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, >m_VarNuclear.Q_FACTOR ); MbufControl( MilImageSeq2[n], 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 = >GetActiveDocument(); documento->OnCloseDocument(); return; } /*//////////////////////////////////////////// (CProjectDoc*) frame-

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]);

pAppFrameM_Q_FACTOR, 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);

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 = >GetActiveDocument(); documento->OnCloseDocument(); return; } /*//////////////////////////////////////////// (CProjectDoc*) frame-

MdigControl(pAppFrame>m_VarNuclear.MilDigitizer,M_GRAB_MODE,M_SYNCHRONOUS); StartThreadNuclear(); AfxBeginThread (MilApplication,(LPVOID) THREAD_PRIORITY_NORMAL);

NULL

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 >m_VarNuclear.m_csFileName.Left(t);

filenameout

=pAppFrame-

{ MIL_ID* MilImageSeq;

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 >m_VarNuclear.m_CameraNum2)) && (!pAppFrameMbufClear(MilImageSeq[n],0); //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]); }

if (pAppFrame->m_VarNuclear.m_bCompressed == TRUE ) MbufControl( MilImageSeq[n], M_Q_FACTOR, >m_VarNuclear.Q_FACTOR ); } //////////////////////////////////////////////////////

pAppFrame-

//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 */

/*/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 = >GetActiveDocument(); documento->OnCloseDocument(); return; } /*//////////////////////////////////////////// (CProjectDoc*) frame-

//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);

aux="Time Ellapsed "; aux+= _fcvt( r, 0, &decimal, &sign ); aux+="."; aux+=_fcvt( y*1000, 0, &decimal, &sign ); aux+=" "; edit->ReplaceSel(aux,FALSE );

t--; /* 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); if (t<3) t=len-1; CString >m_VarNuclear.m_csFileName.Left(t); /*/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 = >GetActiveDocument(); documento->OnCloseDocument(); return; } //*/////////////////////////////////////////// (CProjectDoc*) framefilenameout+=".avi"; filenameout =pAppFrame-

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);

MdigControl(pAppFrame>m_VarNuclear.MilDigitizer,M_GRAB_MODE,M_SYNCHRONOUS); StartThreadNuclear(); AfxBeginThread (MilApplication,(LPVOID) THREAD_PRIORITY_NORMAL); /* Save the sequence into a file */ //printf( "Saving the sequence into an AVI file...\n" );

} NULL , CloseHandle (pAppFrame->m_VarNuclear.Semaphore); return 0; } /*---------------------------------------------------------------Function: void ShotTemp() Purpose: Gets shots from frame grabber with time conditions -----------------------------------------------------------------*/ UINT ShotTemp(LPVOID id) {

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) )

CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); MappControl(M_ERROR, M_PRINT_DISABLE); UINT n = 0; CString aux; char numero[4];

// 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]); } && (!pAppFrameMbufClear(MilImageSeq[n],0); } ///////////////////////////////////////////////////////// //Begin grab// //MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame>m_VarNuclear.m_lChannel1);

MdigChannel(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame>m_VarNuclear.m_lChannel1); MdigGrabContinuous(pAppFrame->m_VarNuclear.MilDigitizer,pAppFrame>m_VarNuclear.MilImage[0]); //Comments// CEdit* >GetDlgItem(IDC_EDIT1); CButton* >GetDlgItem(IDC_BUTTON1); CButton* >GetDlgItem(IDC_BUTTON2); edit=(CEdit*) button=(CButton*) button2=(CButton*) pAppFrame->m_VarNuclear.dlgpAppFrame->m_VarNuclear.dlgpAppFrame->m_VarNuclear.dlg-

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 >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)); /////////////////////

// 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 >m_VarNuclear.m_csFileName.Left(t); if(pAppFrame->m_VarNuclear.m_iNbFrames > 1) filenameout+=(_itoa( n+1, numero, 10 )); =pAppFrame-

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) WM_NUCLEAR, 0 ,0); }

id,

} 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) THREAD_PRIORITY_NORMAL); } else if (pAppFrame->m_VarNuclear.m_CameraNum1 >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); } ///////////////////////////////////////////////////////////////

NULL

&&

pAppFrame-

Sleep(200); //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); 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 >m_VarNuclear.m_csFileName.Left(t); filenameout =pAppFrame-

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); } //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) 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) NULL ,

PortInitialize ("COM1"); pAppFrame->m_VarNuclear.SerialSem= CreateSemaphore(NULL, 0, 1,NULL ); ////////////////////////////// //Comments// CEdit* >GetDlgItem(IDC_EDIT1); CButton* >GetDlgItem(IDC_BUTTON1); CButton* >GetDlgItem(IDC_BUTTON2); edit=(CEdit*) button=(CButton*) button2=(CButton*) pAppFrame->m_VarNuclear.dlgpAppFrame->m_VarNuclear.dlgpAppFrame->m_VarNuclear.dlg-

// 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]); }

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 >m_VarNuclear.m_CameraNum2)) { MIL_ID* MilImageSeq;

&&

(!pAppFrameMbufClear(MilImageSeq[n],0); } /////////////////////////////////////////////////////////

//Memory Allocation// MilImageSeq = (MIL_ID*) ::GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT ,(pAppFrame>m_VarNuclear.m_iNbFrames)*sizeof(MIL_ID)); ///////////////////// MappControl(M_ERROR, M_PRINT_DISABLE);

//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++) {

/* 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 >m_VarNuclear.m_csFileName.Left(t); if(pAppFrame->m_VarNuclear.m_iNbFrames > 1) filenameout+=(_itoa( n+1, numero, 10 )); =pAppFrame-

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) 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) THREAD_PRIORITY_NORMAL); } else if (pAppFrame->m_VarNuclear.m_CameraNum1 >m_VarNuclear.m_CameraNum2) { MIL_ID* MilImageSeq; MIL_ID* MilImageSeq2; //Memory Allocation// MilImageSeq = (MIL_ID*) ::GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT

id,

NULL &&

pAppFrame-

filenameout+="."+pAppFrame->m_VarNuclear.m_csImage;

,(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]);

filenameout2+="_cam2."+pAppFrameMdigChannel(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 >m_VarNuclear.m_csFileName.Left(t); filenameout =pAppFrameSleep(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"; >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); }

if(pAppFrame->m_VarNuclear.m_iNbFrames> 1) filenameout+=(_itoa( n+1, numero, 10 )); CString filenameout2 = filenameout; filenameout+="_cam1."+pAppFrame>m_VarNuclear.m_csImage;

edit->ReplaceSel(aux,FALSE ); button->EnableWindow(TRUE); StartThreadNuclear(); AfxBeginThread (MilApplication,(LPVOID) THREAD_PRIORITY_NORMAL); } CloseHandle (pAppFrame->m_VarNuclear.SerialSem); CloseHandle (pAppFrame->m_VarNuclear.Semaphore); return 0; } NULL ,

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);

//////////////////////////////////////////////////////////////////////////////////// //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; // para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); apontador

// 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 ();

// 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

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; // para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); apontador

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; // 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; apontador

// 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; } }

{ 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) {

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))

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";

MessageBox(NULL, strMsg, MB_ICONEXCLAMATION | MB_OK); file.Abort(); // will not throw an exception return ; } END_CATCH return ; }

NULL,

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], &TransparentColor); M_KEY_COLOR,

/*---------------------------------------------------------------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_TRANSPARENT); if (pAppFrame->m_VarNuclear.m_bDataTypeRGB) { if (color==0) M_BACKGROUND_MODE,

// 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);

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_DEFAULT); M_MODIFIED,

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); } }*/

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 //AUX //AUX //AUX //AUX =

//////////////////////////////////////////////////////////////////////// // Implementao da classe CVariaveisNuclear // valores por defeito CVariaveisNuclear::CVariaveisNuclear() { //Compresso// /* 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"; m_MILImageType=M_BMP; //////////////////// //Seleco// m_bSequencia = FALSE; sequencia(FALSE)/shot(TRUE) m_bTriggerMode = FALSE; temporal //////////// ///////////////////////////////////// //Sequence// // Grab em //AUX

m_lChannel1 = M_CH0; m_csCh1 = "CH1"; m_lChannel2 = M_CH1; m_csCh2 = "CH2"; m_pcDataFormat="M_CCIR"; m_csSinal = "CCIR"; m_bDataTypeRGB = FALSE; m_csData = "GRAY";

// Grab por Modo trigger ou

m_lDispMode M_WINDOWED+M_DISPLAY_24_BASIC+M_DISPLAY_8_BASIC; m_csDisplay = "Basic"; //AUX m_bSignature = FALSE; m_cstext = "NSB Production"; m_iBrightness=M_DEFAULT; m_iContrast=M_DEFAULT; //AUX

m_iTimeBetween = 5;

m_iHue=M_DEFAULT; m_iSaturation=M_DEFAULT; } /////////////////////////////////////

m_bVisualize=FALSE; id=NULL;

//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; camara m_hWndNuclear2 = NULL; camara m_bvideo = FALSE; via matrox //Cameras Activas// m_CameraNum1 = FALSE; m_CameraNum2 = FALSE; /////////////////// BufSizeBand=1; BufSizeX= 640; BufSizeY= 480; m_bTimeBetween=FALSE; first=FALSE; Semaphore= NULL; SerialSem=NULL; ExitSerial=FALSE; hReadThread=NULL; hPort=NULL; // camera 1 activa // camera 2 activa //Sinal de modo aquisicao // Handle da janela da

Dacquire.h #include "resource.h" ///////////////////////////////////////////////////////////////////////////// // CDAcquire dialog class CDAcquire : public CDialog { // Construction public: CDAcquire(CWnd* pParent = NULL); // standard constructor // Handle da janela da // 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

// 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 //{{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_iradio1; 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

//{{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

//

{ // 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 insert additional declarations immediately before the previous line. #endif // !defined(AFX_DACQUIRE_H__131459F0_3577_11D5_954D_0080AD1CB308__INCLUDE D_)

// Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDImage) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}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

Dacquire.cpp // DAcquire.cpp : implementation file

// #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); DDX_Text(pDX, IDC_EDIT1, m_iedit1); 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); DDX_Check(pDX, IDC_CHECK5, m_bcheck5); 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()

///////////////////////////////////////////////////////////////////////////// // 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 );

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);

m_csedit3 =buffer; m_csedit3+="\\imagem"; m_csedit3+="."+pAppFrame->m_VarNuclear.m_csImage; m_csedit4 =buffer; m_csedit4+="\\sequence.avi"; }

GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE);

return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE

void CDAcquire::OnRadio1() { // TODO: Add your control notification handler code here

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); }

UpdateData(TRUE); if (m_iradio1 == 1) { //LEFT// GetDlgItem(IDC_RADIO3)->EnableWindow(TRUE); 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);

//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); } 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);

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_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) { GetDlgItem(IDC_RADIO3)->EnableWindow(TRUE); 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); }

UpdateData(TRUE); } 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 void CDAcquire::OnRadio4() { // TODO: Add your control notification handler code here UpdateData(TRUE); 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); } 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); } else{ GetDlgItem(IDC_EDIT1)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT2)->EnableWindow(TRUE); GetDlgItem(IDC_COMBO5)->EnableWindow(TRUE); GetDlgItem(IDC_COMBO6)->EnableWindow(TRUE);

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); }

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

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

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 else 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)));

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; } { 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.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;

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_DISP LAY_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_DISPL AY_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") { 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; 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_bcheck2) pAppFrame->m_VarNuclear.m_bSignature=TRUE;

else pAppFrame->m_VarNuclear.m_bSignature=FALSE; pAppFrame->m_VarNuclear.m_cstext=dlg.m_csedit1; } UpdateData(FALSE); }

if (m_bcheck2 == 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; level m_min = 1;

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); else if (m_bcheck1 == FALSE) GetDlgItem(IDC_COMBO7)->EnableWindow(FALSE); } void CDAcquire::OnCheck2() { // 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);

//

maximum

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) 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"); 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")

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); }

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

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") {

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); } }

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 // maximum 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);

///////////////////////////////////////////////////////////////////////////// // 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; 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); DDX_Check(pDX, IDC_CHECK1, m_bcheck1); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDImage, CDialog) //{{AFX_MSG_MAP(CDImage)

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) {

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); 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; } }

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); }

UpdateData(FALSE); CDialog::OnHScroll(nSBCode, nPos, pScrollBar); }

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);

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);

if (pAppFrame->m_VarNuclear.m_CameraNum1==FALSE) return; MdigHalt(pAppFrame->m_VarNuclear.MilDigitizer); MdigGrab(pAppFrame->m_VarNuclear.MilDigitizer, >m_VarNuclear.MilImage[0]); CString aux; LPCSTR lpszDefExt; BOOL bOpen = FALSE; // File Open Dialog DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; // default

pAppFrame-

// file filters CComboBox* combo=(CComboBox*) GetDlgItem(IDC_COMBO1); 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) >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))); 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);

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, >m_VarNuclear.MilImage[0]); UpdateData(TRUE); } void CDImage::OnOK() { // TODO: Add extra validation here CDialog::OnOK(); } void CDImage::OnCancel() { // TODO: Add extra cleanup here pAppFrame-

pAppFrame-

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; // para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); ReleaseSemaphore(pAppFrame->m_VarNuclear.Semaphore, 1, NULL); apontador

typedef struct{ } double x; double y; CString tag; 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 } 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; conversion2x2D_3D.h 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

// 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); }

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]; //Verificao de deteco 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; };

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 Code By Joo Tavares

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* ________________________________________________________________

Based On:

________________________________________________________________

*/ void compdeep() { CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); apontador

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];

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; for (i=0 ; i< pAppFrame->m_VarCalib.npoints;i++ ){ 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]; /* 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); mpp2[0][0] = pAppFrame->m_VarCalib.mpp2[0][0]; mpp2[0][1] = pAppFrame->m_VarCalib.mpp2[0][1]; pAppFrame->m_VarCalib.final_mark3D[i].x=a[0]; pAppFrame->m_VarCalib.final_mark3D[i].y=a[1];

pAppFrame->m_VarCalib.final_mark3D[i].z=a[2]; pAppFrame->m_VarCalib.final_mark3D[i].tag >m_VarCalib.marks[i].tag; }

*/ = pAppFrameint 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; // para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame))); apontador

return; } /*******************************************************************/ /*F:compute_mpp* ________________________________________________________________ compute_mpp ________________________________________________________________ Name: Syntax: compute_mpp - compute the perspective projection matrix | 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: Author: Based On: | 0 => Ok. Sergio Barros; Nuno S Couto; Joao Tavares Code By Joo Tavares

________________________________________________________________

/* 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*aux4aux1*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*aux4aux1*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;

mpp[2][2] = pAppFrame->m_VarCalib.mpp2[2][2];//aux3*aux1/f; mpp[2][3] = pAppFrame->m_VarCalib.mpp2[2][3];//trans[2]/f; }

Restrictions: 'dx' and 'dy' must be different of zero. Author: Based On: Sergio Barros; Nuno S Couto; Joao Tavares Code By Joo Tavares

________________________________________________________________ */ return(0); } /*******************************************************************/ /* compute from frame coordinates the undistorted coordinates */ /*F:frame_undistorted* double r2, xd, yd, aux1, aux2, aux3; ________________________________________________________________ frame_undistorted ________________________________________________________________ Name: frame_undistorted - compute the undistorted coordinates from the frame buffer's coordinates 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 */ int frame_undistorted(int xf,int yf, double *xu, double *yu,double k,double dxl,double dy,int cx,int cy) {

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.

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: Syntax: svdfit - make the linear least-squares regression using SVD decomposition | 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. | None. Sergio Barros; Nuno S Couto; Joao Tavares Code By Joo Tavares

Return value: Author: Based On:

________________________________________________________________ */ 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);

/* 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: Syntax: svbksb - compute A.X=B | void svbksb(u, w, v, m, n, b, x) | double **u, w[], **v, b[], x[]; | int m, n; '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: Author: Based On:

| None. Sergio Barros; Nuno S Couto; Joao Tavares Code By Joo 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;

Description:

} free_vector(tmp,n); return;

rv1 = vector(n); g = scale = anorm = 0.0; /* Householder reduction to bidiagonal form */ for ( i = 1; i <= n; i++) {

} /******************************************************************/ /*F:svdcmp* ________________________________________________________________ svdcmp ________________________________________________________________ Name: Syntax: svdcmp - construct the singular value decomposition | void svdcmp(a, m, n, w, v) | double **a, w[], **v; | int m, n; 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]'. | 1 => No converge in 30 svdcmp iterations. Sergio Barros; Nuno S Couto; Joao Tavares Code By Joo Tavares } } 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++) { } for (k = i; k <= m; k++) a[k][i] *= scale; 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(sqrt(s), f); h = f*g-s; 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];

Description:

Return value: EAuthor: Based On:

________________________________________________________________ */ 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;

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 */ } }

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; 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]; } for ( j = i; j <= m; j++) a[j][i] *= g; } 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 (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 ( l = k; l >= 1; l--) { for (its = 1; its <= 30; its++) { flag = 1; /* Test for splitting */

} for (j = 1; j <= n; j++) v[i][j] = v [j][i] = 0.0; }

nm = l-1; /* Note that rv1[1] is always zero */

/* Singular value is made nonnegative */ 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) { x = w[l]; nm = k-1; y = w[nm]; g = rv1[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/(f+SIGN2(g, f)))-h))/x; 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; 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 */

} 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; } } rv1[l] = 0.0; rv1[k] = f; w[k] = x; } } free_vector(rv1,n); Ddetect.h return; }

sx =0.710935; dx =8.37765957e-3; dy =8.07560136e-3; cx =256; cy =256; camerasF1_T2=TRUE; 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;

#include "resource.h" } /******************************************************************/ /******************************************************************/ CVariaveisCalib::CVariaveisCalib() { ///////////////////////////////////////////////////////////////////////////// // CDdetect_3D dialog class CDdetect_3D : public CDialog { // Construction public: CDdetect_3D(CWnd* pParent = NULL); // standard constructor

// 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

// 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); virtual BOOL OnInitDialog(); 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

//}}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_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) { //{{AFX_DATA_INIT(CDdetect_3D) 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)

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 )));

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));

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); }

UpdateData(FALSE); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE }

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_iedit21][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::OnCancel() { // TODO: Add extra cleanup here //DestroyWindow(); //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;

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 CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd;

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); }

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,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);

void CDdetect_3D::OnOK() { } void CDdetect_3D::OnButton5() { // TODO: Add your control notification handler code here UpdateData(TRUE); CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame ))); HDIB hNewDIB = NULL; 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;

char arg[200]; FILE *outftp; LPTSTR name1; CString m_strInputfile; LPCSTR lpszFilter = "Project File Types (*.txt) | *.txt;;|All files (*.*) | *.*; ||";

//correct// pAppFrame->m_VarCalib.pict_numb=size; CDialog::OnOK(); } ///////////////////////////////////////////////////////////////////////////// // CDInitDetect3D dialog CDInitDetect3D::CDInitDetect3D(CWnd* pParent /*=NULL*/) : 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;

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++) { 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);

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) 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(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::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); } UpdateData(FALSE); } } else {

GetDlgItem(IDC_EDIT29)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON5)->EnableWindow(FALSE);

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);

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];

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);

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;

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); }

// file filters lpszFilter = "Windows Bitmap (*.txt) | *.txt; |Cmis ASCII File (*.cmi) | *.cmi; |All files (*.*) | *.*; ||"; // Criao do ficheiro de destino CFileDialog dlg( bOpen, lpszDefExt,FALSE, 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; } 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() { // TODO: Add your control notification handler code here 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); int ch = 'C',result=0; for (i=1; i<= 4; i++) fscanf (infpt,"%s", valid); // file filters fscanf (infpt, "%g", &k1); FILE *infpt; LPTSTR name1; char valid[500], *pdest; calpoint rot[6], trans[2]; int i; float k1, f1; default LPCSTR lpszFilter; UpdateData(TRUE); BOOL bOpen = TRUE; // File Open Dialog LPCSTR lpszDefExt = "txt"; // Default Extension DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; //

lpszFilter = "Windows Bitmap (*.txt) | *.txt; |Cmis ASCII File (*.cmi) | *.cmi; |All files (*.*) | *.*; ||"; // Criao do ficheiro de destino CFileDialog dlg( bOpen, lpszDefExt,NULL, dwFlags, lpszFilter );

fscanf (infpt, "%g", &f1); for (i=1; i<= 4; i++) fscanf (infpt,"%s", valid); fscanf (infpt, "%g", &k1);

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; } 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); }

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); 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;

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; 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;

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; m_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()

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;

///////////////////////////////////////////////////////////////////////////// // 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 >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; } <= pAppFrameVERIFY(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;

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;

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 GlobalLock( pDoc->m_hDIB); HDIB hNewDIB = NULL; HDIB hNewDIB2 = NULL; BeginWaitCursor(); lpDIBHdr_in = (LPBITMAPINFOHEADER)

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( (const char*) title); } else ::GlobalFree((HGLOBAL) hNewDIB); EndWaitCursor(); // message beep pAppFrame->OnEnd(); hNewDIB2, TRUE,

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; m_ip = -1; 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);

pAppFrame->m_VarCalib.made[m_iedit2-1].final3D=TRUE; final3D.LoadBitmaps(IDB_YES,0,0,0); final3D.InvalidateRect(NULL,TRUE); UpdateData(FALSE); }

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) {

//{{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);

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;

void movement(int pos);

//Second point2.x=(q2.x+q8.x)/2;

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; } 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; } 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; //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;

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;

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;

//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] );

if (!pAppFrame->m_VarCalib.flag){ pAppFrame->m_VarCalib.flag=TRUE; pos=pAppFrame->m_VarCalib.reference_number; //Referncia// 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;

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"

#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;

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_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 dlg.m_idx, dlg.m_idy, dlg.m_itolerance, dlg.m_strInputFile,

// 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

, dlg.m_strOutputFile); }

dlg.m_idx,

dlg.m_idy,

dlg.m_itolerance,

dlg.m_strInputFile,

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;

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) { } 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")

m_VarNuclear.m_dBetweenTimeUnit=1; else if (dialog.m_cscombo6=="min") m_VarNuclear.m_dBetweenTimeUnit=60; 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; }

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 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 ("No 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////// } m_VarNuclear.m_csFileName=dialog.m_csedit3; } } else return; ////////////////////////////////////////////////////////////////////////////////////////// /* allocation of MIL display. */ //Tests if it is one or 2 cameras///////////////////////////////////////////////////////// /* 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_VarNuclear.MilSystem); M_DEV0, M_DEFAULT,

MdispAlloc(m_VarNuclear.MilSystem, M_DEF_DISPLAY_FORMAT,m_VarNuclear.m_lDispMode, &m_VarNuclear.MilDisplay[0]);

M_DEFAULT,

/* 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 Reporting",MB_OK); //CWnd* destrwnd; //destrwnd->Attach(m_VarNuclear.m_hWndNuclear); //MDIActivate(destrwnd); CMDIFrameWnd* frame = (CMDIFrameWnd*) MDIGetActive(); CProjectDoc* documento = >GetActiveDocument(); documento->OnCloseDocument(); return; } ///////////////////////////////////////////// (CProjectDoc*) frame-

//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);

parameter","Error

//Image contrast.... MdigReference(m_VarNuclear.MilDigitizer,M_BRIGHTNESS_REF,m_VarNuclea r.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_VarNucle ar.m_iSaturation); //Digitizer initialization MdigControl(m_VarNuclear.MilDigitizer, m_VarNuclear.m_dImageScale); //ERROR////////////////////////////////////// MappGetError(M_CURRENT,&m_VarNuclear.ErrorPtr); if ( m_VarNuclear.ErrorPtr != M_NULL) { MessageBox("Some kind of invalide Reporting",MB_OK); //CWnd* destrwnd; //destrwnd->Attach(m_VarNuclear.m_hWndNuclear); //MDIActivate(destrwnd); CMDIFrameWnd* frame = (CMDIFrameWnd*) MDIGetActive(); CProjectDoc* documento = >GetActiveDocument(); documento->OnCloseDocument(); return; } ///////////////////////////////////////////// //Calls right function/// if (m_VarNuclear.m_bSequencia == TRUE) { { // Print a message. ////////////////////////////////////// (CProjectDoc*) frameM_GRAB_SCALE, {

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* >GetDlgItem(IDC_EDIT1); CButton* >GetDlgItem(IDC_BUTTON1); CButton* >GetDlgItem(IDC_BUTTON2); parameter","Error

edit=(CEdit*) button=(CButton*) button2=(CButton*)

m_VarNuclear.dlgm_VarNuclear.dlgm_VarNuclear.dlg-

CString aux; aux="Begin sequence acquisition edit->ReplaceSel( aux,FALSE ); aux=""; //////////////////////////////////////////////////////////// AfxBeginThread (SequenciaNuclear,(LPVOID) THREAD_PRIORITY_NORMAL); } else { if (m_VarNuclear.m_bTriggerMode == FALSE) { // Print a message. / m_VarNuclear.dlg = new CDComents; if(m_VarNuclear.dlg != NULL)

";

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");

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* >GetDlgItem(IDC_EDIT1); CButton* >GetDlgItem(IDC_BUTTON1); CButton* >GetDlgItem(IDC_BUTTON2);

edit=(CEdit*) button=(CButton*) button2=(CButton*)

m_VarNuclear.dlg>GetDlgItem(IDC_EDIT1); m_VarNuclear.dlg>GetDlgItem(IDC_BUTTON1); m_VarNuclear.dlg>GetDlgItem(IDC_BUTTON2);

CEdit* CButton* CButton*

edit=(CEdit*) button=(CButton*) button2=(CButton*)

m_VarNuclear.dlgm_VarNuclear.dlgm_VarNuclear.dlg-

CString aux; char numero[4]; "; aux="Multiple shot acquisition... aux+=(_itoa(m_VarNuclear.m_iNbFrames , numero, 10 )); aux+=" shot to be taken "; edit->ReplaceSel( aux,FALSE ); aux=""; AfxBeginThread THREAD_PRIORITY_NORMAL); (ShotTemp,(LPVOID) m_myID ,

CString aux; aux="Begin acquisition "; edit->ReplaceSel( aux,FALSE ); aux=""; //////////////////////////////////////////////////////////// AfxBeginThread (ShotTrigger,(LPVOID) m_myID THREAD_PRIORITY_NORMAL); } }

} else if (m_VarNuclear.m_bTriggerMode == TRUE) { // Print a message. ////////////////////////////////////// m_VarNuclear.dlg = new CDComents; if(m_VarNuclear.dlg != NULL) {

} 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();

CProjectDoc* pDoc = (CProjectDoc*) pChild->GetActiveDocument(); pDoc->SetTitle("Camera 1"); 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 ("No existe uma MDI child frame activa", "", MB_ICONERROR); return; } //Associates View to frame 2 CView* pView2 = pMDIChildWnd2->GetActiveView(); ASSERT(pView2 != NULL);

/* 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_VarNuclear.MilSystem); M_DEV0, M_DEFAULT,

/* Allocation of MIL display. */ MdispAlloc(m_VarNuclear.MilSystem, M_DEF_DISPLAY_FORMAT,m_VarNuclear.m_lDispMode, &m_VarNuclear.MilDisplay[0]); MdispAlloc(m_VarNuclear.MilSystem, M_DEF_DISPLAY_FORMAT,m_VarNuclear.m_lDispMode, &m_VarNuclear.MilDisplay[1]);

M_DEFAULT, M_DEFAULT,

//Activates MDI associated with pChild ( 1st window) pChild->SetActiveView(pView,TRUE ); //Activates MDI to associate with View CMDIChildWnd* pMDIChildWnd = MDIGetActive(); if (pMDIChildWnd == NULL) { MessageBox ("No existe uma MDI child frame activa", "", MB_ICONERROR); return; }

/* 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; } ///////////////////// //ERROR////////////////////////////////////// MappGetError(M_CURRENT,&m_VarNuclear.ErrorPtr); if ( m_VarNuclear.ErrorPtr != M_NULL) { MessageBox("Some kind of invalide Reporting",MB_OK); //CWnd* destrwnd; //destrwnd->Attach(m_VarNuclear.m_hWndNuclear);

//Variaveis Globais com handle das MDI sao associadas m_VarNuclear.m_hWndNuclear = pView->m_hWnd; m_VarNuclear.m_hWndNuclear2 = pView2->m_hWnd;

parameter","Error

///Initialization of acquisition//////

//MDIActivate(destrwnd); CMDIFrameWnd* frame = (CMDIFrameWnd*) MDIGetActive(); CProjectDoc* documento = >GetActiveDocument(); documento->OnCloseDocument(); CProjectDoc* documento2 = >GetActiveDocument(); documento2->OnCloseDocument(); return; } ///////////////////////////////////////////// (CProjectDoc*) (CProjectDoc*) frameframe-

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[1]); } 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]); 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[1]); } //////////////////////////// /* Clear the buffer */ MbufClear(m_VarNuclear.MilImage[0],0); MbufClear(m_VarNuclear.MilImage[1],0); //Display intialization MdispSelectWindow(m_VarNuclear.MilDisplay[0], m_VarNuclear.m_hWndNuclear ); MdispSelectWindow(m_VarNuclear.MilDisplay[1], m_VarNuclear.m_hWndNuclear2 ); //Control of the display MdispControl(m_VarNuclear.MilDisplay[0], M_ENABLE); * *

//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 ); CFrameWnd* pFrame2 = (CFrameWnd*) pView2->GetParentFrame(); ASSERT(pFrame2 != NULL); pFrame2->SetWindowPos(NULL, 0, 0,(UINT)(m_VarNuclear.BufSizeX* m_VarNuclear.m_dImageScale + (UINT)(m_VarNuclear.BufSizeY* m_VarNuclear.m_dImageScale+ 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]);

12), 31),

m_VarNuclear.MilImage[0], m_VarNuclear.MilImage[1],

M_WINDOW_OVERLAP

MdispControl(m_VarNuclear.MilDisplay[1], M_ENABLE); //Control initialization MdigControl(m_VarNuclear.MilDigitizer, m_VarNuclear.m_dImageScale);

M_WINDOW_OVERLAP

, {

m_VarNuclear.dlg = new CDComents; if(m_VarNuclear.dlg != NULL)

M_GRAB_SCALE,

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");

//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 Reporting",MB_OK); //CWnd* destrwnd; //destrwnd->Attach(m_VarNuclear.m_hWndNuclear); //MDIActivate(destrwnd); CMDIFrameWnd* frame = (CMDIFrameWnd*) MDIGetActive(); CProjectDoc* documento = >GetActiveDocument(); documento->OnCloseDocument(); CProjectDoc* documento2 = >GetActiveDocument(); documento2->OnCloseDocument(); return; } ///////////////////////////////////////////// (CProjectDoc*) (CProjectDoc*) frameframe-

CEdit* parameter","Error >GetDlgItem(IDC_EDIT1); CButton* >GetDlgItem(IDC_BUTTON1); CButton* >GetDlgItem(IDC_BUTTON2);

edit=(CEdit*) button=(CButton*) button2=(CButton*)

m_VarNuclear.dlgm_VarNuclear.dlgm_VarNuclear.dlg-

CString aux; aux="Begin sequence acquisition edit->ReplaceSel( aux,FALSE ); aux=""; //////////////////////////////////////////////////////////// AfxBeginThread (SequenciaNuclear,(LPVOID) THREAD_PRIORITY_NORMAL); } else { if (m_VarNuclear.m_bTriggerMode == FALSE) { // Print a message. ////////////////////////////////////// m_VarNuclear.dlg = new CDComents;

";

NULL

if (m_VarNuclear.m_bSequencia == TRUE) { // Print a message. //////////////////////////////////////

if(m_VarNuclear.dlg != NULL) { BOOL ret >Create(IDD_COMMENT,NULL); if(!ret) //Create failed. = m_VarNuclear.dlg-

AfxMessageBox("Error creating Dialog"); m_VarNuclear.dlg->CenterWindow(); m_VarNuclear.dlg->ShowWindow(SW_SHOW); } else AfxMessageBox("Error Creating Dialog Object");

CEdit* >GetDlgItem(IDC_EDIT1); CButton* >GetDlgItem(IDC_BUTTON1); CButton* >GetDlgItem(IDC_BUTTON2);

edit=(CEdit*) button=(CButton*) button2=(CButton*)

m_VarNuclear.dlgm_VarNuclear.dlgm_VarNuclear.dlg-

CEdit* >GetDlgItem(IDC_EDIT1); CButton* >GetDlgItem(IDC_BUTTON1); CButton* >GetDlgItem(IDC_BUTTON2);

edit=(CEdit*) button=(CButton*) button2=(CButton*)

m_VarNuclear.dlgm_VarNuclear.dlgm_VarNuclear.dlg-

CString aux; aux="Begin acquisition "; edit->ReplaceSel( aux,FALSE ); aux=""; //////////////////////////////////////////////////////////// AfxBeginThread (ShotTrigger,(LPVOID) m_myID THREAD_PRIORITY_NORMAL); } } }

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; if(m_VarNuclear.dlg != NULL) {

} 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;

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");

CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // apontador para main frame ASSERT (pAppFrame->IsKindOf(RUNTIME_CLASS(CMainFrame)));

else if (dlg.m_cscombo2=="CH4") pAppFrame->m_VarNuclear.m_lChannel2=M_CH3; 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; 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_DISP LAY_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_DISPL AY_8_BASIC; } 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; }

// TODO: Add your command handler code here 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; 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 ("No 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; 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() { /* allocation of MIL system. */ MsysAlloc(M_DEF_SYSTEM_TYPE, &m_VarNuclear.MilSystem); /* allocation of MIL display. */ M_DEV0, M_DEFAULT,

///Initialization of frame grabber////// /* allocation of MIL application. */ MappAlloc(M_DEFAULT, &m_VarNuclear.MilApplication); MappControl(M_ERROR,M_PRINT_DISABLE);

MdispAlloc(m_VarNuclear.MilSystem, M_DEF_DISPLAY_FORMAT,m_VarNuclear.m_lDispMode, &m_VarNuclear.MilDisplay[0]);

M_DEFAULT,

/* 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) ); M_SIZE_Y, (long)(MdigInquire(m_VarNuclear.MilDigitizer, &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 Reporting",MB_OK); //CWnd* destrwnd; //destrwnd->Attach(m_VarNuclear.m_hWndNuclear); //MDIActivate(destrwnd); CMDIFrameWnd* frame = (CMDIFrameWnd*) MDIGetActive(); CProjectDoc* documento = >GetActiveDocument(); documento->OnCloseDocument(); return; } ///////////////////////////////////////////// (CProjectDoc*) frame-

//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 ); M_WINDOW_OVERLAP , MdispControl(m_VarNuclear.MilDisplay[0], M_ENABLE);

parameter","Error

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_VarNuclea r.m_iSaturation); } //Digitizer initialization MdigControl(m_VarNuclear.MilDigitizer, m_VarNuclear.m_dImageScale); //ERROR////////////////////////////////////// MappGetError(M_CURRENT,&m_VarNuclear.ErrorPtr); if ( m_VarNuclear.ErrorPtr != M_NULL) { MessageBox("Some kind of invalide Reporting",MB_OK); M_GRAB_SCALE,

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_VarNucl ear.MilImage[0]); StartThreadNuclear(); AfxBeginThread (MilApplication,(LPVOID) THREAD_PRIORITY_NORMAL); } ProjectDoc.h NULL ,

parameter","Error

//nuclear// BOOL m_video_nuclear; //nuclear ProjectDoc.cpp

//CWnd* destrwnd; //destrwnd->Attach(m_VarNuclear.m_hWndNuclear); //MDIActivate(destrwnd); CMDIFrameWnd* frame = (CMDIFrameWnd*) MDIGetActive(); CProjectDoc* documento = >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 ))); //Nuclear// CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( CMainFrame (CProjectDoc*) framevoid 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* >m_pMainWnd; ASSERT(pAppFrame->IsKindOf(RUNTIME_CLASS( ))); pAppFrame->m_modeless = FALSE; } CMainFrame pAppFrame = (CMainFrame*) AfxGetApp()-

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 ) ) StopThreadNuclear(); /* Deselect the MIL buffer from the display. */ 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 ) ) StopThreadNuclear(); /* Deselect the MIL buffer from the display. */ MdispDeselect(pAppFrame->m_VarNuclear.MilDisplay[1], pAppFrame->m_VarNuclear.MilImage[1]); }

MdispFree(pAppFrame>m_VarNuclear.MilDisplay[0]); } if 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// (pAppFrame->m_VarNuclear.m_hWndNuclear2 !=

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]);

//Nuclear// void CProjectView::OnMednuclearCalibracaoGetpoints() {

// TODO: Add your command handler code here CProjectDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); { HDIB hDIB = pDoc->GetHDIB(); cal_point(hDIB);

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"); }

//Nuclear// void CProjectView::OnMednuclearDetectand3d() { // TODO: Add your command handler code here CDInitDetect3D dlg; if (dlg.DoModal() != IDOK ) return; CDdetect_3D* dialog; 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 AfxMessageBox("Error Creating Dialog Object"); } void CProjectView::OnCorrect() { // TODO: Add your command handler code here

Vous aimerez peut-être aussi