Você está na página 1de 71

Viso Computacional e

Reconhecimento de Imagens para


Sistemas Embarcados
AULA 6

Prof. Msc. Francisco Fambrini


Vdeo no Youtube

Uma excelente apresentao dos recursos do


SimpleCV pode ser vista aqui, na apresentao da
PyCon2013:

https://www.youtube.com/watch?v=O4_kWEDd52o
Sugesto de Projeto: Rob que fala
Que tal fazer um projeto de um rob que fala o
nome das cores que ele enxerga atravs da
cmera ?

Para fazer o rob falar, basta carregar o programa


"Espeak" na sua raspberry PI

http://espeak.sourceforge.net/

Veja o tutorial em anexo !


Usar OpenCV ao invs de usar SimpleCV

Ao invs de usar o SimpleCV, voc pode usar o OpenCV. Experimente o script


Python a seguir, que utiliza OpenCV:

import numpy as np
import cv2
# Carrega uma imagem em escala de cinza
img = cv2.imread('lenaTest3.jpg',0)
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Obs: De modo geral, usar OpenCv bem mais complexo do que SimpleCV, a
estrutura de programao bem mais complicada.
OUTRAS OPERAES MORFOLGICAS
Alm da Dilatao, Eroso, Abertura e Fechamento,
existem muitas outras Transformaes Morfolgicas.
Todas elas dependem de se definir um Elemento
Estruturante adequado.
Os principais formatos dos elementos estruturantes so
mostrados a seguir:
OUTRAS OPERAES MORFOLGICAS
Image.logicalAND()
Faz um AND da imagem binria com a mscara

Image.logicalOR()
Faz um OR da imagem binria com a mscara

Image.logicalXOR()
Faz um XOR da imagem binria com a mscara

Image.logicalNAND()
Faz um NAND da imagem binria com a mscara

Image.floodFill()
funciona como a ferramenta balde de tinta em um editor de imagens.
Ela pode apagar determinadas reas da imagem.
Transformada TopHat
Em morfologia matemtica e processamento de imagens digitais, top-hat uma
operao morfolgica que extrai pequenos elementos e detalhes de imagens
dadas. Existem dois tipos: Transformada top-hat branca definida como a
diferena entre a imagem de entrada e sua abertura por algum elemento
estruturante:

A transformao top-hat preta definida como a diferena entre a imagem de


entrada e a imagem aps o Fechamento Morfologico.

So usados para diversas tarefas de processamento de imagem, como a extrao


de caractersticas, equalizao fundo, realce de imagem, entre outros.
Transformada Top-Hat
Exemplo em MATLAB
BW = imread('aviao.jpg');
se = strel('disk',20); % define o elemento estruturante redondo
tophatFiltered = imtophat(BW,se); % faz a transformada TopHat
figure, imshow(tophatFiltered)
Transformada Watershed
A palavra Watershed significa Bacia Hidrogrfica. uma ferramenta morfolgica que
serve para ajudar na segmentao das imagens. Fazemos uma analogia de certas
regies na imagem com um Poo dgua (Catchment basins). A linha divisria entre
dois poos dgua o Watershed Line.
Watershed no SimpleCV
S funciona na verso SimpleCV 1.7 em diante !
from SimpleCV import Image
img = Image(lena.jpg")
img1 = img.watershed()
img1.show()
img2 = img.watershed(color=True)
img2.show()
#OBS: S funciona na verso SimpleCV 1.7 em diante !

#--------------------------------------------------------------------------------------------------------
Alguns parmetros que podem ser usados na funo watersheds( )
def watershed(self , color = False)
def watershed( self, mask=None, erode=2, dilate=2, useMyMask=False )
#---------------------------------------------------------------------------------------------------------

color- Seleciona o tipo de imagem de saida, colorida ou em escala de cinzas.


mask- Uma mscara binria opcional. Se nenhuma fornecida, o programa binariza e inverte a imagem
erode- o numero de vezes que a mascara vai erodir at encontrar o primeiro plano
dilate- o numero de vezes que a mascara vai dilatar at encontrar o plano de fundo da imagem
useMyMask- se for "True" a mascara no ser modificada pelo programa
Criando uma mscara com a transformada Watershed

from SimpleCV import Image


img = Image('lenna')
myMask = Image((img.width,img.height))
myMask = myMask.floodFill((0,0),color=Color.WATERSHED_BG)
mask = img.threshold(128)
myMask = ( myMask - mask.dilate(2) + mask.erode(2) )
result = img.watershed(mask=myMask,useMyMask=True)

No funciona no SimpleCV verso 1.3, somente nas versoes 1.7 em diante !


Obs: mais alguns Parmetros para a funo watershed()
Color.WATERSHED_FG - Transf. watershed para a cor de primeiro plano
Color.WATERSHED_BG Transf. watershed para a cor de fundo
Color.WATERSHED_UNSURE plano no definido
Esqueletos
O processo morfolgico que reduz todos os objetos de uma imagem em
linhas, sem alterar a estrutura essencial da imagem conhecido como
esqueletizao (skeleton). O termo esqueleto geralmente utilizado para
denotar uma representao de um padro atravs de uma coleo de
arcos e curvas finas. Alguns autores usam termos diferentes, por exemplo,
"eixo mdio" (medial axis) e "thinned image". Contudo, "thinning" e
"esqueletonizao" tornaram-se os mais utilizados na literatura. Alm
disso, o termo "esqueleto" utilizado para referir-se ao resultado do
algoritmo.
Esqueletos para vrias figuras
Esqueleto para uma letra H
Observe que o esqueleto de um crculo um nico ponto no seu centro
A obteno do esqueleto geralmente exige grande
esforo computacional. Em 1984, Zhang e Suen
publicaram um trabalho chamado "A fast parallel
Algorithm for thinning digital patterns", no qual
propuseram um novo algoritmo paralelo de
esqueletonizao. Este trabalho trouxe resultados muito
superiores quando comparados a outros da sua poca.
Mais tarde, muitos pesquisadores, incluindo o prprio
Zhang, propuseram nosvos testes e metodologias que
melhoraram ainda mais o algoritmo de Zhang e Suen.
Contudo, mesmo nos dias de hoje (2001), trabalhos
recentes ainda comparam os resultados conseguidos com
o trabalho original de Zhang e Suen. Por isso, esse
algoritmo o mais usado na prtica. tambm chamado
de algoritmo Transformada Distncia.
Observe o esqueleto do avio na ltima foto
Espao de Cores HSV
HSV a abreviatura para o sistema de cores formadas pelas componentes
hue (matiz), saturation (saturao) e value (valor). O HSV tambm
conhecido como HSB (hue, saturation e brightness matiz, saturao e
brilho, respectivamente).
Esse sistema de cores define o espao de cor conforme descrito abaixo,
utilizando seus trs parmetros:

Matiz (tonalidade): Verifica o tipo de cor, abrangendo todas as cores do


espectro, desde o vermelho at o violeta, mais o magenta. Atinge valores
de 0 a 360, mas para algumas aplicaes, esse valor normalizado de 0 a
100%.

Saturao: Tambm chamado de "pureza". Quanto menor esse valor, mais


com tom de cinza aparecer a imagem. Quanto maior o valor, mais "pura"
a imagem. Atinge valores de 0 a 100%.

Valor (brilho): Define o brilho da cor. Atinge valores de 0 a 100%.


Transformando RGB para HSV
Espao de cores HSV
Algumas vezes til transformar a imagem (R,G,B) para o espao de cores
HSV onde temos:
a) Hue: (matiz) ou cor pura, varia entre 0 e 180 graus;
b) Saturao: conta-nos o quo longe a cor est do branco;
c) Value: nos informa o quanto escura a cor ;
Este sistema apresenta a vantagem de ser imune com relao a iluminao: um sistema RGB,
apesar de mais simples de trabalhar, muito suscetvel variaes na cor da luz que
ilumina o objeto.
Como trabalhar em cores HSV no SimpleCV
Image.toHSV(): converte a imagem de RGB para HSV

Image.toBGR(): converte de volta para BGR

Image.toGray(): converte a imagem para escalas de cinza

Image.toRGB(): converte a imagem de volta para RGB

Image.huePeaks(): encontra os picos de matiz na sua imagem

Image.hueDistance(): ajuda a encontrar objetos que tem o matiz que


voce deseja;

Image.hueHistogram(): visualiza o histograma no espao colorido


Exemplo
import pylab as plt
from SimpleCV import Image
img = Image("flower.jpg")
img.show()
peaks=img.huePeaks()
print peaks
hist = img.hueHistogram()
plt.plot(hist)
plt.draw()
hdist = img.hueDistance(peaks[2][0])
binary = img.hueDistance(peaks[2][0]).invert().threshold(220)
hdist.show()
hdist.save("hflower.png")
binary.save("bflower.png")
Descritores
Descritores so parmetros da imagem que podem ser transformados em nmeros.
Um bom descritor deve ser invariante mudana de escala, rotao e translao.
Blobs (como j explicado neste curso) so regies da imagem que se distinguem do
background e que possuem pixels similares.

Uma vez que um Blob identificado, ns podemos medir:


a) A rea (quantos pixels tem este blog);
b) Sua largura e sua altura;
c) Achar seu centro (baseado no centro de massa)
d) Pode-se contar o numero de blobs para descobrir diferentes objetos
e) Medir angulos
f) Olhar as cores presentes no blob
g) Podemos descobrir o quanto este blob se aproxima de um crculo, de um
quadrado ou de um retngulo.
Encontrando Blobs: findBlobs()
A funo findBlobs(): Se voc no especificar nenhum parmetro, ela vai
encontrar o Blob mais brilhante e o mais escuro na imagem.
Blobs so mais facilmente encontrados em imagens binrias.
O exemplo abaixo encontra Blobs na imagem moedas.png.
A cor padro o verde, mas a cor no contorno dos blobs() pode ser mudada
facilmente atravs da funo packs.show(Color.RED) (por exemplo)

from SimpleCV import Image


pennies = Image ("moedas.png")
binPen = pennies.binarize()
blobs = binPen.findBlobs()
blobs.show(width=5)
Encontrando outros descritores na imagem
Voc pode encontrar outros descritores na imagem das moedas:

from SimpleCV import Image


pennies = Image("moedas.png")
binPen = pennies.binarize()
blobs = binPen.findBlobs()
print "Areas=", blobs.area()
print "Angulos=", blobs.angle()
print "Centros=", blobs.coordinates()
Encontrando Blobs escuros na imagem
Como a funo Blobs() retorna apenas os Blobs mais claros da imagem, se ns
queremos detectar Blobs escuros precisamos primeiro inverter a imagem:

from SimpleCV import Image


img = Image("chessmen.png")
invImg = img.invert()
blobs = invImg.findBlobs()
blobs.show(width=2)
img.addDrawingLayer(invImg.dl())
img.show()
Encontrando Blobs de uma cor especfica

Encontrando todas as balas azuis na imagem:

from SimpleCV import Image, Color


img = Image("mandms.png")
blue_distance = img.colorDistance(Color.BLUE).invert()
blobs = blue_distance.findBlobs()
blobs.draw(color=Color.PUCE, width=3)
blue_distance.show()
img.addDrawingLayer(blue_distance.dl())
img.show()
Explicando o programa do Slide anterior
A funo colorDistance() retorna uma imagem que mostra o quo longe as
cores da imagem original esto da cor passada no parametro Color (no
caso, azul). Para tornar esta funo ainda mais precisa, poderiamos
encontrar os 3 numeros RGB para a cor azul verdadeira das balas, mas
para este exemplo o que fizemos foi suficiente. Uma vez que qualquer cor
prxima do azul se tornar preta, e as cores longe do azul se tornaro
branca, ns usamos novamente a funo invert() para inverter a imagem,
tornando brancas as balas azuis e o fundo ser preto (demais balas).
Usamos ento a nova imagem para encontrar os blobs que contornam as
balas azuis. Ns tambm podemos fazer um ajuste fino da funo
findBlobs() passando para esta funo um parmetro de threshold. O
threshold pode ser um inteiro ou 3 nmeros RGB. Quando um threshold
passado na funo, ela ir alterar todos os pixels que so mais escuros do
que o threshold para branco, e todos os pixels acima do valor de threshold
para preto. No final, ns mostramos na tela a imagem blue_distance.
Vantagens de se usar o espao HSV
Algumas vezes as condies de iluminao podem tornar a deteco de cores mais
dificil. Para demosntrar este problema, a imagem seguinte baseada na mesma
imagem balas anterior, mas a metade direita da imagem est no escuro. A
funo hueDistance() a melhor escolha para este tipo de problema. Mesmo com
a metade direita da imagem estando muito escura, a funo anterior ainda pode
ser usada para encontrar blobs e mostra as vantagens de se trabalhar no espao
Hue ao invs de usar o espao RGB:
Aplicando na imagem metade-
escura...
from SimpleCV import Image, Color
img = Image("mandms-dark.png")
blue_distance = img.colorDistance(Color.BLUE).invert()
blobs = blue_distance.findBlobs()
blobs.draw(color=Color.PUCE, width=3)
img.addDrawingLayer(blue_distance.dl())
img.show()

Note que somente as balas azuis do lado esquerdo da imagem so


detectadas.
Usando hueDistance()
Teste agora o mesmo programa do slide
anterior, porm usando a funo
hueDistance() no lugar da funo
colorDistance()

Observe que no espao de cores Hue (HSV) as


mudanas na luz no criam problemas !
Funo findLines()

Usa Transformada de Hough para encontrar as linhas em uma imagem, mas


retorna o FeatureSet (conjunto de caracteristicas) destas linhas:

coordinates(): retorna as coordenadas (X, Y) do ponto inicial da linha achada.

width(): retorna a diferena entre o ponto X final e o ponto X inicial da linha

height(): retorna a diferena entre a coordenada Y final e a coordenada Y


inicial da linha;

length(): retorna o comprimento da linha em pixels


Usando a funo findLines()
from SimpleCV import Image
img = Image("block.png")
lines = img.findLines()
lines.draw(width=3)
img.show()

A funo findLines() i nclui 5 diferentes parmetros para ajudar a melhorar a


qualidade do resultado:
Threshold: determina quo forte deve ser a borda antes de ser reconhecida como uma
linha reta;
Minlinelength: qual o comprimento minimo das linhas que sero reconhecidas
Maxlinegap: qual o comprimento do buraco (lacuna) que ser tolerado em uma
linha.
Cannyth1: um parmetro de limiar utilizado com o passo de deteco de
borda que define a mnima "resistncia da borda.
Cannyth2: um segundo parmetro para a deteco de borda que define a
persistncia da borda.
findLines()
O parmetro threshold para findLines () funciona quase da mesma maneira que o
parmetro limiar para a funo findBlobs ().
Se voc no passar um valor, o valor padro que ele usa definido para 80.
Para valores menores mais linhas sero encontradas pela funo.
Para valores maiores, menos linhas sero encontrados.
Usando ao imagem do bloco de madeira novo, experimente um limiar baixo:

from SimpleCV import Image


img = Image("block.png")
# Ajusta um valor baixo de threshold
lines = img.findLines(threshold=10)
lines.draw(width=3)
img.show()
Eliminando linhas muito curtas

Uma maneira de se livrar de pequenas linhas usar o parmetro


minlinelength para eliminar linhas curtas. O comprimento da linha
medida em pixels, e o valor padro da funo findLines() 30 pixels de
comprimento. No exemplo abaixo, o comprimento mnimo ajustado,
eliminando algumas linhas no desejadas:

from SimpleCV import Image


img = Image("block.png")
lines = img.findLines(threshold=10, minlinelength=50)
lines.draw(width=3)
img.show()
O resultado mostrado na figura a seguir.

Observe que eliminou um par de linhas extras, mas a um custo de eliminar as linhas
laterais novamente.
Alterar o comprimento da linha no resolve o problema. As duas extremidades da imagem
ainda no foram achadas.
Na verdade, ele poderia criar o problema oposto.
s vezes, o algoritmo pode achar linhas muito pequenas e ele precisa saber se esses
pequenos segmentos de linha, na verdade, representam um maior linha contnua.
A funo findLines () pode ignorar pequenos espaos em uma linha, e reconhec-lo como
uma linha geral maior.
Por padro, a funo ir combinar dois segmentos de uma linha se a distncia entre eles
de 10 pixels ou menos. Voc pode usar o parmetro maxlinegap para ajustar como isso
funciona.
O exemplo que se segue permite um maior buraco entre linhas, potencialmente
permitindo-lhe descobrir algumas pequenas linhas que constituem a borda.
Exemplo: Ajustando a funo findLines()
from SimpleCV import Image
img = Image("block.png")
lines = img.findLines(threshold=10, maxlinegap=20)
lines.draw(width=3)
img.show()
O resultado restaura a linha de borda direita novamente, mas, mais uma vez,
ele encontra um monte de linhas indesejadas, como demonstrado na
Figura ao lado. Note-se que ao definir o comprimento mnimo da linha
diminuiu o nmero de linhas encontradas na figura, a adio de um
intervalo mais longo, em seguida, aumentou dramaticamente o nmero
de linhas.
Com o buraco maior (maior gap), os segmentos de linha podem ser combinados para satisfazer os
requisitos de comprimento da linha, e mais linhas so ento reconhecidas. Os dois ltimos
parmetros, cannyth1 e cannyth2, so limiares para o detector de bordas Canny. A grosso
modo, as bordas so detectados pela procura de mudanas no brilho. O primeiro destes
parmetros de limiar controla quanto o brilho tem de mudar para detectar uma borda. O
segundo parmetro controla o threshold para a ligao em conjunto vrias bordas. Ambos
estes parmetros agem da mesma maneira que os trs parmetros anteriores: valores
menores significam que mais linhas sero detectadas, o que poderia ser apenas a adio de
rudo. Por outro lado, valores maiores resultar em menos linhas detectadas, mas pode
significar que algumas linhas vlidas no esto sendo detectadas. O truque trabalhar com
os parmetros at que voc esteja em um intervalo que faz mais sentido para a sua
aplicao. Claro que, por vezes mais fcil do que simplesmente modificar a imagem para
reduzir o rudo, em vez de afinar os parmetros. O exemplo a seguir, encontra as linhas
desejadas no bloco de madeira:
from SimpleCV import Image
img = Image('block.png')
dist = img.colorDistance((150, 90, 50))
bin = dist.binarize(70).morphClose()
lines = bin.findLines(threshold=10, minlinelength=15)
lines.draw(width=3)
# Move as linhas desenhadas na imagem binria de volta para a imagem principal
img.addDrawingLayer(bin.dl())
img.show()
Nosso objetivo final...

... segmentar o bloco de madeira nas 4 arestas, conforme a foto acima, usando
a funo findLines() corretamente parametrizada.
Encontrando Crculos: findCircle()
Alm de linhas retas, voc tambm pode trabalhar com circulos. O mtodo para
encontrar caracteristicas circulares chamado findCircle(), e ele funciona da
mesma maneira que findLines(). Ele retorna um conjunto de caracteristicas [
FeatureSet() ] da figura circular encontrada e tambm tem parametros para
ajudar a ajustar a sensibilidade: Alguns parametros so
Canny: Este um parmetro de limite para o detector de bordas Canny. O valor
padro 100. Se voc definir um valor mais baixo, um maior nmero de crculos
ser reconhecido, enquanto um valor maior, ao contrrio, significam menos
crculos sendo detectados.
Thresh: Este o equivalente do parmetro threshold para findLines (). estabelece
quo perto uma borda tem que estar de um circulo tem que ser antes de ser
reconhecido. O valor padro para este parmetro 350.
Distance: Similar ao parmetro maxlinegap para findLines (). Ele determina o quanto o
blob pode estar proximo de uma circulo , antes de serem tratados como crculo.
Se deixado indefinido, o sistema tenta encontrar o melhor valor, com base na
imagem que est sendo analisado.
Tal como acontece com as linhas, existem funes featureset que so mais
apropriados quando se lida com crculos, tambm. Estas funes incluem:
raio (): Como o nome sugere, este o raio do crculo.
dimetro (): O dimetro do crculo.
permetro (): retorna o permetro da funcionalidade, que, no caso de um crculo,
o comprimento da circunferncia.
Encontrando Crculos: findCircle()
from SimpleCV import Image
img = Image("pong.png")
circles = img.findCircle(canny=200, thresh=250, distance=15)
circles = circles.sortArea()
circles.draw(width=4)
circles[0].draw( width=4)
img_with_circles = img.applyLayers()
edges_in_image = img.edges(t2=200)
final = img.sideBySide(edges_in_image.sideBySide(img_with_circles)).scale(0.5)
final.show()
Corners (cantos)
A grosso modo, os cantos so lugares em uma imagem onde duas linhas se
encontram.

Os cantos so interessante em termos de viso computacional porque cantos,


ao contrrio arestas, so relativamente nicos e bons para a identificao
de partes de uma imagem.

Por exemplo, se voc estiver tentando analisar um quadrado, se voc tentou


encontrar as linhas que representam os lados de um quadrado, voc
poderia encontrar duas linhas horizontais e duas linhas verticais para cada
um dos lados.

Contudo, voc no seria capaz de dizer qual das duas linhas horizontais
pertence a parte superior ou inferior, ou qual das duas linhas verticais era
o lado esquerdo ou direito.

Cada canto, por outro, nico, e possivel identificar facilmente onde ele
est localizado na imagem.
findCorners()
A funo findCorners() analisa a imagem e retorna os locais onde todos os cantos possam
ser encontrados.
Note-se que um canto no precisa ser um ngulo reto em 90 graus.
Duas linhas que se cruzam em qualquer ngulo pode constituir um canto.
Tal como acontece com findLines() e findCircle (), a funo findCorners() retorna uma
featureset de todas as caracteristicas do canto que foi achado.

Apesar do featureset dos cantos compartilhar as mesmas funes que qualquer


outro FeatureSet, existem funes que no fazem muito sentido no contexto de um
canto. Por exemplo, tentar encontrar a largura, comprimento ou rea de um canto
realmente no faz muito sentido.

Tecnicamente, as funes usadas para encontrar essas coisas ainda funcionam, mas
o que eles vo voltar so valores padro e dados no verdadeiros sobre os cantos.
Similar s funes findLines() e findCircle(), a funo findCorners() tambm tem parmetros
para ajudar a determinar quais cantos so encontrados em uma imagem.

Vamos explorar os parmetros disponveis usando uma imagem de um suporte como um


exemplo.
from SimpleCV import Image
img = Image('corners.png')
img.findCorners.show()

Os pequenos crculos verdes representam os cantos detectados. Observe que


o exemplo encontra muitas curvas. Por padro, ele procura por 50 cantos,
que , obviamente, muitos falsos positivos.
Com base na inspeo visual, verifica-se que existem quatro cantos principais.
Para restringir o nmero de cantos voltou, podemos usar o parmetro
MAXNUM.

from SimpleCV import Image


img = Image('corners.png')
img.findCorners.(maxnum=9).show()
O mtodo findCorners( ) classifica todos os cantos antes de retornar seus resultados,
ento se ele encontra mais do que o nmero mximo de cantos determinados, ele
ir retornar apenas os melhores. Alternativamente, o parmetro minquality define
a qualidade mnima de um canto antes de que ele seja mostrado.
Esta abordagem filtra o rudo sem ter que codificar um mximo nmero de cantos de
um objeto. Isso j melhora a performance, mas o algoritmo encontrou dois cantos
na parte inferior esquerda e nenhum na parte superior direita.
Os dois cantos na parte inferior esquerda so realmente parte do mesmo canto, mas a
iluminao e as cores esto confundindo o algoritmo.
Para evitar cantos prximos de serem contados como dois cantos separados,
definimos o parmetro mindistance, que define o mnimo nmero de pixels entre
dois cantos.

from SimpleCV import Image


img = Image('corners.png')
img.findCorners.(maxnum=9, mindistance=10).show()
Exemplo: Contando Moedas
Neste exemplo, vamos usar uma foto de algumas
moedas norte-americanas e calcular o seu valor
total em dinheiro.
Para fazer isso, encontramos as bolhas que
representam cada moeda, e depois comparamos
os seus dimetros para saber o valor de cada
moeda.
No exemplo, usamos como referncia a moeda de
25 cents para comparar com as demais.
from SimpleCV import Image, Blob
import numpy as np
img = Image("coins.png")
coins = img.invert().findBlobs(minsize = 500)
value = 0.0
# O valor das moedas determinado pelo seu tamanho
# http://www.usmint.gov/about_the_mint/?action=coin_specifications
coin_diameter_values = np.array([
[ 19.05, 0.10],
[ 21.21, 0.01],
[ 17.91, 0.05],
[ 24.26, 0.25]]);
#use uma moeda de 25cents para calibrar (tem que existir pelo menos uma)
px2mm = coin_diameter_values[3,0] / max([c.radius()*2 for c in coins])
for c in coins:
diameter_in_mm = c.radius() * 2 * px2mm
distance = np.abs(diameter_in_mm - coin_diameter_values[:,0])
index = np.where(distance == np.min(distance))[0][0]
value += coin_diameter_values[index, 1]
Ao executar este cdigo usando o nosso exemplo da foto, o
valor total das moedas exibido pelo programa deve ser
de US $ 0,91.

Neste exemplo, a deteco de base era bastante simples,


mas passamos a maior parte do tempo analisando os
dados que se reuniram a partir da imagem.

Uma idia interessante de projeto fazer um programa


que reconhece e fala o valor de um conjunto de moedas,
para ajudar pessoas com deficiencia de viso (cegos) que
no podem contar o dinheiro.
CLASSIFICADORES
Etapas para o Reconhecimento de
Imagens
Classificadores: separam as imagens por classes
semelhantes
Classificadores
So programas baseados no conceito de Machine Learning (aprendizado de
mquina) que podem ser usados para classificar imagens baseado nos
Vetores de Caractersticas. Cita-se:

KNNClassifier (K-Nearest-Neighbors ou K-vizinhos mais prximos): Retorna a


classe do conjunto de caractersticas dentro do conjunto de treinamento que
est mais perto do vetor da imagem de entrada.
SVMClassifier (Support Vector Machine): Encontra a funo matemtica que
define o hiperplano que melhora separa as classes de objetos.
NaiveBayesClassifier (baseado em probabilidade Bayesiana): Pesa a
probabilidade de cada classe comparando-a com a probabilidade de uma
caracterstica que aparece na figura.
TreeClassifier (rvore de Deciso): basicamente uma enorme e longa lista de
if/else para tomar uma deciso. Existe diversos tipos de rvores e florestas
para analisar cada caracterstica.

(existem outros algoritmos, mas que no esto implementados no SimpleCV e


nem no Orange: http://orange.biolab.si/ )
Funes teis para Treinamento dos Classificadores

Conforme j foi dito, para que um algoritmo classificador funcione, necessrio


termos um Banco de Imagens de Treinamento (para poder extrair o conjunto de
vetores de caractersticas necessrio para fazer a identificao da imagem).
Algumas funes do SimpleCV podem ajudar no Treinamento (ou seja, na hora de
obter os Conjuntos de Classes).

Treinar e testar seus programas de Machine Learning mais fcil se voc salvar seus
dados em um arquivo, geralmente classificados dentro de diretrios por Classes.

TurkingModule pode ajudar a separar manualmente seus dados e salv-los.

ConfusionMatriz (Matriz de Confuso) : Pode ser usado para ajudar voc a perceber o
quo bom seu Classificador funciona. Nenhum classificador 100% perfeito.
Imprimir quais classes so confundidas com quais outras classes ajuda a
melhorar o software.
Ilustrao bsica de como funciona o SVM
O algoritmo Support Vector Machine separa as classes atravs
do melhor hiperplano de separao ( bom para classes no-
linearmente separveis):
FeatureExtractors
FeatureExtractors pode ser usado para extrair os vetores de caracteristicas de
imagens e aramazena-los na forma de uma lista de numeros;

HueHistogramFeatureExtractor - devolve um histograma de matizes.

EdgeHistogramFeatureExtractor - Calcula ngulos da linha em uma imagem.

HaarLikeFeatureExtractor - medidas speras de simetria e forma.

BOFFeatureExtracor - Pequenas e minsculas caractersticas do gradiente


das bordas.

MorphologyFeatureExtractor extrai momentos de Hu dos Blobs,


comprimento,largura, relao de aspecto, permetro, etc.

Muitos mais - escrever o seu prprio extrator de descritores !


Momentos de Hu
Os momentos invariantes de uma imagem (tambm chamados Momentos de Hu),
permitem o clculo da rea de um objeto (conjunto de pixels), centride de um
objeto ou tambm permite identificar um determinado objeto mesmo que tenha
sofrido mudana de tamanho ou mesmo que seja rotacionado. Esta teoria muito
utilizada em reconhecimento de padres. Geralmente utiliza-se algum tipo de
software que extrai os referidos momentos de uma imagem binarizada.
Os 7 momentos de Hu podem ser calculados e colocados numa tabela e tero valores
muito aproximados. Sendo assim, os momentos de Hu servem para identificar um
objeto, mesmo que tenha sofrido mudana de tamanho ou seja rotacionado.

Mais sobre este assunto:


http://www.sci.utah.edu/~gerig/CS7960-S2010/handouts/Hu.pdf
Orange: Machine Learning Tools
Para testar estes softwares de Aprendizado de
Mquina, voc precisar instalar tambm o
pacote Orange: http://orange.biolab.si/
https://github.com/biolab/orange
Os passos para instalao podem ser seguidos a
partir deste site:
http://jonahgroup.github.io/SnackWatcher/Raspberry-Pi-3-for-Computer-Vision
Instalando e Compilando o Orange
1- Clone o Orange (so 129,56 Mb) . No terminal do Raspbian, digite:
$ git clone https://github.com/biolab/orange.git
Isso vai carregar o Orange a partir da internet.

2 Compile o Orange na sua Raspberry ou no seu PC:

$ cd orange
$ python setup.py build
$ sudo python setup.py install

OBS: O processo todo pode demorar mais de 8 horas para compilar na


Raspberry PI, no PC bem mais rpido !
Todas as instrues esto detalhadas neste site:

http://jonahgroup.github.io/SnackWatcher/Raspberry-Pi-3-for-Computer-Vision

Alguns exemplos na Internet:


1- Um software para classificao e reconhecimento de imagens de frutas:
http://jmgomez.me/a-fruit-image-classifier-with-python-and-simplecv/

2- Um software para classificar LEGOs


https://www.youtube.com/watch?v=yupShUY5WS4

3-Acompanhamento facial com camera


https://www.youtube.com/watch?v=GD8ArIM-5BQ

4- Sistema de deteco de esquilos nos jardins:


https://www.youtube.com/watch?v=QPgqfnKG_T4
Para testar se o Orange foi
corretamente instalado
Digite no terminal de linha de comando:
$ cd orange
$ python setup.py test

Depois, experimente o seguinte programa Python:


img = Image('cookie_001.png')
hue_feature_vec = extractors[0].extract(img)
print hue_feature_vec
Programa SnackClassifier
Como exemplo de como se trabalha com classificadores, depois de instalado o pacote
Orange, abra a pasta SnackClassifier Software.

Este programa classifica vrios tipos de lanches em diversas classes:

"brownie (bolo)
"candy", (bala)
"cookie", (bolacha)
"package (pacote)
Exemplo Prtico: SnackClassifier
1 O programa snack-trainer.py extrai as caracteristicas dos objetos:

class SnackTrainer():

def __init__(self):
self.classifier = None

def createExtractor(self, extractorName, trainPaths=[]):


if (extractorName == 'hue'):
extractor = HueHistogramFeatureExtractor(10)
elif (extractorName == 'edge'):
extractor = EdgeHistogramFeatureExtractor(10)
elif (extractorName == 'haar'):
extractor = HaarLikeFeatureExtractor(fname='haar.txt')
elif (extractorName == 'bof'):
extractor = BOFFeatureExtractor()
extractor.generate(trainPaths, imgs_per_dir=40)
# need to build the vocabuary (feature words) for bag of feature
# extractor.generate(trainPaths, imgs_per_dir=40)
return extractor
Pasta SnackClassifier
A pasta contendo todas as imagens de treinamento train,
A pasta contendo todas as imagens de teste test e
O caminho padro onde os resultados so escritos result
O Tipo de classe tambm deve estar de acordo com os
diretrios.
Todas as classes de imagem deve ser de layout para os diretrios
separados. Os rtulos de classe devem estar alinhados aos
diretrios.
Por exemplo, se temos 2 classes cookie` e other , a chamada
deve ser:
python snack-trainer.py -g -c "cookie,other" -s tree
Sobre o slide anterior

Neste exemplo, estamos classificando cookie e other.

Ns especificamos o uso do classificador tree para


classificar as imagens na pasta test.

As imagens do resultado sero guardadas na pasta "result"

Alm disso, os parmetros de classificadores treinados so


salvos por padro, com o nome do classificador, por
exemplo: "Tree.dat".
Podemos usar o programa classificador "Snack-classify.py"
para a classificao de outras imagens aps o treinamento.
Snack-Classify.py
import sys
from optparse import OptionParser
from SimpleCV import *

class SnackClassify():
def __init__(self):
pass
def load(self, classifierFile):
self.classifier = TreeClassifier.load(classifierFile)
def classify(self, imageFile):
image = Image(imageFile)
return self.classifier.classify(image)
def classNames(self):
return self.classifier.mClassNames
def parse_options(self, args):
# Parse command-line options
usage = "%prog [options] -c <classifier_file> -i <image>"
parser = OptionParser(usage=usage)
parser.add_option("-g", "--debug", action="store_true", dest="debug",
default=False,
help="debugging mode"),
parser.add_option("-c", "--classifier", action="store", dest="classifier_file",
default="",
help="load classifier from file"),
parser.add_option("-i", "--image", action="store", dest="image_file", default="",
help="classify this image file"),

(self.options, args) = parser.parse_args(args)


if not self.options.classifier_file or not self.options.image_file:
parser.print_help()
exit(0)

def process():
snack_bot = SnackClassify()
snack_bot.parse_options(sys.argv)

classifierFile = snack_bot.options.classifier_file
imageFile = snack_bot.options.image_file

snack_bot.load(classifierFile)
class_name = snack_bot.classify(imageFile)
print class_name

"""
main program
"""
if __name__ == "__main__":
process()
Descrio completa do exemplo
https://github.com/jonahgroup/SnackClassifier/
commit/31851b5483664e55975576e444a272
6dda5fed61
Desafio
1- Rode o exemplo SnackClassifier na sua mquina;
2 Adaptar este exemplo para classificar folhas de rvores, usando as
imagens da pasta: Folhas de rvores

Circinatum
Glabrum
Garryana

kelloggii
Negundo
Macrophyllum

Você também pode gostar