.


Processamento digital de imagens
Filtros


Exercício, construir um filtro

Para filtrar, então, devemos varrer a imagem dentro da área possível e, para cada posição, fazer uma segunda varredura em milhas e colunas, da vizinhança.

Para construir um filtro, devemos definir inicialmente uns parâmetros geométricos.

Cuidado!A varredura não pode ser feita para o primeiro pixel, devemos começar no elemento (lado) e não podemos terminar na ultima linha (n) mas devemos terminar em (n-lado )

Verifique nas imagens abaixo o que ocorre nos casos dos filtros 3x3 ou 5x5.

3x3 ou 5x5

Na primeira parte vamos abrir o drive, inckuir as bibliotecas, ler a imagem e seu tamanho... # ler imagem de entrada e recuperar dimensoes ##########################
url="https://docs.ufpr.br/~centeno/m_pdi/exepy/004/capi01.jpg"
X1 = io.imread(url)
nl,nc= I.shape
plt.imshow(X1, cmap=plt.get_cmap('gray'),vmin=0,vmax=255)

Dimensionamos o filtro. Adotamos uma vizinhança ímpar para que o pixel em questão fique no centro.. dim=5 # dimensao do filtro exe 3x3 dim=3, 5x5 dim=5...
lado=(dim-1)/2 # numero de vizinhos antes ou depois do central
lado=np.uint8(lado)

Neste exercício vamos criar o filtro de médias passa-baixas, tamanho 3x3, para começar.

Após ler a imagem temos seu tamanho (nl, nc), então criamos uma imagem vazia para armazenar a saída. Nunca use a imagem original., pois os dados dos vizinhos são alterados

Note que a imagem é armazenada em 8 bits e para efetuar multiplicacoes e divisões, combinando com outros valores "float", devemos transformar sua representação para "float".


# ler imagem de entrada e recuperar dimensões
ler imagem... em X1
nl,nc = ...

X=np.array(X1, dtype=float) #transforma em float para facilitar multiplicacoes
Y=np.zeros((nl,nc),dtype = float) # replica imagem para gerar uma saida
Y=np.uint8(Y) # em uint 8 para armazenar em byte

Agora dseenvolvemos o filtro... a media dos 9 vizinhos

   

for L in range(lado,nl-lado): # varrer em linhas, para vizinhos+central
    for C in range (lado, nc-lado): # varrer em colunas
        s=0. # zerar soma para convolucao
        for i in range(dim): # varrer filtro em linhas e colunas
            for j in range(dim): 
                # determina o pixel na imagem
                p=(L-lado)+i 
                q=(C-lado)+j
                s=s+X[p,q]  # acumula os valores
            if s>255: #truncar se ficar fora da faixa
                s=255	
            if s<0:	
                s=0	
            v=np.uint8( np.round( s ) ) # muda a uint8	
            Y[L,C]=v # salva na posicao do central	
 
 # aqui pode salvar seu resultado na sua pasta do drive, ou ver na tela	
  

  

Também podemos usar uma matriz de pesos para o filtro. Neste caso, uma matriz 3x3.

  

F=[ [1,1,1], [1 ,1,1], [1,1,1] ] # filtro 3x3
F=F/9		# pesos
for L in range(lado,nl-lado): # varrer em linhas, para vizinhos+central
    for C in range (lado, nc-lado): # varrer em colunas
        s=0. # zerar soma para convolucao
        for i in range(dim): # varrer filtro em linhas e colunas
            for j in range(dim): 
                # determina o pixel na imagem
                p=(L-lado)+i 
                q=(C-lado)+j
                s=s+X[p,q]*f[i,j] #pixel*peso
            if s>255: #truncar se ficar fora da faixa
                s=255	
            if s<0:	
                s=0	
            v=np.uint8( np.round( s ) ) # muda a uint8	
            Y[L,C]=v # salva na posicao do central	
 


  


Salve o resultado no drive e compare as duas imagens.

Vale a pena lembrar que a posição do pixel central não pode ser definida nas bordas da imagem, pois não não é possível ler sua vizinhança.

você seria capaz de escrever um filtro:

então vamos ver!

Filtro passa baixas (3x3) ponderado
1 2 1
2 4 2
1 2 1

O efeito de cada filtro depende dos pesos atribuídos à posições da janela móvel. Com base na análise dos resultados acima: