Convolução e Correlação

Este código faz a Correlação em uma imagem com uma máscara simples de pesos 1 e tamanho 3×3. É possível ver que a imagem resultante da convolução teve um leve “borramento”.

O tempo de execução do algoritmo para aplicar a máscara simples foi de 2.331 segundos. Com a imagem “percorrendo” a máscara, o tempo foi de 0.00454 segundos. Desta última forma, há maneiras implícitas de executar um for para percorrer algumas linhas e colunas da imagem, o que ajuda a tornar o processo muito mais rápido.

# -*- coding: utf-8 -*-
"""
@author: Rafael Zottesso
"""

# Apenas para contagem de tempo
import timeit

# Outros imports necessários
import numpy as np
import cv2

# Cria uma função para fazer a correlação simples, movendo a máscara sobre a imagem
def correlacao_comum(img, img_corr, mascara):

 # Percorre cada pixel da imagem
 for x in range(img.shape[0]):
 for y in range(img.shape[1]):

 # Usa o try porque algumas coordenadas não existem, assim não apresenta o erro. As bordas não estão sendo consideradas.
 try:
 
 # Cálculo da máscara coluna a coluna: multuplica o peso que está na máscara pela intensidade do pixel

 ### Máscara simples, primeira coluna ##
 m = img[x-1][y+1] * mascara[0][0]
 m += img[x-1][y] * mascara[1][0]
 m += img[x-1][y-1] * mascara[2][0]

 # Segunda coluna
 m += img[x][y+1] * mascara[0][1]
 m += img[x][y] * mascara[1][1]
 m += img[x][y-1] * mascara[2][1]
 
 # Terceira coluna
 m += img[x+1][y+1] * mascara[0][2]
 m += img[x+1][y] * mascara[1][2]
 m += img[x+1][y-1] * mascara[2][2]

 # Faz a média dos valores e guarda como intensidade do pixel
 img_corr[x][y] = m/9

 # Quando a coordenada não existir, passe para o próximo pixel
 except:
 continue

 return img_corr

# Função com a imagem percorrendo a máscara (contrário da outra)
def correlacao_rapida(img, img_corr, mascara):

 # criando uma nova imagem = tamanho da imagem + bordas da mascara
 img_corr_rap = np.zeros(np.array(img.shape) + np.array(mascara.shape) - 1)

 # Percorre a máscara
 for x in range(mascara.shape[0]):
 for y in range(mascara.shape[1]):

 # Copia os valores para a imagem nova, que é maior para armazenar o cálculo
 img_corr_rap[x:x+img.shape[0], y:y+img.shape[1]] += img * mascara[x,y]

 return img_corr_rap.astype('uint8')

# imread ( nome da imagem, [1=cor, 0=grayscape, -1=alpha])
# Cada coluna da imagem é armazenada em um subvetor, onde cada coluna é uma posição
img = cv2.imread('./Imagens/original.jpg', 0)

# Abre a imagem novamente para comparar com a original
img_corr = cv2.imread('./Imagens/original.jpg', 0)

# Cria uma máscara simples com o mesmo peso
mascara = np.array([ [1,1,1], [1,1,1], [1,1,1] ])

################### Comum ################
# Verifica o horário inicial da convolução
time_start = timeit.default_timer()

# Executa a função de correlação
img_corr_comum = correlacao_comum(img, img_corr, mascara)

# Verifica o tempo final da convolução
time_end = timeit.default_timer()

# Apresenta a duração do processo de convolução
time = time_end - time_start
print 'Tempo de processamento Comum:', time, 'segundos'

################ Rápida #######################

# Verifica o horário inicial da convolução
time_start = timeit.default_timer()

# Executa a função de correlação
img_corr_rapida = correlacao_rapida(img, img_corr, mascara)

# Verifica o tempo final da convolução
time_end = timeit.default_timer()

# Apresenta a duração do processo de convolução
time = time_end - time_start
print 'Tempo de processamento Rápida:', time, 'segundos'


# Mostrar imagem
# nome da janela, matriz
cv2.imshow('Original',img)

cv2.imshow('Correlação Másc. Simples',img_corr_comum)
cv2.imwrite('./Imagens/original_corr.jpg', img_corr_comum)

# Funções para funcionamento correto ao mostrar a imagem numa janela
cv2.waitKey(0)
cv2.destroyAllWindows()

Imagens resultantes

# Imagem original

original

# Após a convolução com a máscara imples

original_conv

Útil(1)Desprezível(2)

Amostragem e Quantização

Para realizar este trabalho, foram utilizados os pacotes NumPy e OpenCV. O código está todo comentado e na sequência é possível ver as imagens resultantes.

Código

# -*- coding: utf-8 -*-
import numpy as np
import cv2

# Função: imread ( nome da imagem, [1=cor, 0=grayscape, -1=alpha])
# Cada coluna da imagem é armazenada em um subvetor, onde cada coluna é uma posição
img = cv2.imread('./Imagens/original.jpg', 0)

## Amostragem ##
# Reduzindo a imagem #
# Seleciona uma em cada 2 colunas, e de cada coluna uma a cada duas linhas
n = 2
img_red = img[::n,::n]

# Aumentando a imagem #
# Os pixels da imagem atual serão duplucados no eixo x e y. Assim, a imagem volta a ter o tamanho original, mas a partir da imagem reduzida
# Função: np.repeat(matriz, vezes, eixo). O eixo 0 é a altura e 1 a largura.
m = 2
img_aum = np.repeat(img_red, m, axis=0)
img_aum = np.repeat(img_aum, m, axis=1)

## Quantização ##
# 255 / 31 = 8,22...
# Assim, teremos uma imagem com 8 tons de cinza. A conta é feita desta forma para descartar a parte decimal dos números e alterar o vetor para que possua apenas 8 valores possíveis.
r = 31
img = np.uint8(img / r) * r

# Salvar imagem no disco #
#cv2.imwrite('C:/Diretório', img_aum)

# Mostra uma imagem
# Função: cv.imshow(nome da janela, matriz)
cv2.imshow('original',img)
cv2.imshow('reduzida',img_red)
cv2.imshow('aumentada',img_aum)

# Funções para o funcionamento correto do python no Windows.
cv2.waitKey(0)
cv2.destroyAllWindows()

Imagens Resultantes

# Original

DCIM100GOPROGOPR0157.

# Reduzida

reduzida

# Aumentada

aumentada

# Quantizada

quantizada

Útil(2)Desprezível(0)