图像处理─般分为空间域处理和频率域处理。
空间域处理是直接对图像内的像素进行处理。空间域处理主要划分为灰度变换和空间滤波两种形式。灰度变换是对图像内的单个像素进行处理,比如调节对比度和处理阈值等。空间滤波涉及图像质量的改变,例如图像平滑处理。
在图像处理过程中,傅里叶变换就是将图像分解为正弦分量和余弦分量两部分。数字图像经过傅里叶变换后,得到的频域值是复数。因此,显示傅里叶变换的结果需要使用实数图像(real image)加虚数图像(complex image),或者幅度图像(magnitude image)加相位图像(phaseimage)的形式。
因为幅度图像包含了原图像中我们所需要的大部分信息,所以在图像处理过程中,通常仅使用幅度图像。
对图像进行傅里叶变换后,我们会得到图像中的低频和高频信息。低频信息对应图像内变化缓慢的灰度分量。高频信息对应图像内变化越来越快的灰度分量,是由灰度的尖锐过渡造成的。傅里叶变换的目的,就是为了将图像从空域转换到频域,并在频域内实现对图像内特定对象的处理,然后再对经过处理的频域图像进行逆傅里叶变换得到空域图像。傅里叶变换在图像处理领域发挥着非常关键的作用,可以实现图像增强、图像去噪、边缘检测、特征提取、图像压缩和加密等。
返回值=numpy.fft.fft2(原始图像)
原始图像的类型为灰度图像,返回值是复数的数组 。
fft.fftshift()将零频率成分移动到频率图像的中心位置
返回值=numpy.fft.fftshift(原始频谱)
将复数数组的值调整到**[0,255]的灰度空间**内
像素新值=20*np.log (np.abs(频谱值))
示例:Numpy实现傅里叶变换
import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread ('lena.png',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()
需要注意的是,如果在傅里叶变换过程中使用了numpy.fft.fftshift ()函数移动零频率分量,那么在逆傅里叶变换过程中,需要先使用numpy.fft.ifftshift ()函数将零频率分量移到原来的位置,再进行逆傅里叶变换。
逆变换:返回值也是一个复数数组
返回值=numpy.fft.ifft2(频域数据)
将复数调整到[0,255]灰度空间
iimg=np.abs(逆傅里叶变换结果)
示例:傅里叶逆变换
import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread ('boat.png',0)
f=np.fft.fft2 (img) #傅里叶变换
fshift=np.fft.fftshift (f) #移到中间
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 ()
低频信号对应图像内变化缓慢的灰度分量,低通滤波器允许低频信号通过,图像变模糊。
高频信号对应图像内变化越来越快的灰度分量,高通滤波器允许高频信号通过,增强图像的尖锐细节,导致图像对比度降低。
示例:高通滤波
import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread ( 'boat.png',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 #上下左右各30个像素大小的区域,将这个区域内的像素值置零
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()
返回结果=cv2.dft(原始图像,转换标识)
原始图像: 要转成np.float32格式
转换标识: 值为cv2.DFT_COMPLEX_OUTPUT,输出复数阵列
返回值是双通道,第1个通道是结果的实数部分,第2个通道是结果的虚数部分。
零频率移动到中间:
dftShift=np.fft.fftshift(dft)
计算频谱的幅度:
返回值=cv2.magnitude (参数1,参数2)
参数1:浮点型x坐标值,实部
参数2:浮点型y坐标值,虚部
返回结果=cv2.idft(原始数据)
恢复零频率到原来位置:
dftShift=np.fft.ifftshift(dft)
计算频谱的幅度:
返回值=cv2.magnitude (参数1,参数2)
示例:实现低通滤波
构造低通滤波器
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 #掩模中间为白色
代码:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread ('lena.png',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)
ilmg=cv2.idft (ishift) #傅里叶反变换
ilmg=cv2.magnitude (ilmg[:,:,0],ilmg[:,:,1]) #计算幅度
plt.subplot (121) ,plt.imshow (img,cmap='gray')
plt.title ('original') ,plt.axis ( 'off')
plt.subplot (122) ,plt.imshow (ilmg,cmap='gray')
plt.title ('inverse') ,plt.axis ( 'off')
plt.show()
右边为低通滤波后的图像,边缘信息被削弱,变模糊了。