Вы находитесь на странице: 1из 85

Processamento de Imagens

e
Reconhecimento de Padres

AULA 5

Prof. Francisco Fambrini


UNISAL Maro/2017
PROCESSAMENTO MORFOLGICO
A palavra morfologia significa o estudo da forma ou estrutura. Em
processamento de imagens usamos morfologia matemtica para
identificar e extrair descritores de imagens com base em propriedades de
formas e contornos das imagens. Importantes reas de aplicao so
segmentao, contagem e inspeo automatizadas. A morfologia possui
vrios mtodos que so estudados em Teoria dos Conjuntos. O principal
uso da Morfologia no Processamento de Imagens Binrias, e os
principais operadores morfolgicos so os operadores de Dilatao e de
Eroso. Os procedimentos morfolgicos muito mais sofisticados podem
ser reduzidos a uma sequencia de dilataes e eroses.
Operaes Lgicas envolvendo imagens binrias
Dilatao
Elemento Estruturante
No existe Operao Morfolgica sem elemento estruturante. Primeiro passo
definir o formato do elemento estruturante e qual sua posio de origem.
Dilatao na prtica
Elemento Estruturante 3X3

Elemento Estruturante 5X3


Exemplos - Dilatao:
Para que serve a dilatao ?
Eroso
Eroso
Elemento Estruturante 3X3

Elemento Estruturante 5X3


Eroso - exemplos
Outro exemplo de Eroso
Aplicao da Eroso seguida de Dilatao
remoo de componentes
Abertura e Fechamento
Propriedades da Abertura e do Fechamento
Operador Morfolgico de Abertura (Eroso seguida por uma
dilatao)
Operador Morfolgico de Fechamento (dilatao seguido por
uma eroso)
Eroso e Dilatao feitas usando um elemento estruturante na forma de um pequeno disco circular
Aplicao do Fechamento
Exemplo 1 MATLAB (DILATAO)

No exemplo a seguir, o elemento estruturante definido como uma matriz


3X3. A sintaxe bsica requer a imagem e o elemento estruturante como
entradas para a funo, e a imagem dilatada retornada como sada.

bw= imread(text.png)
se = [ 0 1 0; 1 1 1; 0 1 0 ]
bw_out= imdilate(bw,se)
subplot(1,2,1); imshow(bw);
subplot(1,2,2); imshow(bw_out);
Exemplo 2 MATLAB (EROSO)

bw= imread('text2.png')
se = ones(6,1);
bw_out= imerode(bw,se)
subplot(1,2,1); imshow(bw);
subplot(1,2,2); imshow(bw_out);
Funo strel (MATLAB)
A funo strel do Toolbox de Processamento de Imagens do MATLAB serve
para definir elementos estruturantes de diferentes formatos.

bw= imread('text2.png')
se1 = strel('square',4); % elem estrut quadrado
se2 = strel('line',5,45); % elem estrut reta
bw_1=imdilate(bw, se1);
bw_2=imdilate(bw, se2);

subplot(1,2,1); imshow(bw_1);
subplot(1,2,2); imshow(bw_2);
Efeitos e usos da eroso e dilatao
A eroso reduz o tamanho de um objeto binrio, enquanto a
dilatao o aumenta. A eroso tem o efeito de remover todas
as pequenas caractersticas isoladas, de separar regies
adjuntas e delgadas de uma caracterstica, de reduzir o
tamanho de objetos slidos erodindo-os nas fronteiras. A
dilatao tem um efeito aproximadamente reverso ao da
eroso: alarga e espessa regies estreitas, ressalta
caractersticas em torno das bordas. Dilatao e eroso so o
reverso uma da outra, embora no sejam inversas no sentido
matemtico. No possivel restaurar por dilatao um objeto
que tenha sido completamente removido por eroso.
Exemplo 3-Uso de dilatao e eroso para identificar caractersticas baseadas em
forma.

tlevel = 0.2; %define nivel de treshold para binarizao


A=imread('circuit.tif');subplot(2,3,1), imshow(A) % le a imagem e mostra na tela
B = im2bw(A,tlevel); subplot(2,3,2), imshow(~B); %binariza e mostra a imagem
SE =ones(3,18); bw1 =imerode(~B,SE); %Erode retas verticais

subplot(2,3,3), imshow(bw1); %Exibe resultado


bw2 = imerode(bw1,SE');subplot(2,3,4),imshow(bw2) %erode retas horizontais
bw3= imdilate(bw2, SE'); bw4=imdilate(bw3,SE); %dilata a imagem
subplot(2,3,5),imshow(bw4); %exibe a imagem dilatada
boundary= bwperim(bw4); [i,j] =find(boundary); %sobrepe fronteiras
subplot(2,3,6), imshow(A); plot(j,i,'r.');
Exerccio
Use os operadores de Eroso (principalmente)
e Dilatao (se necessrio) para apagar as
unhas da mulher e deixar apenas os lbios na
foto, no exerccio da aula passada.
Eroso no SimpleCV
from SimpleCV import Image
im = Image ( Jacopo.png )
Img = im.grayscale()
imgBin = img.binarize()
imgBin.erode().show()
Dilatao no SimpleCV
from SimpleCV import Image
im = Image ( Jacopo.png )
img = im.grayscale()
imgBin = img.binarize()
imgBin.dilate().show()
Combinando Dilatao e Eroso
A funo Dilate() ajuda a preencher o interior dos buracos, mas
ela tambm amplifica alguns tipos de rudos nas imagens.
Por outro lado, a funo erode() elimina vrios ruidos
(pontinhos brancos), mas elimina tambm informaes teis.
A soluo para este problema combinar as duas funes.

Estas combinaes de dilatao e eroso so to comuns que


existem funes prprias:
morphOpen( ) e morphClose( ) ... Abertura e
fechamento, respectivamente.
morphOpen()
ABERTURA:
Erode e depois dilata a imagem. A eroso elimina pequenos objetos e a
dilatao restaura mais ou menos o tamanho dos objetos originais que
sobraram aps a eroso.

from SimpleCV import Image


im = Image ( Jacopo.png )
img = im.grayscale()
imgBin = img.binarize()
imgBin.morphOpen().show
morphClose()
FECHAMENTO:
a dilatao seguida de eroso. A dilatao primeiro preenche os pequenos
buracos entre os objetos. Se aqueles buracos forem pequenos o
suficiente, a dilatao vai preenche-los completamente, e a subsequente
eroso no ir abrir os buracos. A finalidade reduzir a quantidade de
rudo na imagem.

from SimpleCV import Image


im = Image ( Jacopo.png )
img = im.grayscale()
imgBin = img.binarize()
imgBin.morphClose().show
s vezes, o melhor fazer mltiplas eroses seguidas por multiplas
dilataes na imagem. Para simplificar este processo, as funes dilate() e
erode() aceitam um parmetro que representa o nmero de vezes em que
a funo ser executada.
Por exemplo, dilate(5) significa fazer 5 dilataes seguidas na imagem:
Vamos ver outro exemplo de dilataes seguidas de eroses:
OUTROS EFEITOS
EM
VDEO
Imagens so matrizes
J explicamos, desde a primeira aula, que imagens so
matrizes. Uma imagem em (RGB) na verdade uma
matriz de dimenses mXnX3 onde m a largura, n a
altura e 3 corresponde quantidade de R,G e B da
imagem. Em muitos casos, til transformar esta
matriz tridimensional num nico vetor (matriz linha).
Para transformar uma imagem RGB num vetor, use o
NumPy e faa:

m1 = Image( sua_imagemRGB.png )
mp1 = m1.getNumpy()
f1 = mp1.flatten()
Fazendo Rotao no vdeo !
Este um efeito muito legal de processamento de imagens: O script a seguir
vai fazer rotao continua na imagem capturada pela cmera e tambm
aumenta progressivamente o ngulo de rotao:
Medindo objetos
Este segundo exemplo mais prtico: mostra como medir objetos com a
cmera. A idia bsica comparar o objeto que est sendo medido com
outro objeto de tamanho conhecido.
Por exemplo: Se um objeto est situado em cima do pedao de uma folha de
papel que mede 21,25 x 27,5 cm , podemos usar o tamanho conhecido da
folha de papel para determinar o tamanho do objeto. Entretanto, isso
complicado, se o papel no parecer quadrado para a cmera (ou seja, se o
papel visto em perspectiva).
O prximo exemplo mostra como consertar isso com a funo warp().

X=?

21,25cm
Medindo objetos
from SimpleCV import Image

img = Image ('skew.png')

corners = [(0,0), (480,0), (336,237),(147,237)]

warped = img.warp(corners)

bgcolor = warped.getPixel(240,115)

dist = warped.colorDistance(bgcolor)

blobs = dist.invert().findBlobs()

paper = blobs[-1].crop()

toyBlobs = paper.invert().findBlobs()

toy = toyBlobs[-1].crop()

paperSize = paper.width

toySize = toy.width

print float(toySize)/float (paperSize)*21.25


Explicando o cdigo
corners = [(0,0), (480,0), (336,237),(147,237)]
Estas so as coordenadas para os 4 cantos da folha. Uma boa maneira para
identificar os pontos dos cantos usar o Shell do SimpleCV para carregar a
imagem e depois usar a funo image.live() para mostr-la. Ento voc
pode dar um click com o boto esquerdo do mouse para descobrir as
coordenadas dos cantos da folha de papel vermelho.

warped = img.warp(corners)
Deforma a imagem transformando-a no quadrado das bordas da folha de
papel, como mostrado na figura a seguir:
Explicando o cdigo

dist = warped.colorDistance(bgcolor)
Use o truque do image.live() tambm para encontrar a cor do
papel. Isso tornar mais fcil descobrir qual parte da imagem
o papel e qual parte so os objetos de fundo. A imagem a
seguir mostra o resultado. Perceba que o papel preto
enquanto o restante da imagem representado em vrios
tons de cinza.
Explicando o cdigo

blobs = dist.invert().findBlobs()
Fazendo preto o papel, fica mais fcil detectar a pea azul usando a funo
Blobs()

paper = blobs[-1].crop()
Agora recorta da imagem original o maior Blob (que o papel) e
isso representado por blobs[-1].
(-1) o maior blob encontrado na imagem.

Isso cria uma nova imagem que apenas o papel.


Explicando o cdigo
toy = toyBlobs[-1].crop()
Agora, olhando apenas a rea do papel, usa a funo findBlobs()
novamente para localizar a pea azul. Cria uma imagem da
pea azul cortando-a do papel.
print float(toySize)/float (paperSize)*21.25
Usando a largura do papel e a pea azul, combinado com o fato de que a
largura do papel conhecida e igual a 21,25cm, calcula o tamanho da pea
azul, que de 4,67 cm.

Observe que este exemplo trabalha melhor com objetos planos. Quando
ajustamos o esquadro da imagem, isso faz a parte de cima do objeto
parecer mais larga do que a base, o que pode resultar em erros de
medida.
COR
E
SEGMENTAO
Segmentao
Segmentao o processo de dividir uma imagem em reas de
contedo relacionado.
Essas reas consistem de pixels que compartilham uma caracterstica
particular, e uma das caractersticas mais frequentemente usadas
a cor.

fcil usar a cor para segmentar uma imagem.

Essa tcnica muito efetiva quando a cor do objeto desejado


substancialmente diferente da cor do fundo.

Neste caso, voc pode usar a cor para segmentar uma imagem e
remover o contedo do fundo da imagem, deixando apenas o
objeto de interesse.
Exemplo de Segmentao de imagem
colorida
from SimpleCV import *
yellowTool = Image( "yellowtool.png )
yellowDist = yellowTool.colorDistance((223, 191, 29))
yellowDistBin = yellowDist.binarize(50).invert()
yellowDistBin.show()

Observe que a combinao (R,G,B) = (223, 191, 29) corresponde


a cor amarela da pistola de cola quente.
Detectando um carro ilegalmente estacionado
Veja a imagem do estacionamento, sem o carro amarelo
estacionado em lugar proibido:
Carro amarelo no lugar proibido
Como fazer ?
Um simples teste procuraria segmentar o
amarelo.
Entretanto, se o carro amarelo estiver
estacionado ao lado da vaga para deficientes,
ento no estar em local proibido.

Ento, esta viso detectora de amarelo ter


que verificar se o carro aparece dentro de
uma rea especifica da imagem.
Carregamos as imagens dos carros

from SimpleCV import Image


car_in_lot = Image("parking-car.png")
car_not_in_lot = Image("parking-no-car.png")
O prximo passo usar a figura do carro no ponto para
determinar a rea por inspeo. Uma vez que a imagem
original contm espaos legais e ilegais para estacionar, ela
precisa ser recortada para cobrir somente o espao destinado
aos deficientes (rea ilegal para estacionar). O tamanho total
da imagem 800x600 pixels. A localizao do espao proibido
a caixa em torno do carro, chamada ROI ( Regio de
Interesse). Neste caso, a ROI comea no ponto(470,200) e tem
aproximadamente 200x200 pixels.

from SimpleCV import Image


car_in_lot = Image("parking-car.png")
car_not_in_lot = Image("parking-no-car.png")
car = car_in_lot.crop(470,200,200,200)
# Mostra o resultado
car.show()
Agora que a imagem est cortada somente para a rea de
estacionamento ilegal, o prximo passo encontrar o carro na
imagem. A tcnica similar ao exemplo da pistola de cola quente.
Primeiro, vamos achar os pixels que esto prximos da rea
amarela:

From SimpleCV import *


car_in_lot = Image( "parking-car.png )
car_not_in_lot = Image( "parking-no-car.png )
car = car_in_lot.crop(470,200,200,200)

yellow_car = car.colorDistance(Color.YELLOW)

# Mostra os resultados
yellow_car.show( )
Subtrai agora a imagem em escala de cinzas da imagem cortada, para obtermos
somente a imagem do carro amarelo.
Para comparar esta imagem com a imagem que no tem o carro amarelo, deve haver
vrios tipos de medidas para representar o carro. Uma maneira simples de fazer
isso usando a funo meanColor().

Como o prprio nome diz, esta funo calcula a cor mdia de uma imagem:
From SimpleCV import *
car_in_lot = Image( "parking-car.png )
car_not_in_lot = Image( "parking-no-car.png )
car = car_in_lot.crop(470,200,200,200)
yellow_car = car.colorDistance(Color.YELLOW)
only_car = car - yellow_car
print only_car.meanColor()

Esta funo vai imprimir o valor mdio das cores:


( 25.604575, 18.880775, 4.482825)
Isso uma medida para o espao quando ocupado pelo carro amarelo. Repita
o mesmo processo para o lugar com o espao vazio (sem o carro
estacionado):

from SimpleCV import *


car_in_lot = Image( "parking-car.png )
car_not_in_lot = Image( "parking-no-car.png )
car = car_in_lot.crop(470,200,200,200)
yellow_car = car.colorDistance(Color.YELLOW)
only_car = car - yellow_car
no_car = car_not_in_lot.crop(470,200,200,200)
without_yellow_car = no_car.colorDistance(Color.YELLOW)
without_yellow_car.show()
Retorne para a imagem em escala de cinza mostrando o quanto longe esto
as cores no espao vazio em relao imagem com o carro amarelo
estacionado.
Mais uma vez, subtraia a color_distance e calcule o valor mdio da cor:

From SimpleCV import *


car_in_lot = Image( "parking-car.png )
car_not_in_lot = Image( "parking-no-car.png )
car = car_in_lot.crop(470,200,200,200)
yellow_car = car.colorDistance(Color.YELLOW)
only_car = car - yellow_car
no_car = car_not_in_lot.crop(470,200,200,200)
without_yellow_car = no_car.colorDistance(Color.YELLOW)
only_space = no_car - without_yellow_car
print only_space.meanColor()
O resultado da cor mdia ser:
( 5.031350000000001, 3.6336250000000003, 4.683625)

Esta mdia substancialmente diferente da mdia quando o carro est na


imagem, que de (25.604575, 18.880775, 4.4940750000000005).

A quantidade de azul ( lembre-se (R,G,B) ) quase igual, mas as


quantidades de vermelho e verde so muito diferentes. Isso ocorre porque
o amarelo criado pela combinao do vermelho e do verde.

Sabendo disso, fica relativamente fcil definir os limiares para determinar se


o carro amarelo est ou no estacionado na regio proibida.

O prximo slide ilustra um exemplo de como ficaria o programa em SimpleCV:


from SimpleCV import *
car_in_lot = Image( "parking-car.png )
car_not_in_lot = Image( "parking-no-car.png )
car = car_in_lot.crop(470,200,200,200)
yellow_car = car.colorDistance(Color.YELLOW)
only_car = car - yellow_car
(r, g, b) = only_car.meanColor()
if ((r > 15) and (g > 10):
print Carro no lugar proibido. Chamar o Guarda.

(Se os valores de R e de G so suficientemente altos, ento o carro amarelo est provavelmente


estacionado no espao para deficientes)
Subtraindo uma imagem da outra
Suponha que voc queira saber se algum est pegando as balas que voc
deixa num pote na mesa do escritrio.
Contar as balas todos os dias um jeito, mas a Viso Computacional pode
nos dar uma soluo melhor: fotografar o pote de bales e subtrair uma
imagem da outra. Se a diferena entre as imagens for maior do que um
certo limiar (treshold) ento voc saber que a foto mudou e algum
provavelmente pegou balas dali sem sua autorizao.

#Carrega as duas fotos, tiradas nos instante de tempo A e B:


timeA = Image( "candyA.png )
timeB = Image( "candyB.png )
# Compara as 2 imagens, subtraindo uma da outra
diff = timeA - timeB
O ladro de balas...
from SimpleCV import *
#Carrega a diferena entre as duas imagens
diff = Image( "candydiff.png )
# Extrai os pixels individuais dentro de uma matriz plana
matrix = diff.getNumpy()
flat = matrix.flatten()
# Calcula quantos pixels mudaram
num_change = np.count_nonzero(flat)
percent_change = float(num_change) / float(len(flat))
if percent_change > 0.1:
print Pare de chupar meus doces!

No script acima, se a diferena entre os pixels for maior do que 10% ele vai dizer
que as balas foram mudadas (aumentaram ou diminuiram) ou seja, que
houve mudanas significativas entre a foto 1 e a foto 2.
Comentrios sobre o programa anterior
matrix = diff.getNumpy()
Lembre-se de que uma imagem essencialmente uma matriz de valores de
pixels. Portanto, para aplicar tcnicas matemticas em uma imagem, s
vezes mais fcil transformar esta imagem em formato de matriz. A
funo getNumpy () retorna uma matriz NumPy da imagem.

flat = matrix.flatten()
A matriz NumPy , na verdade, uma matriz tridimensional com as dimenses
640x 480 x 3.
Isto corresponde s dimenses de imagem de 640 x 480, com uma adicional
dimenso para os trs valores para vermelho, verde e azul.
No entanto, ao invs de trabalhar com uma matriz tridimensional, ser mais
rpido achatar esta em uma matriz de 1 dimenso: 921.600 x 1.
num_change = np.count_nonzero(flat)
Podemos usar Numpy (importado por padro no SimpleCV como "np") para
rapidamente contar o nmero de pixels diferentes de zero.

percent_change = float(num_change) / float(len(flat))


Calcula a porcentagem de valores que mudou.
Lembre-se que num_change a varivel que conta o nmero de pixels que no
so pretos, indicando uma diferena na imagem.

len (flat) calcula o nmero total de pixels na imagem (ou mais


com preciso, na matriz achatada que representa a imagem).

if percent_change > 0.1:


print pare de pegar as balas do pote!
Finalmente, verifica se o nmero de pixels que mudou excede o limiar (10%).
Se isso ocorreu imprime um aviso. Neste caso, cerca de 22% dos pixels foi
alterado, o que imprime a mensagem na Tela: "Pare de roubar minhas
balas".
Funo meanColor()
A funo meanColor () seria uma outra maneira para detectar uma alterao
nas imagens.
Se as imagens so iguais, a mdia de cor ser preto (ou seja, zero).
Caso contrrio, as diferenas vo ter cores diferentes,que ter impacto sobre
o valor da cor mdia.
Claro que, para menores alteraes, as diferenas na cor mdia sero
mnimas.
De novo, a fixao de um limiar adequado (treshold) para a diferena em
valores mdios de cor vai ajudar a gerenciar os alertas falsos positivos ou
negativos.
CAMERA DE SEGURANA
(DETETOR DE MOVIMENTOS)
Aplicao Prtica:
Cmera de Segurana
Detectando movimento na frente de uma
cmera atravs da variao da mdia de cor
de uma imagem .

No exemplo do prximo slide, o treshold


representa a MDIA DAS CORES e no o
percentual de pixels que mudou de um frame
para outro.
from SimpleCV import *
import time
threshold = 5.0 # Se a mdia das cores exceder este valor, faz algo
cam = Camera()
previous = cam.getImage()
disp = Display(previous.size())
while not disp.isDone():
current = cam.getImage()
# Obtm outro frame e compara com o anterior
diff = current - previous
# Converte para uma Matriz no programa Numpy e calcula a media das cores
matrix = diff.getNumpy()
mean = matrix.mean()
diff.save(disp) # Mostra na tela
if mean >= threshold: # verifica se algo mudou
print "Movimento Detectado ! "
#espera 1 segundo
time.sleep(1)
previous = current
Sugesto de Projeto 1

Hoje em dia fala-se muito de IoT (internet das coisas).


Baseado no exemplo do estacionamento e do carro amarelo,
projete um sistema que monitora o interior de uma geladeira
atravs de uma webcam, olhando sempre o nmero de latas
de cerveja contidas em determinado compartimento.
Quando as cervejas acabarem, o sistema dever enviar um email
automaticamente para o Supermercado:
supermercado@gmail.com
contendo seu nome, endereo e telefone, pedindo para trazer
mais 6 latas de cerveja da sua marca preferida.
Sugesto de Projeto 2
Ainda baseando-se no exemplo do estacionamento de carros, projete um
sistema de viso computacional que monitora 5 vagas em um pequeno
estacionamento, cada vaga devendo ser ocupada por um automvel.
Seu sistema dever identificar os carros e contar quantas vagas esto
disponiveis em seus estacionamento, para avisar as pessoas antes de
entrar. Voc pode fazer uma maquete para testar seu sistema usando
carrinhos de brinquedo e uma chapa de madeira:
Sugesto de maquete para o estacionamento
Histogramas
Podemos usar o SimpleCV para plotar o histograma de uma
imagem, de modo similar ao que fizemos com o MATLAB na
primeira aula, porm imprimimos os nmeros na forma de
uma matriz:

from SimpleCV import *


img = Image( starry_night.png )
# Gera o histograma
histogram = img.histogram()
# Gera a matriz de saida do histograma
Print histogram
Histogramas com SimpleCV
Este exemplo de cdigo gera uma lista de 50 valores. Cada valor representa o nmero de pixels
que ocorre em cada nvel de brilho. Mas porque foram mostrados 50 valores se existem 256
tons de cinza? A funo de histograma () divide o conjunto de dados em intervalos que
combinam os valores a partir do eixo x do grfico. Isto tende a suavizar o grfico, agrupando
nveis juntos. No entanto, o nmero de intervalos ajustvel por software.
O cdigo Python a seguir mostra os 256 nveis de cinza:

from SimpleCV import *


img = Image( 'starry_night.png )
# Generate the histogram with 256 bins, one for each color
histogram = img.histogram(256)
# Show how many elements are in the list
len(histogram)
Plotando o grfico do Histograma
Assim como no MATLAB, possivel no SimpleCV plotar o histograma
de uma imagem na forma de um grfico. Experimente o cdigo a
seguir:

from SimpleCV import *


img = Image( 'starry_night.png )
# Gera o grfico mostrando os 256 valores da escala de cinza
histogram = img.histogram(256)
plot (histogram)

Observao: a Funo plot() est na library MATPLOTLIB (http://matplotlib.org/ )que


precisa ser carregada parte (no faz parte do SimpleCV). Para carregar esta library
voce pode carregar no terminal de linha de comando, conectado na internet:
$ sudo pip install matplotlib

Se voc encontrar dificuldades, veja aqui outras maneiras de instalar esta library no Python:
https://www.raspberrypi.org/learning/visualising-sorting-with-python/lesson-1/plan/
Problemas com a instalao de matplotlib

Se voc instalou sua biblioteca matplotlib, mas na hora de


plotar na tela no aparece nenhum grfico (e tambm no
aparece nenhum erro) olhe estes links:
http://stackoverflow.com/questions/19721385/matplotlib-
pyplot-does-not-show-output-no-error

http://stackoverflow.com/questions/27798829/importerror-
no-module-named-pyside

Obs: voc pode tambm usar OpenCV (ao invs do SimpleCV)


na sua raspberry. Veja aqui:
http://docs.opencv.org/3.1.0/d1/db7/tutorial_py_histogram_
begins.html
Experimente tambm
from SimpleCV import *
import pylab as plt
cam = Camera()
plt.ion()
while (1):
img = cam.getImage()
img.show()
peaks = img.huePeaks()
hist = img.hueHistogram()
plt.plot(hist)
plt.pause(0.0001)
plt.draw()
Plotando os 3 histogramas R,G e B

Ao invs de olhar o histograma geral, s vezes mais til dividir a imagem em seus
canais de cor a olhar para o equilbrio de cor.
Isto demonstrado no seguinte script:

from SimpleCV import *


img = Image('starry_night.png')
# Extrai da imagem os 3 canais de cor
(red, green, blue) = img.splitChannels(False)
# Separa os 3 histogramas individuais
red_histogram = red.histogram(255)
green_histogram = green.histogram(255)
blue_histogram = blue.histogram(255)
# Plota os histogramas OBS: PRECISA TER A BIBLIOTECA MATPLOTLIB INSTALADA !
plot(red_histogram)
plot(green_histogram)
plot(blue_histogram)
Comentrios sobre o programa
(red, green, blue) = img.splitChannels(False)
A funo splitChannels () cria trs imagens. As trs imagens contm
componentes vermelho, verde e azul, respectivamente.
Por padro, isso na verdade cria trs imagens em tons de cinza, mostrando a
intensidade de cada cor individual. Passando o parmetro False, ele mantm a cor
original, que mais intuitivamente atraente.

red_histogram = red.histogram(255)
Uma vez que os canais de cor individuais so separados, gera o histograma, como foi
foi feito no exemplo da imagem com tons de cinza. Trs canais significa que temos
trs histogramas.

plot(red_histogram)
Traa os histogramas. Observe que cada comando plot espera at que a janela do
histograma esteja terminada.
Em outras palavras, o cdigo em primeiro lugar mostrar o histograma vermelho. O
histograma verde no ser exibido at que a janela do histograma vermelha seja
finalizada. Ento o histograma azul no ser exibido at que a janela do verde seja
finalizada.
Histogramas R,G e B
Funo Hue Peaks()
HUE SIGNIFICA MATIZ
Depois de olhar para a distribuio de diferentes cores em uma imagem, a prxima questo
lgica de identificar a cor dominante na imagem. Isto conhecido como encontrar os
picos de matiz (Hue Peaks) e feita utilizando a funo huePeaks() para encontrar a(s)
cor(es) dominante(s).
Apesar de uma imagem poder ser primeiro convertido para o formato de HSV e, em
seguida, um histograma pode ser calculado para obter as informaes de matiz, o
SimpleCV tem um atalho para fazer isso em qualquer formato de imagem. a funo
hueHistogram (). Ele funciona exatamente como a funo Histogram() mas no mostra
os nveis de cinza e sim os nveis de intensidade de cada cor componente.
from SimpleCV import *
img = Image('monalisa.png')
# calcula o histograma
histogram = img.hueHistogram()
plot(histogram)
# calcula os picos do histograma
peaks = img.huePeaks()
# imprime: [(12.927374301675977, 0.11747342828238252)]
print peaks
Comentrios sobre a funo HuePeaks()

[ (12.927374301675977, 0.11747342828238252) ]
A sada da funo huePeaks so dois nmeros neste caso.
Se houver um nico pico dominante, ento haver apenas um elemento na
matriz. O primeiro valor da o bin que ocorre com mais frequncia.
O segundo valor a porcentagem de pixels que correspondem a essa
cor.
Por exemplo, no exemplo acima, o valor 13 a mais comum, e aparece em
12% do total de pixels da imagem.
Este deve parecer aproximadamente correto dado o histograma da
imagem Monsa Lisa:
Esta informao pode ser utilizada para subtrair os matizes menos
frequentes.
Este truque semelhante aos exemplos anteriores que subtraem valores
com base na distncia de cor.
Usando a matriz para criar uma mscara
Experimente o script a seguir com a imagem monalisa

from SimpleCV import *


img = Image('monalisa.png')
# Encontra o valor da matiz dominante (Hue)
peaks = img.huePeaks()
peak_one = peaks[0][0]
# Calcula a distncia da matiz para criar a mscara
hue = img.hueDistance(peak_one)
mask = hue.binarize().invert()
# Subtrai o valor da matiz dominante
lessBackground = img - mask
lessBackground.show()
Comentrios sobre o programa anterior
A funo hueDistance() parecida com a funo colorDistance() j usada nas aulas.Ela vai
retornar uma imagem representando a distncia de cada pixel do valor de pico da matiz
(Hue). Valores pequenos esto prximos do pico dominante de matiz da imagem (Hue peak)
e vo aparecer nesta imagem na cor preta. Valores grandes esto mais distantes do pico
dominante da matiz e vo aparecer como regies brancas na imagem binria.
A seguir, a funo: mask = hue.binarize().invert() binariza a matriz distncia da imagem,
eliminando os nveis de cinza e gerando uma imagem em preto e branco pura. Criamos assim
uma mascara (mask) que capaz de separar a moa do fundo da imagem.
Subtraimos ento a mscara criada da imagem original:
Rudo na imagem resultante
Existe ainda uma boa quantidade de rudo esquerda na imagem extrada.Os
truques usando as funes morfolgicas (dilatao, eroso, abertura e
fechamento) ajudam a limpar a mscara.
Nos exemplos anteriores, mostramos como fazer uma mscara usando a
matemtica da imagem. O SimpleCV inclui um mtodo de atalho para as
operaes de mscara.
Trata-se uma funo mscara binria que permite especificar as cores a
serem ocultadas.
O seguinte exemplo mostra como extrair o rosto da Mona Lisa.

from SimpleCV import *


img = Image( "monalisa.png )
mask = img.createBinaryMask(color1=(130,125,100),color2=(0,0,0) )
mask = mask.morphClose()
result = img - mask.invert()
result.show()
Comentrios sobre o programa do slide anterior

mask = img.createBinaryMask(color1=(130,125,100),color2=(0,0,0) )
Cria uma mscara binria,
usando os valores comprendidos entre color1 e color2

mask = mask.morphClose()
Usa a funo morphClose() para limpar o rudo restante na imagem
Motion Blur effect
Um dos truques clssicos em fotografia artstica utilizar uma exposio longa. Ao deixar o obturador da cmera
aberto, ele cria um efeito de borro, conforme os objetos se movem atravs do campo de Viso.
Embora as cmeras web no tenham persianas para replicar diretamente esse efeito, ele pode ser simulado
adicionando uma srie de imagens, efetivamente criando um borro de movimento.

from operator import add

from SimpleCV import *

cam = Camera()

frames_to_blur = 4

frames = ImageSet()

while True:
frames.append(cam.getImage())

if len(frames) > frames_to_blur:


frames.pop(0) #remove o frame mais antigo se estivermos no mximo

pic = reduce(add, [i / float(len(frames)) for i in frames])

#add =soma os frames na matriz com peso 1 / numero de frames

pic.show()
Efeito Croma-Key
Agora voc vai aprender como se faz um dos efeitos de
Processamento de Imagens mais utilizados na TV e no
cinema: o Croma-Key.

Uma imagem de uma pessoa filmada sobre um fundo


verde (ou azul). Depois, a imagem da pessoa
recortada e montada sobre outro fundo, que pode
ser uma paisagem ou outro lugar qualquer.

ATENO: Para este script funcionar fundamental


que as duas imagens que participam da montagem
tenham exatamente o mesmo nmero de pixels !
Chroma Key (Tela Verde)
from SimpleCV import *
sleep_time = 2 #a quantia de tempo para mostrar cada imagem
#carrega e mostra a imagem com fundo verde
print "Mostrando imagem com Tela verde"
greenscreen = Image("fig1.png")
greenscreen.show()
time.sleep(sleep_time)
# carrega e mostra a imagem de fundo
print "Mostrando imagem de fundo"
background = Image("fig2.png")
background.show()
time.sleep(sleep_time)
#Cria e aplica a mascara
print "Mostrando imagem na mascara"
mask = greenscreen.hueDistance(color=Color.GREEN).binarize()
mask.show()
time.sleep(sleep_time)
#Combina a mascara com a outra imagem para obter o resultado final
print "Mostrando imagem final"
result = (greenscreen - mask) + ( background - mask.invert() )
result.show()
time.sleep(sleep_time)
Deteco de Face usando o OpenCV
Embora o SimpleCV seja mais recomendado para
Raspberry PI (por ser mais leve e mais otimizado
do que o OpenCV) voc tambm pode utilizar o
OpenCV na sua placa. Se voc tem uma Rasp
modelo I ele ficar bastante lento, mas vai
funcionar.
O slide a seguir uma pequena amostra do
contedo da prxima aula (AULA-6) e ilustra um
sistema de reconhecimento de Faces baseado em
OpenCV.
Classificadores
Na prxima aula abordaremos o tema
Classificadores.
Para este programa funcionar, voc precisa
incluir na mesma um arquivo .xml que traz os
vetores caractersticos que permitem o
reconhecimento da face. Este arquivo
chamado de haar-cascade classifier.
O arquivo o:
haarcascade_frontalface_default.xml
import cv2
arqCasc = 'haarcascade_frontalface_default.xml'
faceCascade = cv2.CascadeClassifier(arqCasc)
webcam = cv2.VideoCapture(0) #instancia o uso da webcam
while True:
s, imagem = webcam.read() #pega efetivamente a imagem da webcam
imagem = cv2.flip(imagem,180) #espelha a imagem
faces = faceCascade.detectMultiScale(
imagem,
minNeighbors=5,
minSize=(30, 30),
maxSize=(200,200)
)
# Desenha um retngulo nas faces detectadas
for (x, y, w, h) in faces:
cv2.rectangle(imagem, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.imshow('Video', imagem) #mostra a imagem captura na janela
#o trecho seguinte apenas para parar o cdigo e fechar a janela
if cv2.waitKey(1) & 0xFF == ord('q'):
break
webcam.release( ) #dispensa o uso da webcam
cv2.destroyAllWindows() #fecha todas a janelas abertas

Вам также может понравиться