欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

荐 opencv学习笔记22:傅里叶变换,高通滤波,低通滤波

程序员文章站 2022-03-30 09:50:41
傅里叶变换原理任何连续的周期信号,都可以由一组适当的正弦曲线组合而成。下列左上图由其他三图构成。左图经过傅里叶变换,由时域图转换到频域图。相互可逆相位:不是同时开始的一组余弦函数,在叠加时要体现刚开始的时间。sin(wx+a)中a是相位numpy实现傅里叶变换numpy.fft.fft2()实现傅里叶变换,返回的是一个复数数组。numpy.fft.fftshift()将零频域分量移到频谱中心白色为fft.fft2得到的低频部分。将低频部分移到中心。20*np.log(np.ab...

傅里叶变换原理

任何连续的周期信号,都可以由一组适当的正弦曲线组合而成。
下列左上图由其他三图构成。
荐
                                                        opencv学习笔记22:傅里叶变换,高通滤波,低通滤波

左图经过傅里叶变换,由时域图转换到频域图。相互可逆
荐
                                                        opencv学习笔记22:傅里叶变换,高通滤波,低通滤波
相位:不是同时开始的一组余弦函数,在叠加时要体现刚开始的时间。

sin(wx+a)中a是相位

numpy实现傅里叶变换

numpy.fft.fft2()
实现傅里叶变换,返回的是一个复数数组。
numpy.fft.fftshift()
将零频域分量移到频谱中心
白色为fft.fft2得到的低频部分。将低频部分移到中心。
荐
                                                        opencv学习笔记22:傅里叶变换,高通滤波,低通滤波
20*np.log(np.abs(fshift))
傅里叶得到有负数数据,重新设置频谱的范围如【0-255】,否则图像无法展示。

import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('lena.bmp',0)
f = np.fft.fft2(img)@#傅里叶变换
fshift = np.fft.fftshift(f)#移动低频到中间
magnitude_spectrum = 20*np.log(np.abs(fshift))#设置频谱到【0-255】
plt.subplot(121)
plt.imshow(img, cmap = 'gray')
plt.title('original')
plt.axis('off')
plt.subplot(122)
plt.imshow(magnitude_spectrum, cmap = 'gray')
plt.title('result')
plt.axis('off')
plt.show()

荐
                                                        opencv学习笔记22:傅里叶变换,高通滤波,低通滤波
傅里叶变换能得到高频,低频信息。针对低频,高频处理能得到不同的目的。

傅里叶变换是可逆的,逆傅里叶变换能得到原始图像。
在频域对图像进行处理后,在频域处理的结果能反映到逆傅里叶变换图像上。

numpy实现逆傅里叶变换

numpy.fft.ifftshift()
numpy.fft.fftshift()的逆操作
numpyfft.ifft2().
逆傅里叶变换
iimg = np.abs(逆傅里叶变换结果)
逆傅里叶变换也有负数,调整至的范围为[0-255}

import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('boat.bmp',0)
f = np.fft.fft2(img)#傅里叶变换
fshift = np.fft.fftshift(f)#移动位置
ishift = np.fft.ifftshift(fshift)#逆移动位置
iimg = np.fft.ifft2(ishift)#逆傅里叶变换
print(iimg)
iimg = np.abs(iimg)#取绝对值
print(iimg)
plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('original'),plt.axis('off')
plt.subplot(122),plt.imshow(iimg, cmap = 'gray')
plt.title('iimg'),plt.axis('off')
plt.show()
荐
                                                        opencv学习笔记22:傅里叶变换,高通滤波,低通滤波荐
                                                        opencv学习笔记22:傅里叶变换,高通滤波,低通滤波

荐
                                                        opencv学习笔记22:傅里叶变换,高通滤波,低通滤波

高通滤波,低通滤波

低频对应图像中变化缓慢的灰度分量,例如在一幅草原图上,低频对应着广袤的颜色趋于一致额草原。
高频对应着图像内变化越来越快的灰度分量,是由灰度的过度尖锐造成的。如对应草原图中狮子的边缘信息。

滤波
接受或者拒绝一定频率的分量
通过低频的滤波器叫低通滤波器
通过高频的滤波器叫高通滤波器
频域滤波
修改傅里叶变换达到特殊目的,然后计算IDFT返回图像域
特殊目的:图像增强,图像去噪,边缘检测,特征提取,压缩,加密等。

低通滤波:衰减高频通低频,会模糊一张图。
高通滤波:衰减低频通高频,增强图像尖锐细节,但是会造成图像对比度下降。

高通滤波numpy实现

高通滤波:将频谱图像的中心的位置区域设置为0(中心部位为低频,之前傅里叶变换将低频移到中心位置啦,由前文得知低频为白色)

荐
                                                        opencv学习笔记22:傅里叶变换,高通滤波,低通滤波
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('lena.bmp',0)
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
rows, cols = img.shape
crow,ccol = int(rows/2) , int(cols/2)
fshift[crow-30:crow+30, ccol-30:ccol+30] = 0
ishift = np.fft.ifftshift(fshift)
iimg = np.fft.ifft2(ishift)
iimg = np.abs(iimg)
plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('original'),plt.axis('off')
plt.subplot(122),plt.imshow(iimg, cmap = 'gray')
plt.title('iimg'),plt.axis('off')
plt.show()
荐
                                                        opencv学习笔记22:傅里叶变换,高通滤波,低通滤波

opencv实现傅里叶变换

返回结果=cv2.dft(原始图像,转换标识)
返回结果:是双通道的,第一个为结果的实数部分。第二个为结果的虚数部分。
原始图像:要求图像格式是np.float32。得首先转换np.float32(img)
转换标识: 一般使用flags = cv2.DFT_COMPLEX_OUTPUT,输出的是一个复数阵列。
numpy.fft.fftshift(dft)
仍然使用这个将频破谱谱图像低频移到中心位置
返回值=cv2.magnitude(参数1,参数2)
使用这个函数将数值转换到8位数值形式(图像形式)
荐
                                                        opencv学习笔记22:傅里叶变换,高通滤波,低通滤波
result = 20*np.log(cv2.magnitude(dftShift[:,:,0],dftShift[:,:,1]))
使用这个将值转换到【0-255】

import numpy as np
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('lena.bmp',0)
dft = cv2.dft(np.float32(img),flags = cv2.DFT_COMPLEX_OUTPUT)
dftShift = np.fft.fftshift(dft)
result = 20*np.log(cv2.magnitude(dftShift[:,:,0],dftShift[:,:,1]))
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()
荐
                                                        opencv学习笔记22:傅里叶变换,高通滤波,低通滤波

opencv实现逆傅里叶变换

返回结果=cv2.idft(原始数据)

cv2.dft()的逆操作.
返回结果:取决于原始数据的类型和大小。
原始数据:实数或者复数均可。

返回值=cv2.magnitude(参数1,参数2)
荐
                                                        opencv学习笔记22:傅里叶变换,高通滤波,低通滤波
使用这个将值转换到【0-255】即把这个数值转换到8位数值形式
ishift = np.fft.ifftshift(dftShift)
将中间低频部分,移动会原处。numpy.fft.fftshift(dft)的逆操作

import numpy as np
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('lena.bmp',0)
dft = cv2.dft(np.float32(img),flags = cv2.DFT_COMPLEX_OUTPUT)
dftShift = np.fft.fftshift(dft)
ishift = np.fft.ifftshift(dftShift)
iImg = cv2.idft(ishift)
iImg= cv2.magnitude(iImg[:,:,0],iImg[:,:,1])
plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('original'), plt.axis('off')
plt.subplot(122),plt.imshow(iImg, cmap = 'gray')
plt.title('inverse'), plt.axis('off')
plt.show()
荐
                                                        opencv学习笔记22:傅里叶变换,高通滤波,低通滤波

低通滤波opencv实现
前面实现了高通滤波
这里实现低通滤波。用opencv。也可以用numpy,参考前面高通滤波numpy实现.
低频是大量细节,高频是边缘。
低通滤波:相当于把下面右图中心部分白色保留,周围黑色舍弃。
荐
                                                        opencv学习笔记22:傅里叶变换,高通滤波,低通滤波
实现方法
荐
                                                        opencv学习笔记22:傅里叶变换,高通滤波,低通滤波
低通滤波器构造
荐
                                                        opencv学习笔记22:傅里叶变换,高通滤波,低通滤波

import numpy as np
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('lena.bmp',0)
#傅里叶变换
dft = cv2.dft(np.float32(img),flags = cv2.DFT_COMPLEX_OUTPUT)#傅里叶变换
dftShift = np.fft.fftshift(dft)#移动低频部分到中心
#低通滤波器构造
rows, cols = img.shape
crow,ccol = int(rows/2) , int(cols/2)
mask = np.zeros((rows,cols,2),np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 1
#两个通道,与频谱图像匹配
fShift = dftShift*mask
#逆傅里叶变换
ishift = np.fft.ifftshift(fShift)#移动中心位低频到原处
iImg = cv2.idft(ishift)#逆傅里叶变换
iImg= cv2.magnitude(iImg[:,:,0],iImg[:,:,1])#将数值变换到8位二进制数值图像格式
#图像显示
plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('original'), plt.axis('off')
plt.subplot(122),plt.imshow(iImg, cmap = 'gray')
plt.title('result'), plt.axis('off')
plt.show()

荐
                                                        opencv学习笔记22:傅里叶变换,高通滤波,低通滤波
总目录链接:
python3+opencv学习笔记汇总目录(适合基础入门学习)
电气专业的计算机小白,写博文不容易。如果你觉得本文不错。请点个赞支持下。谢谢

本文地址:https://blog.csdn.net/kobeyu652453/article/details/107196751