Você está na página 1de 80

INSTITUTO POLITCNICO DE LEIRIA

ESCOLA SUPERIOR DE TECNOLOGIA E GESTO


DEPARTAMENTO DE ENGENHARIA ELECTROTCNICA





AUTOBOT
CONDUO AUTNOMA F2


Relatrio final da Unidade Curricular de Projecto da Licenciatura em Engenharia
Electrotcnica, ramo de Energia e Automao




Autor:
Nuno Miguel Gonalves Reis
Orientadores:
Prof. Carlos Manuel Cerqueira Simplcio
Prof. Pedro Antnio Amado Assuno


Setembro 2010

I



Agradecimentos


Aos meus orientadores, Professor Carlos Manuel Cerqueira Simplcio e Professor Pedro Antnio
Amado Assuno, pelo estmulo, orientao e disponibilidade demonstrada ao longo do
desenvolvimento deste projecto.

Ao Professor Hugo Filipe Costelha de Castro, pela ajuda que me deu em diferentes aspectos no
decorrer deste projecto.

minha famlia, que sempre me proporcionou as condies necessrias para eu seguir o caminho que
escolhi e ao total apoio, dando fora e incentivo para que eu o atingisse.

A todos que, directa ou indirectamente, colaboraram para a realizao deste trabalho.

II



Resumo


O presente relatrio apresenta um sistema baseado em viso, para a navegao autnoma do rob
mvel Pioneer P3-DX, que inclui aquisio e processamento de informao visual (vdeo) com uma
cmara USB (webcam
1
) colocada sob a plataforma do rob. Este sistema est a ser desenvolvido com
o objectivo de participar no Festival Nacional de Robtica na prova snior de conduo autnoma
2
.
Neste trabalho so apresentados dois mtodos para a identificao visual das vias da pista onde circula
o rob.
Este relatrio est dividido em trs mdulos principais: o primeiro apresenta uma descrio do modelo
matemtico de uma cmara e suas transformaes assim como o processo para a calibrao da cmara
a ser aplicada no sistema de viso. O segundo mdulo, de extrao de caractersticas da imagem
recolhida, baseado no uso de algoritmos de viso computacional como o detector de bordos Canny
e a transformada de Hough, para identificao das vias. Descreve tambm a utilizao da funo de
Threshold e Histograma. O terceiro mdulo apresenta o software ARIA para o controlo do rob, assim
como as funes necessrias para o poder movimentar, de modo adequado, e a tomar as decises que
sejam consideradas correctas com base na informao gerada no segundo mdulo.


Palavras-chave: calibrao de cmara, viso computacional, OpenCV, conduo autnoma,
ARIA.


1
Foi usada a seguinte webcam: Logitech QuickCam chat
2
http://www.spr.ua.pt/fnr/

III



ndice


Agradecimentos ...................................................................................................................... I
Resumo ................................................................................................................................. II
ndice ................................................................................................................................... III
Lista de Abreviaturas ............................................................................................................ V
Lista de Figuras e Tabelas .................................................................................................... VI
1. Introduo ......................................................................................................................... 1
1.1 Consideraes Gerais ....................................................................................................... 2
1.2 Objectivos do trabalho ...................................................................................................... 2
1.3 Organizao do trabalho ................................................................................................... 3
2. Calibrao de uma cmara ................................................................................................. 4
2.1 Modelo de uma cmara e suas transformaes .................................................................. 4
2.2 Processo de calibrao ...................................................................................................... 8
2.3 Mtodo de Calibrao de Zhang ...................................................................................12
2.4 Implementao e resultados .............................................................................................13
3. Viso do Rob Viso computacional. ........................................................................... 15
3.1 Implementao da funo de Threshold ...........................................................................15
3.2 Extraco e visualizao do Histograma ..........................................................................17
3.3 Mtodo de identificao de uma via .................................................................................18
3.4 Mtodo de identificao de duas vias ...............................................................................21


IV
4. Controlo do Rob ............................................................................................................ 24
4.1 Introduo ao software ARIA ..........................................................................................24
4.2 Comandos utilizados .......................................................................................................25
4.3 Teste e Resultados ...........................................................................................................27
5. Concluses e Trabalho futuro .......................................................................................... 28
5.1 Concluses ......................................................................................................................28
5.2 Trabalho futuro e possveis melhorias ..............................................................................30
Referncias Bibliogrficas ................................................................................................... 31
ANEXOS ............................................................................................................................. 33
ANEXO I: Instalao do OpenCV no OpenSUSE 11.0 ..........................................................33
ANEXO II: Tutorial de instalao do OpenSUSE 11.3 no Pioneer P3-DX ..............................34
1. Material extra necessrio para instalao: .......................................................................34
2. Instalao dos componentes ...........................................................................................34
3. Backup do disco.............................................................................................................35
4. Instalao do OpenSUSE ...............................................................................................36
ANEXO III: threshold.c .........................................................................................................43
ANEXO IV: threshist.c ..........................................................................................................45
ANEXO V: Resultado da calibrao..........................................................................................49
ANEXO VI: Mtodo de identificao de uma via ......................................................................52
- Fluxograma.........................................................................................................................52
- Cdigo ................................................................................................................................53
ANEXO VII: Mtodo de identificao de duas vias ...................................................................61
- Fluxograma.........................................................................................................................61
- Cdigo ................................................................................................................................62



V



Lista de Abreviaturas


API Do Ingls Application Programming Interface
ARIA Do Ingls ActivMedia Robotics Interface for Applications
CCD Do Ingls Charge-Coupled Device
CMOS Do Ingls Complementary Metal-Oxide-Semiconductor
FNR Festival Nacional de Robtica
FOV Do Ingls Field of view
MI1V Mtodo identificao de uma via
MI2V Mtodo identificao de duas vias
OPENCV Do Ingls Open Source Computer Vision Library
PIXEL Do Ingls Picture element
SCC Sistema de Coordenadas da Cmara
SCI Sistema de Coordenadas da Imagem
SCM Sistema de Coordenadas do Mundo
SCP Sistema de Coordenadas em Pixels
SDK Do Ingls Software Development Kit
USB Do Ingls Universal Serial Bus


VI



Lista de Figuras e Tabelas

Figura 2.1. 1 Projeco 3D sobre uma superfcie plana. ................................................................... 5
Figura 2.1. 2 a) Modelo de uma cmara pontual; b) Sistema de eixos. .............................................. 5
Figura 2.1. 3 Geometria aproximada da cmara pontual [16]. .......................................................... 6
Figura 2.2. 1 Converso do sistema de coordenadas do objecto no sistema da Cmara [1]. ............... 9
Figura 2.3. 1 Imagens do chessboard [1]. ....................................................................................12
Figura 2.4. 1 Imagens do chessboard em diferentes posies. ......................................................13
Figura 2.4. 2 a) Imagem da correcta extraco de pontos; b) Incorrecta extraco de pontos. ..........13
Figura 3.2. 1 Histograma de uma imagem e escala de cinzentos. .....................................................17
Figura 3.3. 1 Colocao da cmara no rob. ...................................................................................18
Figura 3.3. 2 Imagem original do MI1V. ........................................................................................18
Figura 3.3. 3 a) Imagem em tons de cinzentos: b) Imagem com Threshold adaptativo. ....................19
Figura 3.3. 4 - Aplicao do filtro de Canny. .....................................................................................19
Figura 3.3. 5 Imagem Vector em anlise. .....................................................................................19
Figura 3.3. 6 Recta final do MI1V: a) Regio 1; b) Regio 2, c) Regio 3. ......................................20
Figura 3.3. 7 Deteco da passadeira. .............................................................................................21
Figura 3.4. 1 Imagem original com ajuste de brilho e contrate MI2V. .............................................21
Figura 3.4. 2 Imagem com Threshold adaptativo MI2V. ..................................................................22
Figura 3.4. 3 Aplicao da transformada de Canny MI2V. ..............................................................22
Figura 3.4. 4 Aplicao da transformada de Hough MI2V. .............................................................22
Figura 3.4. 5 Diviso da imagem por quadrantes.............................................................................23
Figura 3.4. 6 Resultado final do MI2V. ..........................................................................................23
Figura 4.3. 1 Regies do movimento do rob. .................................................................................27

VII
Anexos
Figura A2.1. 1 - a) Coneco do cabo IDE; b) Ligao dos dispositivos. ...........................................34
Figura A2.2. 1 Conector da fonte de alimentao. ...........................................................................35
Figura A2.2. 2 Montagem completa ...............................................................................................35
Figura A2.3. 1 Ambiente grfico do system rescue cd. ................................................................36
Figura A2.4. 1 a) Resoluo de ecr; b) Incio de instalao ...........................................................37
Figura A2.4. 2 Modo de instalao. ................................................................................................37
Figura A2.4. 3 Seleo do ambiente de trabalho. ............................................................................38
Figura A2.4. 4 a) Editar parties; b) Detalhe do disco. ..................................................................38
Figura A2.4. 5 Novo utilizador .......................................................................................................39
Figura A2.4. 6 a) Boot loader settings; b) Boot loader Options. ......................................................39
Figura A2.4. 7 Seleo de software. ...............................................................................................40
Figura A2.4. 8 Instalao dos pacotes e final da instalao. ............................................................40
Figura A2.4. 9 Configurao do servio SSH. ................................................................................40
Figura A2.4. 10 Instalao do software. ..........................................................................................41
Figura A2.4. 11 Hostname e domnio. ............................................................................................41
Figura A2.4. 12 a) Teste de coneco; b) Fim de teste. ...................................................................41
Figura A2.4. 13 a) Online Update; b) Download e instalao. .........................................................42
Figura A2.4. 14 Fim da instalao do OpenSUSE. ..........................................................................42
Figura A3. 1 a) Valor de Threshold 80. Iluminao natural; b) iluminao direccionada. ................44
Figura A3. 2 a) Valor de Threshold 150. Iluminao natural; b) iluminao direccionada. ..............44
Figura A4. 1 Valor de Threshold dinmico com fraca iluminao. ..................................................48
Figura A4. 2 Valor de Threshold dinmico com pouca iluminao. ................................................48
Figura A4. 3 Valor de Threshold dinmico com iluminao............................................................48





VIII
Tabelas
Tabela A2. 1 Detalhes dos discos rgidos. ........................................................................................38

Fluxogramas

Fluxograma 1 Mtodo de identificao de uma via .........................................................................52
Fluxograma 2 Mtodo de identificao de duas vias .......................................................................61



1



1. Introduo


A viso por computador cada vez mais utilizada como um conjunto de mtodos e tcnicas de
computao digital atravs dos quais os sistemas computacionais podem ser capazes de analisar e
interpretar imagens. Um dos objectivos da viso por computador , na robtica mvel, permitir
desenvolver sistemas para modelar e manipular o ambiente real no qual o rob se situa, atravs de
sensores [6].
Diversas tarefas podem assim ser realizadas com a utilizao de imagens capturadas por uma cmara
(ou vrias), sendo possvel extrair informaes do mundo real (3D) para, ps-processamento, fazer
actuar um rob mvel de acordo com os dados retirados da anlise da imagem adquirida. Sistemas de
viso podem assim ser usados como solues ou simplificaes para problemas de deteco e
localizao de objectos, obstculos ou formas.
Um rob mvel consiste numa plataforma mvel sobre a qual integrada, de forma inteligente,
percepo e aco sobre o mundo que o rodeia.
- A aco guia e controla o rob durante o seu movimento.
- A percepo recolhe os dados dos sensores (neste caso a cmara), interpretando-os de
forma a melhorar a compreenso do mundo envolvente e prope aces.

A introduo de viso num rob mvel traduz-se num significativo aumento das suas capacidades
sensoriais e, portanto, num correspondente aumento de versatilidade e segurana nas suas operaes.
A deteco de obstculos uma tarefa fundamental quando se pretende que um rob mvel se
desloque sem colises num ambiente onde existem, partida, obstculos fixos ou mveis durante o
percurso efectuado pelo rob.
Contudo este relatrio destina-se essencialmente navegao do rob num ambiente isento de
obstculos e ao longo do percurso pr-definido.



2

1.1 Consideraes Gerais

Para a concretizao dos objectivos propostos foram utilizadas duas ferramentas essenciais:
- Para a parte de processamento de imagem, a biblioteca OpenCV. Esta ferramneta possui um
vasto conjunto de funes em linguagem C/C++ implementando alguns dos algoritmos mais
usuais para a aquisio e tratamento de imagens por computador. Possui funes para
captura da imagem de uma cmara e para a execuo de operaes sobre essas imagens que
facilmente se podem exibir. Contm implementado um mtodo de calibrao usado e
descrito neste relatrio. Para o mtodo de identificao de uma via desenvolvido, apenas foi
utilizada a linguagem C.
- Para a parte de controlo do rob foi utilizado o software ARIA. Escrita em linguagem C++,
ARIA uma API orientada a objectos destinada criao de software de alto nvel.
essencialmente uma biblioteca de programao C++ para controlo do rob.

Neste trabalho so propostos dois mtodos para identificao das vias:
- No mtodo de identificao de uma via foi considerado que o rob circula junto via mais
direita e que segue somente essa via restrigindo assim o problema de identificao das duas
vias utilizando uma s cmara (ver seco 3.3).
- O mtodo de identificao de duas vias foi implementado atravs de vdeo (pr-gravado),
no ficando este vlido nos testes efectuados em ambiente real. Neste mtodo considerado
que o rob se encontra ao meio da pista, entre as duas vias, mantendo sempre a sua
trajectria entre as mesmas (ver seco 3.4).

1.2 Objectivos do trabalho

Com este projecto pretende-se desenvolver um sistema de conduo autnoma, baseado em aquisio
e processamento de informao visual (vdeo), recorrendo ao rob Pioneer P3-DX e a uma cmara de
vdeo USB (webcam), tendo em vista a criao do software para identificao das vias da estrada
(pista) onde o rob se movimenta e controlo do rob ao longo da mesma.
Este trabalho pretende tambm descrever os procedimentos efectuados ao longo do projecto e
introduzir alguns conceitos base para o seu desenvolvimento.


3
1.3 Organizao do trabalho

Numa primeira fase, comeou-se por aprofundar conhecimentos sobre o sistema operativo OpenSUSE
11, para efectuar a importao da biblioteca OpenCV 2.0.0 (ANEXO I) , que mais tarde veio a ser
substituido pela verso OpenSUSE 11.3 (ANEXO II) passando-se depois ao estudo de alguns
exemplos e funes mais importantes implementadas na biblioteca OpenCV.
Para a segunda fase efectuou-se um estudo sobre a implementao da funo Threshold (ver seco
3.1) e o histograma (ver seco 3.2) numa imagem previamente adquirida. Desenvolveu-se cdigo (em
linguagem C) para a reproduo de vdeo, gravado em memria ou capturado pela cmara, em escalas
de cinzentos, com o respectivo histograma e binarizado utilizando a funo threshold.
Na terceira fase, procedeu-se ao estudo do mtodo de calibrao da cmara (ver seco 2.2). Para isso
foi necessrio uma pesquisa mais aprofundada sobre geometria projectiva e projeco de perspectiva
(aprofundando tambm conhecimentos de lgebra), sobre o modelo matemtico de uma cmara, o
mtodo de calibrao da cmara proposto por Zhang (existente no OpenCV) e a descrio dos
parmetros devolvidos ao realizar a calibrao.
A fase seguinte foi dedicada elaborao do algoritmo para o MI2V com recurso a um video, no qual
se simulou o precurso efectuado pelo rob visualizando as duas vias, pois at data no havia um
ambiente real para efectuar os testes.
Aps efectuada a montagem da pista foi iniciada a ltima fase do projecto. Esta fase consitiu no estudo
do software ARIA (SDK), para desenvolver o controlo do rob, procedendo-se alterao do mtodo
ateriormente desenvolvido para efectuar os testes em ambiente real. Verificou-se que este mtodo no
era vlido pois a cmara utilizada no tinha um FOV
3
necessrio para se poder visualizar as duas vias
da pista. Posto isto foi desenvolvido o MI1V que se tornou o mtodo final para este trabalho.


3
Representa a rea visvel do objeto em estudo que incide sobre o sensor, ou seja, a poro do objeto do ambiente real que
preenche a rea do sensor.

4



2. Calibrao de uma cmara


Nesta seco apresentado um modelo matemtico de uma cmara e alguns conceitos bsicos de
geometria projectiva e projeco de perspectiva. Estes conceitos esto associados ao processo de
captao de uma imagem (associado ao sensor) e forma como se podem relacionar as coordenadas
tridimensionais de um ponto (3D) com a sua projeco no plano da imagem (2D).
descrito tambm o processo de calibrao da cmara usada, bem como o mtodo utilizado para tal
(facilitando a sua posterior utilizao). Este processo d-nos um modelo de geometria da cmara e um
modelo de distoro da lente, assim como uma estimativa do posicionamento e orientao da cmara
relativamente a um objecto do mundo 3D.
Para este trabalho, a calibrao da camar em causa foi realizada usando o mtodo de calibrao de
Zhang [8], pois este simples de realizar e encontra-se disponvel na biblioteca do OpenCV.

2.1 Modelo de uma cmara e suas transformaes

Do ponto de vista do desenvolvimento de sistemas de viso o problema de aquisio de imagem
simplificado, pois existe uma grande variedade de cmaras de vdeo
4
(webcam) no mercado,
digitalizando sinais de vdeo produzidos pela cmara, memorizando-os [7].
Para desenvolver algoritmos de viso por computador importante perceber o processo de formao
da imagem, ou seja, a relao entre o espao tridimensional (o mundo real) e a imagem bidimensional
que capturada pela cmara.
A projeco de um ponto 3D no plano de imagem 2D pode ser descrita por uma projeco de
perspectiva, que uma representao aproximada projeco feita pelo olho humano, quando este
capta imagens de um objecto atravs de uma superfcie plana (Fig.2.1.1).


4
Tipicamente baseadas em sensores fotoelctricos (CCD ou CMOS). Emitem um sinal elctrico em funo da intensidade de
ondas electromagnticas (com um determinado comprimento de onda) que incide sobre o sensor.

5
A geometria projectiva fornece um modelo linear do processo de formao da imagem (se no houver
distoro
5
), que relaciona figuras geomtricas com a sua projeco, isto , mapeia as coordenadas do
mundo real nos pontos do plano da imagem. Um exemplo comum usado o de figuras 3D com
projeces no plano 2D.

Figura 2.1. 1 Projeco 3D sobre uma superfcie plana.

O modelo mais simples de uma cmara, para obter na imagem a posio de um dado ponto
tridimensional, um modelo de cmara pontual (pin-hole cmera model) que baseado na
geometria perspectiva (Fig.2.1.2). Tal modelo pode ser representado por uma caixa fechada com um
pequeno orifcio (um ponto). Os raios luminosos passam por este orifcio (centro de projeco) e
atingem o plano do fundo da caixa, onde a imagem se forma no sensor de imagem.
A distncia do objecto e o comprimento da caixa influenciam na altura da imagem formada.

a) b)
Figura 2.1. 2 a) Modelo de uma cmara pontual; b) Sistema de eixos.

Para a cmara pontual ideal, a distncia entre o orifcio e o plano de imagem precisamente a
distncia focal
6
(. a distncia entre a cmara e o objecto, o comprimento do objecto e a
imagem do objecto no plano de imagem, sendo que neste modelo a imagem aparece invertida (Figura
2.1.2b).


5
Na realidade as lentes provocam distores, o que equivalem as no-lineariedades da geometria projectiva.
6
A distncia focal de uma cmara a distncia existente entre ela e o seu foco. No presuposto que a lente da cmara
convergente, a distncia focal assume valores positivos.

6
usado ento, para a cmara pontual, um modelo aproximado em que o ponto do orifcio (centro de
projeco) intrepretado como o centro da cmara ou centro ptico. A recta perpendicular ao plano da
imagem que passa pelo centro da cmara chamada de eixo principal da cmara. O ponto onde o eixo
principal encontra o plano da imagem chamado de ponto principal. No plano da imagem as
coordenadas so expressas em pixels, enquanto nos outros sistemas em unidades de comprimento (por
exemplo, coordenadas mtricas).
O plano da imagem colocado agora frente do sensor (centro da cmara) e o sistema de coordenada
reorientado, aparecendo assim a imagem do objecto no sentido directo (Figura 2.1.3). Neste caso o
modelo afasta-se um pouco da realidade, mas adapta-se melhor aos actuais dispositivos de aquisio e
exibio de imagens.

Figura 2.1. 3 Geometria aproximada da cmara pontual [16].

O modelo aproximado da cmara pontual caracterizado por uma relao de tringulos. As equaes
2.1 e 2.2 relacionam as coordenadas de um ponto tridimensional com as coordenadas da sua projeco
bidimensional.
Quanto maior a distncia do objecto, menor a sua imagem e quanto maior for a distncia entre o
orifcio da caixa e o seu fundo, maior ser a imagem formada.

(2.1)

(2.2)

Nas equaes anteriores (2.1 e 2.2) foram introduzidas duas distncias focais diferentes pois
geralmente os pixels so rectangulares e no quadrados. Tambm o centro da cmara no ,
geralmente, sobre o eixo principal, sendo introduzidos dois novos parmetros,

, que podem ser


entendidos como um possvel deslocamento do centro de coordenadas (centro da cmara) em relao
ao eixo principal.

7
Como tal, o ponto , cujas coordenadas reais so , agora projectado no plano, conforme as
seguintes equaes:

(2.3)

(2.4)

Ento, segundo o modelo da cmara pin-hole, um ponto 3D com coordenadas


mapeado para o ponto

, onde passa a recta que passa por e pelo centro de projeco ,


conforme ilustrado na Figura 2.1.3. Desta forma, o ponto

mapeado para o ponto


sobre o plano da imagem. Ignorando a coordenada Z, tem-se:



(2.5)

Representando os pontos tridimensionais e os pontos da imagem por vectores de coordenadas
homogneas, pode-se expressar a projeco central como um mapeamento linear entre esses vectores.
Desta forma, a equao (2.5) pode ser escrita como uma multiplicao de matrizes:

(2.6)

Basicamente, como descrito na equao 2.6, este modelo aplica uma matriz de projeco para
transformar as coordenadas 3D dos pontos do objecto (coordenadas do mundo) em coordenadas 2D da
imagem:
=


Por outro lado, para encontrar as coordenadas em relao ao eixo real (3D), sabendo as coordenadas
da imagem (2D), aplica-se o clculo inverso:

=




8
2.2 Processo de calibrao

A calibrao de uma cmara um processo que realizado para que seja possvel obter informaes
(mtricas) 3D a partir de uma imagem 2D capturada pela cmara [8]. Nesse processo obtido um
conjunto de parmetros que nos do essas informaes.
Os referidos parmetros incluem a geometria interna e ptica da cmara (caractersticas intrnsecas), e
a estimativa do posicionamento e da orientao da cmara associada a uma determinada imagem
(caractersticas extrnsecas).
A aquisio desses parmetros pode ser dividida em duas etapas:
- Determinao dos parmetros intrnsecos
- Determinao dos parmetros extrnsecos

Os parmetros intrnsecos descrevem a forma como a cmara cria uma imagem, fornecendo a relao
entre a imagem e a cmara. Consiste em determinar as propriedades intrnsecas da cmara, tais como:
distncia focal , centro da imagem , coeficiente de distoro das lentes e factor de escala. Estes
parmetros so importantes para poder relacionar as coordenadas de um pixel da imagem com as
coordenadas correspondentes do referencial da cmara.
Os parmetros extrnsecos indicam a posio e a orientao da cmara. So definidos como um
conjunto de parmetros que identificam a transformao entre um referencial desconhecido e o
referencial do mundo, ou seja, um referencial conhecido.
Para expressar a correspondncia entre pontos do espao e pontos da imagem conveniente considerar
quatro sistemas de coordenadas de modo a que a transformao da cmara possa ser expressa como a
composta de transformaes simples realizadas entre estes sistemas.

Os sistemas de coordenadas considerados so:
- SCM Sistema de Coordenadas do Mundo :
Sistema tridimensional em que as suas coordenadas descrevem a posio de pontos 3D do
objecto real, coordenadas do mundo real.
- SCC Sistema de Coordenadas da Cmara


Sistema tridimensional com origem no centro ptico da cmara ,ou seja, o orifcio (para o
caso de uma cmara pin-hole), em que as suas coordenadas descrevem a posio do ponto
3D em relao cmara (coordenadas locais da cmara). O plano de projeco o plano de
equao

.

9
- SCI Sistema de Coordenadas da Imagem
Sistema bidimensionalem em que as suas coordenadas descrevem a posio do pondo 2D em
relao ao plano da imagem.
- SCP Sistema de Coordenadas em Pixel
Sistema bidimensional, com coordenadas expressas em pixels, que define a posio de um
ponto da imagem na matriz de pixels.

Para cada imagem (frame) tirada pela cmara podemos descrever a posio do objecto em relao ao
SCC em termos de rotao e translao. O primeiro passo na obteno da posio na
imagem2D, correspondente ao ponto do espao 3D , expressar estas coordenadas
tridimensionais no SCC.

Figura 2.2. 1 Converso do sistema de coordenadas do objecto no sistema da Cmara [1].

A rotao feita em trs dimenses pode ser decomposta numa matriz bidimensional da rotao feita
em torno de cada eixo. Se rodarmos em torno de com os respectivos ngulos o
resultado a matriz R (rotao total) que dada pelo produto das trs matrizes:

, e





;

Ou seja,







(2.7)

10
Assim, sendo


o vector de coordenadas do ponto no SCC,

vector de coordenadas do ponto no


sistema de coordenadas do objecto (SCM) e o vector de translao, temos a seguinte equao:

(2.8)

Em coordenadas Homogneas:

(2.9)

A transformao do SCC para o SCI, em cmaras pin-hole, consiste numa projeco perspectiva. A
projeco perspectiva efectuada por uma cmara pin-hole com distncia focal pode ser escrita como:

(2.10)

Do sistema de coordenadas da imagem (SCI) para o sistema de coordenadas em pixel (SCP):

(2.11)

Os coeficientes da matriz acima representada formam, juntamente com a distncia focal , os
parmetros intrnsecos da cmara. Os significados destes parmetros so os seguintes:
-

representam o nmero de pixels por unidade de comprimento nas direces


horizontal e vertical, respectivamente. Idealmente

so iguais, ou seja, os pixels so


quadrados;
-

fornecem a posio, em pixels, da projeco ortogonal, , da origem sobre o plano


de projeco. Na maior parte das cmaras, est no centro da imagem e os valores de

so idealmente iguais metade das respectivas dimenses da imagem.



11
- a tangente do ngulo que as colunas de pixels formam com a perpendicular s linhas. Na
maior parte das cmaras, idealmente, as colunas so perpendiculares s linhas, ou seja, = 0.

Posto isto, a transformao que leva um ponto do sistema de coordenadas do mundo sua projeco
no sistema de coordenadas em pixel pode ser obtida multiplicando as transformaes das equaes
(2.9), (2.10) e (2.11):

(2.12)

Ou ainda,


(2.13)



Como os parmetros ,

aparecem na transformao da cmara atravs dos seus produtos


(

) no possvel estimar os seus valores individuais.


Assim sendo, a matriz dos parmetros intrnsecos da cmara (K), que a matriz para converso de
coordenadas mtricas para pixels, ou seja, do SCM para o SCP, dada da seguinte forma:






12

2.3 Mtodo de Calibrao de Zhang

Para resolver o problema de calibrao da cmara, ou seja, determinar os parmetros intrnsecos e
extrnsecos, foi utilizado o mtodo proposto por Zhang. Este mtodo usa um padro (bidimensional)
que posicionado de diversas formas no espao dando origem a m imagens (conforme ilustrado na
Figura 2.3.1). Em cada uma destas imagens admitimos que h n pontos cujas coordenadas no sistema
de referncia do padro so conhecidas. Admitimos ainda que os parmetros intrnsecos da cmara so
os mesmos em todas as imagens. Somente os parmetros extrnsecos mudam quando o padro
reposicionado.

Figura 2.3. 1 Imagens do chessboard [1].

O facto de termos mais do que uma imagem do padro permite que, no mtodo de Zhang, possamos
ajustar um modelo mais geral de cmara, definido por uma transformao, em coordenadas
homogneas, e que se representa da seguinte forma:

(2.14)

A restrio ao plano de Z = 0 define uma transformao projectiva, ou homografia, entre este plano e o
plano imagem.
Etapas do mtodo de Zhang:
- Primeira etapa - obteno de um conjunto de imagens do padro de calibrao segundo
diferentes orientaes e posies no espao;

13
- Segunda etapa: extraco dos vrtices dos quadrados que constituem o padro de calibrao
em todas as imagens adquiridas;
- Terceira etapa: clculo dos parmetros intrnsecos, extrnsecos e de distoro da cmara
considerada.

2.4 Implementao e resultados

Para a realizao da calibrao foi utilizado um padro de oito vrtices por seis e com 2,9cm de
distncia entre eles (figura 2.4.1). Este padro foi posicionado em vrias formas perante a cmara.
Segue-se um exemplo da aquisio de vrias imagens do padro de calibrao utilizando uma cmara
digital convencional:

Figura 2.4. 1 Imagens do chessboard em diferentes posies.

As seguintes imagens demonstram um exemplo da extraco automtica dos vrtices dos quadrados
do padro de calibrao nas imagens adquiridas, utilizando o algoritmo de Zhang que se encontra
implementado nos exemplos do OpenCV (calibration.cpp):

a) b)
Figura 2.4. 2 a) Imagem da correcta extraco de pontos; b) Incorrecta extraco de pontos.


14
Dos resultados obtidos, podemos retirar os parmetros que nos permitem preencher a matriz de
transformao , assim como a posio e orientao da cmara em relao ao padro de
calibrao usado. Utilizando 5 imagens do padro de calibrao, em que todos os vrtices foram
correctamente detectados, foi realizada a calibrao da cmara, obtendo-se os seguintes parmetros
intrnsecos.

- Distncia focal:


- Ponto principal:



O resultado da realizao da calibrao encontra-se em anexo (ANEXO V) com mais detalhes
relativamente aos parmetros extrnsecos e de distoro da lente.

15



3. Viso do Rob Viso computacional.


O sistema de navegao do rob mvel utilizado baseado num sistema de viso com uma nica
cmara. Este sistema composto por uma srie de algoritmos executados sequncialmente para
cumprir tarefas pr-determinadas de navegao dentro de pista.
Neste captulo so apresentadas algumas tcnicas e conceitos bsicos teis no processamento de
imagens e viso por computador, assim como os algoritmos desenvolvidos para a identificao das
vias. Os algoritmos foram implementados em linguagem C com recurso a funes existentes na
biblioteca OpenCV [1].

3.1 Implementao da funo de Threshold

A funo de threshold usada essencialmente com o objectivo de segmentar
7
a imagem obtida em
tons de cinzentos, numa imagem binria (dois tons - preto e branco). Esta tcnica procura agrupar os
diferentes objectos e regies da imagem conforme o nvel de intensidade luminosa, ou seja, pretende
separar os objectos (vias da estrada) do fundo da imagem (pavimento).
A ideia , dado um valor de threshold , restringir o valor dos pixels a um de dois valores de modo a
obtermos uma imagem binarizada, ou seja:
- Valor 0 binrio (cor preta);
- Valor 1 binrio (cor branca).





(2.15)


7
Em viso computacional, segmentao refere-se ao processo de dividir uma imagem digital em mltiplas regies (conjunto
de pixels) ou objectos, simplificando a representao de uma imagem facilitando a sua anlise.

16
Numa imagem com 256 tons de cinzento, caso , as tonalidades entre 0 e 50
tornam-se informao de fundo da imagem (cor preta) enquanto que os valores superiores a 50
tornam-se informao correspondente aos objectos da imagem.
Desta forma, a definio de um valor de threshold suficiente para dividir a imagem em duas regies:
fundo e objectos, sendo til quando existe um bom contraste entre essas regies.
Existem dois mtodos de Threshold em imagens: o fixo e o adaptativo. Comeou-se por implementar
o mtodo fixo, sendo criado o ficheiro threshold.c (ANEXO III). Neste mtodo fixa-se o valor de
threshold. No OpenCV, este mtodo implementado na funo cvThreshold ().
Um dos problemas de usarmos um valor fixo de threshold em termos de iluminao e contraste, pois
se o objecto e o fundo no tiverem nveis de iluminao distintos, isto , a existncia de um bom
contraste entre ambos, difcil separar o fundo do objecto, tornando-se por vezes impossvel.
O mtodo adaptativo j nos permite resolver melhor esse problema. Nesse mtodo o valor de threshold
uma varivel que depende de valores obtidos da anlise do histograma da imagem, em que se
calcula o valor mdio da intensidade dos pixels de duas regies

relativamente ao
valor de threshold inicial. Assim, temos:

(2.16)

Esta tcnica torna-se til quando existem variaes de iluminao, provocando variaes de contraste.
Foi criado ento o ficheiro threshist.c (ANEXO IV) para reproduzir vdeo em tons de cinzentos, o
respectivo histograma, e utilizao de um threshold dinmico.


17
3.2 Extraco e visualizao do Histograma

O histograma de uma imagem representa, para cada nvel de intensidade, o nmero de pixels desse
nvel, ou seja, o eixo horizontal refere-se intensidade (0 a 255) e o eixo vertical quantidade de
pixels que apresenta essa intensidade.

Figura 3.2. 1 Histograma de uma imagem e escala de cinzentos.

Uma das utilidades de um histograma o realce de imagens a partir da sua equalizao. A equalizao
consiste numa transformao da imagem a partir da resistribuio dos nveis de intensidade luminosa
dos seus pontos, de forma a atingir uma distribuio mais uniforme de uma faixa ou de todas as faixas
do histograma da imagem.
Desta forma, imagens escuras teriam os nveis de intensidades redistribudos gerando um histograma
mais uniforme, ou seja, resulta numa imagem mais clara e ntida, com maior contraste entre o objecto
e o fundo da imagem. O mesmo principio pode ser aplicado a imagens muito claras, realando
caractersticas importantes da imagem.
A extraco e anlise do histograma so relevantes para a escolha do valor de threshold, pois
analisando o histograma de uma imagem em tons de cinza verificamos que os pixels pertencentes ao
objecto (vias da estrada) se encontram mais direita e os pixels referentes ao fundo mais esquerda,
de intensidades predominantemente baixas.
Assim, como referido na seco anterior, atravs da anlise do histograma da imagem, calcula-se a
rea esquerda e direita do valor de threshold para a obteno de um novo valor de threshold
(ANEXO IV).


18
3.3 Mtodo de identificao de uma via

Neste mtodo foi desenvolvido um sistema para identificao de uma via. Este sistema inclui uma
cmara colocada sobre a plataforma do rob de modo a visualizar a via mais direita da pista (Figura
3.3.1).

Figura 3.3. 1 Colocao da cmara no rob.

Desta forma visualiza-se somente a via de interesse para anlise. Essa via ser utilizada como principal
guia para o movimento do rob.
Ao colocarmos o rob na pista ele dever ser posicionado de forma a obter a imagem da via com a
seguinte representao:

Figura 3.3. 2 Imagem original do MI1V.

Ou seja, a parte superior da via dever ficar ao centro da parte superior da imagem, pois necessrio
para o funcionamento correcto do MI1V.
Seguidamente procede-se anlise da imagem. Esta ser convertida para tons de cinzentos (Figura
3.3.3a) para que seja possvel aplicar a funo de threshold adaptativo implementada no OpenCV em
cvAdaptiveThreshold () (Figura 3.3.3b).

19

a) b)
Figura 3.3. 3 a) Imagem em tons de cinzentos: b) Imagem com Threshold adaptativo.

Como a imagem passa a ter dois tons, preto e branco (fundo e objecto, respectivamente), procede-se
ao algoritmo de Canny (implementado no OpenCV em cvCanny()) para retirar os contornos da
imagem adquirida (Figura 3.3.4).
Esse algoritmo essencial neste mtodo, pois atravs dele que se extraem as caractersticas
necessrias para o posterior controlo do rob.

Figura 3.3. 4 - Aplicao do filtro de Canny.

Uma imagem pode ser considerada como uma matriz , em que corresponde resoluo
horizontal da imagem e resoluo vertical. Para anlise foi considerada uma imagem com a
resoluo de 320x240 (pixels).

Figura 3.3. 5 Imagem Vector em anlise.

20
Analisando a imagem da Figura 3.3.4 podemos retirar ento caractersticas (os pontos de interesse).
Isto , percorrendo o vector superior da imagem , analisamos todas as posies desse vector
at serem encontrados pontos brancos, ou seja, com o valor 255, e guardam-se esses valores que
correspondem coordenada , para , do pixel detectado (Figura 3.3.5).
Portanto, encontrada a posio dos pontos de referncia no vector em causa (crculos a branco na
Figura 3.3.6), achada a mdia aritmtica (designado por ponto mdio) das posies encontradas (em
termos de coordenadas em pixel), para que se possa traar a recta final. Essa recta indica a regio
que o rob se encontra (Figura 3.3.6) e traada do ponto mdio at ao centro da imagem (160,120).

a) b) c)
Figura 3.3. 6 Recta final do MI1V: a) Regio 1; b) Regio 2, c) Regio 3.

Foi considerado para anlise um vector com 320 posies, correspondente resoluo horizontal da
imagem. O movimento do rob pode ser definido em quatro regies (ver seco 3.3) e efectuado
perante as seguintes situaes:
- Regio 1: Se o ponto mdio estiver entre 150 e 170 o rob segue em frente;
- Regio 2: Se o ponto mdio for menor que 150 e for maior ou igual que 50 o rob vira para a
direita com velocidade de rotao 1;
- Regio 2: Se o ponto mdio for maior que 170 e for menor ou igual que 270 o rob vira para a
esquerda com velocidade de rotao 1;
- Regio 3: Se o ponto mdio for maior que 270 e for menor que 320 o rob vira para a
esquerda com velocidade de rotao 2;
- Regio 3: Se o ponto mdio for menor que 50 e for maior que 0 o rob vira para a direita com
velocidade de rotao 2;
- Regio 4: Qualquer outro caso o rob pra ( ponto mdio <= 0 e ponto mdio >= 320) .

Considera-se que a velocidade de rotao 1 inferior velocidade de rotao 2. Isto para que, como o
ponto mdio se est a aproximar das margens da imagem, fazer com que o rob vire mais rpido de
forma a colocar o ponto mdio novamente entre os valores aceitveis, ou seja, mais ao centro da parte
superior da imagem.

21
Ao ser detectada a passadeira, e como em ambiente real s existe metade da pista, foi considerado que
o rob pra no instante em que so encontrados mais que dez pontos brancos no vector em anlise.

Figura 3.3. 7 Deteco da passadeira.

3.4 Mtodo de identificao de duas vias

Este mtodo foi desenvolvido com recurso a um vdeo, facultado pelos alunos de mestrado em
robtica avanada, que simula as faixas de rodagem onde o rob se movimenta, como ilustrado na
Figura 3.4.1.
Na aquisio da imagem original foram introduzidas duas barras para ajuste do brilho e do contraste,
pois ajuda a retirar algum rudo para a utilizao da funo de Threshold por forma a posteriormente
se extrair os contornos das vias (baseado no filtro de Canny) e detectar as rectas com a transformada
de Hough (implementada no OpenCV em cvHoughLines2()).

Figura 3.4. 1 Imagem original com ajuste de brilho e contrate MI2V.

Aps o carregamento do vdeo so retiradas vrias imagens (frames) para que a anlise seja feita frame
a frame. De seguida aplicado um procedimento para transformar a imagem a cores em tons de
cinzento, numa escala de oito bits, para que se possa utilizar a funo de threshold. Neste mtodo foi
utilizada a funo de threshold adaptativo (invertido).

22

Figura 3.4. 2 Imagem com Threshold adaptativo MI2V.

Seguidamente, como a imagem j se encontra binarizada, podemos aplicar o filtro de Canny. Com a
filtro de Canny podemos obter os contornos dos objectos existentes (neste caso, das vias).

Figura 3.4. 3 Aplicao da transformada de Canny MI2V.

Para retirar os pontos de interesse dos contornos obtidos necessrio utilizar a transformada de Hough
que, quando aplicada frame em anlise, nos d os pontos de incio e fim de cada recta encontrada.
Neste caso no foram traadas as rectas, mas sim marcados os pontos iniciais e finais das mesmas. Na
figura seguinte so ilustrados esses pontos de interesse.

Figura 3.4. 4 Aplicao da transformada de Hough MI2V.

Cada frame dividida em quatro quadrantes relativamente resoluo da imagem adquirida (Figura
3.4.5):

23

Figura 3.4. 5 Diviso da imagem por quadrantes.

Para cada quadrante analisada a posio de cada ponto encontrado no plano da imagem aplicando o
transformada de Hough, ou seja, so retiradas as coordenadas de cada ponto (em pixels) para que seja
possvel obter a mdia da posio dos pontos em cada quadrante. Essa mdia ser utilizada para traar
a recta que indica a posio e a orientao que o rob deve tomar para seguir o seu caminho.
Ou seja, o ponto superior da recta final ser dado pela soma da posio dos pontos do primeiro e
segundo quadrante, dividida por dois, enquanto o ponto inferior dado pela soma da posio dos
pontos do terceiro e quarto quadrante, dividida tambm por dois. O resultado final ilustrado na figura
seguinte.

Figura 3.4. 6 Resultado final do MI2V.

Aps ser traada a recta final (recta a verde) consegue-se ento determinar os parmetros necessrios
para fazer actuar o rob.
Esses parmetros so o ngulo formado entre a recta final e o eixo horizontal (a branco), e o desvio
dessa mesma recta em relao ao centro da imagem. Com esses parmetros conseguimos que o rob se
mantenha ao centro das vias, como pretendido pelo MI2V.


24



4. Controlo do Rob


Nesta seco apresentada uma introduo ao software ARIA assim como a descrio dos comandos
mais importantes para a utilizao e controlo do rob.
O comportamento do rob baseado somente na classe ArRobot, pois apenas foi implementado em
ambiente real o MI1V (ver seco 3.3), pelo que somente necessrio o rob efectuar movimento para
a frente, de rotao para a esquerda, de rotao para a direita e parar.

4.1 Introduo ao software ARIA

O software ARIA fornecido pelos fabricantes Pioneer, MobileRobots Inc, e pode ser usado para
controlar qualquer um dos seus modelos. essencialmente uma biblioteca para programadores C++
que se destina criao de software de alto nvel para controlar do rob [21].
Contudo necessrio estar familiarizado com o uso de conceitos tpicos de linguagem C++, incluindo
o uso de classes e objectos com uma hierarquia simples, construtores, apontadores e o processo de
compilao do cdigo [4] [5].
O software ARIA inclui muitas ferramentas utis para a programao dos robs. Pode ser acedida em
diferentes nves, desde um simples envio de comandos para o rob atravs da classe ArRobot ou o
desenvolvimento mais de alto nvel como o comportamento do rob atravs de aces (no abordado
neste trabalho).
Atravs da sua infra-estrutura de aces, ARIA fornece um mecanismo poderoso para combinar
comportamentos independentes, de forma a alcanar o controlo de movimentos coordenados e
orientao inteligente.
A classe mais importante do ARIA a classe ArRobot. Esta classe controla o ciclo de comunicao
com o firmware, recebendo e fornecendo acesso os dados sobre o estado do rob, desencadeando as
tarefas pretendidas determinando os comandos a serem enviados para o rob.


25
4.2 Comandos utilizados

A classe ArRobot , para alm de muitas outras classes existentes na biblioteca do ARIA, a classe base
para comunicao e operao do rob, actuando como um gateway de comunicaes cliente-servidor.
ArRobot contem todas as informaes primrias sobre o rob a ser controlado, representando uma
base padro, sem sensores, apenas com os motores como actuadores [19].
Relativamente programao, para que se possa usar a biblioteca do ARIA importante que esta seja
inicializada no nosso programa (cdigo). Para tal usa-se o seguinte comando:
Aria::init ();
Este comando deve de ser inserido no inicio da funo main principal do programa, ou seja, antes de
efectuar qualquer aco ou operao do rob. No final, em vez de se usar o retorno padro para
abandonar o programa, ou seja, return (0); usa-se o seguinte comando:
Aria::exit (0);
Para que se mantenha uma uniformidade entre os programas baseados em ARIA, a biblioteca vem
com um analizador de argumentos padro. Durante a inicializao de um programa (na linha de
comandos da consola, no OpenSUSE), este analizador pode ser usado para garantir que todos os
elementos configurveis de um programa baseado em ARIA (endereo IP do rob, etc) possam ser
transmitidos da mesma forma em qualquer programa ARIA:
ArArgumentParser parser (&argc, argv);
parser.loadDefaultArguments ();
ArArgumentParser::loadDefaultArguments () ir alocar os padres exigidos para se consiga
estabelecer a ligao ao Local Host, isto , ao rob real ou a uma simulao (MobileSim
8
).
Na verdade, para que se estabelea uma ligao ao rob utilizada a classe ArSimpleConnector. Esta
classe pode receber como argumento uma classe ArArgumentParser para inicializar o seu construtor.
ArSimpleConnector connector (&parser);
A ligao ao rob exige um objecto ArRobot, que uma interface para o rob e os seus dispositivos
integrados, gerindo o controlo do rob. Por outras palavras pode entender-se como sendo um rob que
se cria virtualmente com os atributos da classe ArRobot.
ArRobot robot;

8
MobileSim um software para silumao de plataformas mveis MobileRobots/ActivMedia e os seus ambientes.
http://robots.mobilerobots.com/wiki/MobileSim

26
Uma vez estabelecida a ligao, o rob pode ser colocado em modo assncrono, o que garante que, se
a ligao for perdida, o rob vai deixar de operar.
robot.runAsync (true);
Efectuada a ligao, tambm necessrio permitir que os motores do rob possam actuar. Para isso
usa-se o seguinte comando:
robot.enableMotors ();
contudo, antes do rob executar qualquer aco ou operao, deve-se colocar os motores num estado
habilitado e seguro. Isto feito utilizando os mtodos ArRobot::lock() e ArRobot::unlock() na seguinte
ordem;
robot.lock ();
robot.aco a executar;
robot.unlock ();
Relativamente aos comandos utilizados para o controlo do rob, ou seja, para manipular directamente
os motores, usando os mtodos do objecto ArRobot criado (robot), foram os seguintes:
robot.setVel (double vel); Define a velocidade de translao do rob em milmetros/segundo.
robot.setRotVel (double vel); Define a velocidade rotacional do rob em graus/segundo.
robot.stop (); Pra o rob. Define uma velocidade de translao e rotao igual a zero.
Os valores so armazenados e enviados no prximo ciclo do programa.
Quando dada ordem para terminar o programa, pelo utilizador, necessrio enviar comandos para o
rob de modo a interromper e impedir que faa mais processamentos. O comando enviado interrompe
o ciclo de processamento do rob, pois este est a ser executado em modo assncrono:
robot.stopRunning ()
necessrio aguardar que a tarefa que o rob est a executar termine antes de sair do programa, ou
seja, antes de utilizar o mtodo Aria::exit(0) utilizado o seguinte comando:
robot.waitForRunExit ();
Para alm dos comandos e mtodos acima referidos, para utilizao e controlo do rob, foram tambm
usados outros comandos, informativos, da classe ArRobot:
robot.getX (); - Obtm a posio global X do rob;
robot.getY (); - Obtm a posio global Y do rob;
robot.getTh (); - Obtm a posio angular (theta) global do rob;
robot.getVel (); - Obtm a velocidade de translao do rob;

27
robot.getRotVel (); - Obtm a velocidade rotacional do rob;
robot.getBatteryVoltage (); - Obtm a tenso instantnea da bateria.
Em anexo (ANEXO VI), encontra-se disponvel o cdigo fonte onde so usados estes comandos, entre
outros, juntamente com o algoritmo de anlise da imagem adquirida.

4.3 Teste e Resultados

Como descrito no captulo 3, apenas foi testado em ambiente real o mtodo de identificao de uma
via.
Os testes, referentes ao movimento do rob, foram testes realizados de forma a encontrar as
velocidades correctas, de translao e rotao, que o rob deve tomar ao longo do seu percurso.
De acordo com a anlise da imagem adquirida (ver seco 3.3), partindo do principio que o rob est
na posio inicial definida (Regio 1), este inicia o seu percurso com uma velocidade constante de 400
mm/seg (robot.setVel (400)), mantendo sempre essa velocidade durante o percurso efectuado, ou seja,
durante o tempo de execuo.
Segundo o MI1V, assim que o ponto mdio entra na Regio 2, considerado que o rob chega zona
da curva. Foi verificado que a velocidade de rotao necessria para seguir a trajectria correcta era de
8 graus/seg (robot.setRotVel (8)).
Entrando o ponto mdio na Regio 3, o rob encontra-se numa zona crtica da curva, ou seja,
encontra-se na zona em que o raio de curvatura menor (por exemplo, quando se aproxima da zona da
passadeira). Ento, e como o rob mantm a sua velocidade constante, necessita de uma velocidade
rotao superior. Foi definida ento uma velocidade de 30 graus/seg (robot.setRotVel (30)).

Figura 4.3. 1 Regies do movimento do rob.

Todos estes parmetros foram recolhidos de forma a tornar a trajectria do rob o mais estvel
possvel, segundo o mtodo usado. Assim, para velocidades de translao superiores necessrio
velocidades de rotao tambm superiores e vice-versa.

28



5. Concluses e Trabalho futuro


5.1 Concluses

Neste trabalho foi apresentado um mtodo para a calibrao da cmara utilizada no rob. Esse
processo necessrio para que se possa fazer a correspondncia das coordenadas retiradas em pixels
(SCP) com as coordenadas do mundo real (SCM) e vice-versa. A no utilizao da calibrao impede
afirmaes tais como o rob est desviado x metros da via ou o rob encontra-se a uma distncia
de x metros.
No entanto esse processo de calibrao no viria a ser utilizado nos algoritmos de deteco das vias
elaborados, pois o MI1V foi baseado na anlise da imagem atravs das coordenadas em pixels
(posio do ponto mdio) e no na anlise das suas coordenadas reais. O MI2V apenas foi testado com
uso de vdeo.
Em relao utilizao do histograma da imagem este til para a equalizao da imagem quando se
verifica um fraco contraste entre os diferentes objectos e o fundo da imagem. Contudo, neste trabalho
no foi utilizado o histograma da imagem, na parte de processamento, para a elaborao dos mtodos
propostos uma vez que a imagem adquirida era aceitvel em termos de iluminao e contraste.
Relativamente aos dois mtodos apresentados para identificao visual das vias, estes pressupem que
o rob se move sobre um pavimento plano, isento de obstculos e que as vias da estrada onde o rob
se movimenta so predefinidas. Em termos de iluminao do local onde a pista se econtrava, esta era
satisfatria de forma a conseguir um bom contraste na imagem para o seu processamento,
conseguindo-se assim uma boa segmentao na utilizao da funo threshold para posterior uso do
filtro de Canny.
As principais concluses tiradas so:
No mtodo de identificao de uma via:
O algoritmo proposto no se torna muito eficaz no que diz respeito navegao do rob
seguindo uma trajectria totalmente estvel e regular. Pois, segundo o MI1V, o rob opera em

29
somente quatro regies com velocidades rotacionais distintas e pr-definidas, o que faz com
que a trajectria do rob se possa tornar um pouco instvel.
Na fase de anlise da imagem, o algoritmo converte a imagem para tons de cinzentos, aplica a
funo de threshold, aplica o filtro de canny e verifica para todos os pixels do vector da
imagem (frame) em anlise, se branco ou preto, guardando o valor da sua posio caso seja
branco. Apesar do processamento de imagem ser efectuado em toda a matriz de imagem
(320x240), o facto de se estar a analisar somente um nico vector dessa matriz, permite que
este seja um algoritmo rpido, podendo ser executado com velocidades superiores as testadas
na seco 4.3 permitindo uma rpida taxa para aquisio de frames para anlise.
O facto de apenas ser necessrio analisar uma via da estrada torna tambm possvel colocar a
cmara no lado oposto ao estipulado no MI1V, de forma a visualizar a via mais a esquerda, e
executar o percurso no sentido inverso.

No mtodo de identificao de duas vias:
Este algoritmo, em relao ao anteriormente proposto, torna-se mais eficaz uma vez que a fase
de anlise da imagem feita em toda a matriz da imagem. Assim sendo, e passando pela
mesma fase de precessamento da imagem do MI1V (converso para tons de cinzentos, funo
de threshold e o filtro de canny), possvel uma anlise mais pormenorizada utilizando a
transformada de Hough para determinar dos pontos de interesse.
O vdeo utilizado para testes foi simulado assumindo que a cmara se encontra posicionada no
rob de forma a ser possvel visualizar as vias da estrada na frame adquirida (paralela ao
pavimento), pois o algoritmo proposto apenas funciona assumindo que se encontram pontos
nos quatro quadrantes. Ao ser testado o algoritmo proposto em ambiente real verificou-se que
este no era vlido uma vez que no se conseguia visualizar as duas vias devido ao facto de a
cmara estar colocada a uma altura relativamente baixa (sobre o rob).

No MI1V os resultados obtidos relativamente parte de controlo do rob foram satisfatrios, mas com
as suas limitaes.
No entanto, no MI2V, apesar de no serem realizados testes em ambiente real, torna-se mais eficaz,
pois a trajectria do rob ser dada em funo da inclinao da recta final (ngulo) e a distncia (em
mdulo) da mesma em relao ao eixo vertical da imagem. Isto far com que a trajectria do rob se
torne mais estvel.



30
5.2 Trabalho futuro e possveis melhorias

Ao longo do projecto foram encontradas diferentes direes de desenvolvimento e evoluo para o
sistema de identificao visual proposto que seriam interessantes de seguir, mas no poderam ser
tomadas devido aos recursos e ao tempo disponveis no momento.
Com base nos resultados obtidos e continuando o desenvolvimento efectuado, podem ser listadas as
seguintes sugestes para futuros trabalhos e melhorias:
Adaptar o mtodo de identificao de duas vias ao ambiente real utilizando um soporte para a
cmara de forma a tornar possivel visualizar as duas vias, utilizando uma cmara com um
FOV superior (por exemplo a cmara digital PlayStation eye da PlayStation 3).
Utilizar o processo de calibrao para tornar o sistema mais robusto de forma a ser possivel
tomar a correspondencia com o mundo real, utilizando para isso o mtodo de calibrao
proposto por Zhang descrito na seco 2.3.
Por ultimo, possivel ainda realizar diversos melhoramentos na fase de processamento de
imagem com a introduo de filtros para a reduo de rudo que possa existir na imagem e
aprofundar conhecimentos relativamente ao uso da transformada de Hough para a anlise da
imagem.


31



Referncias Bibliogrficas


[1] Bradski, G., Kaebler, A., Learning OpenCV: Computer Vision with OpenCV Library, OReilly,
2008.
[2] Wikipdia, http://pt.wikipedia.org/wiki/Cmara_pinhole, acesso em 20 de Novembro de 2009.
[3] Stroustrup, B., The C++ Programming Language, Second Edition, Addison Wesley Publishing
Company, 1992.
[4] Schildt, H., Teach yourself C++, Second Edition, Osborne McGraw-Hill, 1994.
[5] Gererd, S., C++ math class library, John Wiley & Sons, 1994.
[6] Zhihui, X., Computer Vision, IN-TECH, 2008.
[7] Gaspar, J., Viso para Robtica Mvel: Deteco de Obstculos sobre Pavimento Plano,
Lisboa:[s.n.], 1994.
[8] Azevedo, T., Tavares, J., Vaz, M., Anlise do mtodo de Calibrao de Cmaras Proposto por
Zhang, CLME'2008 - 5 Congresso Luso-Moambicano de Engenharia / 2 Congresso de Engenharia
de Moambique, 2008.
[9] Velho, L. et al, Fotografia 3D, 25 Coloquio Brasileiro de Matemtica IMPA, Rio de Janeiro,
2005.
[10] Cyganek, B., Siebert, J., An Introduction to 3D Computer Vision Techniques and Algorithms,
John Wiley & Sons, 2009.
[11] Hartley, R., Zisserman, A., Multiple View Geometry in Computer Vision, Second Edition,
Cambridge University Press, 2000.
[12] Schmidt, R., Lages, W., Identificao Visual Para Navegao De Robs Mveis Utilizando Um
Controlador Fuzzy Sintonizado Por Otimizao Numrica, Anais do XIII Congresso Brasileiro de
Automtica, CBA 2000, 2000.
[13] Ferriani, V., Ribeiro, C., Deteco de Guias Utilizando Variaes da Transformada de Hough,
Relatrio Final PIBIC/CNPq, Instituto Tecnolgico de Aeronutica, 2005.

32
[14] Pitas, I., Digital image processing algorithms and applications, John Wiley & Sons, 2000.
[15] Ritter, G., Wilson, J., Handbook of computer vision algorithms in image lgebra, CRC Press,
1996.
[16] Karlstroem, A., Estimao de Posio e Quantificao de Erro Utilizando Geometria Equipolar
entre Imagens, So Paulo, 2007.
[17] Stemmer, M. et al, Apostila de sistemas de viso, Florianpolis, 2005.
[18] Sukthankar, R., et al, Panacea: An Active Sensor Controller for the ALVINN Autonomous
Driving System, Carnegie Mellon University, Pittsburgh, 1993.
[19] Aria Reference Manual 1.1.7, http://www-ee.ccny.cuny.edu/www/web/jxiao/P2-Aria-
Reference.pdf, acesso em 20 de Maro de 2010.
[20] MobileRobots - ActiveMedia Robotics., Pioneer 3 Operations Manual with MobileRobots
Exclusive Advanced Robot Control & Operations Software. 2006.
[21] ARIA Overview (HTML), disponvel com a instalao padro de ARIA (ndex.html).

33
ANEXOS
ANEXO I: Instalao do OpenCV no OpenSUSE 11.0

A instalao do OpenCV foi, numa primeira fase, efectuada atravs de pacotes, pois existe um
repositrio (Packman) que inclui a biblioteca OpenCV evitando assim a importao da mesma atravs
de comandos.
Foi ento realizada do seguinte modo:
- Atravs do instalador de software do OpenSUSE foram adicionados os repositrios Packman
repository que contem a biblioteca OpenCV e VideoLan repository que contem os codec's
necessrios para imagem e vdeo, entre os quais o ffmpeg;
- Antes da importao do OpenCV foi necessrio descarregar e instalar os seguintes pacotes:
cmake, gcc-c++, ffmpeg e GTK +2.x;
- Foram ento importados os pacotes do OpenCV contidos no repositrio Packman: opencv,
libopencv2, opencv-debuginfo, opencv-devel e python-opencv (facultativo).


34
ANEXO II: Tutorial de instalao do OpenSUSE 11.3 no Pioneer P3-DX

A utilizao deste tutorial pressupe que exista uma ligao a internet para instalao do OpenSUSE,
assim como uma drive de CDs para uso do software de backup e um disco rgido para o respectivo
armazenamento.

1. Material extra necessrio para instalao:
- Drive CDs:
utilizada para que se possa efectuar o backup do risco rgido do rob utilizando o
software de bakup System Rescue Cd prviamente gravado em cd;
- Disco rgido auxiliar:
utilizado para armazenar a cpia integral do disco rgido do rob;
- Fonte de alimentao PC:
necessria para que se consiga ligar os dispositivos acima referidos alimentao.

2. Instalao dos componentes

2.1 - Drive CDs e disco rgido
Aps a remoo das tampas do rob, conecta-se na slot disponivel o cabo IDE (Fig.A2.1.1a) para
ligar a drive de CDs e utiliza-se o cabo IDE j existente (de cor creme) para a ligao do disco rigido
para backup (Fig.A2.1.1b).

a) b)
Figura A2.1. 1 - a) Coneco do cabo IDE; b) Ligao dos dispositivos.


35
2.2 - Fonte de alimentao
Aps conectados os dispositivos vamos lig-los fonte de alimentao. Uma vez que esta para
funcionar precisa de estar ligada a uma placa-me foi necesrio fazer um curto-circuito entre dois
terminais do conector (Fig.A2.2.1).

Figura A2.2. 1 Conector da fonte de alimentao.

A seguinte figura ilustra a montagem completa dos dispositivos utilizados.

Figura A2.2. 2 Montagem completa

3. Backup do disco
Para efecuar a cpia integral do disco rgido do rob, foi utilizado o system rescue cd (disponvel em
http://www.sysresccd.org/Download) que uma ferramenta para recuperao do sistema em Linux.
Foi ento efectuada a gravao da imagem (ISO) disponibilizada num CD .
Insere-se o CD antes de iniciar o computador para se poder fazer boot do CD, precionando F2 para
tal.

36
O system rescue cd inclui vrias ferramentas para o sistema, das quais se utilizou a que nos permite
fazer uma cpia de um disco rgido para outro. Para isso bastou introduzir o seguinte comando
(Fig.A2.3.1):
> ddrescue -v /dev/sda /dev/sdb
Nota: necessrio confirmar qual o disco a copiar e para onde se vai copiar sendo este
preferencialmente do mesmo tamanho do disco rgido a copiar.


Figura A2.3. 1 Ambiente grfico do system rescue cd.

4. Instalao do OpenSUSE

Efectuar o download de openSUSE-11.3-NET-i586 que se encontra disponvel em
http://download.opensuse.org/distribution/11.3/iso/ para realizar a instalao via internet, pois para
uma boa ligao torna-se mais rpido. Gravar ento a imagem (ISO) para um cd e fazer boot a partir
do mesmo.
Antes de iniciar a instalao mudar a resoluo de ecr para a resoluo que se pretende usar de futuro
(Fig.A2.4.1a) e de seguida iniciar instalao (Fig.A2.4.1b).
Nota: Caso no consiga efectuar a ligao ao servidor pressionar F4 para alterar a fonte.

37

a) b)
Figura A2.4. 1 a) Resoluo de ecr; b) Incio de instalao

Iniciada ento a instalao no esquecer de alterar o teclado para Portugus, deixando o idioma em
Ingls.
No menu seguinte selecionar nova instalao e no usar a configurao automtica.

Figura A2.4. 2 Modo de instalao.

No separador Desktop Selection selecionar o ambiente grfico LXDE (Lightweight X11 Desktop
Environment), pois um ambiente de trabalho que consome menos recursos que o KDE ou GNOME
(Fig.A2.4.3).

38

Figura A2.4. 3 Seleo do ambiente de trabalho.

No separador seguinte ,Disk, selecionar Edit Partition Setup... (Fig.A2.4.4a) para verificar os
discos (Fig.A2.4.4b).

Deveram ser apresentados os seguintes valores:
Device Size FS Type Start End
/dev/sda1 736 Mb Swap 0 2943
/dev/sda2 5.0 Gb Ext4 2944 23423
/dev/sda3 1.91 Gb Ext4 23424 31261
Tabela A2. 1 Detalhes dos discos rgidos.


a) b)
Figura A2.4. 4 a) Editar parties; b) Detalhe do disco.

39
Seguidamente criar novo usurio como ilustrado na figura seguinte (password: linux):

Figura A2.4. 5 Novo utilizador

No separador Instalation Overview selecionar Change e de seguida Booting. Selecionar Boot
Loader Options (Fig.A2.4.6a) para alterar o campo Timeout in Seconds para 3 (Fig.A2.4.6b).

a) b)
Figura A2.4. 6 a) Boot loader settings; b) Boot loader Options.

Seguidamente, no mesmo separador anteriormente referido, selecionar Change e depois Software.
Nesse menu selecionar Details para instalar algum software necessrio (Fig.A2.4.7). Selecionando
ento a opo search (Fig.A2.4.8) instalamos os seguintes pacotes:
- Kdevelop;
- Opencv e opencv-devel;
- cmake;
- gcc++;
- C/C++ Development.

40

Figura A2.4. 7 Seleo de software.

Figura A2.4. 8 Instalao dos pacotes e final da instalao.

Assim terminada a procura do software desejado carregar em accept e de seguida em continue.
Continuando no separador anteriormente referido, selecionar agora Firewall and SSH para dar
permisso ao porto SSH e servio SSH (Fig.A2.4.9).


Figura A2.4. 9 Configurao do servio SSH.


41
Inicia-se ento a instalao.

Figura A2.4. 10 Instalao do software.

Aps a instalao segue-se as configuraes.
No separador Hostname prenche-se os campos como ilustrado na figura seguinte, no esquecendo
de retirar o visto em Change Hostname via DHCP.

Figura A2.4. 11 Hostname e domnio.

No separador seguinte, Network, correr o teste de coneco internet (Fig.A2.4.12).

a) b)
Figura A2.4. 12 a) Teste de coneco; b) Fim de teste.

42
No prximo separador selecionar Run Update (Fig.A2.4.13) finalizando assim a instalao do
OpenSUSE 11.3 (Fig.A2.4.14).

a) b)
Figura A2.4. 13 a) Online Update; b) Download e instalao.


Figura A2.4. 14 Fim da instalao do OpenSUSE.


43
ANEXO III: threshold.c

/*para executar na consola:
>> ./threshold <valor> <maximo valor>
*/
#include "cv.h"
#include "highgui.h"
#include <stdio.h> //Funcoes de linguagem c
#include <stdlib.h> //Funcoes de linguagem c

int main( int argc, char** argv )
{
int i = 1;
int x = atoi(argv[1]); //Valor de threshold
int y = atoi(argv[2]); //Maximo valor

cvNamedWindow ("Video", 0);
CvCapture* capture = cvCreateCameraCapture (0);
if(!capture){
return -1;
}
printf("\n\"ESC\" - Sair\n");

while(1){
IplImage* frame = cvQueryFrame (capture);
if (!frame) break;
IplImage* img_gray = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,1);
cvCvtColor( frame, img_gray, CV_BGR2GRAY );
// cvCvtColor( ) converte imagem a cores para escala de cinzentos

cvThreshold( img_gray, img_gray, x, y, CV_THRESH_BINARY );
// aplicacao da funcao threshold com tipo de threshold binario, ou seja,
// imagem destino = (imagem origem >Threshold ) ?Valor mximo : 0

cvShowImage("Video", img_gray );
char c = cvWaitKey (33);
i++;
if(c==27) break; //(esc - ascii)
}

cvReleaseCapture ( &capture);
cvDestroyWindow( "Video");
return 0;
}


44


Resultados:


a) b)
Figura A3. 1 a) Valor de Threshold 80. Iluminao natural; b) iluminao direccionada.


a) b)
Figura A3. 2 a) Valor de Threshold 150. Iluminao natural; b) iluminao direccionada.


45
ANEXO IV: threshist.c

/*para executar na consola:
>> ./threshist
*/

#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <stdlib.h>

#define min(a,b) ( (a)<(b) ? (a) : (b) ) //define mimino de dois valores
#define max(a,b) ( (a)>(b) ? (a) : (b) ) //define maximo de dois valores

//Funcao para encontrar o valor medio das areas de intensidades inferiores e superiores ao valor de threshold
double segment_img(IplImage * img, double T) {

CvScalar z;
unsigned int coluna = img->width;
unsigned int linha = img->height;
unsigned int i, j;
double g1=0, g2=0, valor=0;
int counterg1 = 0, counterg2 = 0;

for (i = 0; i < coluna; i++)
for (j = 0; j < linha; j++) {
z = cvGet2D( img, j, i);
valor = z.val[0];
if (valor >= T ) {
g1 += valor;
counterg1++;
} else {
g2 += valor;
counterg2++;
}
}
return ( (g1/counterg1) + (g2/counterg2));
}

// Funcao para implementacao de threshold dimanico
double thresh_dinamico(IplImage * img) {

CvScalar z;
double minimo, maximo, thresh, thresh_next;
unsigned int coluna = img->width;
unsigned int linha = img->height;
unsigned int i, j;
double done = 0;

z = cvGet2D( img, 0, 0 );
minimo = maximo = z.val[0];

for ( i = 0; i < coluna; i++ )
for ( j = 0; j < linha; j++ ) {
z = cvGet2D( img, j, i);
minimo = min(minimo,z.val[0]);
maximo = max(maximo,z.val[0]);
}

thresh = 0.5*(minimo+maximo);


46
while (!done) {
thresh_next = 0.5*segment_img(img, thresh);
// encontra valor do proximo threshold

done = abs(thresh_next - thresh) < 0.5;
thresh = thresh_next;
}

return thresh;
}

int main( int argc, char** argv )
{
int i, j;
int hdims = 256;
float hranges_arr[] = {0,255};
float* hranges = hranges_arr;
int bin_w = 1;
float maximo_val, minimo_val;
char c;
double val, t;

cvNamedWindow ("Video Gray", 0);
cvNamedWindow ("Video Binary", 0);
cvNamedWindow ("Histogram", 0 );

CvCapture* capture = cvCreateCameraCapture (0);
if(!capture){
printf("\nNo Capture\n\n");
return -1;
}
printf("\n\"ESC\" - Sair\n\n");

IplImage* frame;
IplImage* img_gray;
IplImage* img_bin;
IplImage *histimg = cvCreateImage( cvSize(256,300), 8, 1 ); // 8-bit/ 1 canal por pixel

CvHistogram *hist = cvCreateHist( 1, &hdims, CV_HIST_ARRAY, &hranges, 1 );
// Histograma com 1 dimensao do tipo array

CvScalar cor = CV_RGB(255,255,255); // Cor branca

while(1){
frame = cvQueryFrame (capture);
if (!frame) break;
img_gray = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,1);
img_bin = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,1);
cvCvtColor( frame, img_gray, CV_BGR2GRAY );
cvZero( histimg );
//coloca elementos do vector a 0

cvCalcHist( &img_gray, hist, 0, 0 );
// calcula histograma

cvNormalizeHist( hist, 1.0);
// Normaliza o histograma

cvGetMinMaxHistValue( hist, &minimo_val, &maximo_val, 0, 0 );
// encontra indices e valores de minimo e mximo dos bins do histograma

cvConvertScale( hist->bins, hist->bins, maximo_val ? 255. / maximo_val : 0., 0 );

47
bin_w = histimg->width / 256;

for( i = 0; i <256; i++ )
{
cvGetMinMaxHistValue( hist, &minimo_val, &maximo_val, 0, 0 );
// encontra indices e valores de minimo e mximo dos bins do histograma

val = ( cvGetReal1D(hist->bins,i)*histimg->height/maximo_val );
cvRectangle( histimg, cvPoint(i*bin_w,histimg->height), cvPoint((i+1)*bin_w,(int)(histimg->height -
val)),cor, CV_FILLED, 1, 0 );
// desenha as barras do histograma

}//End For

t = thresh_dinamico( img_gray );
cvThreshold( img_gray, img_bin, t, 255, CV_THRESH_BINARY );

cvShowImage("Video Gray", img_gray );
cvShowImage("Video Binary", img_bin );
cvShowImage("Histogram", histimg );
c = cvWaitKey (300);
if(c==27) break; //("esc" - ascii)
}//End While

cvReleaseImage( &img_gray );
cvReleaseImage( &img_bin );
cvReleaseImage( &histimg );
cvReleaseHist ( &hist );
cvReleaseCapture ( &capture);
cvDestroyWindow("Video Gray");
cvDestroyWindow("Video Binary");
cvDestroyWindow("Histogram");
return 0;

}//End Main




48

Resultados:


Figura A4. 1 Valor de Threshold dinmico com fraca iluminao.


Figura A4. 2 Valor de Threshold dinmico com pouca iluminao.


Figura A4. 3 Valor de Threshold dinmico com iluminao.


49
ANEXO V: Resultado da calibrao

Com a realizao da calibrao, utilizando um padro de calibrao com 6 vertices por 8, e com uma
distncia entre eles de 2,9 centimetros, obteve-se o seguinte resultado (neste resultado retira-se os
parmetros descritos nas seces 2.2 e 2.3):
%YAML:1.0
calibration_time: "Qui 17 Dez 2009 11:25:02 WET"

//Numero de imagens retiradas para o processo de calibrao
image_count: 5

//Dimenso da frame capturada
image_width: 160
image_height: 120

//Quantidade de vertices retirados na posio vertical e horizontal
board_width: 6
board_height: 8

// Distncia entre vrtices
square_size: 2.9000000953674316
flags: 0

//Obteno da matriz dos parmetros intrnsecos
camera_matrix: !!opencv-matrix
rows: 3
cols: 3
dt: d
//Parmetros intrnsecos
data: [ 151.0492228021207950, 0., 76.3822088193910531, 0.,
151.6216972139991128, 63.5509310734817063, 0., 0., 1. ]

//Obteno dos queficientes de distoro
distortion_coefficients: !!opencv-matrix
rows: 1
cols: 4
dt: d
data: [ -0.5956224170132687, 1.7481555940003135, 0.0117369012853710,
-1.4485431200574083e-03 ]
avg_reprojection_error: 1.6073610504468283
per_view_reprojection_errors: !!opencv-matrix
rows: 1
cols: 5
dt: d
data: [ 0.5391962528228760, 0.6057443618774414, 2.9254736900329590,
3.2581842343012490, 0.7082067131996155 ]

//Obteno dos parmetros extrnsecos (vector rotao e translao) para as 5 frames capturadas
extrinsic_parameters: !!opencv-matrix
rows: 5
cols: 6
dt: f
data: [ 3.10622907, -0.01103038, 0.12557971, -11.16460800, 5.12553787,
29.78573227, -0.02031964, -2.98973441, 0.06476486, 10.66071224,
-8.60595989, 28.92044067, -1.31164584e-03, 2.75725102,
-0.08050375, 9.69400787, -7.44153547, 33.55916977, 0.02832068,
3.04689837, -0.48824352, 10.58997154, -8.64666080, 32.26971054,

50
7.90356286e-03, 3.01666689, 0.37365636, 11.44549847, -9.04483604,
27.86407089 ]

//Descrio dos cantos (vertices) encontrados e usados para a calibrao
image_points: !!opencv-matrix
rows: 1
cols: 240
dt: "2f"
data: [ 21.57544327, 88.69639587, 22.15519142, 74.46207428,
22.39159966, 60.28555298, 22.52618217, 46.41658020, 22.82502556,
32.68410492, 23.23790741, 19.34250450, 36.31382751, 88.61573792,
36.38088989, 74.31353760, 36.49544907, 60.30868912, 36.55658722,
46.46142197, 36.67848969, 32.77919388, 36.95088959, 19.49452400,
50.42252350, 88.39981842, 50.52153397, 74.27995300, 50.47317886,
60.23228455, 50.51266098, 46.47121429, 50.49483871, 32.88315201,
50.54012299, 19.60214233, 64.51478577, 88.30674744, 64.44929504,
74.16114807, 64.44934845, 60.27708054, 64.34678650, 46.53518677,
64.38710785, 33.18721008, 64.18010712, 19.82207680, 78.39717865,
87.99214172, 78.28274536, 74.10897064, 77.83798981, 60.31797409,
77.67213440, 46.59974670, 77.51657104, 33.31914902, 77.48420715,
20.19950294, 92.14296722, 87.72351837, 91.57469177, 73.78565216,
91.47539520, 60.19674683, 91.21553802, 46.60754395, 90.82509613,
33.38061905, 90.51510620, 20.44246864, 105.52169800, 87.49132538,
105.24569702, 73.65924072, 104.59204865, 60.18839264,
104.47409058, 46.62934875, 103.90460968, 33.51981735,
103.63291168, 20.50703049, 118.98424530, 87.33956909,
118.39765930, 73.43827057, 117.77340698, 60.11244583,
117.47349548, 46.64938354, 116.96466064, 33.50217819,
116.55567932, 20.56713867, 128.97341919, 20.63063622,
129.54745483, 34.81664658, 129.89497375, 49.37603378,
130.50497437, 64.04695129, 130.75572205, 78.75939941,
131.46612549, 93.92960358, 114.53469849, 21.56669235,
114.76762390, 35.59261322, 115.41342926, 49.75924683,
115.53320312, 64.34811401, 115.83535767, 78.97812653,
116.29739380, 93.76979065, 100.37824249, 22.45384598,
100.61418915, 36.26230621, 100.70864105, 50.27769852,
101.16661072, 64.53940582, 101.34725952, 79.12358856,
101.53197479, 93.77306366, 86.47757721, 23.26000977, 86.59488678,
36.74244690, 86.67273712, 50.70153809, 86.80688477, 64.79064178,
87.03342438, 79.30004120, 87.05692291, 93.64757538, 72.94007874,
23.89997673, 73.11211395, 37.45384979, 73.09389496, 51.18316269,
73.14536285, 65.14435577, 73.04280090, 79.25325775, 72.93585205,
93.61742401, 59.58543015, 24.59176064, 59.58527756, 37.99052429,
59.56602478, 51.52066040, 59.45576859, 65.27154541, 59.46320724,
79.34270477, 59.29814911, 93.45883942, 47.09764862, 25.54775620,
46.73960876, 38.58440399, 46.35845566, 52.01308823, 46.43052292,
65.52270508, 46.13978958, 79.31656647, 45.74983215, 93.39044189,
33.44626236, 26.12700462, 34.60275650, 39.13238144, 32.48576355,
52.54501343, 33.44001389, 65.61412048, 33.33335495, 79.38373566,
32.61592484, 93.20008850, 112.59777069, 29.54019547, 112.49952698,
42.68335342, 112.56754303, 56.19777298, 112.69506073, 69.52129364,
114.17683411, 83.05636597, 114.54431915, 96.45102692,
112.57182312, 29.54278946, 111.97738647, 42.67565536,
112.07843018, 56.19239426, 112.67853546, 69.52107239,
113.97323608, 83.08310699, 114.45905304, 96.45565796,
101.50469971, 28.71349335, 101.70684814, 42.25146866,
101.34065247, 55.64062881, 101.43914032, 69.48872375,
101.57118225, 83.29402161, 102.33778381, 97.41148376, 83.25320435,
27.17176247, 83.00867462, 41.10808563, 83.14065552, 55.24765015,
83.12245941, 69.53244019, 89.46458435, 83.74886322, 83.43579865,
98.44480896, 69.94771576, 26.01169205, 69.90672302, 40.28789139,
69.73117065, 54.76144791, 69.84693146, 69.43109894, 69.86881256,

51
84.30506134, 70.06008911, 99.24869537, 56.33437729, 24.67664146,
56.03504562, 39.45328903, 55.91140366, 54.34410477, 55.79745865,
69.38834381, 55.85448456, 84.57382965, 55.66686249, 99.96847534,
41.48801041, 23.52204514, 41.46690369, 38.59434509, 41.28130722,
53.83922958, 41.18746948, 69.33825684, 40.89011383, 84.93253326,
40.79147720, 100.76219177, 26.28728676, 22.30418396, 25.80389786,
37.71573257, 25.57279587, 53.43766785, 25.44425583, 69.30434418,
25.38778496, 85.36746979, 24.81701469, 101.55191803, 125.29216003,
31.73820686, 125.24403381, 31.76114655, 126.24182892, 43.33575821,
128.95359802, 63.06774139, 130.88290405, 76.56555176,
133.23722839, 90.88146210, 117.65735626, 31.17439461,
111.80989075, 31.58822060, 112.76120758, 44.53160095,
114.95459747, 63.40968704, 116.64216614, 76.94346619,
118.37249756, 91.36541748, 98.14555359, 31.61387062, 98.13254547,
31.72469330, 99.39671326, 44.95730591, 100.93962097, 63.53279114,
102.18391418, 77.34306335, 103.51257324, 91.71222687, 84.88834381,
31.92614937, 84.91272736, 32.20766830, 85.55043793, 44.21051025,
86.66693115, 63.79961777, 87.59384918, 77.63649750, 88.43180084,
92.20967102, 71.46580505, 31.84549713, 71.46897888, 32.15230179,
71.94979095, 43.76610184, 72.51799774, 63.89209747, 72.76409912,
77.71138763, 73.42046356, 92.49967194, 58.16894150, 24.47778130,
58.05164719, 31.86977768, 57.90837860, 43.76971817, 57.91298676,
63.95322800, 57.98184967, 77.92593384, 57.80279160, 92.63882446,
44.41322327, 26.55235291, 44.41606522, 32.24102783, 43.65969467,
50.91077423, 43.41028976, 64.22763824, 42.84105682, 78.21077728,
42.50139999, 93.08811951, 31.42263222, 23.86544228, 30.58331871,
32.65800476, 29.47257423, 50.89335632, 28.55002022, 64.25836182,
27.74249458, 78.38512421, 26.69224930, 93.32386780, 135.40890503,
17.22026062, 134.02426147, 31.98043633, 132.59872437, 46.46612167,
131.40174866, 60.39638901, 130.07778931, 73.76789093,
129.20297241, 86.96225739, 121.13961029, 16.85395813,
119.76466370, 31.94252014, 118.81401062, 46.48900604,
117.62567139, 60.57686234, 116.74936676, 74.30053711,
115.77299500, 87.52222443, 106.35582733, 16.69334984,
105.56030273, 31.79231644, 104.60562897, 46.57885361,
103.83800507, 60.74651337, 103.16106415, 74.63589478,
102.47494507, 88.16284943, 91.51708984, 16.57758331, 90.78408813,
31.84788132, 90.42549896, 46.69573975, 89.61204529, 61.26783371,
89.36799622, 75.16734314, 88.67022705, 88.59865570, 76.36830902,
16.44038773, 76.03401184, 31.88538551, 75.59289551, 46.95421982,
75.46169281, 61.50686646, 75.27768707, 75.56385803, 74.82732391,
89.34141541, 60.63705444, 16.31904793, 60.60562134, 31.93997765,
60.61705780, 47.20875549, 60.57909775, 61.71610641, 60.67253494,
76.14163208, 60.57510757, 89.76140594, 44.79751968, 16.15568733,
45.30832672, 32.01316071, 45.41616821, 47.35488892, 45.63619232,
62.18765259, 45.94222641, 76.50252533, 46.38366699, 90.46402740,
28.64701080, 16.02121925, 29.39186478, 32.04727554, 29.80850410,
47.56336975, 30.40970802, 62.52282715, 31.03952599, 77.00220490,
31.44651413, 90.97264099 ]


52
ANEXO VI: Mtodo de identificao de uma via
- Fluxograma
INCIO
MI1V
Conecta Rob
Cmara
Detectada?
SIM
NO
FIM
MI1V
Captura Frame
Aplicao da
funo Threshold
Visualizao do
Histograma
Aplicao da
Transformada de
Canny
Convero para a
escala de
cinzentos
Nr. Pixeis
brancos>10?
Actua Rob
Rotao negativa
(Esquerda)
PM < 20
Segue em frente
Rotao positiva
(Direita)
150 < PM < 170
PM > 310
Disconecta Rob
NO
NO
MI1V - Mtodo de identificao de uma via
PM - Ponto mdio retirado da anlise da imagem
PM <= 0
ou
PM >= 320?
SIM
SIM

Fluxograma 1 Mtodo de identificao de uma via

53
- Cdigo
// Exemplo da linha de comandos (para copy-n-paste):
// ./main -b [<Block_size>] -o [<Offset>] [<video.avi>]
// -b <Block_size> # Block_size cvAdaptiveThreshold
// -o <Offset> # Offset cvAdaptiveThreshold


#ifdef _CH_
#pragma package <opencv>
#endif

//Bibliotecas utilizadas

#ifndef _EiC
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <time.h>
#include "Aria.h"
#endif

#define WIDTH 320
#define HEIGTH 240

#define MYSPEED 400
//400
#define MYROTVEL1 8
//8 - velocidade rotacao padrao na curva
#define MYROTVEL2 30
//30 velocidade rotacao padrao na zona critica da curva


enum { DETECT = 0, CAPTURA = 1, VIDEO = 2 };


//Funcao para processamento e analiseda imagem

int analisaimagem ( IplImage *org, int bl/*block size*/, int os/*offset*/)
{
int i;

CvScalar sup;
int aux_sup = 0;
int val = 0;
int ct2 = 0;

IplImage *gray = cvCreateImage ( cvGetSize ( org ), IPL_DEPTH_8U, 1 );
IplImage *bin = cvCreateImage ( cvGetSize ( org ), IPL_DEPTH_8U, 1 );
IplImage *view = cvCreateImage ( cvGetSize ( org ), IPL_DEPTH_8U, 3 );
IplImage *view_canny = cvCreateImage ( cvGetSize ( org ), IPL_DEPTH_8U,
1 );

cvCvtColor ( org, gray, CV_RGB2GRAY );

cvAdaptiveThreshold ( gray, bin, 255, CV_ADAPTIVE_THRESH_MEAN_C,
CV_THRESH_BINARY_INV, bl, os );
cvShowImage ("Adaptive Threshold", bin);

cvZero( view );

54
cvZero( view_canny );


cvCanny ( bin, view_canny, 150, 50, 3/*angulo_abertura */);
cvShowImage ("Canny", view_canny);

//cvSmooth (r_bin, r_bin, CV_GAUSSIAN, 9, 9);
//cvErode (r_bin, r_bin, NULL, 1);
//cvDilate (r_bin, r_bin, NULL, 1);
//cvMerge( l_bin, r_bin, NULL, NULL, view);
//cvMax (l_bin, r_bin, view);

cvLine ( view, cvPoint ( 0, view->height/2 ), cvPoint ( view->width,
view->height/2 ), CV_RGB ( 0,255,255 ), 1, CV_AA, 0 );

//Analise do vector superior da imagem para encontrar os pontos brancos
de referencia
for (i = 0; i<view_canny->width ; i++)
{
sup = cvGet2D ( view_canny, 0, i);

if ( sup.val[0] == 255 ) //cor branca
{
cvCircle ( view ,cvPoint ( i , 0 ),2,CV_RGB ( 255,255,255 ),1,4,0
);
aux_sup += i;
//printf("%d\n", aux_sup);
ct2++;
}
}

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

if ( ct2 != 0 && ct2<10)
{
val = aux_sup/(ct2);
cvCircle ( view ,cvPoint ( val , 0 ),2,CV_RGB ( 0,255,255 ),1,4,0
);
aux_sup = 0;
ct2 = 0;
}
else
{
val = 0;

return 0;
}

//Condicao para o caso em que seja detectada a passadeira
if ( ct2 >= 10 )
{
val = 0;
printf("Mais de 10 pontos\n");
}

//Condicao para o caso em que o ponto medio se encontra fora da imagem
if ( val >= WIDTH || val <= 0 )
{
val = 0;
printf("Ponto fora da imagem\n");
}


55
//cvLine ( view, cvPoint ( val_sup, 0 ), cvPoint ( val_inf, view-
>height-1 ), CV_RGB ( 0,255,0 ), 1, CV_AA, 0 );
cvLine ( view, cvPoint ( val, 0 ), cvPoint ( view->width/2, view-
>height/2 ), CV_RGB ( 0,255,0 ), 1, CV_AA, 0 );

printf("Valor = %d\n", val);
//printf("Val Inf = %d\n", val_inf);

cvShowImage ( "Gray Image", gray );
cvShowImage ("Anlise", view);

//Liberta memoria reservada para as imagens
cvReleaseImage ( &view );
cvReleaseImage ( &gray );
cvReleaseImage ( &bin );
cvReleaseImage ( &view_canny );

//retorna o valor da posicao do ponto medio
return val;

}


/*MAIN*/
int main ( int argc, char** argv )
{

CvCapture *capture;
IplImage *frame = 0, *view_org = 0;

char c;
int i;
int modo = DETECT;

int block_size = 3;
double offset = 5;

int val_sup = 0;

int show_hist = 0;


Aria::init();
ArRobot robot;

ArArgumentParser parser(&argc, argv);
parser.loadDefaultArguments();


ArLog::log(ArLog::Terse, "AVISO: este programa nao detecta obstaculos!
Confirme que o robo tem aproximadamente 3 metros de espaco livre em todos
os lados.");


ArSimpleConnector connector(&parser);

//Verifica a coneccao ao robo
if(!connector.connectRobot(&robot))
{
ArLog::log(ArLog::Terse, "Nao conectado ao robo.");
if(parser.checkHelpAndWarnUnparsed())
{
Aria::logOptions();

56
Aria::exit(1);
}
}
if (!Aria::parseArgs())
{
Aria::logOptions();
Aria::shutdown();
return 1;
}

ArLog::log(ArLog::Normal, "simpleMotionCommands: Connected.");

//Inicia o robo em modo assincrono
robot.runAsync(true);

//Desabilita os sonares
robot.disableSonar();


robot.lock();
ArLog::log(ArLog::Normal, "Informacao inicial: Pose=(%.2f,%.2f,%.2f),
Trans. Vel=%.2f, Rot. Vel=%.2f, Bateria=%.2fV",
robot.getX(), robot.getY(), robot.getTh(), robot.getVel(),
robot.getRotVel(), robot.getBatteryVoltage());
robot.unlock();


time_t t;
time ( &t );
printf ( "\n%s", ctime ( &t ) );


for ( i = 1; i < argc; i++ )
{
const char* s = argv[i];
if ( strcmp ( s, "--help" ) == 0 )
{
printf ( "Exemplo da linha de comandos:\n"
"./main -b [<Block_size>] -o [<Offset>]
[<video.avi>]\n\n"
"\t-b <Block_size>\t# Block_size
cvAdaptiveThreshold\n"
"\t-o <Offset>\t# Offset cvAdaptiveThreshold\n\n" );
return 0;
}
if ( strcmp ( s, "-b" ) == 0 )
{
block_size = atoi ( argv[++i] );
//printf("Block size = %d\n", block_size);
}
else if ( strcmp ( s, "-o" ) == 0 )
{
offset = atoi ( argv[++i] );
//printf("Offset = %.f\n", offset);
}
}



capture = cvCreateCameraCapture ( 0 );
cvSetCaptureProperty ( capture, CV_CAP_PROP_FRAME_WIDTH,WIDTH );
cvSetCaptureProperty ( capture, CV_CAP_PROP_FRAME_HEIGHT,HEIGTH );
printf ( "\nMODO CAPTURA\n" );

57
modo = CAPTURA;


if ( !capture ) //se nao for carregado nada o programa e terminado
{
printf ( "Falha na captura da camara\n" );
return -1;
}

//Menu
printf ( "\nOpcoes: \n"
"\tESC - Sair do Programa\n"
"\th - Mostra/Esconde Histograma\n"
"\tp - Pause\n" );


printf ( "\n\t(Press any key to start)\n" );

//Captura frame
frame = cvQueryFrame ( capture );

cvNamedWindow ( "Original", CV_WINDOW_AUTOSIZE );
cvShowImage ( "Original", frame );

c = cvWaitKey ( 0 );


val_sup = analisaimagem (frame, block_size, offset);

//cvNamedWindow ( "Imagem Original", CV_WINDOW_AUTOSIZE );
cvNamedWindow ( "Gray Image", CV_WINDOW_AUTOSIZE );
cvNamedWindow ( "Adaptive Threshold", CV_WINDOW_AUTOSIZE );
cvNamedWindow ( "Anlise", CV_WINDOW_AUTOSIZE );
cvNamedWindow ( "Canny", CV_WINDOW_AUTOSIZE );


//Habilita o funcionamento dos motores
robot.enableMotors();

//while ( 1 )
for (;;)
{

if ( capture )
{
frame = 0;
frame = cvQueryFrame ( capture );// captura da frame

view_org = cvCreateImage ( cvGetSize ( frame ), IPL_DEPTH_8U,
frame->nChannels );

if ( frame->origin == IPL_ORIGIN_BL )
cvFlip ( frame, view_org, 0 );
else
cvCopy ( frame, view_org, 0 );
}


switch ( c )
{
case 'h':

show_hist ^= 1;

58
if ( !show_hist )
{
cvDestroyWindow ( "Histograma" );
}
else
{
cvNamedWindow ( "Histograma", 1 );
}

break;

case 'p':

robot.lock();
robot.stop();
robot.unlock();

printf ( "\nPause\n" );
printf ( "\t(Pressione qualquer tecla para continuar)\n" );

c = cvWaitKey ( 0 );

printf ( "\nContinua\n" );

break;
default:
;
}

if ( show_hist )
{
int i;
int hdims = 256;
float hranges_arr[] = {0,255};
float* hranges = hranges_arr;
int bin_w = 1;
float maximo_val, minimo_val;
int val;

IplImage *histimg = cvCreateImage ( cvSize ( 256,300 ), 8, 1 );
//8-bit/ 1 canal por pixel

IplImage *view_gray = cvCreateImage ( cvGetSize ( view_org ), 8,
1 );

CvHistogram *hist = cvCreateHist ( 1, &hdims, CV_HIST_ARRAY,
&hranges, 1 ); //1 dimenso
CvScalar cor = CV_RGB ( 255,255,255 ); //white
cvCvtColor ( view_org, view_gray, CV_BGR2GRAY );

cvZero ( histimg );//coloca elementos do vector a 0
cvCalcHist ( &view_gray, hist, 0, 0 );

cvNormalizeHist ( hist, 1.0 );//Normalizes histogram by dividing
all bins by sum of the bins, multiplied by <factor>.
//After that sum of histogram bins is equal to <factor>
cvGetMinMaxHistValue ( hist, &minimo_val, &maximo_val, 0, 0 ); //
encontra indices e valores de minimo e mximo dos bins do histograma
cvConvertScale ( hist->bins, hist->bins, maximo_val ? 255. /
maximo_val : 0., 0 );
bin_w = histimg->width / 256;

for ( i = 0; i <256; i++ )

59
{
cvGetMinMaxHistValue ( hist, &minimo_val, &maximo_val, 0, 0 );
// encontra indices e valores de minimo e mximo dos bins do histograma
val = ( cvGetReal1D ( hist->bins,i ) *histimg-
>height/maximo_val );
cvRectangle ( histimg, cvPoint ( i*bin_w,histimg->height ),
cvPoint ( ( i+1 ) *bin_w, ( int ) ( histimg->height - val ) ),cor,
CV_FILLED, 1, 0 );
}//End For


cvShowImage ( "Histograma", histimg );
cvReleaseImage ( &histimg );
}

//Determinacao dos parametros para controlo do robo
val_sup = analisaimagem (view_org, block_size, offset);


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

//Controlo do robo
if ( val_sup >= 150 && val_sup <= 170)
{
// Atribui uma velocidade de 400 mm/seg
ArLog::log(ArLog::Normal, "Comando: Segue em frente a 400 mm/s");
robot.lock();
robot.setVel( MYSPEED );
robot.unlock();
}
else
{
//Regiao 2
if (val_sup > 170 && val_sup <= 270)
{
ArLog::log(ArLog::Normal, "Comando: Ajuste negativo");
robot.lock();
robot.setRotVel( -MYROTVEL1 );
//robot.setHeading(-1);
robot.setVel( MYSPEED );
robot.unlock();
}
//Regiao 2
if (val_sup < 150 && val_sup >= 50)
{
ArLog::log(ArLog::Normal, "Comando: Ajuste positivo");
robot.lock();
robot.setRotVel( MYROTVEL1 );
//robot.setHeading(1);
robot.setVel( MYSPEED );
robot.unlock();
}
//Regiao 3
if (val_sup > 270 && val_sup < WIDTH)
{
ArLog::log(ArLog::Normal, "Comando: ajuste critico
negativo");
robot.lock();
robot.setRotVel( -MYROTVEL2 );
//robot.setHeading(-30);
robot.setVel( MYSPEED );
robot.unlock();
}

60
//Regiao 3
if (val_sup < 50 && val_sup > 0)
{
ArLog::log(ArLog::Normal, "Comando: ajuste critico
positivo");
robot.lock();
robot.setRotVel( MYROTVEL2 );
//robot.setHeading(30);
robot.setVel( MYSPEED );
robot.unlock();
}
//Regiao 4
if (val_sup == 0 || val_sup == WIDTH)
{
break;
}
}

c = cvWaitKey ( 15 );


if ( c == 27 )
break;

}


if ( capture )
cvReleaseCapture ( &capture );

cvDestroyAllWindows();


ArLog::log(ArLog::Normal, "Comando: Parar.");
robot.lock();
robot.stop();
robot.unlock();
ArUtil::sleep(1000);

robot.lock();
ArLog::log(ArLog::Normal, "Informacao final: Pose=(%.2f,%.2f,%.2f),
Trans. Vel=%.2f, Rot. Vel=%.2f, Battery=%.2fV",
robot.getX(), robot.getY(), robot.getTh(), robot.getVel(),
robot.getRotVel(), robot.getBatteryVoltage());
robot.unlock();


ArLog::log(ArLog::Normal, "A parar o processamento do robo...");
robot.stopRunning();

//Esperar pelo fim de processamento
robot.waitForRunExit();

//exit
ArLog::log(ArLog::Normal, "Comando: Encerrar.");

//return 0;
Aria::exit(0);
}
#ifdef _EiC
main ( 1,"main.c" );
#endif


61
ANEXO VII: Mtodo de identificao de duas vias
- Fluxograma



INCIO
MI2V
Carrega Video
Video
Detectado?
SIM
NO
FIM
MI2V
Captura Frame
Aplicao da
funo Threshold
Visualizao do
Histograma
Aplicao da
Transformada de
Canny
Convero para a
escala de
cinzentos
Aplicao da
Transformada de
Hough
MI2V - Mtodo de identificao de duas vias
Anlise da
imagem
Determinao dos
parmetros
(ngulo e desvio)

Fluxograma 2 Mtodo de identificao de duas vias




62
- Cdigo
// Exemplo da linha de comandos (para copy-n-paste):
// ./main -b [<Block_size>] -o [<Offset>] [<video.avi>]
// -b <Block_size> # Block_size cvAdaptiveThreshold
// -o <Offset> # Offset cvAdaptiveThreshold


#ifdef _CH_
#pragma package <opencv>
#endif

//Bibliotecas utilizadas

#ifndef _EiC
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <time.h>
#endif


#define ABS(a) (((a) > 0 ? (a) : -(a))

#define min(a,b) ( (a)<(b) ? (a) : (b) )
#define max(a,b) ( (a)>(b) ? (a) : (b) )


#define RADIANS 0.01745
#define DEGREES 57.2958


#define DIM 30


enum { DETECT = 0, CAPTURA = 1, VIDEO = 2 };

//Estrutura que armazena a frame capturada e as respectivas dimensoes.

typedef struct {
CvCapture *capture;
IplImage *frame;
int width;
int height;
} Movie;


//Estrutura que armazena o valor dos pontos em analise e oa parametros
obtidos da analise.

typedef struct {
int eixo;
int eixo1;
int ct1;
int ct2;
int ct3;
int ct4;
double angulo;
double dist;
int nr_pontos;

63
} Buff;

//Variaveis globais

int _brightness = 100;
int _contrast = 100;

uchar lut[256];
CvMat* lut_mat;

IplImage *src_img, *dst_img;

Buff buff_op = {0};



//Funo utilizada para ajuste do brilho e contraste na imagem original

void update_brightcont( int arg)
{
int brightness = _brightness - 100;
int contrast = _contrast - 100;
int i;

if( contrast > 0 )
{
double delta = 127.*contrast/100;
double a = 255./(255. - delta*2);
double b = a*(brightness - delta);
for( i = 0; i < 256; i++ )
{
int v = cvRound(a*i + b);
if( v < 0 )
v = 0;
if( v > 255 )
v = 255;
lut[i] = (uchar)v;
}
}
else
{
double delta = -128.*contrast/100;
double a = (256.-delta*2)/255.;
double b = a*brightness + delta;
for( i = 0; i < 256; i++ )
{
int v = cvRound(a*i + b);
if( v < 0 )
v = 0;
if( v > 255 )
v = 255;
lut[i] = (uchar)v;
}
}
cvLUT( src_img, dst_img, lut_mat );
cvShowImage( "Original", dst_img );
}

//Funcao de processamento e analise da imagem

void TrataImagem( IplImage *img, IplImage *img_h, IplImage *orig)
{
int i=0;

64
int soma1 = 0, soma2 = 0, soma3 = 0, soma4 = 0;

CvPoint* line;

CvMemStorage* storage;

storage = cvCreateMemStorage(0);

cvClearMemStorage( storage );


buff_op.ct1 = 1;
buff_op.ct2 = 1;
buff_op.ct3 = 1;
buff_op.ct4 = 1;

//utilizacao da transformada de Hough
CvSeq* lines = cvHoughLines2( img, storage, CV_HOUGH_PROBABILISTIC, 1,
CV_PI/180, 38 , 35, 10 );

IplImage *final = cvCloneImage( orig );
IplImage *final_h = cvCloneImage( orig );
//printf("\nLines = %d\n", lines->total);


cvZero (final_h); //coloca todos os elementos da matriz de imagem a
zero


for( i = 0; i < lines->total; i++ )
{
line = (CvPoint*)cvGetSeqElem(lines,i);


//Analisa o primeiro e segundo quadrante
if( line->y < img->height/2 )
{
if(line->x < buff_op.eixo )
{
soma1 +=line->x;
buff_op.ct1++;
cvCircle(final_h,cvPoint(line->x, line-
>y),2,CV_RGB(0,255,255),1,4,0 );
}
if(line->x > buff_op.eixo )
{
soma2 +=line->x;
buff_op.ct2++;
cvCircle(final_h,cvPoint(line->x, line-
>y),2,CV_RGB(255,0,255),1,4,0 );
}
}

//Analisa o terceiro e quarto quadrante
if( line->y > img->height/2 )
{
if(line->x < buff_op.eixo1 )
{
soma3 +=line->x;
buff_op.ct3++;
cvCircle(final_h,cvPoint(line->x, line-
>y),2,CV_RGB(0,255,255),1,4,0 );
}

65
if(line->x > buff_op.eixo1 )
{
soma4 +=line->x;
buff_op.ct4++;
cvCircle(final_h,cvPoint(line->x, line-
>y),2,CV_RGB(255,0,255),1,4,0 );
}
}

cvShowImage("Transformada de Hough", final_h );

//cvWaitKey ( 0 );

}

//Determinacao do ponto superior e inferior da recta final
if(buff_op.ct1 > 1 && buff_op.ct2 > 1 && buff_op.ct3 > 1 && buff_op.ct4
> 1)
{
soma1 = soma1/(buff_op.ct1-1);
soma2 = soma2/(buff_op.ct2-1);
soma3 = soma3/(buff_op.ct3-1);
soma4 = soma4/(buff_op.ct4-1);

buff_op.eixo = (soma1 + soma2)/2; // ponto superior
buff_op.eixo1 = (soma3 + soma4)/2; // ponto inferior
printf("Ponto Sup = (%d,%d)\n", buff_op.eixo, img->height/4);
printf("Ponto Inf = (%d,%d)\n", buff_op.eixo1, img->height - img-
>height/4);

cvCircle(final, cvPoint(buff_op.eixo, img->height/4), 2,
CV_RGB(100,200,100), 2, 4, 0 );
cvCircle(final, cvPoint(buff_op.eixo1, img->height/4*3), 2,
CV_RGB(100,200,100), 2, 4, 0 );
cvLine( final, cvPoint(buff_op.eixo, img->height/4), cvPoint(
buff_op.eixo1, img_h->height/4*3 ), CV_RGB(0,255,0), 1, CV_AA, 0 );
}

//Determinacao da recta final - angulo e desvio
//Y=mx+b
if((buff_op.eixo1- buff_op.eixo)!=0)
{
int m = (img->height/4*3 - img->height/4)/(buff_op.eixo1-
buff_op.eixo);
int b = img->height/4 - m * buff_op.eixo;

double angulo = atan( m )*DEGREES*(-1);

if(angulo < 0)
angulo = 180+angulo;

printf("Angulo = %.2f\n", angulo);
buff_op.angulo = angulo;

int intercep = ((img->height/2)-b)/m;
int dist = (img->width/2-intercep)*(-1);

printf("Intercept= %d\n", intercep);
printf("Distancia = %d\n", dist);

double mod_dist = abs( dist );

buff_op.dist = mod_dist;

66

printf("Modulo Distancia = %.2f\n", mod_dist);

cvLine( final, cvPoint( intercep, img->height/2 ), cvPoint( img-
>width/2, img->height/2 ), CV_RGB(102,139,139), 3, CV_AA, 0 );
cvCircle(final, cvPoint(intercep, img->height/2), 2,
CV_RGB(100,0,100), 4, 4, 0 );
}
else
{
cvLine(final, cvPoint( img->width/2, 0 ), cvPoint( img->width/2, img-
>height/2 ), CV_RGB(0,255,255), 3, CV_AA, 0 );
buff_op.angulo = 90.0;
//printf("\nVertical\n");
}


cvLine( final, cvPoint( img->width/2, 0 ), cvPoint( img->width/2,
img_h->height ), CV_RGB(255,255,255), 1, CV_AA, 0 );
cvLine( final, cvPoint( 0, img_h->height/2 ), cvPoint( img->width,
img_h->height/2 ), CV_RGB(255,255,255), 1, CV_AA, 0 );

cvShowImage("Final", final );


cvClearSeq( lines ); //Liberta a memoria utilizada para guardar os
pontos encontrados pela trasnformada de Hough

if( storage )
cvReleaseMemStorage( &storage );

cvReleaseImage( &final );
cvReleaseImage( &final_h );

}

/*MAIN*/

int main( int argc, char** argv )
{
Movie movie;

IplImage *view = 0;
char c;
int i;
const char* video_in = 0;
int modo = DETECT;

int show_hist = 0, ad_thresh = 0;

int block_size = 3;
double offset = 5;


for( i = 1; i < argc; i++ )
{
const char* s = argv[i];
if( strcmp( s, "--help" ) == 0 )
{
printf("Exemplo da linha de comandos:\n"
"./main -b [<Block_size>] -o [<Offset>]
[<video.avi>]\n\n"
"\t-b <Block_size>\t# Block_size cvAdaptiveThreshold\n"

67
"\t-o <Offset>\t# Offset cvAdaptiveThreshold\n\n");
return 0;
}
if( strcmp( s, "-b" ) == 0 )
{
block_size = atoi (argv[++i]);
//printf("Block size = %d\n", block_size);
}
else if( strcmp( s, "-o" ) == 0 )
{
offset = atoi (argv[++i]);
//printf("Offset = %.f\n", offset);
}
else if( s[0] != '-' )
video_in = s;
}

if( video_in )
{
movie.capture = cvCreateFileCapture( video_in ); //carregamento do
video
printf("\nMODO VIDEO\n");
modo = VIDEO;
}
else
{
movie.capture = cvCreateCameraCapture(CV_CAP_ANY);
printf("\nMODO CAPTURA\n");
cvSetCaptureProperty(movie.capture, CV_CAP_PROP_FRAME_WIDTH,320);
cvSetCaptureProperty(movie.capture, CV_CAP_PROP_FRAME_HEIGHT,240);
modo = DETECT;
}


if( !movie.capture ) //se nao for carregado nada o programa e terminado
{
printf("Falha na captura de ficheiro/camara\n");
return -1;
}


time_t t;
time( &t );
printf("\n%s\n", ctime (&t) );


printf( "\nOpcoes: \n"
"\tESC - Sair do Programa\n"
"\th - Mostra/Esconde Histograma\n"
"\tt - Mostra/Esconde Adaptive Threshold\n"
"\tp - Pause\n");



cvNamedWindow( "Transformada de Canny", 0 );
cvNamedWindow( "Transformada de Hough", 0 );
cvNamedWindow( "Original", CV_WINDOW_AUTOSIZE );
cvNamedWindow( "Final", 0 );


// Para brilho e contraste
lut_mat = cvCreateMatHeader( 1, 256, CV_8UC1 );
cvSetData( lut_mat, lut, 0 );

68

buff_op.eixo = 160; // movie.width/2;
buff_op.eixo1 = 140; // movie.width/2;

for(;;)
{
IplImage *view_bin = 0, *view_canny = 0, *view_gray = 0;
int angulo_abertura = 3;

if( (char) c == 80 || c == 112 )// P ou p
{
printf("\nPause\n");
printf("\t(Press any key to continue)\n");
do
{
c = cvWaitKey ( 0 );
}while( c == 80 || c == 112);
printf("\nContinue\n");
}

if( (char) c == 27 )
break;

if( movie.capture )
{
movie.frame = 0;
movie.frame = cvQueryFrame( movie.capture );// captura do frame

view = cvCreateImage( cvGetSize(movie.frame), IPL_DEPTH_8U,
movie.frame->nChannels );

if( movie.frame->origin == IPL_ORIGIN_BL )
cvFlip( movie.frame, view, 0 );
else
cvCopy( movie.frame, view, 0 );

src_img = cvCloneImage(view);
dst_img = cvCloneImage(view);

cvCreateTrackbar("brightness", "Original", &_brightness, 200,
update_brightcont);
cvCreateTrackbar("contrast", "Original", &_contrast, 200,
update_brightcont);

update_brightcont(0);

}

if( modo == DETECT || modo == VIDEO )
{
view_bin = cvCreateImage( cvGetSize(view), IPL_DEPTH_8U, 1 );
view_canny = cvCreateImage( cvGetSize(view), IPL_DEPTH_8U, 1 );

cvCvtColor( dst_img, view_bin, CV_RGB2GRAY );

cvAdaptiveThreshold( view_bin, view_bin, 255,
CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, block_size, offset);


cvCanny( view_bin, view_canny, 150, 50, angulo_abertura );

cvShowImage( "Transformada de Canny", view_canny );


69
if( ad_thresh )
cvShowImage( "Adaptive Threshold", view_bin );

IplImage *img_hough = cvCreateImage( cvGetSize(view),
IPL_DEPTH_8U, 1 );

cvZero(img_hough);

cvCvtColor( dst_img, img_hough, CV_BGR2GRAY );


TrataImagem( view_canny, img_hough, view);


//printf("Angulo buff = %.1f\n", buff_op.angulo);
//printf("Dist buff = %.1f\n", buff_op.dist);

cvReleaseImage( &img_hough );
}

if ( show_hist )
{
int i;
int hdims = 256;
float hranges_arr[] = {0,255};
float* hranges = hranges_arr;
int bin_w = 1;
float maximo_val, minimo_val;
int val;

IplImage *histimg = cvCreateImage( cvSize(256,300), 8, 1 ); //8-
bit/ 1 canal por pixel

view_gray = cvCreateImage( cvGetSize(view), 8, 1 );

CvHistogram *hist = cvCreateHist( 1, &hdims, CV_HIST_ARRAY,
&hranges, 1 ); //1 dimenso
CvScalar cor = CV_RGB(255,255,255); //white
cvCvtColor( dst_img, view_gray, CV_BGR2GRAY );

cvZero( histimg );//coloca elementos do vector a 0
cvCalcHist( &view_gray, hist, 0, 0 );

cvNormalizeHist( hist, 1.0);//Normalizes histogram by dividing all
bins by sum of the bins, multiplied by <factor>.
//After that sum of histogram
bins is equal to <factor>
cvGetMinMaxHistValue( hist, &minimo_val, &maximo_val, 0, 0 ); //
encontra indices e valores de minimo e maximo dos bins do histograma
cvConvertScale( hist->bins, hist->bins, maximo_val ? 255. /
maximo_val : 0., 0 );
bin_w = histimg->width / 256;

for( i = 0; i <256; i++ )
{
cvGetMinMaxHistValue( hist, &minimo_val, &maximo_val, 0, 0 );
// encontra indices e valores de minimo e maximo dos bins do histograma
val = ( cvGetReal1D(hist->bins,i)*histimg->height/maximo_val );
cvRectangle( histimg, cvPoint(i*bin_w,histimg->height),
cvPoint((i+1)*bin_w,(int)(histimg->height - val)),cor, CV_FILLED, 1, 0 );
}//End For



70
cvShowImage("Histogram Hough", histimg );
//cvShowImage("Video Gray", view_gray );

cvReleaseImage( &histimg );
}

/*
if ( contors )
{
IplImage *img, *cc_cores; //IplImage - tipo que representa uma
imagem
CvMemStorage *mem;
CvSeq *contornos, *ptr;
CvRect bbox;

img = cvCloneImage( view_gray );

cc_cores = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 3);

cvThreshold(img, img, 150, 255, CV_THRESH_BINARY);
//cvAdaptiveThreshold( img, img, 255, CV_ADAPTIVE_THRESH_MEAN_C,
CV_THRESH_BINARY, block_size, offset);

//cvNot(img, img); //inverts the image.
mem = cvCreateMemStorage(0);
cvFindContours(img, mem, &contornos, sizeof(CvContour),
CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));

for (ptr = contornos; ptr != NULL; ptr = ptr->h_next)
{
//CvScalar color = CV_RGB( rand()&255, rand()&255, rand()&255
);
CvScalar color = CV_RGB( 255,255,111 );
cvDrawContours(cc_cores, ptr, color, CV_RGB(255,213,0), -1,
CV_FILLED, 4, cvPoint(0,0));
}

cvShowImage("Contors", cc_cores);
cvReleaseImage(&img);
}*/

//med_fim=0;
//med_inic=0;

//c = cvWaitKey(capture ? 500 : 1000);

/*if ( modo == VIDEO )
{
printf("\nMODO VIDEO\n");

c = cvWaitKey(capture ? 50 : 500);


}*/

switch( (char) c )
{
case 'h':

show_hist ^= 1;
if( !show_hist )
{
cvDestroyWindow( "Histogram Hough" );

71
//cvDestroyWindow( "Video Gray" );
}
else
{
cvNamedWindow ("Histogram Hough", 1 );
//cvNamedWindow ("Video Gray", CV_WINDOW_AUTOSIZE );
}

break;
case 't':

ad_thresh ^= 1;
if( !ad_thresh )
{
cvDestroyWindow( "Adaptive Threshold" );
}
else
{
cvNamedWindow( "Adaptive Threshold", 0 );
}

break;
/*case 'c':

contors ^= 1;
if( !contors )
{
cvDestroyWindow( "Contors" );
}
else
{
cvNamedWindow ("Contors", CV_WINDOW_AUTOSIZE );
}

break;*/
default:
;
}


if( !view )
break;

cvReleaseImage( &view_canny );
cvReleaseImage( &view_bin );
cvReleaseImage( &view_gray );

c = cvWaitKey ( 30 );

}


if( movie.capture )
cvReleaseCapture( &movie.capture );
cvReleaseImage( &view );
cvDestroyAllWindows();

return 0;
}
#ifdef _EiC
main(1,"main.c");
#endif

Você também pode gostar