<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Aula8 - Continuação DFT
Correção dos Exercícios
DFT Decompose
Step1:  Aprendizados
Nunca tirar o valor absoluto do resultado do filtro, para eliminar do resíduo da parte imaginária. Como é esperado que o resultado do filtro seja uma imagem real, e pelo fato de erros de cálculo numérico, o resultado é complexo, com valores imaginários muito próximos a zero. A melhor forma de fazer este resultado ser real é apenas tirar a parte da real
Step2:  Rotação
Escala
Implementando a DFT matricialmente
A implementação da DFT é muito fácil de ser feita matricialmente usando a operação matricial de potenciação a**B onde B é uma matriz. Com isso, evita-se a necessidade de laço explícitopara fazer a soma dos produtos.
A DFT multidimensional pode ser calculada a partir da DFT unidimensional.
Como a implementação matricial tem complexidade proporcional a $N^2$, existe implementação muito famosa denominada FFT Fast Fourier Transform cuja complexidade é proporcional a $ N log(N)$.
Filtros
Filtro ideal passa baixas
É feito multipliando-se a transformada de Fourier por uma máscara de multiplicação que elimina (zera) as "telhas" de frequencia menor que (U,V) ciclos na imagem. A ideia é que a imagem resultante só contenha componentes de telhas com períodos menor ou igual a (U,V). Por exemplo poderia ser (10,5).
Step3:  Processamento
Step4:  Visualização
<ASSISTANT_TASK:>
Python Code:
import numpy as np
np.set_printoptions(suppress=True, precision=1)
fw = np.array([200,200,50,50,50,50,200,200])
f = np.array([fw,fw,fw,fw])
print(f)
F = np.fft.fft2(f)
print(F)
frestaurado = np.fft.ifft2(F)
print(frestaurado)
Faux = np.zeros_like(F)
Faux[0,0] = F[0,0]
print(Faux)
fr0 = np.fft.ifft2(Faux)
print(fr0.real)
Faux = np.zeros_like(F)
Faux[0,1] = F[0,1]
Faux[0,-1] = F[0,-1]
print(Faux)
fr1 = np.fft.ifft2(Faux)
print(fr1.real)
Faux = np.zeros_like(F)
Faux[0,3] = F[0,3]
Faux[0,-3] = F[0,-3]
print(Faux)
fr3 = np.fft.ifft2(Faux)
print(fr3.real)
fr = fr0 + fr1 + fr3
print(fr)
%matplotlib inline
import matplotlib.pyplot as plt
plt.plot(fr3.real[0])
x = np.arange(80)
y = np.cos(2*np.pi*x*3/80)
plt.plot(y)
Explanation: Aula8 - Continuação DFT
Correção dos Exercícios
DFT Decompose
End of explanation
import matplotlib.image as mpimg
f = mpimg.imread('../data/keyb.tif')
plt.imshow(f[:50,:50],cmap='gray')
                 
F = np.fft.fft2(f)
H,W = F.shape
import sys,os
sys.path.append('/home/lotufo')
import ia898.src as ia
Fview = np.abs(np.log(ia.ptrans(F,(H//2,W//2))+1))
plt.imshow(Fview,cmap='gray')
x = np.arange(4).reshape(4,1)
A = x.dot(x.T)
print(2**A*1.j)
Explanation: Aprendizados
Nunca tirar o valor absoluto do resultado do filtro, para eliminar do resíduo da parte imaginária. Como é esperado que o resultado do filtro seja uma imagem real, e pelo fato de erros de cálculo numérico, o resultado é complexo, com valores imaginários muito próximos a zero. A melhor forma de fazer este resultado ser real é apenas tirar a parte da real: f.real e nunca np.abs(f).
Fazer caso numérico pequeno é sempre importante no aprendizado e para encontrar erros.
sempre que houver uma borda na imagem, ela dá origem a uma linha no espectro de Fourier e se esta imagem for filtrada de forma ideal, existe um efeito de ring (ondulação) na imagem. Não esquecer que a imagem é periódica e muitas vezes este degrau acontece na borda, por exemplo, a parte de baixo da imagem é branca e parte de cima é escura.
Na filtragem no domínio da frequência é sempre importante verificar se a transformada de Fourier resultante exibe a propriedade do simetria de complexo conjugado.
End of explanation
plt.imshow(f,cmap='gray')
F = np.fft.fft2(f)
Fview = np.abs(np.log(ia.ptrans(F,(H//2,W//2))+1))
plt.imshow(Fview,cmap='gray')
Explanation: Rotação
Escala
Implementando a DFT matricialmente
A implementação da DFT é muito fácil de ser feita matricialmente usando a operação matricial de potenciação a**B onde B é uma matriz. Com isso, evita-se a necessidade de laço explícitopara fazer a soma dos produtos.
A DFT multidimensional pode ser calculada a partir da DFT unidimensional.
Como a implementação matricial tem complexidade proporcional a $N^2$, existe implementação muito famosa denominada FFT Fast Fourier Transform cuja complexidade é proporcional a $ N log(N)$.
Filtros
Filtro ideal passa baixas
É feito multipliando-se a transformada de Fourier por uma máscara de multiplicação que elimina (zera) as "telhas" de frequencia menor que (U,V) ciclos na imagem. A ideia é que a imagem resultante só contenha componentes de telhas com períodos menor ou igual a (U,V). Por exemplo poderia ser (10,5).
End of explanation
U,V = (6,4)
H,W = F.shape
FW = np.zeros_like(F)
FW[0:U,0:V] = 1.
FW[-U:,-V:] = 1.
FW[0:U,-V:] = 1.
FW[-U:,0:V] = 1.
fw = np.fft.ifft2(F * FW)
print((fw.imag).sum())  # cheque para verificar se o resultado é real
Explanation: Processamento
End of explanation
plt.imshow(ia.ptrans(np.log(1+ np.abs(F*FW)),(H//2,W//2)),cmap='gray')
plt.imshow(fw.real,cmap='gray')
Explanation: Visualização
End of explanation
<END_TASK>