数字图像处理与深度学习-实验4(python)

  1. 一、实验目的和要求
  2. 理解傅里叶变换的思想与功能。
  3. 掌握傅里叶变换的Python实现方法:包括OpenCV工具包相关函数和NumPy工具包相关函数。
  4. 理解并掌握图像频域滤波的用途与实现方法。

二、实验内容和步骤

1. 编程分别使用OpenCV和NumPy工具包中的函数对图像peppers.bmp进行傅里叶变换,要求显示原图像、变换后图像的幅值谱、变换后图像的对数变换幅值谱、变换后图像的相位谱,以及重构后的图像。

2. 图像alphabet.jpg分别使用截止频率15,30,80,220进行理想低通滤波,观察不同的滤波效果。

3. 图像alphabet.jpg分别使用截止频率15,30,80,220进行高斯低通滤波,观察不同的滤波效果。

4. 图像lena.jpg分别使用截止频率15,30,80,220,阶数分别取2和5进行巴特沃斯高通滤波,观察不同的滤波效果。


1. 编程分别使用OpenCV和NumPy工具包中的函数对图像peppers.bmp进行傅里叶变换,要求显示原图像、变换后图像的幅值谱、变换后图像的对数变换幅值谱、变换后图像的相位谱,以及重构后的图像。

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

plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负

#Numpy函数实现傅里叶变换
img = cv2.imread(r"C:\Users\Administrator\Desktop\photo\peppers.bmp",0)#读取bmp文件
dft = np.fft.fft2(img)#对图像进行二维FFT
magnitude0= np.abs(dft)#计算幅值谱
magnitude1= 20*np.log(1+magnitude0)# 可视化幅值谱(取对数并显示)
phase_angle0=np.angle(dft)
print(phase_angle0)
img_back=np.fft.ifft2(dft)
img_back1 = np.abs(img_back)

plt.figure(figsize=(10,6))
plt.subplot(151),plt.imshow(img, cmap = 'gray')
plt.title('原图像'), plt.axis('off')

plt.subplot(152),plt.imshow(magnitude0, cmap = 'hsv')
plt.title('幅值谱'), plt.axis('off')

plt.subplot(153),plt.imshow(magnitude1, cmap = 'hsv')
plt.title('对数变换后的幅值谱'), plt.axis('off')

plt.subplot(154),plt.imshow(phase_angle0, cmap = 'hsv')
plt.title('相位谱'), plt.axis('off')

plt.subplot(155),plt.imshow(img_back1,cmap = 'hsv')
plt.title('重构图像'),plt.axis('off')

plt.show()
plt.savefig(r"C:\Users\Administrator\Desktop\photo\sys4-1-2.jpg")
  • dft = np.fft.fft2(img):对输入的二维数组(通常是一个图像)img进行二维FFT,并将结果存储在dft中。
  • img_back=np.fft.ifft2(dft):dft 是原始图像经过二维快速傅里叶变换(FFT)得到的结果。为了从 dft 重构(或反变换)回原始图像,需要执行逆FFT(Inverse FFT)。在NumPy中,可以使用 np.fft.ifft2 函数来实现这一点。
  • img_back1 = np.abs(img_back):img_back 是通过逆FFT得到的复数数组。由于傅里叶变换涉及复数运算,因此逆FFT的结果也是复数。然而,对于图像来说,我们通常只对幅度感兴趣,因此通过取复数的绝对值(np.abs(img_back))得到 img_back1,代表了重构图像的幅度信息。请注意,由于在进行FFT和IFFT时可能会引入一些数值误差,因此重构的图像可能不会与原始图像完全相同,但它们应该非常接近。
  • phase_angle0=np.angle(dft):np.angle(dft) 函数用于计算复数数组 dft 中每个元素的相位角(phase angle)。当 dft 是通过二维快速傅里叶变换(FFT)得到的结果时,np.angle(dft) 返回的是每个频率分量的相位信息。

运行结果:

2. 图像alphabet.jpg分别使用截止频率15,30,80,220进行理想低通滤波,观察不同的滤波效果。

  • import cv2
    import numpy as np
    from math import *
    import random
    from matplotlib import pyplot as plt
    
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
    plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负
    
    
    img = cv2.imread(r"C:\Users\Administrator\Desktop\photo\alphabet.jpg", 0)
    f = np.fft.fft2(img)#对图像进行二维FFT
    fshift = np.fft.fftshift(f) #实现傅里叶频谱的低频移中
    magnitude_spectrum0 = 20 * np.log(1 + np.abs(fshift))
    plt.figure(figsize=(20, 8))
    # 进行理想低通滤波
    dd=[15,30,80,220] #截止频率
    for w in range(4):
        r =dd[w] # 截止频率的设置
        [m, n] = fshift.shape
        H = np.zeros((m, n), dtype=np.complex_)#初始化一个与fshift相同大小的复数矩阵H,用于存储滤波器的值。
        # 接下来的双重循环创建了一个理想低通滤波器H。
        # 如果某个频率分量(由i和j索引表示)的距离小于截止频率r,
        # 则对应的H值设置为1,否则为0。
        for i in range(m):
            for j in range(n):
                d = sqrt((i - m / 2) * (i - m / 2) + (j - n / 2) * (j - n / 2))
                if d < r:
                    H[i, j] = 1
        G = H * fshift#将滤波器H应用于频谱fshift,得到滤波后的频谱。
        magnitude_spectrum1 = 20 * np.log(1 + np.abs(G))  # 理想低通滤波后的幅值谱
        f1 = np.fft.ifftshift(G)
        img1 = abs(np.fft.ifft2(f1))  # 重构图像
    
        plt.subplot(2,4,w+1), plt.imshow(magnitude_spectrum1, cmap='hsv')  # 显示滤波后幅值谱
        plt.title('截止频率'+str(dd[w])+'ILPF滤波后幅值谱'), plt.axis("off")
        
        plt.subplot(2,4,w+5), plt.imshow(img1, cmap='hsv')  # 显示重构图像
        plt.title('截止频率'+str(dd[w])+'ILPF滤波后重构图像'), plt.axis("off")
    plt.show()
    plt.savefig(r"C:\Users\Administrator\Desktop\photo\sys4-2.jpg")
  • fshift = np.fft.fftshift(f) :
  1. 在NumPy中,np.fft.fftshift函数用于将零频率分量(DC分量)移动到频谱的中心。在未经移动的FFT结果中,零频率分量通常位于频谱的第一个位置,而在使用fftshift之后,它会移动到频谱的中间位置。这对于许多信号和图像处理任务来说是非常有用的,因为它允许我们更容易地分析和可视化频谱。
  2. 在图像处理中,通常希望低频(接近DC)分量位于频谱的中心,因为低频分量通常对应于图像的整体亮度或颜色,而高频分量对应于图像的细节和边缘。通过将低频分量移动到频谱中心,我们可以更容易地观察到这些特征。
  • magnitude_spectrum0 = 20 * np.log(1 + np.abs(fshift)):

        这里做了几件事:

  1. np.abs(fshift):计算傅里叶变换结果 fshift 的绝对值,这给出了每个频率分量的幅值。
  2. 1 + np.abs(fshift):在取对数之前,加1是为了避免对0取对数,因为对0取对数在数学上是没有定义的。这样做可以确保即使幅值为0,计算也不会出错。
  3. np.log(1 + np.abs(fshift)):取对数,通常是自然对数(np.log 默认计算的是自然对数,即以 e 为底的对数)。对数变换将幅值谱的范围压缩到一个更易于可视化的区间。
  4. 20 * ...:这是一个常见的缩放因子,用于将对数变换后的结果调整到一个合适的显示范围。这个因子是基于经验选择的,以便在图像显示时能够清楚地看到高频和低频成分

最终,magnitude_spectrum0 将包含对数变换后的幅值谱,它更适合于可视化,因为高频和低频成分在图像上都会有一个合理的亮度表示,而不是被高动态范围所掩盖。

运行结果:

3. 图像alphabet.jpg分别使用截止频率15,30,80,220进行高斯低通滤波,观察不同的滤波效果。

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负

img = cv.imread(r"C:\Users\Administrator\Desktop\photo\alphabet.jpg", 0)
f = np.fft.fft2(img)
fshift0 = np.fft.fftshift(f)

dd = [15, 30, 80, 220]

rows, cols = img.shape
crow, ccol = rows // 2, cols // 2
plt.figure(figsize=(20, 8))
#以下这段循环代码的主要目的是对给定的截止频率列表dd中的每一个值,
# 执行二维高通滤波,并显示滤波后的幅值谱和重构的图像。
for w in range(4):
    d0 = dd[w] ** 2
    H = np.zeros((rows, cols))
    for u in range(rows):
        for v in range(cols):
            d = (u - crow) ** 2 + (v - ccol) ** 2#d是像素到图像中心的距离的平方
            H[u, v] = np.exp(-d / (2 * d0))
    fshift = fshift0 * H#对原始频域数据fshift0应用高通滤波器H。
    f_ishift = np.fft.ifftshift(fshift)#将滤波后的频域数据fshift进行逆移位,以准备进行逆傅里叶变换。
    temp = np.fft.ifft2(f_ishift)#对逆移位后的频域数据进行二维逆傅里叶变换,得到空间域的图像。
    img_back= np.abs(temp)#取逆傅里叶变换结果的绝对值,得到重构的图像。

    plt.subplot(2,4,w+1), plt.imshow(20 * np.log(1 + np.abs(fshift)), cmap='hsv')
    plt.title('截止频率'+str(dd[w])+'GLPF滤波后幅值谱'), plt.axis("off")

    plt.subplot(2,4,w+5), plt.imshow(img_back, cmap='hsv')
    plt.title('截止频率'+str(dd[w])+'GLPF滤波后重构图像'), plt.axis("off")

plt.show()
plt.savefig(r"C:\Users\Administrator\Desktop\photo\sys4-3.jpg")
  • H[u, v] = np.exp(-d / (2 * d0)):

        这个表达式可以用于计算一个二维高斯核(或者称为高斯滤波器),该核可以用于图像处理中的平滑或模糊操作。在这种情况下,u 和 v 通常表示图像中的像素坐标,而 d 可以是像素之间的某种距离度量(例如欧几里得距离)。d0 则控制了高斯核的宽度或平滑程度。

运行结果:

4. 图像lena.jpg分别使用截止频率15,30,80,220,阶数分别取2和5进行巴特沃斯高通滤波,观察不同的滤波效果。

import cv2 as cv
import numpy as np
import math
from matplotlib import pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负

img = cv.imread(r"C:\Users\Administrator\Desktop\photo\lena.jpg", 0)
f = np.fft.fft2(img)
fshift0 = np.fft.fftshift(f)


dd = [15, 30, 80, 220]

rows, cols = img.shape
crow, ccol = rows // 2, cols // 2
plt.figure(figsize=(20, 8))
for w in range(4):
    d0 = dd[w] ** 2
    H = np.zeros((rows, cols))
    for u in range(rows):
        for v in range(cols):
            d = (u - crow) ** 2 + (v - ccol) ** 2
            H[u, v] =1.0/(1.0+(d0/(d+0.01))**5)
    fshift = fshift0 * H
    f_ishift = np.fft.ifftshift(fshift)
    temp = np.fft.ifft2(f_ishift)
    img_back= np.abs(temp)

    plt.subplot(2,4,w+1), plt.imshow(20 * np.log(1 + np.abs(fshift)), cmap='hsv')
    plt.title('截止频率'+str(dd[w])+'BHPF滤波后幅值谱'), plt.axis("off")
    plt.subplot(2,4,w+5), plt.imshow(img_back, cmap='hsv')
    plt.title('截止频率'+str(dd[w])+'BHPF滤波后重构图像'), plt.axis("off")

plt.show()
plt.savefig(r"C:\Users\Administrator\Desktop\photo\sys4-4.jpg")
  • H[u, v] =1.0/(1.0+(d0/(d+0.01))**5)

这个表达式可以看作是一个平滑过渡函数或者称为窗口函数,用于控制某种影响的范围或强度,根据 d 和 d0 的关系来调整 H[u, v] 的值。具体来说:

  • 当 d 远大于 d0 时,d0 / (d + 0.01) 将接近于 0,因此 H[u, v] 将接近于 1.0。
  • 当 d 远小于 d0 时,d0 / (d + 0.01) 将非常大,因此 H[u, v] 将接近于 0.0。
  • 当 d 接近于 d0 时,H[u, v] 的值将在 0.0 和 1.0 之间变化,具体取决于 d 和 d0 的具体数值。

       这里的 +0.01 是一个小的常数,用于防止分母为 0 的情况,确保表达式在所有情况下都是定义良好的。

       这个函数可以用于多种应用,例如图像处理中的权重分配、机器学习中的核函数、空间插值等。根据上下文,u 和 v 可以代表像素坐标、数据点坐标或其他类型的空间坐标。d 可以是这些坐标之间的距离或相似度度量,而 d0 是一个控制函数形状的参数。

       例如,在图像处理中,H[u, v] 可以用于定义一个平滑的权重函数,用于在像素 u, v 周围进行加权平均。这样,距离中心较远的像素将有较小的权重,而距离较近的像素将有较大的权重。这种权重函数可以用于实现图像模糊、特征提取或其他类型的空间滤波操作。

运行结果:

三、补充知识点

  • 相位角(Phase Angle)是指复数在复平面上与正实轴之间的角度,它描述了信号在不同频率上的相位延迟。
  • 相位谱(Phase Spectrum)则是频率域中每个频率分量的相位角的表示。在信号处理中,相位谱与幅值谱(Magnitude Spectrum)一样重要,因为它们共同决定了信号在频率域中的完整表示。
  • 快速傅里叶变换(Fast Fourier Transform,FFT)是离散傅里叶变换(DFT)的高效算法,用于计算DFT及其逆变换。FFT算法通过将DFT分解为若干个小DFT的方式,显著降低了计算复杂度,使得大规模数据处理变得可行。FFT在计算机科学、数字信号处理、图像处理、通信等领域有广泛应用。
  • cmap全称为"colormap parameter",中文为颜色映射参数,用于定义颜色映射的方式。
  • 使用HSV色彩映射来显示相位谱,因为相位通常表示为一个角度,HSV色彩空间中的色调(Hue)可以很好地表示这种周期性变化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值