傅里叶变换是干嘛的:
傅里叶得到低频、高频信息,针对低频、高频处理能够实现不同的目的。
傅里叶过程是可逆的,图像经过傅里叶变换、逆傅里叶变换后,能够恢复到原始图像
在频域对图像进行处理,在频域的处理会反映在逆变换图像上
原理
傅里叶支持值域和频域互推
振幅
相位:开始的时间
numpy实现傅里叶变换
numpy.fft.fft2 傅里叶变换
得到频谱
numpy.fft.fftshift 将零频率分量移动到频谱中心
20*np.log(np.abs(fshift)) 设置频谱的范围
比如图像是0-255的范围,这样就可以约束频谱到可视的范围
numpy逆傅里叶变换
numpy.fft.ifft2 逆傅里叶变换
返回一个复数数组(complex ndarray)
numpy.fft.ifftshift 逆移动
np.abs(逆傅里叶变换结果)
通过数组获得可以图像显示的值
滤波
概念
空域→频域→空域
低频对应图像内变化缓慢的灰度分量。例如,在一幅大草原的图像中,低频对应着广袤的颜色趋于一致的草原。
高频对应图像内变化越来越快的灰度分量,是由灰度的尖锐过渡造成的。例如,在一幅大草原的图像中,其中狮子的边缘等信息,
接受(通过)或拒绝一定频率的分量
通过低频的滤波器成为低通滤波器
通过高频的滤波器成为高通滤波器
作用:
修改傅里叶变换以达到特殊目的,然后计算IDFT返回到图像域。
特殊目的:图像增强、图像去噪、边缘检测、特征提取、压缩、加密等。
高频
思路:调整高低频率主要是设置图像中的选取的位置,然后把不需要的地方换成黑色(0)
低频
OpenCV实现傅里叶变换
cv2.dft(原始图像,转换标识)
返回结果:
双通道:1.结果的实数部分,2.结果的虚数部分
原始图像要先转换成np.float32
转换标识:cv2.DFT_COMPLEX_OUTPUT输出复数阵列
cv2.magnitude(参数1,参数2)计算幅值
参数1∶浮点型X坐标值,也就是实部
参数2: 浮点型Y坐标值,也就是虚部
cv2.idft(原始数据) 逆傅里叶变换
返回结果:取决于原始数据的类型和大小
原始数据:实数或者复数均可
numpy.fft.ifftshift
ffshift函数的逆函数
振幅和相位
这里用numpy和torch的形式分别提取振幅和相位
numpy
import cv2
import numpy as np
import matplotlib.pyplot as plt
filepath = r"D:\tempdataset\TTADataset\CHASE\test\images512\Image_01L.jpg"
# 读取图像
# image = cv2.imread(filepath, cv2.IMREAD_GRAYSCALE)
image = cv2.imread(filepath)[:,:,::-1] #cv2默认是BGR通道顺序,这里调整到RGB
img = cv2.resize(image,(500,500))
fre = np.fft.fft2(img,axes=(0,1)) #变换得到的频域图数据是复数组成的
fre_m = np.abs(fre) #幅度谱,求模得到
fre_p = np.angle(fre) #相位谱,求相角得到
# 把相位设为常数
constant = fre_m.mean()
fre_ = constant * np.e ** (1j * fre_p) # 把幅度谱和相位谱再合并为复数形式的频域图数据
img_onlyphase = np.abs(np.fft.ifft2(fre_, axes=(0, 1))) # 还原为空间域图像
# 把振幅设为常数
constant = fre_p.mean()
fre_ = fre_m * np.e ** (1j * constant)
img_onlymagnitude = np.abs(np.fft.ifft2(fre_, axes=(0, 1)))
# 绘制原始图像和振幅谱
plt.subplot(1, 3, 1), plt.imshow(img.astype('uint8'))
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(1, 3, 2), plt.imshow(img_onlyphase.astype('uint8'))
plt.title('phase Spectrum'), plt.xticks([]), plt.yticks([])
plt.subplot(1, 3, 3), plt.imshow(img_onlymagnitude.astype('uint8'))
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.show()
torch
import torch
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
import torchvision.transforms as transforms
import os
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"
import torch
import numpy as np
import cv2
# 读取图像
# 图像转tensor!
# 读取图像
image = Image.open(r"D:\tempdataset\TTADataset\CHASE\test\images512\Image_01L.jpg") # 替换为你的图像文件路径
# 定义转换
transform = transforms.ToTensor()
# 将图像转换为张量
tensor = transform(image)
# 进行傅里叶变换
fre = torch.fft.fftn(tensor, dim=(-2, -1)) # 在图像的最后两个维度上执行傅里叶变换
fre_m = torch.abs(fre) # 幅度谱,求模得到
fre_p = torch.angle(fre) # 相位谱,求相角得到
# 把相位设为常数
constant = torch.mean(fre_m)
fre_ = constant * torch.exp(1j * fre_p) # 把幅度谱和相位谱再合并为复数形式的频域图数据
img_onlyphase = torch.abs(torch.fft.ifftn(fre_, dim=(-2, -1))) # 还原为空间域图像
# 把振幅设为常数
constant = torch.mean(fre_p)
fre_ = fre_m * torch.exp(1j * constant)
img_onlymagnitude = torch.abs(torch.fft.ifftn(fre_, dim=(-2, -1)))
# tensor转图像!
# 定义转换
transform = transforms.ToPILImage()
# 将张量转换为图像
image2 = transform(fre_p)
# 显示图像
plt.imshow(image2)
plt.axis('off') # 不显示坐标轴
plt.show()