ÍNDICE DE CONTEÚDO
Visão computacional é a visão de máquinas, é possível obter informações de imagens, sejam elas astronômicas, microscópicas ou em tamanho natural, podemos utilizar algoritmos computacionais para descrever e analisar o conteúdo de qualquer imagem digitalizada.
Essa prática é cada vez mais comum na indústria no controle de qualidade de processos e orientação de robôs, a visão computacional é capaz de realizar análises com precisão e velocidades que o olho humano não poderia alcançar, traz um novo leque de possibilidades como navegação de veículos autônomos, descoberta de novos planetas e análises biológicas em células.
Sobre o projeto
Um sistema de visão computacional para identificar e analisar biscoitos em tempo real, desenvolvido com software livre e neste caso voltado para uso educacional.
Funcionamento do sistema
O sistema de visão computacional utiliza uma câmera digital, uma iluminação uniforme tipo domo e um computador com software para processar e analisar as imagens. O software utiliza técnicas de processamento de imagens que são como os filtros do photoshop, os filtros têm o objetivo de tratar as imagens, retirar o fundo (background) e deixar o objeto com o melhor contraste possível e sem ruídos que possam atrapalhar a análise geométrica. Após filtrada a imagem, temos uma imagem binária, uma imagem preto e branco somente com a forma do objeto, chamamos essa imagem binária de máscara e é nela que o software irá realizar as análises de padrões geométricos.
Primeiro o software verifica a presença do biscoito na imagem pela cor/tom com uma função simples e rápida chamada trigger, depois se houver a presença detectada do objeto a imagem passa por filtros é retirada a máscara e em seguida passa para análise do padrão geométrico que vai identificar as peças boas e ruins e ao final o resultado é mostrado na tela em tempo real.
OpenCV – Biblioteca aberta de visão computacional da Intel
OpenCV é a principal biblioteca de código aberto para a visão computacional, processamento de imagem e aprendizagem de máquina, e agora apresenta a aceleração de GPU para operação em tempo real.
OpenCV é liberado sob uma licença de BSD e daqui é livre para o uso acadêmico e comercial. Possui interfaces C++, C, Python e Java e suporta Windows, Linux, Mac OS, iOS e Android. OpenCV foi projetado para eficiência computacional e com um forte foco em aplicações em tempo real. Escrito em C/C++ otimizado, a biblioteca pode aproveitar o processamento multi-core. Adotado em todo o mundo, OpenCV tem mais de 47 mil pessoas da comunidade de usuários e número estimado de downloads superior a 6 milhões. O uso varia de arte interativa, a inspeção de minas, costura mapas na web ou através de robótica avançada.
Documentação oficial do OpenCV.
Recomendo a leitura da documentação oficial do OpenCV para aprendizado e consulta!
Considero que você possui conhecimentos em programação, tem o OpenCV instalado e testou alguns, ou todos os exemplos dele em C++ e Python e fez um hello world com CMAKE.
Esse tutorial é de nível intermediário, apesar da simplicidade do código, é necessário algum conhecimento mas qualquer um pode aprender seguindo a documentação.
O projeto
Vamos apresentar a utilização do OpenCV em um projeto realtime simples, completo e de baixo custo.
Esse projeto poderá ser modificado para muitos outros casos de inspeção visual de objetos e sua arquitetura é fruto de anos de pesquisa e desenvolvimento para obter o melhor desempenho e manter a simplicidade do código com menor custo possível.
Funcionamento algoritmo básico:
- Captura
- Detecção
- Pre-processamento / filtro
- Inspeção / análise
- Resultado
Parametrização, antes de capturar a imagem é necessário configurar a câmera, resolução, fps, tempo de exposição e ganho do sensor manual.
1 2 3 |
//comando do sistema (video1, tempo de exposição manual, ganho do sensor manual) int status = system( "v4l2-ctl -d /dev/video1 -c gain_automatic=0 -c gain=0 -c auto_exposure=1 -c exposure=30 -c power_line_frequency=1" ); |
1 – Captura – abrir conexão, primeiro vamos abrir uma conexão com a câmera para imagem ser capturada.
1.0 – Conexão da câmera, este passo ocorre fora do loop principal, na inicialização do sistema:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
int main(int, char**) { // video 1, exposure manual, gain manual int status = system( "v4l2-ctl -d /dev/video1 -c gain_automatic=0 -c gain=0 -c auto_exposure=1 -c exposure=30 -c power_line_frequency=1" ); double start=0; double end=0; //iniciar captura camera 1 capture.open(1); pthread_mutex_init(&frameLocker, NULL); pthread_t UpdateThread; pthread_create(&UpdateThread, NULL, UpdateFrame, NULL); //loop principal for (;;) {(...)} |
1.1 Captura de frame, esta função é um loop e roda dentro de uma thread independente, aqui utilizei um mutex que tem a função de impedir que a imagem seja acessada simultaneamente por duas threads, pois a frame é uma variável tipo global e é utilizada por duas threads.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/capture void *UpdateFrame(void *arg) { for(;;) { try { Mat tempFrame = Mat::zeros( frame.size(), CV_8UC3 ); capture >> tempFrame; pthread_mutex_lock(&frameLocker); if (!tempFrame.empty()) frame = tempFrame; pthread_mutex_unlock(&frameLocker); } catch(Exception &e) { cout << e.msg << endl; } } } |
2 – Detecção, uma função simples e rápida que verifica se o objeto existe na frame capturada!
A detecção ou trigger é uma área retangular no centro da imagem que testa a média da cor/tom.
Se a comparação for verdadeira a frame capturada contém o objeto e podemos inspecioná-la.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
//Trigger float trigger(Mat &tframe) { try { float resmean = 0; int x=200,y=200,w=300,h=110; Rect roi = Rect(x,y,w,h); Mat mask0 = Mat::zeros( tframe.size(), CV_8UC1 ); rectangle(mask0,roi,255,1); Mat imRoi = frame(roi); Scalar tempMean = mean(imRoi); resmean = tempMean.val[0]; if (resmean < 123) cout << "\n trigger mean: " << resmean << "\n"; return resmean; } catch (Exception &e) { cout << e.msg << endl; return 0; } } |
3 – Pré-processamento, Esta etapa é muito importante, é onde filtramos a imagem cinza e transformamos em uma máscara, ou seja, uma imagem binária preto e branco, onde o objeto é branco e o fundo preto.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
void processing(Mat &frame) { try { vector<Mat> bgr_planes; split( frame, bgr_planes ); //Mat b = bgr_planes[0]; //Mat g = bgr_planes[1]; Mat r = bgr_planes[2]; Mat mask = Mat::zeros( frame.size(), CV_8UC1 ); Mat res = Mat::zeros( frame.size(), CV_8UC1 ); Mat open = Mat::zeros( frame.size(), CV_8UC1 ); Mat close = Mat::zeros( frame.size(), CV_8UC1 ); Mat thresh = Mat::zeros( frame.size(), CV_8UC1 ); resize( r, mask, Size(), 0.5, 0.5, INTER_LINEAR ); threshold(mask,thresh, 120, 255, THRESH_BINARY); //cleanup Mat kernel1 = getStructuringElement(MORPH_ELLIPSE, Size(3, 3)); morphologyEx(thresh,open, MORPH_OPEN, kernel1); morphologyEx(open,close, MORPH_CLOSE, kernel1); GaussianBlur(close,res, Size(3, 3), 3); resize( res, res, Size(), 2, 2, INTER_LINEAR ); inspect(res, frame); } catch (Exception &e) { cout << e.msg << endl; } } |
3.1 Canal – Escolho entre os canais de cor RGB o que melhor representa o objeto
3.2 Canal R – Os canais RGB, são imagens em tons de cinza com profundidade de 8 bits cada, neste caso escolhemos o RED que contém a melhor informação dos tons do biscoito, note que ele é cinza mas representa o vermelho de 0 á 100% na imagem colorida.
3.3 Threshold – Função que binariza a imagem, ou seja, transforma uma imagem em tons de cinza em uma imagem preto e branco, note que ainda existem alguns ruídos na imagem.
3.4 Cleanup – Remoção de ruídos (Reduz a imagem na metade do tamanho, passa filtros de transformação morfológica de abrir e fechar e depois amplia a imagem para o tamanho original).
Após esses passos eliminam se os ruídos e temos uma imagem mais uniforme. Essa operação está dentro da função processing.
4- Inspeção / análise, Após o objeto ser detectado, a frame filtrada e transformada em máscara é chamada a função de inspeção, que vai analisar a geometria do objeto.
Essa função analisa a máscara e verifica se o objeto é convexo, (possui todos os cantos arredondados) e valida as dimensões do objeto. Podemos medir a área, perímetro, altura e largura.
4.1 Contornos, é uma função que transforma a máscara binária em linhas ou contornos.
1 2 |
//função busca contornos(máscara, resultado, hierarquia, modo, método, offset) findContours( mask.clone(), contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE, Point(0, 0) ); |
4.2 – Aproximação poligonal, transforma as linhas em um polígono com ajustes de precisão do comprimento das linhas. Essa precisão é chamada epsilon.
1 2 3 4 5 6 7 8 9 10 |
//Perímetro int cnt_len = arcLength(current_contour, 1); //Fator da precisão epsilon = 0,36% (neste caso) Float epsilon =( 00.0036 * cnt len) //aproximação do poligono(contorno_entrada, contorno_saída, epsilon, flag_recursão ) approxPolyDP( Mat(contours[largestComp]), current_contour, epsilon, true ); //Validação da análise número de pontos, área e convexidade if ( cnt_size > 6 and cnt_area > 60000 and cnt_area < 80000 and cnt_convex )... |
5 – Resultado, Após a análise temos o resultado e podemos mostrar os contornos na tela com cores verde e vermelho indicando passa ou falha e em um sistema completo acionar uma saída digital de rejeito de defeitos.
1 2 |
/desenha contornos(imagem, contornos, maior contorno, cor, linha, hierarquia) drawContours( result, contours, largestComp, color, 1, LINE_8, hierarchy ); |
Existem diversas maneiras de analisar imagens, com muitos outros algoritmos como por exemplo ORB, AKAZE e SURF. Neste caso nós utilizamos análise geométrica básica, que é um código simples, leve e eficiente. Na maioria das aplicações é necessário otimizar o código ao máximo para atingir alta velocidade de inspeção com precisão e segurança.
Materiais utilizados no teste
Fonte 12V, Fita Led, Bola de Isopor, pseye, um suporte de abajur de mesa e uma mesa giratória com fundo de EVA preto para simular o movimento da esteira.
Montagem da iluminação domo, feita com meia bola de isopor e fita led, a lente da câmera fica no centro do domo, os leds apontam para dentro do domo, esta iluminação é difusa, utilizada para evitar reflexo e obter uma iluminação uniforme. Funciona bem próximo ao objeto a ser inspecionado.
Observações
Em projetos industriais utilizamos equipamentos industriais de alto desempenho e precisão, como as câmeras inteligentes da COGNEX, que possuem processadores dedicados com software próprio, iluminações como as da ADVANCED ILLUMINATION e lentes de alta qualidade, para realizar inspeções em linhas de alta velocidade com precisão e repetibilidade, além de conexão com robôs e outros equipamentos industriais.
É possível utilizar este software com câmeras industriais, mas é necessário fazer a integração! Nosso objetivo aqui é fornecer um ambiente de estudos de visão computacional de baixo custo com materiais simples e promover o uso de software livre para fins educacionais!
Isso é o mais simples que posso fazer, não é utilizado para fins industriais e sim para estudos!
Repositório do projeto para download
Vocês podem baixar o exemplo completo neste repositório.
Vídeo
Existe uma versão em Python e uma em C++ para este projeto.
Espero que gostem!
Saudacoes!
Como posso usar o algortimo para reconhecimento de residuos solidos urbanos, gostaria de desenvolver uma aplicacao para reconhecimento de residuos solidos/lixo descartados em locais ilegais?
Olá Aly, saudações 🖖
Esse tipo de aplicação mais avançada precisa ser desenvolvida com IA.
Presto consultoria para essas aplicações através da Agrostorm computer vision.
@agrostorm [email protected]
http://www.agrostorm.com.br
Por favor entre em contato que irei te atender e te apresentar as melhores soluções para o seu desafio.
Faz o treinamento e usa haar cascade, muito mais confiável, não precisa de luz controlada, ambiente controlado. Desse jeito nunca vai funcionar na “vida real”, só em laboratório com tudo (ambiente, luz, objeto) controlados.
Precisamos de um profissional para desenvolver uma solução em visão computacional. Teria alguém para indicar?
Obrigado.
Rogério, me envia um email para conversarmos sobre seu projeto.
Meu email é [email protected]
Fico no aguardo.
Se você ainda tiver interesse em alguém, podemos conversar sobre o projeto que vocês desejam iniciar e então talvez fazermos uma parceria. Eu utilizo outras ferramentas mais precisas que opencv. Email: [email protected]
Leandro boa tarde,
Estou trabalhando em um TCC sobre “PROGRAMA DE OTIMIZAÇÃO DA LÍNGUA BRASILEIRA DE SINAIS (LIBRAS)”, inicialmente na plataforma mobile.
Quero desenvolver um tradutor de LIBRAS para português e vice-versa.
Poderia me ajudar com estudos e/ou pesquisas semelhantes na área?
Ou alguma tecnologia (pesquisei sobre OpenCV que acho vai ajudar muito no desenvolvimento do meu TCC)…
Obrigado!!
Gostaria da saber onde vejo a versão em Python ?
Boa tarde, gostaria de saber qual software de programação o senhor utilizou.
Olá Hericles, utilizei sublime-text, um editor de código simples e o gcc e cmake para compilar o exemplo em c++, e o python para rodar o exemplo em python.
Caro Passarelli, boa tarde!
Estou desenvolvendo um projeto sobre “Processamento de Imagens na Agricultura de Precisão” (foco: Pragas em Folhas) com OpenCV e Python.
Poderia me ajudar com estudos e/ou pesquisas semelhantes na área?
Estou encontrando dificuldades…
Agradeço sua gentileza.
Forte Abraço,
Rô
Boa tarde Rô, posso sim, me manda um e-mail para [email protected] com suas dúvidas.
Abraços
E ai maluco, tudo dentro? Leandro, aqui Airton TAGAI, coloca para eu ver o tempo em ms que cada rotina leva para executar cada função. Só para comparar com o meu feito em Processing. Outra coisa, também estou usando a camera do PS3 aqui, esta camera é fera,. 100 Frames com ajustes muito bacanas. Parabéns pelo trabalho.
Fala Airton, tudo certo! rodei no raspi com tempo de 50ms e no i7 a 4ms, essa câmera é muito boa pra brincar. Quero ver seu artigo de futebol de robôs também!
Foram bons tempos na tagai, muito aprendizado e crescimento!
Obrigado por tudo e um grande abraço!
Parabéns, bom trabalho.
Há dois anos no meu TCC fiz um trabalho com OpenCV semelhante a esse, mas no caso era para reconhecimento de doença em sementes de soja utilizando machine learning e classificação com o WEKA em dispositivos mobile (android)
Obrigado Willian!
Ainda não conheço o weka, mas é muito interessante sua aplicação, parabéns!
Se tiver disponível posta ela aqui ou envia o nome do app pra gente testar!
Abraços!
O objetivo final era medir a melhor performance no quesito acurácia e tempo de descritores (explicados no trabalho) e classificação. Segue o link da monografia https://drive.google.com/open?id=0Bw6ZiUelKGElQ24xckMtN0ZVeEk
Mande um feedback do que achou. Ficarei grato
tem link do seu tcc?
Opa, mandei o no comentário acima… Mande um feedback depois.
Solicitei acesso, quando liberar vou dar uma olhada sim!
Leandro, fiz uma aplicação em Python que ao ser chamada ela grava um arquivo avi de 10 segundos de vídeo. Mas isso tendo acesso por shell através de alguma interface gráfica.
Sabe se tem alguma forma fazer essa gravação via prompt através de um ssh por exemplo?
quando tento rodar ele me reporta esse erro ‘Gtk-WARNING **: cannot open display:’
Olá Márcio, é possível, você só precisa escrever um software de captura, existem até ferramentas como gstreamer, mas recomendo você escrever um codigo em python ou c++ para capturar e gravar o vídeo em uma pasta local e depois copiar para seu host via ssh para visualizar.
Na documentação do opencv tem exemplos de como gravar um avi.
Abraços!
Boa noite amigo ! Desde já quero parabenizá-lo pelo projeto !
Eu tenho algumas dúvidas:
-Alem do python, o que preciso para compilar o codigo no windows?. Sou novato nesta area e estou apanhando muito para conseguir fazer rodar.
-Que tipo de camera preciso para funcionar no codigo?
Obrigado
Olá André, muito obrigado!
Eu recomendo você testar no linux, no windows é um pouco chato de instalar o opencv, porém você pode pesquisar algum tutorial de instalação no windows e depois que conseguir instalar, tenta rodar esse código em python https://github.com/llpassarelli/thcv/blob/master/thcv.py
a câmera utilizada é a pseye 3
Abraços!