opencv中图像的傅里叶变换

你离开我真会死。 提交于 2020-02-28 13:01:49

我们生活在时间的世界中,早上7:00起来吃早饭,8:00去挤地铁,9:00开始上班。。。以时间为参照就是时域分析。但是在频域中一切都是静止的!

高频:变化剧烈的灰度分量,例如边界

低频:变化缓慢的灰度分量,例如一片大海

低通滤波器:只保留低频,会使得图像模糊

高通滤波器:只保留高频,会使得图像细节增强

opencv中主要就是cv2.dft()和cv2.idft(),输入图像需要先转换成np.float32 格式。
得到的结果中频率为0的部分会在左上角,通常要转换到中心位置,可以通过shift变换来实现。
cv2.dft()返回的结果是双通道的(实部,虚部),通常还需要转换成图像格式才能展示(0,255)。

相关函数如下

1. cv2.dft(img, cv2.DFT_COMPLEX_OUTPUT) 进行傅里叶变化

参数说明: img表示输入的图片, cv2.DFT_COMPLEX_OUTPUT表示进行傅里叶变化的方法

2. np.fft.fftshift(img)  将图像中的低频部分移动到图像的中心

参数说明:img表示输入的图片

3. cv2.magnitude(x, y) 将sqrt(x^2 + y^2) 计算矩阵维度的平方根

参数说明:需要进行x和y平方的数

4.np.fft.ifftshift(img) # 进图像的低频和高频部分移动到图像原来的位置

参数说明:img表示输入的图片

5.cv2.idft(img) # 进行傅里叶的逆变化

参数说明:img表示经过傅里叶变化后的图片

一、绘制图像的频域信息

第一步:载入图片

第二步:使用np.float32进行格式转换

第三步:使用cv2.dft进行傅里叶变化

第四步:使用np.fft.shiftfft将低频转移到中间位置

第五步:使用cv2.magnitude将实部和虚部投影到空间域

第六步:进行作图操作

import cv2
import numpy as np
import matplotlib.pyplot as plt


# 第一步读取图片
img = cv2.imread('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.subplot(121)
plt.imshow(img, cmap='gray')
plt.subplot(122)
plt.imshow(img_dft, cmap='gray')
plt.show()

在这里插入图片描述

二、低通滤波

第一步:读取图片

第二步:np.float32进行类型转换

第三步:使用cv2.dft进行傅里叶变化

第四步:使用np.fft.fftshift 将低频部分转换到图像的中心

第五步:构造掩模,使得掩模的中心位置为1,边缘位置为0

第六步:将掩模与傅里叶变换后的图像结合,只保留中心部分的低频位置

第七步:使用np.fft.ifftshift将低频部分转移回图像的原先位置

第八步:使用cv2.idft进行傅里叶的反转换

第九步:使用cv2.magnitude将图像的实部和虚部转换为空间域内

第十步:进行作图操作

# 第一步读入图片
img = cv2.imread('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.subplot(121)
plt.imshow(img, cmap='gray')
plt.subplot(122)
plt.imshow(img_idf, cmap='gray')
plt.show()

在这里插入图片描述

三、高通滤波

流程与上面一样,只是构造的掩模是中间为0,边缘为1,然后与傅里叶变化后的图像结合, 保留高频部分,去除低频部分

# 第一步读入图片
img = cv2.imread('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.subplot(121)
plt.imshow(img, cmap='gray')
plt.subplot(122)
plt.imshow(img_idf, cmap='gray')
plt.show()

在这里插入图片描述

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!