图像变换
傅里叶变换
首先,我们需要理解什么是频率和幅度。在信号处理中,频率表示一个周期性信号中重复出现的次数,而幅度表示信号的强度或大小。例如,在一张图像中,频率可以表示不同的纹理模式、边缘方向和颜色变化,而幅度则表示这些模式或变化的强度或大小。
在图像处理和计算机视觉中,我们经常需要分析和处理图像中的这些频率和幅度信息。而傅里叶变换是一种将图像从空间域转换到频率域的方法,它能够把一个图像分解成一系列的正弦和余弦函数,这些函数在频率域中表示图像中的不同频率成分和幅度。
具体来说,傅里叶变换可以将一个图像表示为频率的总和。对于每个频率,可以计算出它在图像中的幅度和相位信息。图像中的高频率分量表示边缘、纹理等细节信息,而低频率分量表示颜色和光照等整体信息。因此,在频域中,我们可以通过选择特定频率的成分来对图像进行各种处理,如去除噪声、增强细节、边缘检测、特征提取等。
具体应用中,可以使用频率域滤波器对图像进行处理。例如,低通滤波器可以保留图像中的低频分量,从而平滑图像并去除噪声;高通滤波器则可以保留图像中的高频分量,从而强调图像的细节和边缘信息。还可以使用带通或带阻滤波器选择特定的频率范围进行处理,以便提取图像中的特定特征。
总之,频域分析和傅里叶变换在图像处理和计算机视觉中非常重要,它们为我们提供了一种强大的工具来分析、处理和提取图像中的信息
通过傅里叶变换,我们可以计算出图像中的低频和高频部分,从而对图像进行滤波处理。在图像处理中,傅里叶变换常用于图像去噪、边缘检测、特征提取等任务中。在计算机视觉中,傅里叶变换可用于图像拼接、图像配准等应用中。
具体而言,OpenCV提供了以下几种傅里叶变换的实现:
cv2.dft: 用于计算离散傅里叶变换(DFT)。
cv2.idft: 用于计算离散傅里叶反变换(IDFT)。
cv2.magnitude: 用于计算复平面中每个点的幅值。
cv2.phase: 用于计算复平面中每个点的相位角。
通过这些函数,我们可以在OpenCV中方便地进行傅里叶变换和频域分析。
Numpy中的傅里叶变换
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('voice.png',0)
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
#magnitude_spectrum 是经过两个步骤的处理之后生成的幅度谱图像,其中第一个步骤是对 fshift 中的每个值计算绝对值,即得到振幅,
#第二个步骤是对这些振幅进行对数放大,以便更好地显示振幅的变化。因此,magnitude_spectrum = 20*np.log(np.abs(fshift))
#表示 magnitude_spectrum 的每个元素是 fshift 对应元素的振幅值经过对数放大之后的结果。
#np.log() 函数通常与傅里叶变换相关的幅度谱一起使用。由于幅度谱中的值通常具有很大的范围,而且变化较小的值对于图像细节的理解是
#至关重要的,因此对数缩放可以使幅度谱更容易解释和可视化。
#下面这张图片是nishimiya的低频分量和高频分量的图片
#中心特别亮就说明低频分量多。
magnitude_spectrum = 20*np.log(np.abs(fshift))
plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(magnitude_spectrum, cmap = 'gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.show()
#如果说高频分量说明图像之间的差别很大,我们可以认为是边界和噪声
#那么先把低频分量弄没就可以得到边界和噪声了
#把低频分量弄没
rows, cols = img.shape[:2]
crow,ccol = rows/2 , cols/2
fshift[int(crow-30):int(crow+30), int(ccol-30):int(ccol+30)] = 0
#现在把原本傅里叶转换的图片 逆运算到左上角
f_ishift = np.fft.ifftshift(fshift)
#进行傅里叶逆运算
img_back = np.fft.ifft2(f_ishift)
# 取绝对值
img_back = np.abs(img_back)
cv2.imshow("img_back",img_back)
print(img_back.shape)
plt.subplot(131),plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(132),plt.imshow(img_back, cmap = 'gray')
plt.title('Image after HPF'), plt.xticks([]), plt.yticks([])
plt.subplot(133),plt.imshow(img_back)
plt.title('Result in JET'), plt.xticks([]), plt.yticks([])
plt.show()
由此看出只剩边界了
OpenCV 中的傅里叶变换
cv2.dft()是用于计算离散傅里叶变换
cv2.idft()是用于计算离散傅里叶反变换
先说明cv2.dft()
cv2.dft(src, dst=None, flags=None, nonzeroRows=None)
src:输入图像,可以是单通道或多通道图像,图像必须是浮点型(float)或复数型(complex)。
dst:输出数组,可以是与输入图像大小相同的数组或更大的数组,必须是复数型。
flags:傅里叶变换的标志,可以为下列常量之一:cv2.DFT_COMPLEX_OUTPUT(输出是复数类型)、cv2.DFT_REAL_OUTPUT(输出是实数类型)或 cv2.DFT_SCALE(进行缩放)等。默认为 cv2.DFT_COMPLEX_OUTPUT。
讲解下个常量的效果:
频域滤波:将图像转换到频率域,进行滤波操作,最后将结果转换回空间域。此时常用的标志为cv2.DFT_COMPLEX_OUTPUT和cv2.DFT_INVERSE。
图像恢复:根据已知的频率信息,从受损的图像中恢复出原始图像。此时常用的标志为cv2.DFT_COMPLEX_OUTPUT和cv2.DFT_INVERSE。
图像压缩:将图像转换到频率域,将频率较低的系数保留下来,将频率较高的系数丢弃。此时常用的标志为cv2.DFT_COMPLEX_OUTPUT和cv2.DFT_INVERSE。
特征提取:将图像转换到频率域,提取其中的特征信息,例如图像的纹理、边缘等。此时常用的标志为cv2.DFT_COMPLEX_OUTPUT和cv2.DFT_REAL_OUTPUT。
总之,flags参数是cv2.dft()函数非常重要的一个参数,可以控制离散傅里叶变换的输出类型和缩放方式,从而实现不同的图像处理和计算机视觉任务。
nonzeroRows:如果输入图像是二维的,则指定需要变换的行数。对于一维的情况,此参数应为 None。
返回值:
dst:傅里叶变换的结果。
cv2.dft()函数的返回值是一个复数数组,其中的实部和虚部分别表示变换后的图像在频率域中的幅度和相位。可以使用np.abs()函数获取幅度,使用np.angle()函数获取相位。