Escolar Documentos
Profissional Documentos
Cultura Documentos
Quando se trabalha com Visão Computacional é muito comum a necessidade de realizar ajustes em
algoritmos e parâmetros utilizados, sem contar a quantidade de erros que ocorrem até você acertar o ponto
no seu programa. Sendo assim, é crucial verificar o resultado do processo, que normalmente se dá na forma
de imagem, ou vídeo.
Em uma placa que não possui saída de vídeo ou ambiente desktop, normalmente chamada na literatura
de headless, a técnica mais comum era programar o algoritmo para salvar a imagem ou vídeo no sistema
de arquivos da placa, e depois remotamente fazer o download dos arquivos para verificar o resultado. Nem
preciso dizer que esse processo era demorado, né?
Não somente em se tratando de placas que não possuem saída de vídeo fica o ponto do meu trabalho. Ao se
encerrar a interface gráfica e eliminar alguns processos correlacionados, o sistema como um todo fica com
mais recursos de memória e processador disponíveis para a execução de algoritmos de Visão
Computacional, o que pode levar a um melhor desempenho da placa como um todo.
E se você quiser fazer um robô com câmera? E quiser ver o que o robô… vê? Pela rede?
Pensando nesses detalhes apresentados, escrevi em coautoria com o Thiago Lima e o Prof. Dr. Evandro
Luis Linhari Rodrigues o artigo A low cost embedded system with computer vision and video
streaming (Um sistema embarcado de baixo custo com visão computacional e transmissão de vídeo), cujo
pôster foi apresentado no Workshop de Visão Computacional 2015 (WVC2015) em São Carlos – SP. E
agora, demonstro aqui a implementação prática do trabalho, fazendo uso da linguagem Python.
Viola-Jones é um dos muitos algoritmos existentes, e a cada dia surgem mais, frutos de intensa pesquisa na
área.
Não somente em câmeras digitais estão presentes tais algoritmos. Celulares SmartPhones usam câmeras
frontais para acompanhar os olhos do usuário e controlar eventos para leitura e exibição de vídeo,
televisores SmartTVs já reconhecem gestos do usuário e temos inclusive o famoso Kinect, usado nos
consoles Xbox para controle por gestos e movimentos.
Você também pode escrever programas que façam uso de visão computacional. Para isso, uma das
principais bibliotecas disponíveis é a OpenCV, originalmente criada pela Intel em 1999, e agora mantida
por toda uma comunidade de desenvolvedores, com suporte a linguagens tais como C, C++, Python, Java,
dentre outras.
Basicamente, toda imagem é uma matriz, cujas linhas e colunas endereçam os pixels da referida imagem.
Por sua vez, como estes pixels serão referenciados irá depender se a imagem está em escala de cinza,
colorida, etc.
Podemos unicamente realizar algum processo sobre a imagem capturada, e não necessariamente algo de
maior inteligência. Dessa forma, estamos na área de Processamento Digital de Imagens. É nesta área que
entram técnicas para remover ruídos de imagens, alterar propriedades de brilho, contraste, etc. Ou seja,
você aperfeiçoa a imagem ou alguma propriedade importante nela. Se você usa o Instagram e fica
brincando com filtros de imagem, sem saber, está usando de técnicas de Processamento Digital de Imagens.
OpenCV pode ser facilmente instalado e configurado em SBCs tais como a Intel Edison, e juntamente com
uma Webcam, por exemplo, torna-se possível criar programas capazes de controlar um robô seguidor de
linha por imagem, ou um sistema que reconhece gestos e movimentos, ou até mesmo um sistema de
segurança que detecta movimento na imagem, tira foto e envia por e-mail, por exemplo. As
possibilidades… são infinitas. Mãos à obra?
Para instalar as bibliotecas necessárias, realize os seguintes comandos em um terminal de console (com
acesso local ou remoto):
Feito o processo, vamos conferir se as bibliotecas foram devidamente instaladas. Para isso, inicie o console
Python por meio do comando:
# python
E como saber se está tudo OK?! Simples: Se não aparecer nenhuma mensagem de erro, então tá OK!
No meu caso, estou usando uma Câmera USB. Certifique-se que sua Intel Edison esteja reconhecendo
devidamente a sua câmera USB. Para verificar isso, digite o seguinte comando no console Linux:
# ls /dev/video*
Se aparecer “/dev/video0”, então está tudo OK. A princípio… Veja como ficou a minha tela:
Não tem a Intel Edison? Todos os passos aqui mostrados se aplicam também na Intel Galileo,
tanto Gen1quanto Gen2, como demais SBCs com Linux Embarcado, tal como a Raspberry Pi. Bastando, é
claro, ter Python 2.7 instalado, com OpenCV e Numpy.
Arquitetura do Sistema
Como a Intel Edison não possui saída de vídeo, e muito menos um ambiente gráfico em execução, para
visualizar em “tempo real” a execução de algoritmos de Visão Computacional iremos então bolar um
sistema com as seguintes propriedades:
Como base, crie um arquivo chamado openCV-Server.py em sua Intel Edison, e cole o seguinte trecho de
código mostrado abaixo. Salve o arquivo.
#!/usr/bin/python
import socket
import cv2
import numpy
# chmod +x openCV-Server.py
# ./openCV-Server.py
Feito isso, a aplicação será iniciada, e ficará aguardando uma conexão da aplicação Cliente. Agora vamos à
codificação da aplicação cliente.
import socket
import cv2
import numpy
Em se tratando do IDLE, em ambiente Windows, basta ir na opção “Run -> Run Module” para executar o
código Python escrito. De outra forma, basta apertar F5 para iniciar a execução.
Em ambiente Linux, será preciso chamar o código em linha de comando, tal como:
$ python openCV-Client.py
Se tudo correr certo, a aplicação irá conectar na Intel Edison, e logo aparecerá uma janela mostrando os
quadros de imagem. Caso haja um certo delay, um atraso entre o cenário real e o exibido na janela, é
normal. Temos um overhead de processamento ao usarmos Python, serialização de objeto, etc…
Caso não apareça sua janela, veja o erro ocorrido. Certifique-se de usar o IP correto da Intel Edison, de que
a porta de comunicação está disponível, dentre outras coisas.
Execução
Veja na Figura 8 o console de execução na Intel Edison. A aplicação servidora foi iniciada e aguarda
conexões.
Figura 8 – Tela de console Linux da Intel Edison – Servidor Iniciado.
Na Figura 9, é mostrado o IDLE em execução, com a janela de Shell, janela de código, e a janela
do streamde quados mostrando o resultado do processo.
Para isso, basta tratar na aplicação cliente e na aplicação servidora uma comunicação bidirecional. Ou seja,
a aplicação servidora agora passará a receber parâmetros de comando da aplicação cliente, e esta, por sua
vez, passará a enviar parâmetros de comando, conforme digitado pelo usuário. Agora, o usuário poderá ter
o poder de mudar a forma como que os quadros serão processados na máquina servidora.
No exemplo em questão, irei trabalhar de forma que a aplicação trabalhe com 4 estados distintos, além de
poder ser encerrada pela aplicação cliente, tendo por base os seguintes comandos recebidos via Socket:
#!/usr/bin/python
import socket
import cv2
import numpy
Para executar o programa, digite o seguinte comando no console Linux da Intel Edison:
# ./openCV-Server-Tunado.py
Assim sendo, a aplicação cliente terá uma variável chamada estado, que irá variar conforme as seguintes
teclas digitadas pelo usuário:
n – Ao digitar n, o estado atual é ‘normal’, e não é feita nenhuma modificação na imagem capturada
pela Edison;
w – Ao digitar w, o estado atual será ‘gray’, e a aplicação servidora irá tornar os quadros de imagem
capturados de colorido para escala de cinza;
c – Ao digitar c, o estado atual passa para ‘canny’, em que a aplicação servidora irá então aplicar o
Filtro de Canny nos quadros de imagem subsequentes;
b – Ao digitar b, o estado será ‘blur’, e a aplicação servidora irá passar a aplicar o respectivo filtro em
cada imagem capturada;
q – Ao digitar q, a aplicação será encerrada, enviando também comando para encerrar a aplicação
servidora.
Com o estado definido, a cada execução do loop infinito while true é então enviado o estado de operação
para a aplicação servidora, que o tomará por base para a execução do correspondente algoritmo ou ação
sobre a imagem capturada, e podendo eventualmente até mesmo encerrar a própria aplicação servidora.
Dito isso, veja abaixo o código da aplicação cliente devidamente comentado, indicando campos, trechos e
rotinas de código com suas correspondentes funcionalidades. Para reproduzir o feito, salve o código em um
arquivo com nome openCV-Client-Tunado.py para logo ser executado.
import socket
import cv2
import numpy
def recvall(sock, count):
buf = b''
while count:
newbuf = sock.recv(count)
if not newbuf: return None
buf += newbuf
count -= len(newbuf)
return buf
Salvado o arquivo, é possível executá-lo no IDLE pressionando a tecla F5, ou em ambiente Linux por meio
do comando em console:
$ ./openCV-Client-Tunado.py
Se tudo correr bem, irá aparecer uma janela com o stream de imagem, colorida, normal. Para mudar o
estado de operação e verificar a “imediata” mudança no processo, mantenha pressionada a tecla
correspondente até que a aplicação cliente faça a leitura. Pode demorar “um pouquinho”. Assim que a
aplicação cliente lê o comando do usuário, o mesmo é transmitido para a aplicação servidora, que passa a
mudar seu processo. Veja o resultado em execução!
E na máquina cliente, é então iniciada a aplicação. Com isso, surge a janela com o stream de imagens,
agora podendo ser alterado pelas teclas configuradas na aplicação. Ao pressionar ‘c’, por exemplo, é
informado que o estado de operação passa a ser ‘Canny’, devendo então a aplicação servidora realizar o
correspondente algoritmo nos quadros capturados a partir de então. Veja na Figura 12 como ficou o
resultado deste exemplo:
Figura 12 – Exemplo de execução da Aplicação Cliente “Tunada”
E adiante seguem as janelas de exibição para cada estado/modo de exibição. Na Figura 13 é mostrada a
janela de captura para Estado Normal, na Figura 14 é mostrada a janela de captura para Estado Escala de
Cinza, na Figura 15 é mostrada a janela de captura para Estado Blur, e na Figura 16 é mostrada a janela de
captura para Estado Canny. Veja em cada imagem o resultado do processo.
Adiante segue também o vídeo que preparei, justamente quando acabei de escrever este artigo:
Caso afirmativo, você pode fazer o curso de Python no CodeAcademy, e se quiser ver mais detalhes acerca
de Python com OpenCV, o site PyImageSearch é uma opção, além do Python OpenCV Tutorials, sem
esquecer, é claro, da documentação com exemplos oficiais.
Sinta-se à vontade para basear projetos nos códigos apresentados. As possibilidades são infinitas. Agora
você pode controlar um robô com câmera, visualizando a câmera do robô e demais processos realizados
sobre a imagem que ele captura. Ou melhor, você pode fazer um sistema de segurança com reconhecimento
facial ou detecção de objetos, tais como faces humanas!
O que você vai fazer?