Transformada de Fourier

A ideia é criar uma bola no centro de uma imagem e considerá-la que está no domínio da frequência. Após isso, a Transformada Inversa de Fourier foi calculada para voltar ao domínio espacial e a imagem resultante pode ser vista no final deste post.

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

import numpy as np
import cv2

# Cria uma imagem de 300 linhas com 300 colunas dentro de cada linha
t = 300
img = np.zeros((t,t,1), np.uint8)

# Posição do centro da imagem
x = y = int(t/2)
# Tamanho do raio do círculo
raio = 30

# Cria um array de índices com base no tamanho da imagem
I,J=np.meshgrid(np.arange(img.shape[0]),np.arange(img.shape[1]))

# Calcula a distância dos pontos com o centro (euclidiana)
dist=np.sqrt((I-x)**2+(J-y)**2)

# Coloca a intensidade 255 nos pontos onde a distância é menor que o raio
img[np.where(dist<raio)]=255

# Faz a transformada inversa de Fourier na imagem com o círculo no centro
img_fourier = np.fft.fftshift(img)

# Mostra a imagem original e a resultante
# Parâmetros: nome da janela, matriz
cv2.imshow('Resultado',img)
cv2.imwrite('./Imagens/bola.png', img)

cv2.imshow('Fourier',img_fourier)
cv2.imwrite('./Imagens/bola_Fourier.png', img_fourier)

# Funções mostrar as janelas com as imagens
cv2.waitKey(0)
cv2.destroyAllWindows()

Imagens Resultantes

# Imagem gerada com círculo no centro, no domínio da frequência

bola

# Imagem após a Transformada Inversa de Fourier

bola_Fourier

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

Colorindo uma imagem com uma paleta de cores HSI

Dada uma imagem em tons de cinza, a ideia é definir uma cor (inicial) para representar o preto e outra (final) para representar o branco. Em seguida, criar uma paleta de cores HSI que varia da cor inicial até a final e aplicar estas cores na imagem original.

Para realizar este trabalho, foram utilizados os pacotes NumPy e OpenCV. O código está todo comentado e no final do post é possível ver as imagens resultantes.

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

import numpy as np
import cv2

# Função para gerar a peleta de cores com um início e fim de cor
def gerar_paleta(inicio, fim, sv):

	# Função: np.linspace(A, B, X)
	# Descrição: gera um vetor com X valores entre A e B.
	h = np.linspace(inicio, fim, 256)
	s = np.linspace(sv, sv, 256)
	i = np.linspace(sv, sv, 256)
	    
	# Função: a.reshape(alt, largura)
	# Descrição: Da uma nova forma a uma lista. Neste caso, criamos uma altura de 256 e 1 de largura
	# Função: np.tile(array, X)
	# Descrição: Repete um array X vezes. Aqui, repetindo o mesmo valor no eixo da largura para ficar com 256 de largura    
	p1 = np.tile( h.reshape(256,1), 256 )
	p2 = np.tile( s.reshape(256,1), 256 )
	p3 = np.tile( i.reshape(256,1), 256 )
	   
	# Função: np.uint8(num)
	# Descrição: converter números para 8 bits
	p1 = np.uint8(p1)
	p2 = np.uint8(p2)
	p3 = np.uint8(p3)
	    
	# Função: np.dstack( (v1, v2) )
	# Descrição: Faz a concatenação dos dois vetores, por exemplo.
	paleta = np.dstack( (np.dstack( (p1,p2) ), p3) )
	        
	return paleta

# Gera a paleta de cores considerando que o HSI está sendo usado
paleta = gerar_paleta(120, 240, sv=200)

# 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)

# Cria uma matriz com o mesmo tamanho da imagem cinza, mas com 3 dimensões
img_colorida = np.zeros( (img.shape[0], img.shape[1], 3) )

# Como a peleta possui as mesmas cores RGB no eixo da largura, podemos sempre pegar a posição 0
# O for percorre a altura e a largura da nova matriz criada para representar a imagem colorida, e recebe a cor de acordo com a imagem original e o tom de cinza
for i in range(img.shape[0]):
    for j in range(img.shape[1]):
    	# na posição zero porque todas as camadas são iguais
        img_colorida[i][j] = paleta [ img[i][j] ][0]

# Converte a imagem colorida pra 8 bits
img_colorida = np.uint8(img_colorida)

# Transforma pra RGB
paleta = cv2.cvtColor(paleta, cv2.COLOR_HSV2BGR)
img_colorida = cv2.cvtColor(img_colorida, cv2.COLOR_HSV2BGR)
# Mostra a imagem e salva ela
# nome da janela, matriz
cv2.imshow('Original',img)

cv2.imshow('Paleta',paleta)
cv2.imwrite('./Imagens/paleta_hsi.jpg', paleta)

cv2.imshow('Colorida',img_colorida)
cv2.imwrite('./Imagens/original_hsi.jpg', img_colorida)


# Código para manter a jenala com a imagem
cv2.waitKey(0)
cv2.destroyAllWindows()

 

Imagens Resultantes

# Imagem original

original

# Paleta HSI

paleta_hsi

# Imagem colorida

original_hsi

Definindo uma paleta de cores e aplicando em uma imagem

Dada uma imagem em tons de cinza, a ideia é definir uma cor (inicial) para representar o preto e outra (final) para representar o branco. Em seguida, criar uma paleta que varia da cor inicial até a final e aplicar estas cores na imagem original.

Para realizar este trabalho, foram utilizados os pacotes NumPy e OpenCV. O código está todo comentado e no final do post é possível ver as imagens resultantes.

Código

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

# Função para gerar a peleta de cores com um início e fim de cor definida pelo usuário
def gerar_paleta( b1, g1, r1, b2, g2, r2):
    
    # Função: np.linspace(A, B, X)
    # Descrição: gera um vetor com X valores entre A e B.
    b = np.linspace(b1, b2, 256)
    g = np.linspace(g1, g2, 256)
    r = np.linspace(r1, r2, 256)
        
    # Função: a.reshape(alt, largura)
    # Descrição: Da uma nova forma a uma lista. Neste caso, criamos uma altura de 256 e 1 de largura
    # Função: np.tile(array, X)
    # Descrição: Repete um array X vezes. Aqui, repetindo o mesmo valor no eixo da largura para ficar com 256 de largura    
    p1 = np.tile( b.reshape(256,1), 256 )
    p2 = np.tile( g.reshape(256,1), 256 )
    p3 = np.tile( r.reshape(256,1), 256 )
       
    # Função: np.uint8(num)
    # Descrição: converter números para 8 bits
    p1 = np.uint8(p1)
    p2 = np.uint8(p2)
    p3 = np.uint8(p3)
        
    # Função: np.dstack( (v1, v2) )
    # Descrição: Faz a concatenação dos dois vetores, por exemplo.
    paleta = np.dstack( (np.dstack( (p1,p2) ), p3) )
            
    return paleta
    # Fim da função

# Definindo uma cor inicial
b1 = 79
g1 = 79
r1 = 47
# Definindo uma cor final
b2 = 134
g2 = 230
r2 = 240

# Gerando uma paleta de cores da inicial até a final    
paleta = gerar_paleta(b1, g1, r1, b2, g2, r2)

# Abrir a imagem original em tons de cinza, por isso o parâmetro 0
img = cv2.imread('./Imagens/original.jpg', 0)

# Criar uma nova matriz com o mesmo tamanho que a imagem, porém com uma terceira dimensão para armazenar as cores BGR
# Função: np.zeros ( (x,y,z) , dtype=np.int8/16/32/... )
# img.shape[0] = altura, 1 = largura, 2 = profundidade, etc (conforme existir)
img_colorida = np.zeros( (img.shape[0], img.shape[1], 3) )

# Como a peleta possui as mesmas cores RGB no eixo da largura, podemos sempre pegar a posição 0
# O for percorre a altura e a largura da nova matriz criada para representar a imagem colorida, e recebe a cor de acordo com a imagem original e o tom de cinza
for i in range(img.shape[0]):
    for j in range(img.shape[1]):
        img_colorida[i][j] = paleta [ img[i][j] ][0]

# Converte os números da matriz para 8 bits
img_colorida = np.uint8(img_colorida)

# Mostrar uma imagem
cv2.imshow('Paleta de cores', paleta)
cv2.imshow('Imagem Original', img)
cv2.imshow('Imagem resultante', img_colorida)

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

Imagens resultantes

# Paleta

paleta

# Original (tons de cinza)

original

# Colorida

colorida

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