You are on page 1of 70

Clebson Joel Mendes de Oliveira

Reconhecimento de Lugares em Ambientes Externos


Através dos Descritores Visuais SURF e Textura

Vitória-ES
10 de fevereiro de 2010
Clebson Joel Mendes de Oliveira

Reconhecimento de Lugares em Ambientes Externos


Através dos Descritores Visuais SURF e Textura

Monografia apresentada para obtenção do Grau


de Engenheiro de Computação pela Universi-
dade Federal do Espı́rito Santo.

Orientador:
Profa . Dra . Raquel Frizera Vassallo

C ENTRO T ECNOL ÓGICO


U NIVERSIDADE F EDERAL DO E SP ÍRITO S ANTO

Vitória-ES
10 de fevereiro de 2010
Monografia de Projeto Final de Graduação sob o tı́tulo “Reconhecimento de Lugares em
Ambientes Externos Através dos Descritores Visuais SURF e Textura”, defendida por Clebson
Joel Mendes de Oliveira e aprovada em 10 de fevereiro de 2010, em Vitória, Estado do Espı́rito
Santo, pela banca examinadora constituı́da pelos professores:

Profa . Dra . Raquel Frizera Vassallo


Orientador

Profa . Dra . Eliete Maria de Oliveira Caldeira


Universidade Federal do Espı́rito Santo

Profo . Dro . Evandro Ottoni Teatini Salles


Universidade Federal do Espı́rito Santo
Resumo

Considerando os desafios da Robótica Móvel e a atual tendência em realizar trabalhos volta-


dos para ambientes externos, este trabalho propôs-se a desenvolver uma aplicação para realizar
o reconhecimento de lugares baseando-se em imagens, através dos descritores visuais SURF e
Textura.
A aplicação desenvolvida gera a função de similaridade em tempo real para efetuar o re-
conhecimento dos lugares. Para isso, é construı́do um mapa com imagens do ambiente que se
deseja reconhecer e posteriormente é rodada a aplicação, que compara a imagem fornecida por
um câmera firewire com as imagens do mapa.
Abstract

Considering the challenges of Mobile Robotics and the current tendency to work with out-
door environments, this work proposes the development of an application to recognize places
using images, through the visual descriptors SURF e Texture.
The developed application generates in real-time the similarity function that allows rec-
ognizing places. In order to test the proposed approach, a map of the environment was built
offline using a firewire camera. Latter on some new images were captured and compared to
map images in real-time using the developed application.
Dedicatória

Este trabalho é dedicado à minha famı́lia:


Ananete, Osvaldo, Amanda, Luana, Marcelo e Luã,
por todo o amor que tem por mim e por todo sacrifı́cio que fizeram
para me proporcionar educação de qualidade e uma formação superior; e ao Lorenzo,
meu mais novo sobrinho, por ter trazido tanta felicidade à minha famı́lia pelo seu nascimento.
Clebson J. M. Oliveira.
Agradecimentos

A Deus por ter me dado força e clareza nos momentos em que não era possı́vel contar com
o apoio de outras pessoas.

A Christiano Couto Gava (Cricri) pela ideia original, pelo apoio e por toda paciência que
teve comigo durante o desenvolvimento deste trabalho, pois jamais deixou de responder meus
emails cheios de dúvidas e questionamentos, mesmo atolado de trabalho lá na Alemanha.

Aos colegas Tobias Föhst e Christopher Armbrust do RRLab da Universidade Técnica de


Kaiserslautern - Alemanha, por terem me dado acesso direto ao repositório de desenvolvimento
do MCA2-KL e por toda paciência que tiveram em me ensinar a usar este framework.

A Gilberto Alves Santos Segundo (Gilzinho), por ter compartilhado comigo muitos proble-
mas que aconteceram durante o desenvolvimento deste trabalho, por todas as conversas irrever-
entes e por ter me ensinado quase tudo que sei sobre Linux.

A Júlio Storch Dalfior (Chulhão), por ter sido um grande parceiro nas atividades desenvolvi-
das tanto no LAI quanto no PET. Afinal, conseguimos construir o Primeiro Time de Futebol de
Robôs Capixaba, mesmo que ainda seja necessário evoluir bastante.

À minha famı́lia, por ter me dado 100% de apoio durante o desenvolvimento deste trabalho,
pois fez de tudo para não me atrapalhar durante os dias e noites que estive em casa escrevendo.
Agradeço à minha mãe em especial por ter estado sempre presente ao meu lado, acompanhando
todos os passos do trabalho e dividindo angústias e felicidades.

Ao grupo PET-Engenharia de Computação da UFES por ter cedido o espaço para que eu
pudesse desenvolver o trabalho de forma confortável, e por ter me dispensado de algumas re-
uniões para realização de experimentos.

Aos colegas de laboratório, tanto do PET quanto do LAI, que estavam sempre dispostos a
bater papo e a ajudar, sempre perguntando sobre o andamento do trabalho e dando uma palavra
de conforto. Em especial, a Flávio, Gilberto, Rafael e Ebenézer por terem me ajudado com os
experimentos.

E por último, por ser mais difı́cil de escrever, à Raquel Frizera Vassallo por inúmeras coisas.
Pela orientadora maravilhosa que é, pois me deixa livre para pensar e depois ajuda a por em
prática os “devaneios” concebidos; por todas as vezes que me esperou depois da hora marcada
para as reuniões, por conta dos meus atrasos; e por ser amiga antes de ser orientadora, pois isso
faz com que o desenvolvimento do trabalho seja muito mais prazeiroso.
Sumário

Lista de Figuras

Lista de Tabelas

1 Introdução p. 13

2 Navegação através de mapas p. 15

3 Reconhecimento de lugares p. 18

3.1 Descritores visuais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 18

3.1.1 SURF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 18

3.1.2 Textura (LBP) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 21

3.2 Reconhecimento através de descritores . . . . . . . . . . . . . . . . . . . . . p. 21

3.3 Combinação de descritores . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 22

4 Implementação p. 24

4.1 Aplicação desenvolvida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 24

4.1.1 Como gerar o mapa . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 24

4.1.2 Executando a aplicação . . . . . . . . . . . . . . . . . . . . . . . . . p. 26

4.2 Diagramas de estruturação da aplicação . . . . . . . . . . . . . . . . . . . . p. 28

5 Resultados experimentais p. 30

5.1 Construção do mapa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 33

5.2 Reconhecimento dos lugares . . . . . . . . . . . . . . . . . . . . . . . . . . p. 34

5.3 Considerações sobre os resultados . . . . . . . . . . . . . . . . . . . . . . . p. 38


6 Conclusões e trabalhos futuros p. 41

Referências Bibliográficas p. 43

Apêndice A -- Código fonte p. 44

A.1 Modificado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 44

A.1.1 mca2/libraries/place recognition/build map.cpp . . . . . . . . . . . . p. 44

A.2 Desenvolvido . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 47

A.2.1 mca2/projects/clebson PG/SConscript . . . . . . . . . . . . . . . . . p. 47

A.2.2 mca2/projects/clebson PG/test surf matching fw cam wn.cpp . . . . p. 48

A.2.3 mca2/projects/clebson PG/save fw frame wn.cpp . . . . . . . . . . . p. 53

A.2.4 mca2/projects/clebson PG/calc similarity.cpp . . . . . . . . . . . . . p. 57

Apêndice B -- Equipamentos utilizados p. 67

B.1 Câmera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 67

B.2 Lente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 67

B.3 Tripé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 68

B.4 Adaptador firewire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 68

B.5 Notebook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 68

B.6 Visão geral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 69


Lista de Figuras

2.1 Ambiente externo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 16

2.2 Lugar L3 do ambiente da Figura 2.1. . . . . . . . . . . . . . . . . . . . . . . p. 17

3.1 Resultado do algoritmo de matching SURF original. . . . . . . . . . . . . . . p. 20

3.2 Resultado do algoritmo de matching SURF desenvolvido em [1]. . . . . . . . p. 20

3.3 Exemplo de histograma gerado pelo LBP. . . . . . . . . . . . . . . . . . . . p. 21

3.4 Exemplo de função de similaridade. . . . . . . . . . . . . . . . . . . . . . . p. 23

4.1 Exemplo de arquivo images.txt. . . . . . . . . . . . . . . . . . . . . . . . . . p. 25

4.2 Comandos para gerar o mapa. . . . . . . . . . . . . . . . . . . . . . . . . . p. 25

4.3 Comandos para utilizar a aplicação. . . . . . . . . . . . . . . . . . . . . . . p. 26

4.4 Saı́da da aplicação. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 27

4.5 Exemplo de arquivo similarity.txt. . . . . . . . . . . . . . . . . . . . . . . . p. 27

4.6 Estrutura fı́sica. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 28

4.7 Diagrama de classes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 28

5.1 Mapa do ambiente UFES. . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 31

5.2 Lugares L0 a L3 do ambiente da Figura 5.1. . . . . . . . . . . . . . . . . . . p. 31

5.3 Lugares L4 a L7 do ambiente da Figura 5.1. . . . . . . . . . . . . . . . . . . p. 32

5.4 Lugares L8 a L10 do ambiente da Figura 5.1. . . . . . . . . . . . . . . . . . . p. 33

5.5 Reconhecimento do lugar L1 . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 34

5.6 Reconhecimento do lugar L2 . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 35

5.7 Reconhecimento do lugar L3 . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 36

5.8 Reconhecimento do lugar L5 . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 37

5.9 Reconhecimento do lugar L8 . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 38


B.1 Câmera. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 67

B.2 Lente. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 67

B.3 Tripé. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 68

B.4 Adaptador. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 68

B.5 Visão geral. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 69


Lista de Tabelas

5.1 Estatı́stica dos testes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 40


13

1 Introdução

Ao se observar algumas caracterı́sticas básicas da robótica, como percepção e manipulação


do mundo real através de dispositivos controlados por computador, percebe-se que atividades
simples para seres-humanos não são tarefas triviais para robôs. Consequentemente, o campo
da robótica móvel procura, ao menos, reproduzir algumas das tarefas que nós seres-humanos já
fazemos há muito tempo. Dentre estas tarefas, uma das mais exploradas por pesquisadores é a
navegação robótica, que consiste em um robô conseguir explorar um ambiente. Tal tarefa pode
ser executada de várias formas, como: explorar o ambiente desconhecido conseguindo apenas
manter o robô intacto (Controle), explorar o local e ainda guardar informações encontradas
no caminho (Mapeamento), ou algo mais elaborado como seguir um caminho determinado,
baseando-se em informações prévias sobre o ambiente (Localização).

Os esforços realizados para conseguir que um robô navegue de forma autônoma geraram
muitas contribuições para a navegação robótica em ambientes estruturados ou semi-estruturados,
podendo-se citar a navegação através de laser, ultra-som e câmeras. Porém, quando se trata de
ambientes externos1 (não estruturados e com iluminação natural) algumas ferramentas exis-
tentes não funcionam ou não apresentam um bom desempenho, considerando que esses am-
bientes apresentam caracterı́stica bem mais complexas do que os ambientes internos, que são
construı́dos pelo homem e na maioria das vezes objetivam a regularidade e praticidade. Assim,
é necessário uma abordagem diferente para tratar a navegação em ambientes externos.

Como o problema da navegação é composto por três problemas base : Controle, Mapea-
mento e Localização, que são interdependentes e complexos, este trabalho tem por objetivo
contribuir para a Localização Robótica em ambientes externos, através do uso de técnicas de
Visão Computacional. Como ponto de partida, foi utilizado o trabalho realizado em [1], pois
nele é proposto um modelo para extração de caracterı́sticas de ambientes através do uso de
descritores visuais, como SURF e Textura, e a combinação destas caracterı́sticas, não neces-
sariamente visuais, com o objetivo de identificar ambientes de forma robusta.
1 Neste texto as palavras externo(s) e externa(s) serão utilizadas como tradução livre da palavra outdoor do
inglês.
14

Apesar do modelo proposto em [1] ser robusto pela combinação de descritores, ainda é
necessário utilizar descritores minimamente robustos em ambientes externos para garantir a
consistência do modelo. Dessa forma, é necessário considerar as especificidades de ambientes
externos para poder identificar os descritores mais adequados. Abaixo estão listadas algumas
peculiaridades de ambientes externos e suas respectivas influências no processo de reconheci-
mento.

• Ausência de marcos artificiais pré-definidos: força a utilização de marcos naturais, ou


seja, é necessário extrair as caracterı́sticas do ambiente;

• Desnı́veis no terreno: dificulta a comparação entre imagens de um ambiente, pois pode-se


capturar imagens deste com diferentes rotações e escalas;

• Variação de iluminação: diminui a possibilidade de utilização de descritores visuais de


cor;

• Variabilidade de objetos no ambiente: impõe a necessidade de se utilizar descritores que


não utilizem objetos especı́ficos da imagem.

Dessa forma, considerando o grande avanço da robótica móvel interna, e os desafios im-
postos pelas caracterı́sticas de ambientes externos, percebe-se uma grande tendência atual em
realizar trabalhos neste tipo de ambiente. Assim, este trabalho pretende contribuir para a
navegação robótica em ambientes externos, através do desenvolvimento de uma aplicação para
o reconhecimento de lugares.

Para tal, as caracterı́sticas de ambientes externos listadas acima serão abordadas sobre dois
pontos principais: o uso de descritores visuais que sejam robustos o bastante para conseguir car-
acterizar lugares através apenas das caracterı́sticas naturais destes, e a utilização de um método
que consiga combinar essas caracterı́sticas extraı́das pelos descritores para tornar o reconhec-
imento mais robusto ao tentar efetuar o reconhecimento mesmo que um dos descritores não
realize tal tarefa isoladamente.

Espera-se que esses pontos sejam atingidos através do uso dos descritores SURF e Tex-
tura, e da média aritmética para combinar as caracterı́sticas extraı́das do ambiente, pois estes
descritores são pouco sensı́veis à variação de iluminação, à variabilidade de objetos na imagem
e às variações de condições de observação tais como rotação e escala.
15

2 Navegação através de mapas

O primeiro passo para se navegar através de referências é decidir se estas serão métricas ou
topológicas. Como explicado em [5], a literatura de robótica móvel frequentemente distingue a
representação de espaço topológica da métrica. No entanto, como ainda não existem definições
claras desses termos, podem-se fazer as seguintes considerações: representações topológicas
são muitas vezes pensadas como grafos, dos quais os nós correspondem a lugares significativos
no ambiente e as arestas são as diretrizes para ir um nó a outro; já a representação métrica
divide o espaço usando grids regularmente espaçados, o que torna essa representação indepen-
dente da forma e da localização das caracterı́sticas do ambiente, representando os locais como
coordenadas absolutas ou relativas.

Assim, o primeiro problema a ser abordado seria a escolha do tipo de representação de


espaço. No entanto, em robótica externa são frequentemente adotadas referências topológicas,
devido aos problemas inerentes à odometria, como por exemplo o deslizamento de rodas e a
imprecisão de equipamentos de referências métricas como o GPS1 . Logo, a utilização de ima-
gens para descrever ambientes externos é uma opção para navegação topológica, pois imagens
descrevem lugares através das suas caracterı́sticas, ao contrário de representações métricas, que
os descrevem através das suas localizações em relação a uma referência.

Uma vez escolhido o tipo de representação de espaço, ou seja, o tipo de mapa a ser usado,
ainda há três problemas a serem resolvidos: a geração do mapa, o controle do robô através do
ambiente e a auto-localização do robô no mapa. Considere o ambiente apresentado na Figura
2.1.

1 Embora já existam equipamentos com precisão de centı́metros, os custos ainda são muito elevados.
16

Figura 2.1: Ambiente externo.

Cada marcador da Figura 2.1 representa um lugar do ambiente. Vale ressaltar que os mar-
cadores não representam os limites geométricos dos lugares, eles apenas simbolizam o lugar
graficamente. Por exemplo, pode-se dizer que o lugar L3 também poderia ser simbolizado pelo
nome “fim da Av. Copacabana”, como pode ser visto na Figura 2.2. Então, para ser possı́vel
percorrer um caminho (navegar) através desse mapa é necessário fazer o reconhecimento dos
lugares. Por exemplo, considere a seguinte situação: um robô a rodas precisa percorrer o cam-
inho C0 = {L4 , L5 , L2 , L1 , L0 } no mapa da Figura 2.1, utilizando como sensores uma câmera
perspectiva e uma bússola. Para tal, o robô precisa estimatimar sua localização, em tempo real,
através da câmera e utilizar a informação da bússola para determinar a direção que deve seguir
para alcançar o próximo lugar do caminho C0 .
17

(a) Imagem 0. (b) Imagem 1. (c) Imagem 2.

(d) Imagem 3. (e) Imagem 4. (f) Imagem 5.

Figura 2.2: Lugar L3 do ambiente da Figura 2.1.

Como pode ser visto em [5], os problemas de mapeamento, controle e localização em


robótica móvel podem ser resolvidos separadamente e através de diferentes abordagens. Sendo
assim, este trabalho se propôs a resolver apenas o mapeamento do ambiente offline2 e a estimação
da localização do robô em tempo real utilizando mapas topológicos baseados em imagens, dos
quais cada lugar (nó) pode ser definido por n imagens, como será explicado nos Capı́tulos 3 e
4.

2 Este termo foi utilizado no sentido de explicar que o mapeamento não foi feito durante o reconhecimento.
18

3 Reconhecimento de lugares

Ao resolver o problema do reconhecimento de lugares é possı́vel realizar a localização


no mapa, ou seja, dada a imagem obtida pela câmera em tempo real é possı́vel consultar o
mapa, construı́do previamente, e determinar em que lugar deste o robô se encontra. Para isso,
é necessário utilizar as caracterı́sticas dos lugares para encontrar uma semelhança entre as im-
agens do lugar que compuseram o mapa e a imagem atual da câmera, o que é feito através dos
descritores visuais.

3.1 Descritores visuais

Como descrito em [2], a tarefa de encontrar correspondências entre duas imagens da mesma
cena ou objeto é parte de muitas aplicações de Visão Computacional, como: calibração de
câmeras, reconstrução 3D, registro de imagens e reconhecimento de objetos. Sendo assim,
pode-se dizer que os decritores visuais são as ferramentas utilizadas para determinar a cor-
respondências entre duas imagens. Dentre os descritores visuais pode-se citar: histograma
de cores normalizado, SIFT (Scale Invariant Feature Transform), MSER (Maximally Stable
Extremal Regions), SURF (Speeded Up Robust Features), LBP (Local Binary Pattern), entre
outros. Porém, apesar de existirem vários descritores que podem ser utilizados na tarefa de re-
conhecimento de lugares, este trabalho se restringiu à utilização de SURF e LBP considerando
a avaliação de descritores feita em [1]. Neste estudo foi indicada a utilização de SURF e LBP,
por apresentarem caracterı́stica favoráveis à tarefa de reconhecimento e por terem códigos fonte
disponı́veis.

3.1.1 SURF

Como descrito em [2], a busca por corrêspondências entre imagens pode ser dividida em
três passos principais. Primeiramente, pontos de interesse como cantos, blobs1 e junções do
1O termo blob(s) representa um aglomerado de pixels da mesma cor ou com o mesmo nı́vel de cinza.
19

tipo T, são selecionados em localizações distintas na imagem. Posteriormente, a vizinhança de


cada ponto de interesse é representada por um vetor de caracterı́sticas. E por fim, os vetores
de caracterı́sticas de imagens diferentes são comparados, com o objetivo de se encontrar um
casamento (matching) entre eles, o que determina as correspondências. Esses três passos de-
scritos acima são respectivamente conhecidos como: detecção, descrição e casamento. E suas
propriedades desejáveis são:

• Detecção: repetibilidade, por exemplo, quando o detector encontra confiavelmente os


mesmos pontos de interesse sobre diferentes condições de observação;

• Descrição: distinção e robustez a ruı́do, a erros de detecção e a deformações fotométricas


e geométricas;

• Casamento: tempo de processamento satisfatório;

Seguindo essas caracterı́sticas o descritor SURF foi desenvolvido, tentando atingir um


equilı́brio entre tempo computacional baixo e desempenho satisfatório. Esta técnica utiliza im-
agens integrais, [3] e [4], e um vetor de caracterı́sticas de dimensão 64 para reduzir o tempo de
processamento, diferentemente do descritor visual SIFT que trabalha com vetores de dimensão
128.

A biblioteca SURF2 desenvolvida em [2] foi utilizada por [1] e sofreu algumas alterações.
O algoritmo de casamento (matching) fornecido em [2] é o de força bruta, ou seja, compara
cada descritor da primeira imagem com todos os outros da segunda, o que deixa o matching
lento. O algoritmo de matching desenvolvido em [1] usa uma biblioteca gratuita chamada ANN
(Approximate Nearest Neighbors)3 para diminuir o tempo computacional requerido. Porém, o
resultado desse matching é, em geral, igual ao obtido com o algoritmo original de [2], que gera
algumas falsas correspondências, como pode ser visto na Figura 3.1, onde as linhas brancas
ligam os pontos de conrrespondência entre as duas imagens.

2 Disponı́vel em http://www.vision.ee.ethz.ch/ surf/download.html.


3 Disponı́vel em http://www.cs.umd.edu/ mount/ANN/
20

Figura 3.1: Resultado do algoritmo de matching SURF original.

Na tentativa de eliminar essas falsas correspondências o trabalho [1] utilizou o método


RANSAC (Random Sample Consensus). Este método encontra o maior subconjunto das corre-
spondências que melhor se encaixam no modelo fornecido, o qual foi uma transformação linear
entre as imagens. Assim, através da realização dessas modificações no algoritmo de matching
SURF original, obteve-se melhorias tanto no tempo computacional gasto quanto na geração de
falsas correspondências, como pode ser visto na Figura 3.2.

Figura 3.2: Resultado do algoritmo de matching SURF desenvolvido em [1].


21

3.1.2 Textura (LBP)

Dentre os vários descritores visuais que utilizam informação de textura, o utilizado neste
trabalho foi o LBP (Local Binary Pattern). Neste, inicialmente a imagem é dividida em retângulos
de mesmo tamanho e em seguida um histograma é construı́do para cada retângulo. A informação
que se deseja extrair destes histogramas é a frequência dos padrões de textura encontrados nos
retângulos. Após a obtenção de todos os histogramas provenientes dos retângulos da imagem,
estes são concatenados para formar um único vetor descritor. Vale ressaltar que da mesma forma
que o descritor SURF, o LBP também opera em imagens em nı́veis de cinza. Um exemplo da
saı́da do descritor LBP pode ser visto na Figura 3.3, onde o gráfico representa o histograma
extraı́do do retângulo em vermelho.

Figura 3.3: Exemplo de histograma gerado pelo LBP.

3.2 Reconhecimento através de descritores

Para ser possı́vel fazer a localização do robô, é necessário extrair as caracterı́sticas do lu-
gar observado e compará-las às caracterı́sticas presentes em cada lugar (nó) do mapa. Como
descrito em [1], a maneira mais adequada de se fazer essa localização seria utilizando as
distribuições de probabilidade do descritor utilizado. Porém, distribuições de probabilidade
exatas ainda não são possı́veis de serem obtidas na prática. Por isso, o que se faz é aproximar a
função densidade de probabilidade.

Neste trabalho, a função densidade de probabilidade dos descritores foi aproximada pela
função de similaridade dos mesmos, que é definida em [1] como:
22

0 ≤ si ≤ 1, i = 0..(M − 1)

Onde s ∈ ℜ e M é o número de nós presentes no mapa, ou seja, M é o tamanho do mapa.


A determinação da similaridade de cada nó, depende do processo de matching utilizado pelos
descritores. De forma geral, a similaridade de uma imagem é determinada através do número de
correspondências encontradas entre esta e as imagens do nó pesquisado. Por exemplo, considere
que uma imagem I apresenta n correspondências com o nó Nx , e que a quantidade de pontos de
interesse extraı́dos das imagens do nó Nx é igual a T . O valor da similaridade SI/Nx da imagem
I com o nó Nx é dada da seguinte forma:

SI/Nx = n/T

3.3 Combinação de descritores

Mesmo utilizando descritores visuais, que sejam robustos o bastante para executar matching
entre imagens de uma mesma cena, que tenham sido capturadas em condições de observação
diferentes, como por exemplo rotação, translação e iluminação; o resultado do reconhecimento
de lugares utilizando apenas um desses descritores, não garante 100% de confiabilidade. Por
isso, o trabalho desenvolvido em [1] discute o problema da combinação de descritores, não
necessariamente visuais, para aumentar a robustez no reconhecimento de lugares. Existem
vários métodos de combinação de funções densidade de probabilidade, como Filtro de Kalman
e Filtro de Informação. Porém, como discutido em [1], a maioria desses métodos assume que
as distribuições são gaussianas, o que na prática acontece em um número bem reduzido de
situações. Por isso, neste trabalho optou-se por usar o método da média aritimética como fusor
das funções de similaridade dos descritores.

Uma vez determinada a função de similaridade geral, gerada a partir da combinação das
funções de similaridade dos descritores utilizados, o reconhecimento de um lugar do mapa
através de uma imagem é feito observando-se o pico global dessa função. Considere a função
de similaridade da Figura 3.4.
23

Figura 3.4: Exemplo de função de similaridade.

Observando-se a Figura 3.4 pode-se chegar às seguintes conclusões: a função de similar-
idade SURF reconheceu o lugar 2, a função de similaridade Textura reconheceu o lugar 3 e a
função de similaridade geral reconheceu o lugar 3.
24

4 Implementação

Todas as aplicações elaboradas neste trabalho foram desenvolvidas na linguagem C++,


através do framework MCA2-KL (Modular Controller Architecture Version 2)1 , que roda sobre
plataformas Linux2 .

4.1 Aplicação desenvolvida

Utilizando as bibliotecas Place Recognition e Coviroa do MCA2-KL, e uma interface para


GNUPlot3 em C++, GNUPlot-CPP4 , foi desenvolvida uma aplicação que gera as funções de
similaridade de imagens em relação a um mapa em tempo real, através de uma câmera firewire.
Tal mapa é gerado pela aplicação place recogniton build map do MCA2-KL, que teve seu
código fonte alterado durante este trabalho.

Apesar da aplicação desenvolvida não utilizar diretamente todas as bibliotecas do MCA2-


KL, é aconselhado instalar a versão completa deste framework, pois as bibliotecas utilizadas
dependem de outras e a ausência de alguma pode inviabilizar a compilação da aplicação.

4.1.1 Como gerar o mapa

Após a instalação do MCA2-KL estará disponı́vel na pasta mca2/export/i686 Linux debug/bin


o arquivo executável place recognition build map, que gera o mapa. Antes de executar esta
aplicação é preciso: criar uma pasta com todas as imagens5 que representam o ambiente que se
quer mapear; criar um arquivo de texto chamado images.txt, dentro desta pasta, do qual cada
1 Para mais informações sobre este framework de código fonte aberto, visite o site http://rrlib.cs.uni-kl.de/mca2-

kl/.
2A
distribuição utilizada neste trabalho foi Debian versão 2.6.30-8.
3 Para mais informações sobre este aplicativo de código fonte aberto, visite o site
http://www.gnuplot.info/download.html.
4 Para mais informações sobre esta biblioteca de código fonte aberto, visite o site
http://code.google.com/p/gnuplot-cpp/.
5 Todas as imagens precisam ter a mesma resolução.
25

linha deve conter o caminho completo para as imagens, como o exemplo da Figura 4.1; e seguir
a sequência de comandos exibidos na Figura 4.2, utilizando as opções desejadas.

Figura 4.1: Exemplo de arquivo images.txt.

Figura 4.2: Comandos para gerar o mapa.

A ordem de criação dos lugares do mapa é dada pela ordem das imagens no arquivo im-
ages.txt e não pelo nome das imagens. Dessa forma, utilizando o arquivo da Figura 4.1 para
26

gerar um mapa com 5 imagens por lugar é gerado um mapa com 4 lugares, os quais são forma-
dos pelas seguintes imagens:

• Place000: ee.JPG, xxx.JPG, 2.JPG, 3.JPG e 4.JPG;

• Place001: rs.JPG, 6.JPG, 7.JPG, vv.JPG e 9.JPG;

• Place002: 10.JPG, 11.JPG, bbb.JPG, 13.JPG e 14.JPG;

• Place003: 15.JPG, 16.JPG, ttt.JPG, 0.JPG e zzz.JPG;

4.1.2 Executando a aplicação

Mesmo após a instalação do MCA2-KL, a aplicação ainda não estará disponı́vel na pasta
mca2/export/i686 Linux debug/bin. Será necessário criar um projeto, pois a aplicação não faz
parte de nenhuma biblioteca. Para criar o projeto deve-se criar uma pasta (ex: reconhecimento),
colocar os arquivos contidos no apêndice A dentro desta pasta e digitar no terminal a sequência
de comandos exibidos na Figura 4.3.

(a) Compilação.

(b) Execução.

Figura 4.3: Comandos para utilizar a aplicação.

As saı́das do programa são um gráfico apresentado na tela, que exibe as funções de simi-
laridade entre a imagem da câmera e o mapa fornecido, e uma janela que exibe a imagem da
27

câmera, como na Figura 4.4. Além disso, apertando-se a tecla s é possı́vel salvar o gráfico, a
imagem da câmera e um arquivo chamado similarity.txt na pasta mca2. Neste arquivo é salvo
o número da imagem, a hora em que ela foi salva e as funções de similaridade SURF, Textura
e Geral, para ser possı́vel observar os valores exatos de similaridade gerados, como pode ser
observados na Figura 4.5.

Figura 4.4: Saı́da da aplicação.

Figura 4.5: Exemplo de arquivo similarity.txt.


28

4.2 Diagramas de estruturação da aplicação

Nesta seção serão apresentados dois diagramas: um contendo a estrutura fı́sica da aplicação
e outro com as principais classes utilizadas, com o objetivo de explicar melhor a estruturação
do código. Na Figura 4.6 é apresentada a estrutura fı́sica da plataforma utilizada.

Figura 4.6: Estrutura fı́sica.

Na Figura 4.7 é apresentado um diagrama UML (Unified Modeling Language) das princi-
pais classes utilizadas, as quais fazem parte da biblioteca Place Recognition do MCA2-KL.

Figura 4.7: Diagrama de classes.

As principais funções das classes da Figura 4.7 são:

• tMap: gera o mapa guardando as caracterı́sticas dos lugares e arestas de transição entre
eles;
29

• tPlace: gera um lugar utilizando as caracterı́sticas do mesmo;

• tFeatureSetContainer: junta as caracterı́sticas dos lugares, utilizando descritores difer-


entes;

• tFeatureSet: armazena as caracterı́sticas dos lugares, provenientes dos descritores;

• tSURFFeatureSet: armazena as caracterı́sticas provenientes do descritor visual SURF;

• tTextureFeatureSet: armazena as caracterı́sticas provenientes do descritor visual Textura;

• tFeatureExtractor: extrai as caracterı́sticas provenientes das imagens;

• tSURFFeatureExtractor: extrai as caracterı́sticas geradas pelo descritor SURF utilizando


as imagens;

• tTextureFeatureExtractor: extrai as caracterı́sticas geradas pelo descritor Textura uti-


lizando as imagens;

• tSensorData: manipula os dados provenientes dos sensores;

• tImageSensorData: manipula os dados provenientes das imagens;


30

5 Resultados experimentais

Para testar a aplicação construiu-se o mapa com uma câmera firewire, usando uma lente
sem regulagem automática de ı́ris. Por isso, a ı́ris da lente utilizada foi regulada com aber-
tura total tanto para montar o mapa quanto para efetuar o reconhecimento. Considerando as
discussões realizadas nos Capı́tulos 2 e 3, todos os testes foram realizados considerando os
seguintes atributos:

• Mapa composto por 11 lugares (L0 a L10 ), os quais são compostos por 6 imagens, for-
mando um total de 66 imagens utilizadas;

• Considerando um lugar do mapa, as imagens que o representam foram capturadas durante


um único dia;

• Todas as imagens utilizadas foram capturas com resolução de 320x240 em nı́veis de cinza,
a uma altura constante de aproximadamente 90 cm e com abertura total de ı́ris;

• O testes de reconhecimento foram realizados em dias diferentes dos dias em que as ima-
gens que compuseram o mapa foram capturadas.

Nas Figuras 5.1, 5.2, 5.3 e 5.4 temos o mapa utilizado nos experimentos.
31

Figura 5.1: Mapa do ambiente UFES.

(a) L0-Imagem 0. (b) L0-Imagem 1. (c) L0-Imagem 2. (d) L0-Imagem 3. (e) L0-Imagem 4. (f) L0-Imagem 5.

(g) L1-Imagem 0. (h) L1-Imagem 1. (i) L1-Imagem 2. (j) L1-Imagem 3. (k) L1-Imagem 4. (l) L1-Imagem 5.

(m) L2-Imagem 0. (n) L2-Imagem 1. (o) L2-Imagem 2. (p) L2-Imagem 3. (q) L2-Imagem 4. (r) L2-Imagem 5.

(s) L3-Imagem 0. (t) L3-Imagem 1. (u) L3-Imagem 2. (v) L3-Imagem 3. (w) L3-Imagem 4. (x) L3-Imagem 5.

Figura 5.2: Lugares L0 a L3 do ambiente da Figura 5.1.


32

(a) L4-Imagem 0. (b) L4-Imagem 1. (c) L4-Imagem 2. (d) L4-Imagem 3. (e) L4-Imagem 4. (f) L4-Imagem 5.

(g) L5-Imagem 0. (h) L5-Imagem 1. (i) L5-Imagem 2. (j) L5-Imagem 3. (k) L5-Imagem 4. (l) L5-Imagem 5.

(m) L6-Imagem 0. (n) L6-Imagem 1. (o) L6-Imagem 2. (p) L6-Imagem 3. (q) L6-Imagem 4. (r) L6-Imagem 5.

(s) L7-Imagem 0. (t) L7-Imagem 1. (u) L7-Imagem 2. (v) L7-Imagem 3. (w) L7-Imagem 4. (x) L7-Imagem 5.

Figura 5.3: Lugares L4 a L7 do ambiente da Figura 5.1.


33

(a) L8-Imagem 0. (b) L8-Imagem 1. (c) L8-Imagem 2. (d) L8-Imagem 3. (e) L8-Imagem 4. (f) L8-Imagem 5.

(g) L9-Imagem 0. (h) L9-Imagem 1. (i) L9-Imagem 2. (j) L9-Imagem 3. (k) L9-Imagem 4. (l) L9-Imagem 5.

(m) L10-Imagem 0.(n) L10-Imagem 1. (o) L10-Imagem 2. (p) L10-Imagem 3. (q) L10-Imagem 4. (r) L10-Imagem 5.

Figura 5.4: Lugares L8 a L10 do ambiente da Figura 5.1.

5.1 Construção do mapa

Como o objetivo do trabalho é contribuir para a navegação de robôs em ambientes externos,


foram tomados alguns cuidados para que os resultados obtidos fossem o mais próximo possı́vel
do cenário em que, um robô a rodas pudesse fazer o reconhecimento dos lugares utilizando a
aplicação desenvolvida, rodando sobre a plataforma utilizada. Assim, ao invés de utilizar uma
câmera digital para capturar as imagens de geração do mapa, foi utilizada uma câmera firewire
conectada a um notebook que posteriormente foi utilizado para efetuar o reconhecimento em
tempo real. Além disso, a câmera foi colocada sobre um tripé de aproximadamente 90 cm, para
simularar a altura que a mesma ficaria se fosse utilizada juntamente com o notebook sobre um
robô a rodas Pioneer do modelo P3At, que será utilizado para dar prosseguimento ao trabalho.

Ao observar as imagens que compuseram o mapa, nas Figuras 5.2 e 5.4, pode-se perceber
que os lugares L2 e L8 , são internos. O objetivo de utilizar ambientes internos em um trabalho
que se destina a contribuir para a Robótica Móvel em ambientes externos, é descobrir qual o
efeito que esses ambientes provocariam no reconhecimento ao serem misturados aos ambientes
externos. É de se esperar que a identificação dos lugares internos seja feita com facilidade, con-
siderando que os mesmo tem caracterı́sticas muito mais bem comportadas que as dos ambientes
externos.
34

5.2 Reconhecimento dos lugares

Os experimentos consitiram em fazer o reconhecimento dos lugares do mapa através da


função de similaridade, como explicado no Capı́tulo 3. O planejado foi rodar a aplicação em
todos os lugares do mapa para fazer o reconhecimento, porém por problemas com a bateria do
notebook utilizado, só foi possı́vel fazer o reconhecimento em lugares onde havia pontos de
energia elétrica disponı́veis.

Nas Figuras de 5.5 a 5.9, estão apresentadas as funções de similaridade geradas para os
lugares testados e as imagens que geraram estas funções. Em cada gráfico são apresentadas as
funções de similaridade SURF (vermelho), Textura (verde) e Geral (azul) para o mapa da Figura
5.1. O reconhecimento de um lugar é caracterizado pelo maior valor (pico global) da função de
similaridade Geral, como exemplificado na seção 3.3.

(a) L1-Similaridade do melhor caso. (b) L1-Imagem do melhor caso.

(c) L1-Similaridade do pior caso. (d) L1-Imagem do pior caso.

Figura 5.5: Reconhecimento do lugar L1 .


35

(a) L2-Similaridade do melhor caso. (b) L2-Imagem do melhor caso.

(c) L2-Similaridade do pior caso. (d) L2-Imagem do pior caso.

Figura 5.6: Reconhecimento do lugar L2 .


36

(a) L3-Similaridade do melhor caso. (b) L3-Imagem do melhor caso.

(c) L3-Similaridade do pior caso. (d) L3-Imagem do pior caso.

Figura 5.7: Reconhecimento do lugar L3 .


37

(a) L5-Similaridade do melhor caso. (b) L5-Imagem do melhor caso.

(c) L5-Similaridade do pior caso. (d) L5-Imagem do pior caso.

Figura 5.8: Reconhecimento do lugar L5 .


38

(a) L8-Similaridade do melhor caso. (b) L8-Imagem do melhor caso.

(c) L8-Similaridade do pior caso. (d) L8-Imagem do pior caso.

Figura 5.9: Reconhecimento do lugar L8 .

Nas Figuras de 5.5 a 5.9 foram apresentados tanto os melhores casos, quanto os piores
casos do reconhecimento. Para tal caracterização, cosiderou-se que o melhor e o pior caso
são respectivamente determinados pela maior e menor diferença entre o valor da função de
similaridade no lugar a ser reconhecido (SLr ), e o valor da função de similaridade no lugar com
maior valor de similaridade (SLm ), para Lm 6= Lr .

5.3 Considerações sobre os resultados

Ao se analisar o problema pelo melhor caso, percebe-se que a aplicação obteve um desem-
penho muito bom, pois todos os lugares testados foram reconhecidos. Contudo, se o reconheci-
mento for analisado pelo pior caso percebe-se que alguns lugares não foram reconhecidos, pois
39

o pico global da função de similaridade ocorreu em outro lugar que não o esperado. Por exem-
plo, no pior caso do reconhecimento do lugar L3 , Figura 5.7c, a aplicação reconheceu o lugar
L1 . No entanto, os lugares L1 e L3 foram escolhidos propositadamente para estarem geometrica-
mente próximos, com o intuito de analisar se haveria confusão no reconhecimento dos mesmos,
considerando que algumas das imagens que os caracterizam apresentam elementos em comum.
Como pode ser visto nas imagens da Figura 5.2 e confirmada pela função de similaridade SURF
no gráfico da Figura 5.7c.

Outra análise que pode ser feita é a do reconhecimento dos ambientes internos. Observando-
se os gráficos 5.6a e 5.6c percebe-se que as funções de similaridade do melhor e do pior caso são
muito parecidas, e ambas reconhecem perfeitamente o lugar L2 , como dito no fim da seção 5.1.
Porém, o pior caso do reconhecimento do lugar L8 , Figura 5.9c, mostra que o lugar reconhecido
foi L9 , indicando uma falha no reconhecimento através dos descritores utilizados.

É possı́vel perceber no gráfico da Figura 5.9c que o lugar L9 foi reconhecido por causa do
descritor SURF, o que pode ser explicado pela grande quantidade de áreas brancas na imagem
da figura 5.9d e nas imagens do mapa que representam o lugar L9 , pois em regiões com pixels
de mesmo nı́vel de cinza a probabilidade dos vetores descritores SURF serem parecidos é muito
grande. Além disso, é possı́vel explicar o alto valor de similaridade Textura para o lugar L5 e
o baixo valor similaridade Textura para o lugar L8 na Figura 5.9c, respectivamente, pelo alto
nı́vel de iluminação nas imagens do lugar L5 e a ausência de uma imagem de caracterização do
lugar L8 em condições de observação parecidas com as da imagem da Figura 5.9d.

Também pode-se explicar a falha dos descritores no reconhecimento do lugar L1 , Figura


5.5c, pelo alto nı́vel de iluminação em partes da imagem da Figura 5.5d e nas imagens caracter-
izadoras dos lugares L6 e L9 ; e pela ausência de uma imagem de caracterização do lugar L1 em
condições de observação parecidas com as da imagem da Figura 5.5d.

Como não é possı́vel obter uma medida confiável do desempenho da aplicação apenas anal-
isando o melhor e o pior caso, é necessário observar os resultados através de uma visão mais
geral, o que pode ser feito utilizando-se os dados estatı́sticos apresentados na Tabela 5.1.
40

Lugares Reconhecimento(%) No total de testes efetuados No de reconhecimentos


L1 50% 10 5
L2 100% 8 8
L3 62,5% 24 15
L5 100% 14 14
L8 56,25% 16 9
Linternos 70,83% 24 17
Lexternos 70,83% 48 34
Mapa 70,83% 72 51

Tabela 5.1: Estatı́stica dos testes.

Ao se analisar a Tabela 5.1 percebe-se que o desempenho estatı́stico da aplicação não foi
alto, considerando o valor de 70,83% de reconhecimentos no mapa. No entanto, através dos
gráficos apresentados na seção 5.2 percebe-se que todos os lugares foram reconhecidos através
de pelo menos uma condição de observação, o que é muito bom.

Analisando-se separadamente os dados estatı́sticos do reconhecimento de ambientes inter-


nos e externos, também é possı́vel dizer que o desempenho não foi alto. Porém, considerando-se
que o desempenho tanto em ambientes internos quanto externos foi o mesmo, pode-se afirmar
que o reconhecimento feito pela aplicação é pouco variante à presença de pessoas no ambiente,
o que é uma caracterı́stica desejável pois esta poderia ser um problema, dado que as pessoas são
elementos da imagem que mudam muito de posição.
41

6 Conclusões e trabalhos futuros

Observando os desafios da Robótica Móvel e a tendência atual de realizar trabalhos em


ambientes externos, este trabalho se propôs a desenvolver uma aplicação para o reconhecimento
de lugares nesse tipo de ambiente. Através do uso do framework MCA2-KL foi desenvolvida
uma aplicação para realizar o reconhecimento de lugares em tempo real, utilizando uma câmera
firewire conectada a um notebook.

Os testes realizados para avaliar o desempenho da aplicação utilizaram mapas construı́dos


através de imagens, e os resultados obtidos mostraram que a aplicação desenvolvida consegue
reconher lugares em tempo real e que o método de combinação de descritores utilizado fun-
cionou em situações nas quais não seria possı́vel reconhecer os lugares através apenas de um
descritor, como por exemplo nos gráficos 5.8a e 5.8c. Porém, para aumentar o desempenho da
aplicação é necessário usar um número maior de imagens para caracterizar os lugares do mapa,
pois os testes realizados neste trabalho utilizaram apenas 6 imagens por lugar.

Além da utilização de mais imagens por lugar, é possı́vel melhorar o reconhecimento


através da integração de outros descritores à aplicação, como por exemplo lasers e descritores
visuais de cor; e também através do controle de abertura da ı́ris da lente, o que evitaria a
saturação e excesso de iluminação nas imagens.

Frente aos resultados apresentados no Capı́tulo 5 e às colocações feitas acima, são sugeridos
os seguintes trabalhos:

• Adicionar descritores não-visuais ao cálculo da função de similaridade, com o intuito de


aumentar o desempenho da aplicação nos casos em que o reconhecimento dos descritores
visuais falhou, como por exemplo o pior caso do reconhecimento dos lugares L1 , L3 e L8 ;

• Desenvolver um algoritmo de determinação de pesos para as funções de similaridade dos


descritores, para serem usados no cálculo da função de similaridade geral através de uma
média ponderada;

• Implementar um algoritmo de ajuste da ı́ris segundo a intensidade luminosa, com o obje-


42

tivo de diminuir o ruı́do causado pela luminosidade excessiva, o qual pode causar a falha
de descritores visuais, ao gerar áreas completamente brancas em lugares da imagens onde
poderiam ser identificadas caracterı́sticas;

• Implementar um controlador para permitir que um robô possa utilizar a aplicação desen-
volvida para navegar em um ambiente;

• Desenvolver um algoritmo que possibilite a construção do mapa através de um robô, ao


se movimentar no ambiente e detectar lugares dos quais as caracterı́sticas sejam bem
definidas.
43

Referências Bibliográficas

[1] Cristiano Couto Gava. Reconhecimento de ambientes externos usando visão computa-
cional. Technical report, Coordenação de Aperfeiçoamento de Pessoal de Nı́vel Superior-
CAPES, Processo BEX0598/08-9, 2009.

[2] Luc Van Gool Herbert Bay, Tinne Tuytelaars. SURF: Speeded up robust features. In 9th
European Conference on Computer Vision, 2006.

[3] Michael Jones Paul Viola. Rapid object detection using a boosted cascade of simple fea-
tures. In IEEE Computer Society Conference on Computer Vision and Pattern Recognition
(CVPR2001), pages I–511 à I–518, 2001.

[4] Michael Jones Paul Viola. Robust real-time object detection. In International Journal of
Computer Vision, 2002.

[5] Dieter Fox Sebastian Thrun, Wolfram Burgard. Probabilistic Robotics. Massachusetts
Institute of Technology, 2005.
44

APÊNDICE A -- Código fonte

A.1 Modificado

A.1.1 mca2/libraries/place recognition/build map.cpp

1 # include < iostream >


2 # include < qt4 / QtCore / QFile >
3 # include < qt4 / QtCore / QString >
4 # include < vector >
5 # include < cstdlib >
6

7 # include " tMap . h "


8 # include " tImageSensorData . h "
9

10 using namespace std ;


11

12 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
13 // MAIN CODE
14 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
15 int main ( int argc , char * argv [] )
16 {
17 cout << " ===== Running p l a c e _ r e c o g n i t i o n _ b u i l d _ m a p program =====\ n \ n \ n
";
18

19 string path_map , imgs_file ( " images . txt " ) , map_file ( " map_info . txt " ) ;
20 uint P e r s p e c t i v e I m a g e s P e r P l a c e = 4;
21

22 cout << " Provide the folder path to save the map : " ;
23 cin >> path_map ;
24 cout << " Map is going to be saved in this folder : " << path_map + " \ n "
;
25 cout << " OBS : provide a file in this folder named \" images . txt \"\ n " ;
26 cout << " with images path to compose the map " << " \ n " ;
45

27 map_file = path_map + map_file ;


28 imgs_file = path_map + imgs_file ;
29

30 cout << " How many images per place : " ;


31 cin >> P e r s p e c t i v e I m a g e s P e r P l a c e ;
32

33 QFile file ( imgs_file . c_str () ) ;


34 tMap Map ;
35 ptrPlace ptrplace ;
36 vector < tImageSensorData * > all_images ;
37 all_images . clear () ;
38 all_images . reserve ( 220 ) ; // ADJUST THIS NUMBER IF NEEDED !
39

40 cout << " Loading images ... " << endl ;


41 // Reading all images and putting them into the vector all_images
42 if ( file . open ( QFile :: ReadOnly ) )
43 {
44 QString qstr ;
45

46 while ( 1 )
47 {
48 char buf [1024];
49 qint64 lineLength = file . readLine ( buf , sizeof ( buf ) ) ;
50 if ( lineLength == -1 ) break ;
51

52 qstr . append ( buf ) ;


53 qstr . remove ( ’\ n ’ ) ;
54 cout << " Image " << qstr . toAscii () . constData () << " read . " << endl
;
55

56 tImageSensorData * imgdata = new tImageSensorData ( qstr . toAscii () .


constData () ) ;
57 if ( ! ( imgdata - > iplimage ) )
58 {
59 cout << imgdata - > Description () << " : ERROR while creating object
. Image could not be loaded .\ n " ;
60 file . close () ;
61 return EXIT_FAILURE ;
62 }
63

64 all_images . push_back ( imgdata ) ;


65

66 qstr . clear () ;
46

67 }
68 }
69 else
70 {
71 cout << " Error ! Could not open file . Exiting . " << endl ;
72 file . close () ;
73 return EXIT_FAILURE ;
74 }
75

76 file . close () ;
77

78 uint mod = all_images . size () % ( P e r s p e c t i v e I m a g e s P e r P l a c e ) ;


79 if ( mod != 0 )
80 {
81 cout << " ERROR ! The number of images to be used must be a multiple
of the number of perspective images used to represent a single
place , which in this case is " << P e r s p e c t i v e I m a g e s P e r P l a c e << " .
Exiting . " << endl ;
82 return EXIT_FAILURE ;
83 }
84

85 cout << " \ nBuilding the map ... " << endl ;
86 for ( uint i = 0; i < all_images . size () ; i +=
PerspectiveImagesPerPlace )
87 {
88 cout << " Creating new place for the map with images " << i << " -> "
<< i + P e r s p e c t i v e I m a g e s P e r P l a c e - 1 << " of vector all_images . "
<< endl ;
89 ptrplace . reset ( new tPlace () ) ;
90 for ( uint k = i ; k < i + P e r s p e c t i v e I m a g e s P e r P l a c e ; ++ k )
91 {
92 cout << " \ tAdding image number " << k << " . " << endl ;
93 if ( ! ( ptrplace . get () ) -> Pr ocessS ensorD ata ( all_images [ k ] ) )
94 {
95 cout << " Error while building the map . Problem with image number
" << k << " of vector all_images . Exiting ... " << endl ;
96 return EXIT_FAILURE ;
97 }
98 }
99

100 Map . AddPlace ( ptrplace ) ;


101 }
102
47

103 Map . UpdateEdges () ;


104 Map . Save ( map_file . c_str () ) ;
105

106 return EXIT_SUCCESS ;


107 }

A.2 Desenvolvido

A.2.1 mca2/projects/clebson PG/SConscript

1 # this is a -* - python -* - file


2 # -----------------------------
3 Import ( ’* ’)
4

5 # -------------------------------------------------------
6 # CLEBSON ’S CODE
7 # -------------------------------------------------------
8

9 cam_test = MCAProgram ( ’ t e s t _ p l a c e _ r e c o g n i t i o n _ s u r f _ m a t c h i n g _ f w _ c a m ’)
10 cam_test . AddSourceFiles ( " " "
11 t e s t _ s u r f _ m a t c h i n g _ f w _ c a m . cpp
12 """)
13 cam_test . AddLibs ( ’ m c a 2 _ b a y e s _ n a v i g a t o r mca2_kernel mc a 2 _c o v ir o a _d c 1 39 4
m c a2 _ c ov i r oa _ o pe n c v o p en c v _w i t h_ h i gh g u i dc1394 ’)
14 cam_test . BuildIt ()
15

16 # --------------------------------------------------------
17

18 cam_test_wn = MCAProgram ( ’ t e s t _ p l a c e _ r e c o g n i t i o n _ s u r f _ m a t c h i n g _ f w _ c a m _ w n
’)
19 cam_test_wn . AddSourceFiles ( " " "
20 t e s t _ s u r f _ m a t c h i n g _ f w _ c a m _ w n . cpp
21 """)
22 cam_test_wn . AddLibs ( ’ m c a 2 _ b a y e s _ n a v i g a t o r mca2_kernel
m c a2 _ c ov i r oa _ d c1 3 9 4 m c a2 _ c ov i r oa _ o pe n c v o p en c v _w i t h_ h i gh g u i dc1394 ’)
23 cam_test_wn . BuildIt ()
24

25 # --------------------------------------------------------
26

27 save_image = MCAProgram ( ’ p l a c e _ r e c o g n i t i o n _ s a v e _ f w _ f r a m e ’)
28 save_image . AddSourceFiles ( " " "
29 save_fw_frame . cpp
30 """)
48

31 save_image . AddLibs ( ’ m c a 2 _ b a y e s _ n a v i g a t o r mca2_kernel m c a 2_ c o vi r o a_ d c13 9 4


m ca 2 _ c ov i r oa _ o pe n c v o p en c v _w i t h_ h i gh g u i dc1394 mca2_general
mca2_general_ext ’ )
32 save_image . BuildIt ()
33

34 # --------------------------------------------------------
35

36 save_image_wn = MCAProgram ( ’ p l a c e _ r e c o g n i t i o n _ s a v e _ f w _ f r a m e _ w n ’)
37 save_image_wn . AddSourceFiles ( " " "
38 save_fw_frame_wn . cpp
39 """)
40 save_image_wn . AddLibs ( ’ m c a 2 _ b a y e s _ n a v i g a t o r mca2_kernel
m c a2 _ c ov i r oa _ d c1 3 9 4 m c a2 _ c ov i r oa _ o pe n c v o p en c v _w i t h_ h i gh g u i dc1394 ’)
41 save_image_wn . BuildIt ()
42

43 # --------------------------------------------------------
44

45 gnuplot = MCAProgram ( ’ test_place_recognition_gnuplot - cpp ’)


46 gnuplot . AddSourceFiles ( " " "
47 gnuplot - cpp / example . cc
48 """)
49 gnuplot . BuildIt ()
50

51 # --------------------------------------------------------
52

53 calc_simi = MCAProgram ( ’ p l a c e _ r e c o g n i t i o n _ c a l c _ s i m i l a r i t y ’)
54 calc_simi . AddSourceFiles ( " " "
55 calc_similarity . cpp
56 """)
57 calc_simi . AddLibs ( ’ m c a 2 _ b a y e s _ n a v i g a t o r mca2_kernel m c a 2_ c o vi r o a_ d c 13 9 4
m c a2 _ c ov i r oa _ o pe n c v o p en c v _w i t h_ h i gh g u i dc1394 ’)
58 calc_simi . BuildIt ()

A.2.2 mca2/projects/clebson PG/test surf matching fw cam wn.cpp

1 # include < iostream >


2 # include < vector >
3 # include < fstream >
4 # include < iostream >
5 # include < highgui .h >
6 # include < cstdlib >
7

8 # include " ../../ libraries / coviroa / t F r am e G ra b b er D C 13 9 4 . h "


49

9 # include " ../../ libraries / coviroa / sOpenCVUtils . h "


10 # include " ../../ libraries / place _recog nition / tBayesNavigator . h "
11 # include " ../../ libraries / place _recog nition / tImageSensorData . h "
12 # include " ../../ libraries / place _recog nition / tSURFFeatureSet . h "
13 # include " gnuplot - cpp / gnuplot_i . hpp "
14

15

16 using namespace std ;


17

18 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
19 // Funcoes Extra
20 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
21

22

23 unsigned char getPixel ( IplImage * img , int lin , int col , int channel )
24 {
25

26 return (( unsigned char *) ( img - > imageData + img - > widthStep * lin ) ) [ col +
channel ] ;
27

28 }
29

30 void setPixel ( IplImage * img , int lin , int col , int channel , unsigned
char value ) /* Depende da profundidade do pixel */
31 {
32

33 (( unsigned char *) ( img - > imageData + img - > widthStep * lin ) ) [ col + channel ] =
value ;
34

35 }
36

37 void cleanNoise ( IplImage * orig_img , IplImage * dest_img ) /* Tira o ruido


da camera firefly do LAI */
38 { /* Considerando imagem monocromatica */
39 int i , j ;
40 int id = 0 , jd = 0;
41

42 for ( i =0; i <480; ++ i )


43 {
44

45 for ( j =0; j <640; ++ j )


46 {
47
50

48 if ( j %2 == 0 && ( i +1) %2 == 0 )
49 {
50 setPixel ( dest_img , id , jd , 0 , getPixel ( orig_img , i , j , 0)
);
51 ++ jd ;
52 }
53 }
54

55 if ( ( i +1) %2 == 0 )
56 ++ id ;
57

58 jd = 0;
59 }
60

61 }
62

63 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
64 // Codigo Principal
65 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
66 int main ()
67 {
68

69 /* Mensagem para o usuario */


70 cout << " ===== Executando programa
t e s t _ p l a c e _ r e c o g n i t i o n _ s u r f _ m a t c h i n g _ f w _ c a m _ w n =====\ n \ n \ n " ;
71 cout << " Comandos :\ n " ;
72 cout << " q : encerra o programa \ n " ;
73

74 string path_map ;
75

76 cout << " Forneca a pasta ( caminho completo !) onde esta o mapa : " ;
77 cin >> path_map ;
78 cout << " Usando pasta : " << path_map << endl ;
79 cout << " OBS : a correspondecia sera salva na pasta fornecida " ;
80

81 t F ra m e Gr a b be r D C1 3 9 4 fg (1) ; /* Cria um objeto para obter os frames ,


considerando uma unica camera */
82

83 /* Configura os parametros da aquisicao */


84 fg . SetBestVideoMode (640 , 480 , eIMAGE_FORMAT_MONO8 , 30) ;
85 fg . SetGrabMode ( tImageSource :: eGRAB_ON_REQUEST ) ;
86

87 /* Cria estruturas para receber os frames e exibi - los */


51

88 tImage * image_bgr = new tImage ( fg . Ge tAc tu al Gr ab Wi dt h () , fg .


G et A c tu a l G ra b H ei g h t () , eIMAGE_FORMAT_MONO8 , sizeof ( tTime ) ) ; /*
Imagem de aquisicao */
89 IplImage * o u t pu t _ im a g e_ h a nd l e = c v C re a t eI m a ge H e ad e r ( cvSize (640 , 480) ,
IPL_DEPTH_8U , 1) ; /* Imagem de processamento / exibicao */
90

91 IplImage * a u x _ o u t p u t _ i m a g e _ h a n d l e = c v C re a t eI m a ge H e ad e r ( cvSize (320 ,


240) , IPL_DEPTH_8U , 1) ; /* Imagem auxiliar para limpar ruido */
92 cvCr eateIm ageDat a ( a u x _ o u t p u t _ i m a g e _ h a n d l e ) ;
93 cvZero ( a u x _ o u t p u t _ i m a g e _ h a n d l e ) ;
94

95

96 /* Trasforma a imagem de aquisicao em imagem de processamento / exibicao


*/
97 sOpenCVUtils :: A c c e s s I m a g e A s I p l I m a g e (* image_bgr , * o ut p u t_ i m ag e _ h an d l e )
;
98 cvZero ( o ut p u t_ i m ag e _ ha n d le ) ;
99

100 /* Exibe uma janela sem imagem nenhuma */


101 char * frame_name = new char [50];
102 snprintf ( frame_name , 49 , " Quadros da Camera FireWire " ) ;
103 cvNamedWindow ( frame_name , CV _W IN DO W_ AU TO SI ZE ) ;
104 cvShowImage ( frame_name , o u t p ut _ i ma g e _h a n dl e ) ;
105

106 unsigned int actual_width = 0;


107 unsigned int actual_height = 0;
108 unsigned int a c t u a l _ n u m b e r _ o f _ i m a g e s = 0;
109 unsigned int display_updated = 0;
110 char key ;
111

112 ptrMap Map ( new tMap () ) ;


113 cout << " Carregando mapa ... " << endl ;
114 Map . get () -> Load ( ( path_map + " map_info . txt " ) . c_str () ) ;
115

116 tPlace * place = new tPlace () ;


117 tImageSensorData * imgdata = new tImageSensorData () ;
118 imgdata - > iplimage = a u x _ o u t p u t _ i m a g e _ h a n d l e ;
119

120 tImageSensorData * map_image = new tImageSensorData ( ( path_map + " 0.


JPG " ) . c_str () ) ;
121 if ( ! ( map_image - > iplimage ) )
122 {
123 cout << map_image - > Description () << " : ERRO ao criar objeto . A
52

imagem do mapa nao pode ser carregada .\ n " ;


124 return EXIT_FAILURE ;
125 }
126

127

128 float simi ;


129 int j ;
130 Gnuplot g1 ( " lines " ) ;
131 g1 . set_style ( " points " ) ;
132 vector < float > x (1 ,0) ,y (1 ,0) ;
133

134 while ( true ) {


135

136 key = cvWaitKey (2) ;


137

138 if ( key != ’q ’) { /* Checa se a tecla ’q ’ foi pressionada para parar


o programa */
139

140 /* Exibe a nova imagem quando ela for adquirida */


141 if ( fg . Ac q u ir e I m ag e H an d l es ( actual_width , actual_height ,
a c t u a l _ n u m b e r _ o f _ i m a g e s ) && fg . CopyImages (& image_bgr , 1) )
142 {
143

144 cleanNoise ( output_image_handle , a u x _ o u t p u t _ i m a g e _ h a n d l e ) ;


145

146 cout << " Imagem : " << fg . GetFrameCounter () << endl ;
147

148 place - > Pr ocessS ensorD ata ( imgdata ) ;


149 }
150

151 if ( display_updated != fg . GetFrameCounter () )


152 {
153

154 cvShowImage ( frame_name , a u x _ o u t p u t _ i m a g e _ h a n d l e ) ;


155 display_updated = fg . GetFrameCounter () ;
156 }
157

158 /* Extrai a assinatura do no ( SURF + Textura ) desejado do mapa */


159 const vector < ptrFeatureSet > & v e c t o r _ s u r f _ f e a t _ s e t _ m a p = Map .
get () -> places [0]. get () -> fe at ur e_ co nta in er s [0]. get () ->
GetSignatures () ;
160 tSURFFeatureSet * surf_ feat_s et_map = static_cast <
tSURFFeatureSet * >( v e c t o r _ s u r f _ f e a t _ s e t _ m a p [0]. get () ) ;
53

161

162

163 /* Extrai a assinatura do no ( SURF + Textura ) atual */


164 const vector < ptrFeatureSet > & v e c t o r _ s u r f _ f e a t _ s e t _ q u e r y =
place - > f ea tu re _c on ta in er s [0]. get () -> GetSignatures () ;
165 tSURFFeatureSet * s u r f_ f e at _ s et _ q ue r y = static_cast <
tSURFFeatureSet * >( v e c t o r _ s u r f _ f e a t _ s e t _ q u e r y [0]. get () ) ;
166

167

168 /* Calcula a correspondencia SURF entre as imagens */


169 surf_feat_set_map - > C o m p a r e A n d S a v e I m a g e s ( surf_feat_set_query ,
simi , map_image , imgdata , " 0 " , " vivo " , path_map . c_str () ) ;
170

171 cout << " Similaridade : " << simi << " \ n \ n " ;
172

173 y [0]= simi ;


174

175 /* Comandos do Gnuplot */


176 g1 . remove_tmpfiles () ;
177 g1 . reset_plot () ;
178 g1 . plot_xy (x , y , " Similaridade SURF " ) ;
179 }
180 else
181 {
182 fg . SetGrabMode ( tImageSource :: eGRAB_STOP ) ;
183 cout << " Programa encerrado " << endl ;
184

185 return EXIT_SUCCESS ;


186 }
187 }
188 }

A.2.3 mca2/projects/clebson PG/save fw frame wn.cpp

1 # include < iostream >


2 # include < vector >
3 # include < highgui .h >
4 # include < cstdlib >
5 # include < opencv / cv .h >
6

7 # include " ../../ libraries / coviroa / tImage . h "


8 # include " ../../ libraries / coviroa / t F r am e G ra b b er D C 13 9 4 . h "
9 # include " ../../ libraries / coviroa / sOpenCVUtils . h "
54

10 # include " ../../ libraries / place _recog nition / tImageSensorData . h "


11 # include " ../../ libraries / place _recog nition / tSURFFeatureSet . h "
12

13

14 using namespace std ;


15

16

17 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
18 // Funcoens Extra
19 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
20

21

22 unsigned char getPixel ( IplImage * img , int lin , int col , int channel )
23 {
24

25 return (( unsigned char *) ( img - > imageData + img - > widthStep * lin ) ) [ col +
channel ] ;
26

27 }
28

29 void setPixel ( IplImage * img , int lin , int col , int channel , unsigned
char value ) /* Depende da profundidade do pixel */
30 {
31

32 (( unsigned char *) ( img - > imageData + img - > widthStep * lin ) ) [ col + channel ] =
value ;
33

34 }
35

36 void cleanNoise ( IplImage * orig_img , IplImage * dest_img ) /* Tira o ruido


da camera firefly do LAI */
37 { /* Considerando imagem monocromatica */
38 int i , j ;
39 int id = 0 , jd = 0;
40

41 for ( i =0; i <480; ++ i )


42 {
43

44 for ( j =0; j <640; ++ j )


45 {
46

47 if ( j %2 == 0 && ( i +1) %2 == 0 )
48 {
55

49 setPixel ( dest_img , id , jd , 0 , getPixel ( orig_img , i , j , 0)


);
50 ++ jd ;
51 }
52 }
53

54 if ( ( i +1) %2 == 0 )
55 ++ id ;
56

57 jd = 0;
58 }
59

60 }
61

62 string g en er at eR an do mN am e () {
63

64 stringstream name ( stringstream :: in | stringstream :: out ) ;


65 name . precision (10) ;
66

67 srand (( unsigned ) time ( NULL ) ) ;


68 name << rand () ;
69

70 return name . str () ;


71 }
72

73 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
74 // Codigo Principal
75 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
76

77 int main ()
78 {
79

80 /* Mensagem para o usuario */


81 cout << " ===== Executando programa p l a c e _ r e c o g n i t i o n _ s a v e _ f w _ f r a m e _ w n
=====\ n \ n \ n " ;
82 cout << " Comandos :\ n " ;
83 cout << " q : encerra o programa \ n " ;
84 cout << " s : salva imagem no formato JPG \ n " ;
85

86 t F ra m e Gr a b be r D C1 3 9 4 fg (1) ; /* Cria um objeto para obter os frames ,


considerando uma unica camera */
87

88 /* Configura os parametros da aquisicao */


56

89 fg . SetBestVideoMode (640 , 480 , eIMAGE_FORMAT_MONO8 , 30) ;


90 fg . SetGrabMode ( tImageSource :: eGRAB_ON_REQUEST ) ;
91

92 /* Cria estruturas para receber os frames e exibi - los */


93 tImage * image_bgr = new tImage ( fg . Ge tAc tu al Gr ab Wi dt h () , fg .
G et A c tu a l Gr a b H ei g h t () , eIMAGE_FORMAT_MONO8 , sizeof ( tTime ) ) ; /*
Imagem de aquisicao */
94 IplImage * o u t pu t _ im a g e_ h a nd l e = c v C re a t eI m a ge H e ad e r ( cvSize (640 , 480) ,
IPL_DEPTH_8U , 1) ; /* Imagem de processamento / exibicao */
95

96 IplImage * a u x _ o u t p u t _ i m a g e _ h a n d l e = c v C re a t eI m a ge H e ad e r ( cvSize (320 ,


240) , IPL_DEPTH_8U , 1) ; /* Imagem auxiliar para limpar ruido */
97 cvCr eateIm ageDat a ( a u x _ o u t p u t _ i m a g e _ h a n d l e ) ;
98 cvZero ( a u x _ o u t p u t _ i m a g e _ h a n d l e ) ;
99

100 /* Trasforma a imagem de aquisicao em imagem de processamento / exibicao


*/
101 sOpenCVUtils :: A c c e s s I m a g e A s I p l I m a g e (* image_bgr , * o ut p u t_ i m ag e _ h an d l e )
;
102 cvZero ( o ut p u t_ i m ag e _ ha n d le ) ;
103

104 /* Exibe uma janela sem imagem nenhuma */


105 char * frame_name = new char [50];
106 snprintf ( frame_name , 49 , " Quadros da Camera FireWire " ) ;
107 cvNamedWindow ( frame_name , CV _W IN DO W_ AU TO SI ZE ) ;
108 cvShowImage ( frame_name , a u x _ o u t p u t _ i m a g e _ h a n d l e ) ;
109

110 unsigned int actual_width = 0;


111 unsigned int actual_height = 0;
112 unsigned int a c t u a l _ n u m b e r _ o f _ i m a g e s = 0;
113 unsigned int display_updated = 0;
114 char key ;
115

116 tImageSensorData * imgdata = new tImageSensorData () ;


117 imgdata - > iplimage = a u x _ o u t p u t _ i m a g e _ h a n d l e ;
118

119 while ( true )


120 {
121

122 key = cvWaitKey (2) ;


123

124 /* Exibe a nova imagem quando ela for adquirida */


125 if ( fg . Ac q u ir e I ma g e H an d l es ( actual_width , actual_height ,
57

a c t u a l _ n u m b e r _ o f _ i m a g e s ) && fg . CopyImages (& image_bgr , 1) )


126 {
127

128 cleanNoise ( output_image_handle , a u x _ o u t p u t _ i m a g e _ h a n d l e ) ;


129

130 cout << " Imagem : " << fg . GetFrameCounter () << endl ;
131 }
132

133 if ( display_updated != fg . GetFrameCounter () )


134 {
135

136 cvShowImage ( frame_name , a u x _ o u t p u t _ i m a g e _ h a n d l e ) ;


137 display_updated = fg . GetFrameCounter () ;
138 }
139

140 switch ( key )


141 {
142

143 case ’s ’: /* Checa se a tecla ’s ’ foi pressionada para salvar a


imagem */
144

145 /* Salva a imagem da camera */


146 imgdata - > Save (( ge ne ra te Ra nd om Nam e () + " . JPG " ) . c_str () ) ;
147 cout << " Imagem salva \ n " ;
148

149 break ;
150

151 case ’q ’: /* Checa se a tecla ’q ’ foi pressionada para terminar


o programa */
152

153 fg . SetGrabMode ( tImageSource :: eGRAB_STOP ) ;


154 cout << " Programa encerrado " << endl ;
155

156 return EXIT_SUCCESS ;


157

158 default : break ;


159 }
160 }
161 }

A.2.4 mca2/projects/clebson PG/calc similarity.cpp

1 # include < vector >


58

2 # include < fstream >


3 # include < iostream >
4 # include < highgui .h >
5 # include < cstdlib >
6

7 # include " ../../ libraries / coviroa / t F r am e G ra b b er D C 13 9 4 . h "


8 # include " ../../ libraries / coviroa / sOpenCVUtils . h "
9 # include " ../../ libraries / place _recog nition / tBayesNavigator . h "
10 # include " ../../ libraries / place _recog nition / tImageSensorData . h "
11 # include " ../../ libraries / place _recog nition / tSURFFeatureSet . h "
12 # include " gnuplot - cpp / gnuplot_i . hpp "
13

14

15 using namespace std ;


16

17 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
18 // Funcoes Extra
19 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
20

21

22 unsigned char getPixel ( IplImage * img , int lin , int col , int channel )
23 {
24

25 return (( unsigned char *) ( img - > imageData + img - > widthStep * lin ) ) [ col +
channel ] ;
26

27 }
28

29 void setPixel ( IplImage * img , int lin , int col , int channel , unsigned
char value ) /* Depende da profundidade do pixel */
30 {
31

32 (( unsigned char *) ( img - > imageData + img - > widthStep * lin ) ) [ col + channel ] =
value ;
33

34 }
35

36 void cleanNoise ( IplImage * orig_img , IplImage * dest_img ) /* Tira o ruido


da camera firefly do LAI */
37 { /* Considerando imagem monocromatica */
38 int i , j ;
39 int id = 0 , jd = 0;
40
59

41 for ( i =0; i <480; ++ i )


42 {
43

44 for ( j =0; j <640; ++ j )


45 {
46

47 if ( j %2 == 0 && ( i +1) %2 == 0 )
48 {
49 setPixel ( dest_img , id , jd , 0 , getPixel ( orig_img , i , j , 0)
);
50 ++ jd ;
51 }
52 }
53

54 if ( ( i +1) %2 == 0 )
55 ++ id ;
56

57 jd = 0;
58 }
59

60 }
61

62 string g en er at eR an do mN am e () {
63

64 stringstream name ( stringstream :: in | stringstream :: out ) ;


65 name . precision (10) ;
66

67 srand (( unsigned ) time ( NULL ) ) ;


68 name << rand () ;
69

70 return name . str () ;


71 }
72

73 string composeName ( string strb , unsigned int num , string stra ) {


74

75 stringstream result ( stringstream :: in | stringstream :: out ) ;


76 result . precision (10) ;
77

78 result << strb << num << stra ;


79

80 return result . str () ;


81 }
82
60

83 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
84 // Codigo Principal
85 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
86

87 int main ()
88 {
89

90 /* Mensagem para o usuario */


91 cout << " ===== Executando programa p l a c e _ r e c o g n i t i o n _ c a l c _ s i m i l a r i t y
=====\ n \ n \ n " ;
92 cout << " Comandos :\ n " ;
93 cout << " q : encerra o programa \ n " ;
94 cout << " s : salva o grafico no formato PS \ n " ;
95

96 string path_map ;
97

98 cout << " Forneca a pasta ( caminho completo !) onde esta o mapa : " ;
99 cin >> path_map ;
100 path_map = path_map + " map_info . txt " ;
101 cout << " Usando mapa : " << path_map << endl ;
102

103 /* Cria um objeto para obter os frames , considerando uma unica camera
*/
104 t F ra m e Gr a b be r D C1 3 9 4 fg (1) ;
105

106 /* Configura os parametros da aquisicao */


107 fg . SetBestVideoMode (640 , 480 , eIMAGE_FORMAT_MONO8 , 30) ;
108 fg . SetGrabMode ( tImageSource :: eGRAB_ON_REQUEST ) ;
109

110 /* Cria estruturas para receber os frames e exibi - los */


111 tImage * image_bgr = new tImage ( fg . Ge tAc tu al Gr ab Wi dt h () , fg .
G et A c tu a l Gr a b He i g h t () , eIMAGE_FORMAT_MONO8 , sizeof ( tTime ) ) ; /* Imagem
de aquisicao */
112 IplImage * o u t pu t _ im a g e _h a n dl e = cv C r ea t e Im a g eH e a de r ( cvSize (640 , 480) ,
IPL_DEPTH_8U , 1) ; /* Imagem de processamento / exibicao */
113

114 IplImage * a u x _ o u t p u t _ i m a g e _ h a n d l e = cv C r ea t e Im a g eH e a de r ( cvSize (320 ,


240) , IPL_DEPTH_8U , 1) ; /* Imagem auxiliar para limpar ruido */
115 cvCr eateIm ageDat a ( a u x _ o u t p u t _ i m a g e _ h a n d l e ) ;
116 cvZero ( a u x _ o u t p u t _ i m a g e _ h a n d l e ) ;
117

118

119 /* Trasforma a imagem de aquisicao em imagem de processamento /


61

exibicao */
120 sOpenCVUtils :: A c c e s s I m a g e A s I p l I m a g e (* image_bgr , *
o ut p u t_ i m ag e _ ha n d l e ) ;
121 cvZero ( o ut p u t_ i m ag e _ ha n d le ) ;
122

123 /* Exibe uma janela sem imagem nenhuma */


124 char * frame_name = new char [50];
125 snprintf ( frame_name , 49 , " Quadros da Camera FireWire " ) ;
126 cvNamedWindow ( frame_name , C V_W IN DO W_ AU TO SI ZE ) ;
127 cvShowImage ( frame_name , ou t p ut _ i ma g e _h a n dl e ) ;
128

129 unsigned int actual_width = 0;


130 unsigned int actual_height = 0;
131 unsigned int a c t u a l _ n u m b e r _ o f _ i m a g e s = 0;
132 unsigned int display_updated = 0;
133 char key ;
134

135 ptrMap Map ( new tMap () ) ;


136 cout << " Carregando o mapa ... " << endl ;
137 Map - > Load ( path_map . c_str () ) ;
138

139 ptrPlace place ( new tPlace () ) ;


140 tImageSensorData * imgdata = new tImageSensorData () ;
141 imgdata - > iplimage = a u x _ o u t p u t _ i m a g e _ h a n d l e ;
142

143

144 int i ;
145 int map_size = Map - > places . size () ;
146 Gnuplot g1 ( " lines " ) ;
147 g1 . set_title ( " Reconhecimento de Lugares " ) ;
148 g1 . set_pointsize (2.0) ;
149 g1 . set_grid () ;
150 g1 . set_style ( " linespoints " ) ;
151 g1 . set_xlabel ( " Lugares ( num / num ) " ) ;
152 g1 . set_xrange ( 0.0 , ( double ) map_size - 1) ;
153 g1 . set_ylabel ( " Similaridade Normalizada ( num / num ) " ) ;
154 g1 . set_yrange ( 0.0 , 1.0) ;
155 int desc_number = 2; /* E usado o valor 2 pois estamos usando somente
SURF e Textura */
156 vector < float > x ( map_size , 0) , desc_simi , surf ( map_size , 0) , texture
( map_size , 0) , similarity ( map_size , 0) , x_aux , y_aux ;
157 float max_surf , max_texture ;
158 time_t sec_time ;
62

159 tm * local_time ;
160

161 sec_time = time ( NULL ) ;


162 local_time = localtime (& sec_time ) ;
163

164 stringstream simi_name ( stringstream :: in | stringstream :: out ) ;


165

166 simi_name < < " similarity - " << local_time - > tm_year +1900 < < " _ " << local_time - >
tm_mon +1 < < " _ " << local_time - > tm_mday < < " -" << local_time - > tm_hour -1 < < " :
" << local_time - > tm_min < < " . txt " ;
167

168 ofstream similarity_file ( simi_name . str () . c_str () ) ;


169

170 cout << " Tamanho do mapa : " << map_size << " \ n " ;
171

172 /* Preenche o vetor do eixo x a ser plotado ( lugares do mapa ) */


173 for ( i =0; i < map_size ; i ++)
174 {
175 x [ i ]= i ;
176 }
177

178 while ( true ) {


179

180 key = cvWaitKey (2) ;


181

182 switch ( key )


183 {
184 case ’s ’: /* Checa se a tecla ’s ’ foi pressionada para salvar o
grafico */
185

186 /* Salva o grafico */


187 g1 . savetops ( composeName ( " s i m i l a r i d a d e _ i m a g e m _ " ,
display_updated , " " ) . c_str () ) ;
188 g1 . set_style ( " linespoints " ) ;
189 g1 . replot () ;
190 cout << " Grafico salvo na pasta mca2 \ n " ;
191

192 /* Salva a imagem da camera que gerou o grafico */


193 imgdata - > Save ( composeName ( " imagem_ " , display_updated , " . JPG
" ) . c_str () ) ;
194 cout << " Imagem salva \ n " ;
195

196 /* Salva as similaridades que geraram o grafico */


63

197 similarity_file << composeName ( " === Imagem " ,


display_updated , " ===\ n " ) . c_str () ;
198

199 sec_time = time ( NULL ) ;


200 local_time = localtime (& sec_time ) ;
201

202 similarity_file << " Hora : " << local_time - > tm_hour - 1 << " :
" << local_time - > tm_min <<" : " << local_time - > tm_sec << " \ n "
;
203

204 similarity_file << " Surf : " ;


205 for ( i =0; i < map_size ; i ++)
206 {
207 similarity_file << surf [ i ] << " " ;
208 }
209 similarity_file << " \ n " ;
210

211 similarity_file << " Textura : " ;


212 for ( i =0; i < map_size ; i ++)
213 {
214 similarity_file << texture [ i ] << " " ;
215 }
216 similarity_file << " \ n " ;
217

218 similarity_file << " Geral : " ;


219 for ( i =0; i < map_size ; i ++)
220 {
221 similarity_file << similarity [ i ] << " " ;
222 }
223 similarity_file << " \ n " ;
224

225 break ;
226

227 case ’q ’: /* Checa se a tecla ’q ’ foi pressionada para parar o


programa */
228

229 fg . SetGrabMode ( tImageSource :: eGRAB_STOP ) ;


230

231 similarity_file . close () ;


232

233 cout << " Programa encerrado " << endl ;


234

235 return EXIT_SUCCESS ;


64

236

237 default :
238

239 /* Exibe a nova imagem quando ela for adquirida */


240 if ( fg . A cq u i re I m ag e H an d l es ( actual_width , actual_height ,
a c t u a l _ n u m b e r _ o f _ i m a g e s ) && fg . CopyImages (& image_bgr , 1) )
241 {
242

243 cleanNoise ( output_image_handle , a u x _ o u t p u t _ i m a g e _ h a n d l e )


;
244

245 cout << " Imagem : " << fg . GetFrameCounter () << endl ;
246

247 place - > Pr ocessS ensorD ata ( imgdata ) ;


248 }
249

250 if ( display_updated != fg . GetFrameCounter () )


251 {
252

253 cvShowImage ( frame_name , a u x _ o u t p u t _ i m a g e _ h a n d l e ) ;


254 display_updated = fg . GetFrameCounter () ;
255 }
256

257 /* Calculo da Similaridade */


258 Map - > Get Al lS im il ar it ie s ( place , desc_simi ) ;
259

260 /* Extrai as similaridades de cada Descritor ( SURF e Textura )


*/
261 cout << " ====== Similaridades ======\ n " ;
262 cout << " SURF \ n " ;
263 cout << " Textura \ n " ;
264 for ( i =0; i < ( desc_number * map_size ) ; i ++)
265 {
266 if ( i < map_size )
267 {
268 surf [ i ] = desc_simi [ i ];
269 cout << surf [ i ] << " \ n " ;
270 }
271 else
272 {
273 texture [i - map_size ] = desc_simi [ i ];
274 cout << texture [i - map_size ] << " \ n " ;
275 }
65

276 }
277

278 /* Normaliza as similaridades de cada Descritor ( SURF e


Textura ) */
279 max_surf = surf [0];
280 max_texture = texture [0];
281

282 for ( i =0; i < map_size ; i ++)


283 {
284 if ( surf [ i ] > max_surf )
285 max_surf = surf [ i ];
286 if ( texture [ i ] > max_texture )
287 max_texture = texture [ i ];
288 }
289

290 if ( max_surf == 0) /* Checagem necessaria para evitar divisao


por zero */
291 max_surf = 1.0;
292

293 if ( max_texture == 0) /* Checagem necessaria para evitar


divisao por zero */
294 max_texture = 1.0;
295

296 cout << " ====== Similaridades Normalizadas ======\ n " ;


297 cout << " SURF - Textura - Geral \ n " ;
298

299 for ( i =0; i < map_size ; i ++)


300 {
301 surf [ i ] = surf [ i ]/ max_surf ;
302 cout << surf [ i ] << " " ;
303 texture [ i ] = texture [ i ]/ max_texture ;
304 cout << texture [ i ] << " " ;
305 similarity [ i ] = ( surf [ i ] + texture [ i ]) /( float ) desc_number
;
306 cout << similarity [ i ] << " \ n " ;
307 }
308

309 /* Comandos do Gnuplot para plotar as funcoes de similaridade


*/
310 g1 . reset_plot () ;
311 g1 . remove_tmpfiles () ;
312 g1 . plot_xy (x , surf , " SURF " ) ;
313 g1 . plot_xy (x , texture , " Textura " ) ;
66

314 g1 . plot_xy (x , similarity , " Geral " ) ;


315

316 break ;
317 }
318 }
319 }
67

APÊNDICE B -- Equipamentos utilizados

B.1 Câmera

• Fabricante: POINT GREY;

• Modelo: Color Firefly MV.

Figura B.1: Câmera.

B.2 Lente

• Fabricante: Computar.

Figura B.2: Lente.


68

B.3 Tripé

Figura B.3: Tripé.

B.4 Adaptador firewire

Figura B.4: Adaptador.

B.5 Notebook

• Processador: Dual Core 1,7 GHz;

• Memória: 1 GB.
69

B.6 Visão geral

Figura B.5: Visão geral.

You might also like