傅里叶变换
傅里叶变换常用的三个函数
函数一: numpy.fft.fft2: 复数数组
函数二: numpy.fft.fftshift: 将零频率分量移动到频谱中心
函数三: 20*np.log(np.abs(fshift)) 设置频谱的范围
import cv2
import numpy as np
import matplotlib.pyplot as plt
def test_1():
img = cv2.imread(r"E:\script\lx\image\img.png", 0) # 0: 表示保持灰度状态
f = np.fft.fft2(img)
f_shift = np.fft.ifftshift(f) # 低频移动到中间
result = 20*np.log(np.abs(f_shift)) # 设置频谱的范围
plt.subplot(121) # 创建一个显示窗口(位置为第一个, 左边)
plt.imshow(img, cmap="gray") # 保持灰度状态
plt.title("original") # 设置标题
plt.axis("off") # 不设置坐标系
plt.subplot(122) # 创建一个显示窗口(位置为第二个, 右边)
plt.imshow(result, cmap="gray")
plt.title("result")
plt.axis("off")
plt.show()
test_1()
结果展示
傅里叶逆变换
常用的三个函数
函数一: numpy.fft.ifft2 实现逆傅里叶变换 返回一个复数数组
函数二: numpy.fft.ifftshift 逆函数 将低频归放到原来的位置
函数三: np.abs() # 区间转换
def test_2():
img = cv2.imread(r"E:\script\lx\image\img.png", 0) # 0: 表示保持灰度状态
f = np.fft.fft2(img)
f_shift = np.fft.ifftshift(f) # 低频移动到中间
i_shift = np.fft.ifftshift(f_shift) # 低频从中间移动到原有位置
i_img = np.fft.ifft2(i_shift) # 转为复数数组
i_img = np.abs(i_img)
plt.subplot(121) # 创建一个显示窗口(位置为第一个, 左边)
plt.imshow(img, cmap="gray") # 保持灰度设置
plt.title("original") # 设置标题
plt.axis("off") # 不设置坐标系
plt.subplot(122) # 创建一个显示窗口(位置为第二个, 右边)
plt.imshow(i_img, cmap="gray")
plt.title("result")
plt.axis("off")
plt.show()
test_2()
结果如下:
高频及低频
低频: 对应图像内变化缓慢的灰度分量(在一副大草原的图像中,低频代表着颜色趋于一致的草原)
高频: 草原上出现一头大象,大象在草原上很容易显示出来
滤波
1: 接受或者拒绝一定频率的分量
2: 通过低频的滤波器称为低通滤波器
3: 通过高频的滤波器称为高通滤波器
频域滤波
1: 修改傅里叶变换以达到特殊目的,然后计算IDFT返回到图像域
2:特殊目的: 图像增强 图像去噪 边缘检测 特征提取 压缩 加密
3: 衰减高频而通过低频 低通滤波器 将模糊一幅画像
4: 衰减低频而通过高频 高频滤波器 将增强尖锐的细节 但是会导致图像的对比度降低
高通滤波器示例:
def test_3():
# 高通滤波器-去掉低频
img = cv2.imread(r"E:\script\lx\image\lunchuan.png", 0) # 0: 表示保持灰度状态
f = np.fft.fft2(img) # 转为复数数组
f_shift = np.fft.fftshift(f) # 低频移动到中心
rows, cols = img.shape # 获取图片大小
crow, col = int(rows / 2), int(cols / 2) # 中心点
f_shift[crow-30: crow+30, col-30:col+30] = 0 # 去掉指定区间的低频
i_shift = np.fft.ifftshift(f_shift) # 逆变换
i_shift = np.fft.ifft2(i_shift) # 返回一个复数数组
i_mg = np.abs(i_shift) # 区间转换
plt.subplot(121)
plt.imshow(img, cmap="gray")
plt.title("original")
plt.axis("off")
plt.subplot(122)
plt.imshow(i_mg, cmap="gray")
plt.title("result")
plt.axis("off")
plt.show()
test_3()
OpenCV实现傅里叶变换
常用函数
函数一: cv2.dft(原始图像, 转换标识) 返回双通道: 一通道是实数 二通道是虚数 原始图像 首先转换成np.float32格式 转换标识: flags = cv2.DFT_COMPLEX_OUTPUT 输出复数阵列
函数二: cv2.magnitude(参数1, 参数2) 参数1: 浮点型X坐标值 实部 参数2: 浮点型Y坐标值 虚部
def test_4():
"""
OpenCV实现傅里叶变换
@return:
"""
img = cv2.imread(r"E:\script\lx\image\lunchuan.png", 0)
dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
result = 20*np.log(cv2.magnitude(dft_shift[:,:,0], dft_shift[:,:,1])) # 双通道变为[0~255]的矩阵
plt.subplot(121)
plt.imshow(img, cmap="gray")
plt.title("original")
plt.axis("off")
plt.subplot(122)
plt.imshow(result, cmap="gray")
plt.title("result")
plt.axis("off")
plt.show()
test_4()
结果如下
OpenCV实现逆变换
函数一: cv2.idft(原始数据) 原始数据: 实数或者复数均可 返回结果: 取决于原始数据的类型和大小
代码示例
def test_5():
"""
OpenCV实现傅里叶逆变换
@return:
"""
img = cv2.imread(r"E:\script\lx\image\lunchuan.png", 0)
d_ft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)
d_shift = np.fft.fftshift(d_ft)
i_shift = np.fft.ifftshift(d_shift)
i_img = cv2.idft(i_shift)
i_img = cv2.magnitude(i_img[:,:,0], i_img[:,:,1])
plt.subplot(121)
plt.imshow(img, cmap="gray")
plt.title("original")
plt.axis("off")
plt.subplot(122)
plt.imshow(i_img, cmap="gray")
plt.title("result")
plt.axis("off")
plt.show()
test_5()
结果如下:
低通滤波器
def test_6():
# 低频滤波器-去掉高频
img = cv2.imread(r"E:\script\lx\image\lunchuan.png", 0) # 0: 表示保持灰度状态
d_ft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)
d_shift = np.fft.fftshift(d_ft)
rows, cols = img.shape
crow, col = int(rows / 2), int(cols / 2)
mask = np.zeros((rows, cols, 2), np.uint8) # 创建一个新的矩阵
mask[crow-30:crow+30, col-30: col+30] = 1 # 指定区间去掉高频
f_shift = d_shift * mask # 滤波
i_shift = np.fft.ifftshift(f_shift) # 逆变换
i_shift = cv2.idft(i_shift) # 返回一个复数数组
i_mg = cv2.magnitude(i_shift[:,:,0], i_shift[:,:,1]) # 区间转换
plt.subplot(121)
plt.imshow(img, cmap="gray")
plt.title("original")
plt.axis("off")
plt.subplot(122)
plt.imshow(i_mg, cmap="gray")
plt.title("result")
plt.axis("off")
plt.show()
test_6()