傅里叶变换
傅里叶变换比较难和不容易理解,有错的地方请见谅
傅里叶原理表明:任何连续测量的时序或信号,都可以表示为不同频率的正弦波信号的无限叠加。也就是说,傅里叶变换是一种特殊的积分变换,它能将满足一定条件的某个函数表示成正弦基函数的线性组合或者积分。
不同的研究领域,傅里叶变换具有多种不同的变体形式,如连续傅里叶变换和离散傅里叶变换。
可以看这篇文章:https://zhuanlan.zhihu.com/p/19763358
图像处理一般分为空间域处理和频率域处理。
-
空间域处理是直接对图像内的像素进行处理。
-
空间域处理主要划分为灰度变换和空间滤波两种形式。
灰度变换是对图像内的单个像素进行处理,比如调节对比度和处理阈值等。
空间滤波涉及图像质量的改变,例如图像平滑处理。空间域处理的计算简单方便,运算速度更快。
频率域处理是先将图像变换到频率域,然后在频率域对图像进行处理,最后再通过反变换将图像从频率域变换到空间域。
离散傅里叶变换在图像处理领域的应用
对于数字图像这种离散的信号,频率大小表示信号变化的剧烈程度或者说是信号变化的快慢。
截取频域图中的任何一个区域对应的都是原来的整张图的区域,而不是对应的局部
OpenCV提供了函数cv2.dft()
和cv2.idft()
来实现傅里叶变换和逆傅里叶变换
-
dst = cv2.dft (src , flags)
参数:- src:输入图像,需要转换格式为np.float32,可以为实数矩阵或者复数矩阵
- flags:转换标志
- (如DFT_COMPLEX_OUTPUT,对一维或二维实数数组正变换,输出一个同样尺寸的复数矩阵)
- (DFT_REAL_OUTPUT,对一维或二维复数数组反变换,通常输出同样尺寸的复矩阵)
- 返回结果:是双通道的,第一个的结果是虚数部分,第二个通道的结果是实数部分
在使用该函数时,需要注意参数的使用规范:
- 对于参数“原始图像”,要首先使用np.float32()函数将图像转换成np.float32格式。
- “转换标识”的值通常为“cv2.DFT_COMPLEX_OUTPUT”,用来输出一个复数阵列。
函数cv2.dft()
返回的结果与使用Numpy进行傅里叶变换得到的结果是一致的,但是它返回的值是双通道的,第1个通道是结果的实数部分,第2个通道是结果的虚数部分。
经过函数cv2.dft()
的变换后,得到了原始图像的频谱信息。
import cv2
import numpy as np
import matplotlib.pyplot as plt# 以灰度形式读入
img = cv2.imread('img\qiqiqi.png', 0)# 使用cv2.dft()进行傅里叶变换
dst = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)# 将变换后图像的低频部分转移到图像的中心
dst_center = np.fft.fftshift(dst)# 使用cv2.magnitude将实部和虚部转换为实部,乘以20是为了使得结果更大
result = 20 * np.log(np.abs(cv2.magnitude(dst_center[:, :, 0], dst_center[:, :, 1])))# 显示图像
plt.subplot(121)
plt.imshow(img, cmap="gray")
plt.axis("off")
plt.subplot(122)
plt.axis("off")
plt.imshow(result, cmap="gray")
plt.show()
- dst= cv2.idft(src)
参数:- src:经过傅里叶变换后的图片
图像进行傅里叶变换后,通常会将零频率分量移至频谱图像的中心位置。如果使用函数numpy.fft.fftshift()
移动了零频率分量,那么在进行逆傅里叶变换前,要使用函数numpy.fft.ifftshift()
将零频率分量恢复到原来位置。
注意: 在进行逆傅里叶变换后,得到的值仍旧是复数,需要使用函数cv2.magnitude()
计算其幅度。
# %%opencv实现逆傅里叶变换
# 以灰度形式读入
img = cv2.imread('img\qiqiqi.png', 0)# 使用cv2.dft()进行傅里叶变换
dst = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)# 将变换后图像的低频部分转移到图像的中心
dst_center = np.fft.fftshift(dst)#
# 中间可以定义相应的掩膜去留高频或者低频部分
## 使用np.fft.ifftshift将低频移动到原来的位置
dst_origin = np.fft.ifftshift(dst_center)# 使用cv2.idft进行傅里叶的逆变化
img_idft = cv2.idft(dst_origin)# 使用cv2.magnitude转化为空间域内
img_idft = cv2.magnitude(img_idft[:, :, 0], img_idft[:, :, 1])# 显示图像
plt.subplot(121)
plt.imshow(img, cmap="gray")
plt.axis("off")
plt.title('原图')
plt.subplot(122)
plt.axis("off")
plt.imshow(img_idft, cmap=plt.cm.gray)
plt.title('逆傅里叶变换')
plt.show()