OpenCV(9):傅里叶变换
傅里叶分析不仅仅是一个数学工具,更是一种可以彻底颠覆一个人以前世界观的思维模式。
傅里叶分析不仅仅是一个数学工具,更是一种可以彻底颠覆一个人以前世界观的思维模式
9.1 傅里叶变换在图像处理中的作用
- 高频:变化剧烈的灰度分量,例如边界
- 低频:变化缓慢的灰度分量,例如一片大海
- 低通滤波器:只保留低频,会使得图像模糊
- 高通滤波器:只保留高频,会使得图像细节增强
OpenCV中主要就是使用cv2.dft()和cv2.idft(),输入图像要先转换成np.float32格式
得到的结果中频率为0的部分会在左上角,通常要转换到中心位置,可以通过shift变换来实现
cv2.dft()返回的结果是双通道的(实部,虚部),通常还需要转换成图像格式才能显示(0,255)。
9.2 相关函数
cv2.dft(img, cv2.DFT_COMPLEX_OUTPUT) 实现傅里叶变换
np.fft.fftshift(img) 将图像中的低频部分移动到图像的中心
cv2.magnitude(x, y) 将
计算矩阵维度的平方根
np.fft.ifftshift(img) 将图像的低频和高频部分移动到图像原来的位置
cv2.idft(img) 实现逆傅里叶变换
9.3 构建出傅里叶变换的图片的流程
构建出的傅里叶变化的图片,将低频移到中间位置, 通常呈现中间亮,周围暗,是因为对于低频而言,波动较大,因此呈现亮,对于高频而言,波动较小,因此呈现暗。其步骤如下:
第一步:载入图片
第二步:使用np.float32进行格式转换
第三步:使用cv2.dft进行傅里叶变化
第四步:使用np.fft.shiftfft将低频转移到中间位置
第五步:使用cv2.magnitude将实部和虚部投影到空间域
第六步:进行作图操作
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 第一步读取图片
img = cv2.imread('C:/Users/xxx/Downloads/lena.jpg', 0)
# 第二步:进行float32形式转换
float32_img = np.float32(img)
# 第三步: 使用cv2.dft进行傅里叶变化
dft_img = cv2.dft(float32_img, flags=cv2.DFT_COMPLEX_OUTPUT)
# 第四步:使用np.fft.shiftfft()将变化后的图像的低频转移到中心位置
dft_img_ce = np.fft.fftshift(dft_img)
# 第五步:使用cv2.magnitude将实部和虚部转换为实部,乘以20是为了使得结果更大
img_dft = 20 * np.log(cv2.magnitude(dft_img_ce[:, :, 0], dft_img_ce[:, :, 1]))
# 第六步:进行画图操作
plt.figure(figsize=(12.8,4.8))
plt.subplot(121)
plt.imshow(img,cmap='gray'),plt.title('Original',fontSize=30)
plt.subplot(122)
plt.imshow(img_dft,cmap='gray'),plt.title('dft',fontSize=30)
plt.show()
9.4 低通滤波
只保留低频,即进行低通滤波,因为高频表示是一些细节,即图像的轮廓和边缘,失去了高频部分,图像就容易变得模糊。其步骤如下:
第一步:读取图片
第二步:np.float32进行类型转换
第三步:使用cv2.dft进行傅里叶变化
第四步:使用np.fft.fftshift 将低频部分转换到图像的中心
第五步:构造掩模,使得掩模的中心位置为1,边缘位置为0
第六步:将掩模与傅里叶变换后的图像结合,只保留中心部分的低频位置
第七步:使用np.fft.ifftshift将低频部分转移回图像的原先位置
第八步:使用cv2.idft进行傅里叶的反转换
第九步:使用cv2.magnitude将图像的实部和虚部转换为空间域内
第十步:进行作图操作
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 使用掩模只保留低通
# 第一步读入图片
img = cv2.imread('C:/Users/xxx/Downloads/lena.jpg', 0)
# 第二步:进行数据类型转换
img_float = np.float32(img)
# 第三步:使用cv2.dft进行傅里叶变化
dft = cv2.dft(img_float, flags=cv2.DFT_COMPLEX_OUTPUT)
# 第四步:使用np.fft.fftshift将低频转移到图像中心
dft_center = np.fft.fftshift(dft)
# 第五步:定义掩模:生成的掩模中间为1周围为0
crow, ccol = int(img.shape[0] / 2), int(img.shape[1] / 2) # 求得图像的中心点位置
mask = np.zeros((img.shape[0], img.shape[1], 2), np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 1
# 第六步:将掩模与傅里叶变化后图像相乘,保留中间部分
mask_img = dft_center * mask
# 第七步:使用np.fft.ifftshift(将低频移动到原来的位置
img_idf = np.fft.ifftshift(mask_img)
# 第八步:使用cv2.idft进行傅里叶的反变化
img_idf = cv2.idft(img_idf)
# 第九步:使用cv2.magnitude转化为空间域内
img_idf = cv2.magnitude(img_idf[:, :, 0], img_idf[:, :, 1])
# 第十步:进行绘图操作
plt.figure(figsize=(12.8,4.8))
plt.subplot(121)
plt.imshow(img,cmap='gray'),plt.title('Original',fontSize=30)
plt.subplot(122)
plt.imshow(img_idf,cmap='gray'),plt.title('idft',fontSize=30)
plt.show()
9.5 高通滤波
只保留高频,即进行高通滤波,因为高频表示是一些细节,即图像的轮廓和边缘,失去了高频部分,图像就容易变得模糊。其步骤如下:
第一步:读取图片
第二步:np.float32进行类型转换
第三步:使用cv2.dft进行傅里叶变化
第四步:使用np.fft.fftshift 将低频部分转换到图像的中心
第五步:构造掩模,使得掩模的中间位置为0,边缘位置为1
第六步:将掩模与傅里叶变换后的图像结合,只保留中间部分
第七步:使用np.fft.ifftshift将低频部分转移回图像的原先位置
第八步:使用cv2.idft进行傅里叶的反转换
第九步:使用cv2.magnitude将图像的实部和虚部转换为空间域内
第十步:进行作图操作
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 只保留高频部分
# 使用掩模只保留高通
# 第一步读入图片
img = cv2.imread('C:/Users/xxx/Downloads/lena.jpg', 0)
# 第二步:进行数据类型转换
img_float = np.float32(img)
# 第三步:使用cv2.dft进行傅里叶变化
dft = cv2.dft(img_float, flags=cv2.DFT_COMPLEX_OUTPUT)
# 第四步:使用np.fft.fftshift将低频转移到图像中心
dft_center = np.fft.fftshift(dft)
# 第五步:定义掩模:生成的掩模中间为0周围为1
crow, ccol = int(img.shape[0] / 2), int(img.shape[1] / 2) # 求得图像的中心点位置
mask = np.ones((img.shape[0], img.shape[1], 2), np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 0
# 第六步:将掩模与傅里叶变化后图像相乘,保留中间部分
mask_img = dft_center * mask
# 第七步:使用np.fft.ifftshift(将低频移动到原来的位置
img_idf = np.fft.ifftshift(mask_img)
# 第八步:使用cv2.idft进行傅里叶的反变化
img_idf = cv2.idft(img_idf)
# 第九步:使用cv2.magnitude转化为空间域内
img_idf = cv2.magnitude(img_idf[:, :, 0], img_idf[:, :, 1])
# 第十步:进行绘图操作
plt.figure(figsize=(12.8,4.8))
plt.subplot(121)
plt.imshow(img,cmap='gray'),plt.title('Original',fontSize=30)
plt.subplot(122)
plt.imshow(img_idf,cmap='gray'),plt.title('idft',fontSize=30)
plt.show()
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)