OpenCV-Python实战(17)——傅里叶变换

一、原理

参考:【OpenCV-Python】:图像的傅里叶变换与逆傅里叶变换_envi进行傅里叶逆变换结果中间颜色不对-优快云博客

 

二、numpy 傅里叶变换 

1.1 傅里叶变换  np.fft.fft2()

f = np.fft.fft2(src=*,s=None,axes=(-2,-1))

f:函数返回值,含复数的数组(complex,ndarray)。

src:输入图像的像素矩阵,灰度图

s:整数序列,输出数组大小,默认为:与原始图像一样大。

axes:整数轴,默认为:使用最后2个轴。 

fshift = np.fft.fftshift(f)  #  0 频率中心化。

 0 频率中心化。

fimg = 20*np.log(np.abs(fshift))   #  复数数组转 [0,256] 的灰度值。

 复数数组转 [0,256] 的灰度值。

import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.family']=['Microsoft JhengHei']

img = cv2.imread('Lena.png',cv2.IMREAD_GRAYSCALE)  # 灰度图像
# cv2.imshow('Lena',img)

f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
spectrum = 20*np.log(np.abs(fshift))

plt.subplot(121)
plt.imshow(img,cmap='gray')
plt.title('原始图像')
plt.axis('off')
plt.subplot(122)
plt.imshow(spectrum,cmap='gray')
plt.title('频谱图')
plt.axis('off')
 
plt.savefig('DFT.png',dpi=300,bbox_inches='tight')
plt.show()

1.2 逆傅里叶变换 np.fft.ifftshift()

ifshift = np.fft.ifftshift(fshift)  #   0 频率移会左上角。

img_tmp = np.fft.ifft2(ifshift)   #  np.fft.fft2()的逆变换。

img_back = np.abs(img_tmp)     # img_tmp仍是一个复数数组,需要取绝对值。
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.family']=['Microsoft JhengHei']

img = cv2.imread('Lena.png',cv2.IMREAD_GRAYSCALE)  # 灰度图像
# cv2.imshow('Lena',img)
# 正傅里叶变换
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
spectrum = 20*np.log(np.abs(fshift))
# 逆傅里叶变换
ifshift = np.fft.ifftshift(fshift)
img_tem = np.fft.ifft2(ifshift)
img_back = np.abs(img_tem)

plt.subplot(131)
plt.imshow(img,cmap='gray')
plt.title('原始图像')
plt.axis('off')
plt.subplot(132)
plt.imshow(spectrum,cmap='gray')
plt.title('频谱图')
plt.axis('off')
plt.subplot(133)
plt.imshow(img_back,cmap='gray')
plt.title('逆变换')
plt.axis('off')

plt.savefig('DFT1.png',dpi=300,bbox_inches='tight')
plt.show()

三、OpenCV傅里叶变换 

3.1 傅里叶变换 cv2.dft()

dft = cv2.dft(src=*,flags=*)

dft:函数返回值,含复数的数组(complex,ndarray),含有两个通道,一个是实数部分,一个是虚数部分。

src:输入图像的像素矩阵,灰度图

flags:傅里叶变换方法,常见方法如下: 

方法解释
DFT_INVERSE1对一维或二维数组做逆变换
DFT_SCALE2

输出除以元素数目N

DFT_ROWS4对输入变量的每一行进行变换或逆变换
DFT_COMPLEX_OUTPUT16输出含有实数和虚数
DFT_REAL_OUTPUT32输出是复数矩阵
DFT_COMPLEX_INPUT64输入是复数矩阵
dftshift = np.fft.fftshift(dft)   # 0 频率中心化
# 将振幅值映射到 [0,255] 的灰度空间
dst = 20*np.log(cv2.magnitude(dftshift[:,:,0],dftshift[:,:,1]))
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.family']=['Microsoft JhengHei']

img = cv2.imread('Lena.png',cv2.IMREAD_GRAYSCALE)  # 灰度图像
# cv2.imshow('Lena',img)
# 正傅里叶变换
dft = cv2.dft(src=np.float32(img),flags=cv2.DFT_COMPLEX_OUTPUT)
dftshift = np.fft.fftshift(dft)
img1 = 20*np.log(cv2.magnitude(dftshift[:,:,0],dftshift[:,:,1]))
# 画图
plt.subplot(121)
plt.imshow(img,cmap='gray')
plt.title('原始图像')
plt.axis('off')
plt.subplot(122)
plt.imshow(img1,cmap='gray')
plt.title('频谱图')
plt.axis('off')

plt.savefig('OpenCV_DFT1.png',dpi=300,bbox_inches='tight')
plt.show()

 3.2 逆傅里叶变换 cv2.idft()

dst = cv2.idft(src=*,flags)

 参数与 cv2.dft() 函数基本相同。

import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.family']=['Microsoft JhengHei']

img = cv2.imread('Lena.png',cv2.IMREAD_GRAYSCALE)  # 灰度图像
# cv2.imshow('Lena',img)
# 正傅里叶变换
dft = cv2.dft(src=np.float32(img),flags=cv2.DFT_COMPLEX_OUTPUT)
dftshift = np.fft.fftshift(dft)
img1 = 20*np.log(cv2.magnitude(dftshift[:,:,0],dftshift[:,:,1]))
# 逆傅里叶变换
idftshift = np.fft.ifftshift(dftshift)
tmp = cv2.idft(idftshift)
img2 = cv2.magnitude(tmp[:,:,0],tmp[:,:,1])
# 画图
plt.subplot(131)
plt.imshow(img,cmap='gray')
plt.title('原始图像')
plt.axis('off')
plt.subplot(132)
plt.imshow(img1,cmap='gray')
plt.title('频谱图')
plt.axis('off')
plt.subplot(133)
plt.imshow(img2,cmap='gray')
plt.title('逆变换')
plt.axis('off')

plt.savefig('OpenCV_DFT2.png',dpi=300,bbox_inches='tight')
plt.show()

3.3 高通滤波器 

import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.family']=['Microsoft JhengHei']

img = cv2.imread('Lena.png',cv2.IMREAD_GRAYSCALE)  # 灰度图像

# 正傅里叶变换
dft = cv2.dft(src=np.float32(img),flags=cv2.DFT_COMPLEX_OUTPUT)
dftshift = np.fft.fftshift(dft)
# 高通滤波器
h,w = img.shape[:2]
row,col = h//2,w//2  # 中心点坐标
mask = np.ones((h,w,2),float)*255
mask[row-30:row+30,col-30:col+30]=0    # 可以自行控制滤波器的大小
# 滤波
fshift = dftshift * mask
img1 = 20*np.log(cv2.magnitude(fshift[:,:,0]+0.01,fshift[:,:,1]+0.01))
# 逆傅里叶变换
idftshift = np.fft.ifftshift(fshift)
tmp = cv2.idft(idftshift)
img2 = cv2.magnitude(tmp[:,:,0],tmp[:,:,1])
# 画图
plt.subplot(141)
plt.imshow(img,cmap='gray')
plt.title('原始图像')
plt.axis('off')
plt.subplot(142)
plt.imshow(img1,cmap='gray')
plt.title('高通滤波器')
plt.axis('off')
plt.subplot(143)
plt.imshow(img2,cmap='gray')
plt.title('高通滤波器灰度图')
plt.axis('off')
plt.subplot(144)
plt.imshow(img2,)
plt.title('高通滤波图像')
plt.axis('off')

plt.savefig('OpenCV_DFT3.png',dpi=300,bbox_inches='tight')
plt.show()

 3.4 低通滤波器 

import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.family']=['Microsoft JhengHei']

img = cv2.imread('Lena.png',cv2.IMREAD_GRAYSCALE)  # 灰度图像

# 正傅里叶变换
dft = cv2.dft(src=np.float32(img),flags=cv2.DFT_COMPLEX_OUTPUT)
dftshift = np.fft.fftshift(dft)
# 低通滤波器
h,w = img.shape[:2]
row,col = h//2,w//2  # 中心点坐标
mask = np.zeros((h,w,2),float)
mask[row-30:row+30,col-30:col+30]=255    # 可以自行控制滤波器的大小
# 滤波
fshift = dftshift * mask
img1 = 20*np.log(cv2.magnitude(fshift[:,:,0]+0.01,fshift[:,:,1]+0.01))
# 逆傅里叶变换
idftshift = np.fft.ifftshift(fshift)
tmp = cv2.idft(idftshift)
img2 = cv2.magnitude(tmp[:,:,0],tmp[:,:,1])
# 画图
plt.subplot(141)
plt.imshow(img,cmap='gray')
plt.title('原始图像')
plt.axis('off')
plt.subplot(142)
plt.imshow(img1,cmap='gray')
plt.title('低通滤波器')
plt.axis('off')
plt.subplot(143)
plt.imshow(img2,cmap='gray')
plt.title('低通滤波器灰度图')
plt.axis('off')
plt.subplot(144)
plt.imshow(img2,)
plt.title('低通滤波图像')
plt.axis('off')

plt.savefig('OpenCV_DFT4.png',dpi=300,bbox_inches='tight')
plt.show()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小码贾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值