Você está na página 1de 22

Visão Computacional com OpenCV na Intel Edison

23 de outubro de 2015 Deixe seu comentárioEscrito por andrecurvello

Post de minha autoria originalmente publicado no Embarcados.


Durante o 1° IoT RoadShow 2015 da Intel em São Paulo, participei com a equipe do Embarcados na
realização do projeto MonitorAKI, que fez uso primordialmente de Visão Computacional por meio da
biblioteca OpenCV. Além, é claro, de enviar mensagens via WhatsApp, conforme demonstrado em outro
artigo meu.
Uma das questões que mais me pediram foi acerca de como configurar a Intel Edison para operar com
OpenCV, e ainda mais… Como trabalhar com Visão Computacional com uma placa que nem sequer possui
saída de vídeo? Isso é realmente uma limitação…? Não! Se não tem saída de vídeo, que tal usar Rede?
Ainda mais…Wi-Fi!
Figura 1 – Intel Edison – Não possui saída de vídeo!

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.

Um pouco de Visão Computacional


Visão Computacional compreende todo um conjunto de técnicas capazes de fazer um computador
interpretar imagens de uma maneira tão próxima quanto um ser humano é capaz. Dessa forma, com a
aplicação de tais técnicas é possível então fazer um computador reconhecer suas mãos, reconhecer seus
gestos, reconhecer seu rosto, realizar sua identificação por impressão digital, etc.

Figura 2 – Reconhecimento de Objetos em Imagem. Fonte: thevoice.ottawachamber.ca


Já usou uma câmera digital? Viu que ela normalmente identifica os rostos presentes na imagem? Com
certeza ela implementa o algoritmo de Viola-Jones, que detecta padrões numa imagem correspondentes ao
rosto humano. Como exemplo, veja a imagem abaixo, demonstrando um exemplo de detecção de faces.

Figura 3 – Detecção de Faces. Fonte: technologyreview.com

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.

Figura 4 – Tela de depuração do Kinect em Xbox – Fonte: gamerhub.tv

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?

Configuração da Intel Edison


Antes de tudo, tomarei por base uma placa Intel Edison previamente configurada com Poky Linux da Intel.
Caso você queira reconfigurar a sua, pode ver este guia do Diego Sueiro ou o Guia da Intel (inglês).
Agora, certifique-se de duas coisas:

1. Sua Intel Edison possui acesso à rede local e à Internet;


2. Sua Intel Edison possui acesso remoto via SSH.
Para o devido funcionamento do sistema, iremos precisar da biblioteca OpenCV devidamente instalada, e
da biblioteca NumPy, específica para Python. Em se tratando da Intel Edison, é possível instalar a
biblioteca OpenCV para Python somente. Caso queira usar com alguma linguagem tal como C ou C++,
será necessário compilar dos fontes.

Para instalar as bibliotecas necessárias, realize os seguintes comandos em um terminal de console (com
acesso local ou remoto):

# opkg install python-opencv


# opkg install python-numpy

Feito o processo, vamos conferir se as bibliotecas foram devidamente instaladas. Para isso, inicie o console
Python por meio do comando:

# python

E agora verifique se as bibliotecas foram devidamente instaladas digitando:

>> import cv2


>> import numpy

E como saber se está tudo OK?! Simples: Se não aparecer nenhuma mensagem de erro, então tá OK!

Para sair, digite quit() no console Python. Veja o resultado na imagem adiante.

Figura 5 – Teste de Imports em Python – Intel Edison

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:

Figura 6 – Resposta ao comando “ls /dev/video0” na Intel Edison.


Caso  a sua câmera esteja conectada na USB da placa-base da Intel Edison, e mesmo assim não esteja
aparecendo, certifique-se que a USB da Intel Edison esteja configurada para Host.

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:

1. Linguagem de programação utilizada: Python;


2. Forma de comunicação: Socket TCP via Rede Ethernet ou Wi-Fi;
3. Abordagem Cliente-Servidor:
o Intel Edison: Servidor;
o Aplicação Desktop: Cliente;
4. Dispositivo de captura: Câmera USB – WebCam.
Então, a título de exemplo, irei demonstrar uma aplicação escrita em Python executando na Intel Edison, a
qual fará a leitura de quadros de uma Webcam conectada em sua porta USB, irá processar (ou não…) estes
quadros e os transmitirá pela rede para a aplicação cliente, tal como mostrado na figura a seguir.

Figura 7 – Arquitetura do Sistema Proposto


Dessa forma, teremos um stream de quadros sendo transmitido, possibilitando ver o resultado do processo
realizado na Intel Edison, por exemplo.

Codificação da Aplicação Servidora


Para entender fundamentalmente a aplicação, além de OpenCV também é importante ter noções básicas de
Sockets de comunicação. Em termos de Python, alguns conceitos muito breves são apresentados aqui.
A comunicação via rede utilizando sockets precisa de dados “serializados”, ou seja, dados transformados
em uma sequência de informações. O que acontece é que uma imagem é uma matriz. Como transformar
uma matriz em uma sequência? Basta usarmos o método .array() da biblioteca NumPy e o
método .tostring(), que, em sequência, irão serializar um objeto a ser transferido via rede usando Socket.

Na nossa sequência de código para a aplicação servidora, teremos a seguinte lógica:

1. Criação de objeto de Socket;


2. Vínculo com IP e Porta de comunicação;
3. Habilitação de escuta de conexões;
4. Criação de objeto de captura de imagem;
5. Parametrização da codificação da imagem;
6. Aguarda conexão de cliente;
7. Loop infinito:
1. Codificação da imagem;
2. Serialização da imagem;
3. Transmissão da imagem;
4. Captura de nova imagem;
8. Encerramento de objetos de captura e socket.
Adiante, segue o código-fonte desenvolvido para este artigo. Como de costume, está muito bem
comentado, apresentando detalhes e informações acerca de cada trecho e rotina. Leia com atenção.

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

# Variaveis para armazenar IP e porta de comunicacao


TCP_IP = '' # campo vario - vincula a todos os ips que a maquina possui na rede
TCP_PORT = 5052
# Criacao do socket de comunicacao para servidor
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Vincula o socket de servidor com o IP e Porta. IP = '' - rede
serverSocket.bind((TCP_IP,TCP_PORT))
# Habilita que socket de servidor ira escutar requisicoes
serverSocket.listen(True)

# Cria objeto de captura vinculado a device 0 - webcam


capture = cv2.VideoCapture(0)
# Captura um quadro para verificar conexao
ret, frame = capture.read()

# Parametrizacao da codificacao de imagem a ser transmitirda


encode_param = [int(cv2.IMWRITE_JPEG_QUALITY),90]

print 'Aguardando conexoes...'


# Aguarda conexao com cliente e cria objeto "conn" - socket
conn, add = serverSocket.accept()
while ret:
# codifica o quadro de imagem em formato jpg e grava em imgencode
result, imgencode = cv2.imencode('.jpg', frame, encode_param)
# tranforma imgencode em vetor - serializacao
data = numpy.array(imgencode)
# converte o vetor em string
stringData = data.tostring()
# Envia comprimento do quadro de imagem, com 16 caracteres justificado a esquerda
conn.send(str(len(stringData)).ljust(16));
# Envia quadro de imagem serializado em string
conn.send(stringData)
# Realiza leitura de quadro da webcam, grava em frame
ret,frame = capture.read()
# Encerra conexao com camera usb - webcam
capture.release()
# Encerra o socket de comunicacao
serverSocket.close()
Após ter salvado o arquivo, é preciso dar ao mesmo permissão de execução, o que é possível por meio do
seguinte comando:

# chmod +x openCV-Server.py

Agora, para executar o programa basta digitar:

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

Codificação da Aplicação Cliente


O objetivo da aplicação cliente é conectar na aplicação servidora pela rede, receber os quadros de imagem
via socket e exibir esse stream para o usuário em uma janela.
A aplicação cliente pode ser executada tanto em ambiente Windows, quanto em ambiente Linux. Bastando
que Python esteja instalado, juntamente com as bibliotecas OpenCV e Numpy também! Dessa forma, o
presente exemplo foi executado em ambiente Windows 10 por meio do IDLE – Python’s Integrated
Development and Learning Environment. O IDLE possui tanto o acesso ao console Python, como também
pode criar arquivos Python. Basta ir na opção File -> New, que aparecerá uma janela onde você poderá
tranquilamente digitar seu código Python com destaque para palavras da sintaxe.
Em se tratando de ambiente Windows, veja como instalar o Python, com suporte a OpenCV para
Python aqui. Neste mesmo link também é informado onde baixar o Numpy. E sobre como instalar e
configurar o Python com OpenCV para ambiente Linux, tendo como base o Ubuntu, veja aqui.
Na nossa sequência de código para a aplicação cliente, teremos a seguinte lógica:

1. Criação de objeto de Socket;


2. Conexão com máquina servidora;
3. Loop infinito:
1. Recebe tamanho da imagem;
2. Recebe imagem completa;
3. Reconstrói array de dados de string;
4. Decodifica a imagem do array de dados;
5. Exibe a imagem em janela para o usuário;
6. Se digitar ‘q’, encerra loop;
4. Encerramento de objetos de captura e socket.
Um método criado à parte para usar com a aplicação cliente, que receberá os quadros de imagem, é
o recvall, método que irá receber como parâmetros um socket e uma quantidade de dados, quantidade que
será usada como base de “tamanho” para retornar então a informação esperada. Tive uma base de
inspiração para o modelo cliente-servidor utilizado no artigo neste tópico do StackOverflow.
Vamos então à codificação? Crie um arquivo na sua Máquina Desktop (Windows ou Linux – devidamente
configurados com Python + OpenCV + Numpy, chamado  openCV-Client.py, e cole o conteúdo de código
apresentado adiante. Veja, novamente, que o código está muito bem comentado e apresenta detalhes sobre
comandos e trechos de código.

import socket
import cv2
import numpy

# Rotina recvall - trata de receber informacao


def recvall(sock, count):
buf = b''
while count:
newbuf = sock.recv(count)
if not newbuf: return None
buf += newbuf
count -= len(newbuf)
return buf

# Atribui IP da estacao servidora - Intel Edison


TCP_IP = '192.168.1.13'
# Porta de comunicacao
TCP_PORT = 5052

# Cria objeto socket para comunicacao


conn = socket.socket()

# Faz conexao com estacao servidora


conn.connect((TCP_IP,TCP_PORT))

# Loop infinito: Recebe imagem, exibe. Se digitar q - sai.


while True:
# Recebe tamanho da imagem
length = recvall(conn,16)
# Recebe imagem propriamente
stringData = recvall(conn, int(length))
# Recupera a imagem serializada em forma de string
data = numpy.fromstring(stringData, dtype='uint8')
# Decodifica a imagem
decimg=cv2.imdecode(data,1)
# Exibe a imagem
cv2.imshow('EdisonCAM',decimg)
# Se digitar 'q', encerra.
if(cv2.waitKey(1) & 0xFF == ord('q')):
break

# Fecha as janelas do OpenCV


cv2.destroyAllWindows()
# Encerra o socket
conn.close()

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.

Figura 9 – Execução da aplicação Cliente – Exibição da janela de stream de imagens

E na Figura 10 é mostrada uma foto da montagem da Intel Edison correspondente.


Figura 10 – Cenário real da montagem da Intel Edison com Câmera USB.

Aplicação Servidora – Aprimorada


Agora, vamos pensar no seguinte cenário: E se a aplicação servidora pudesse ser parametrizada? Ou seja,
e se durante a execução do sistema, fosse possível mudar o algoritmo em execução, alterar parâmetros
deste algoritmo, etc…?

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:

 normal – Operação normal, não altera o quadro capturado;


 canny – Aplica o Filtro de Canny na imagem capturada;
 gray – Aplica a conversão de espaço de cores de colorida à escala de cinza na imagem capturada;
 blur – Aplica um filtro causando efeito de atenuação na imagem – efeito de “Blur”;
 sair – Encerra a aplicação.
Dessa forma, a aplicação servidora passa a ter a seguinte sequência de lógica de funcionamento:

1. Criação de objeto de Socket;


2. Vínculo com IP e Porta de comunicação;
3. Habilitação de escuta de conexões;
4. Criação de objeto de captura de imagem;
5. Parametrização da codificação da imagem;
6. Aguarda conexão de cliente;
7. Loop infinito:
1. Leitura de comando da aplicação cliente;
2. Codificação da imagem;
3. Serialização da imagem;
4. Transmissão da imagem;
5. Captura de nova imagem;
6. Processo de imagem conforme comando;
8. Encerramento de objetos de captura e socket.
De modo a diferenciar o código simplificado do código aprimorado, crie um novo arquivo para o código da
aplicação servidora na Intel Edison, chamado openCV-Server-Tunado.py, e coloque neste arquivo o
código de programa mostrado adiante. Veja os comentários e os trechos que tratam de avaliar o
recebimento de comandos da aplicação cliente, e o processo de quadros com base nestes comandos.

#!/usr/bin/python
import socket
import cv2
import numpy

# IP de vinculo - '' geral na maquina


TCP_IP = ''
# Porta de conexao
TCP_PORT = 5052

#Variavel para estado de funcionamento - comando recebido do cliente


comando = 'normal'
#Variavel para kernel de blur
kernel = numpy.ones((5,5), numpy.float32)/25
#Tamanho de buffer de comunicacao
BUFFER_SIZE = 20

# Criacao do socket de comunicacao para servidor


serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Vincula o socket de servidor com o IP e Porta. IP = '' - rede
serverSocket.bind((TCP_IP,TCP_PORT))
# Habilita que socket de servidor ira escutar requisicoes
serverSocket.listen(True)

# Cria objeto de captura vinculado a device 0 - webcam


capture = cv2.VideoCapture(0)
# Captura um quadro para verificar conexao
ret, frame = capture.read()

# Parametrizacao da codificacao de imagem a ser transmitirda


encode_param = [int(cv2.IMWRITE_JPEG_QUALITY),90]

print 'Aguardando conexoes...'


# Aguarda conexao com cliente e cria objeto "conn" - socket
conn, add = serverSocket.accept()

# Enquanto houver retorno de quadro na webcam


while ret:
# Espera envio de comando da maquina cliente.
estado = conn.recv(BUFFER_SIZE)
# codifica o quadro de imagem em formato jpg e grava em imgencode
result, imgencode = cv2.imencode('.jpg', frame, encode_param)
# tranforma imgencode em vetor - serializacao
data = numpy.array(imgencode)
# converte o vetor em string
stringData = data.tostring()
# Envia comprimento do quadro de imagem, com 16 caracteres justificado a esquerda
conn.send(str(len(stringData)).ljust(16));
# Envia quadro de imagem serializado em string
conn.send(stringData)
# Realiza leitura de quadro da webcam, grava em frame
ret,frame = capture.read()
# processo do quadro conforme parametro enviado pela maquina cliente
if comando == 'normal':
# Se for normal, nao faz nada.
frame = frame
elif comando == 'canny':
# Se for canny, aplica o detector de bordas.
frame = cv2.Canny(frame,100,200)
elif comando == 'gray':
# Se for blackwhite - aplica transformacao de cor
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
elif comando == 'blur':
# Se for blur, aplica filtro parametrizado
frame = cv2.filter2D(frame, -1, kernel)
elif comando == 'sair':
# Se for sair, encerra.
break

# Encerra conexao com camera usb - webcam


capture.release()
# Encerra o socket de comunicacao
serverSocket.close()

Para executar o programa, digite o seguinte comando no console Linux da Intel Edison:

# ./openCV-Server-Tunado.py

A aplicação será iniciada e aguardará a conexão da aplicação cliente.

Aplicação Cliente – Aprimorada


Não obstante, a aplicação cliente agora também deve implementar uma comunicação bidirecional, ou seja,
deve ser capaz de também enviar mensagens, comandos para a aplicação servidora. E como a “coisa” está
arquitetada, constantemente a aplicação servidora precisa receber o parâmetro indicando como deve
processar o quadro de imagem capturado pela câmera USB. Dessa forma, constantemente também a
aplicação cliente deverá enviar o comando que determina isso.

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

# Atribui IP da estacao servidora - Intel Edison


TCP_IP = '192.168.1.13'
# Porta de comunicacao
TCP_PORT = 5052

# Cria variavel para referencia de estado de operacao - comeca normal


estado = 'normal'
# Cria objeto socket para comunicacao
conn = socket.socket()

# Faz conexao com estacao servidora


conn.connect((TCP_IP,TCP_PORT))
# Envia estado de operacao via socket
conn.send(estado)

# Loop infinito - recebe quadro de imagem, exibe, verifica tecla digitada


# pelo usuario.
while True:
length = recvall(conn,16)
stringData = recvall(conn, int(length))
data = numpy.fromstring(stringData, dtype='uint8')
decimg=cv2.imdecode(data,1)
cv2.imshow('EdisonCAM',decimg)
if(cv2.waitKey(1) & 0xFF == ord('c')):
estado = 'canny'
print 'Estado de operacao: Canny'
elif(cv2.waitKey(1) & 0xFF == ord('w')):
estado = 'gray'
print 'Estado de operacao: Escala de Cinza'
elif(cv2.waitKey(1) & 0xFF == ord('b')):
estado = 'blur'
print 'Estado de operacao: Blur'
elif(cv2.waitKey(1) & 0xFF == ord('n')):
estado = 'normal'
print 'Estado de operacao: Normal'
elif(cv2.waitKey(1) & 0xFF == ord('q')):
estado = 'sair'
print 'Encerrando aplicacao...'
break
conn.send(estado)

# Fecha as janelas do OpenCV


cv2.destroyAllWindows()
# Encerra socket de conexao
conn.close()

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!

Execução da solução aprimorada


Para execução da solução cliente-servidor aprimorada, agora dispondo de comunicação bidirecional e
mudança de estado de operação, é preciso inicialmente começar a execução da aplicação servidora na Intel
Edison. Veja na Figura 11 a aplicação servidora sendo iniciada.

Figura 11 – Iniciando Servidor Tunado na Intel Edison

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.

Figura 13 – Execução Normal.


Figura 14 – Execução em Escala de Cinza.

Figura 15 – Execução em modo Blur.


Figura 16 – Execução em Modo Canny.

Adiante segue também o vídeo que preparei, justamente quando acabei de escrever este artigo:

Gostou? Ficou interessado em Python e OpenCV?

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?

Você também pode gostar