文章目录
- 🧡🧡实验流程🧡🧡
- 1. 傅立叶变换
- 1.a 绘制一个二值图像矩阵,并将其傅立叶函数可视化。
- 1.b 利用傅立叶变换分析两幅图像的相关性,定位图像特征。读入图像‘text.png',抽取其中的字母‘a’
- 2. 离散余弦变换(DCT)
- 2.a 使用dct2对图像‘autumn.tif’进行DCT变换
- 2.b 将上述DCT变换结果中绝对值小于10的系数舍弃,使用idct2重构图像并与原图像比较。
- 2.c 利用DCT变换进行图像压缩
- 3. 对(1)和(2)中经过FFT和DCT的图像进行反变换,试图保留不同维度的低频信息,将去掉的高频成分设置为0,显示保留不同维度的低频信息反变换后的图像,分析保留不同维度下反变换图像的质量区别
- 4.讨论不同的图像内容与FFT、DCT频谱之间的对应关系
- 🧡🧡全部代码🧡🧡
🧡🧡实验流程🧡🧡
1. 傅立叶变换
1.a 绘制一个二值图像矩阵,并将其傅立叶函数可视化。
1.b 利用傅立叶变换分析两幅图像的相关性,定位图像特征。读入图像‘text.png’,抽取其中的字母‘a’
两个函数的卷积的傅立叶变换等于两个函数的傅立叶变换的乘积,与快速傅立叶变换一
起,可以快速计算函数的卷积,进而用于对某些模板对应的特征进行定位:
fft(f1f2)=fft(f1)x fft(f2)
f1f2=ifft(fft(f1)x fft(f2))
2. 离散余弦变换(DCT)
2.a 使用dct2对图像‘autumn.tif’进行DCT变换
2.b 将上述DCT变换结果中绝对值小于10的系数舍弃,使用idct2重构图像并与原图像比较。
2.c 利用DCT变换进行图像压缩
3. 对(1)和(2)中经过FFT和DCT的图像进行反变换,试图保留不同维度的低频信息,将去掉的高频成分设置为0,显示保留不同维度的低频信息反变换后的图像,分析保留不同维度下反变换图像的质量区别
对(1)中的图,逐步将高频部分(中心化后,中心是低频点,向外扩展是高频点,这里取正方形最外围四条边的高频点为0,并逐渐向内缩)
离散余弦变换的频谱图中,低频主要集中于左上角,高频集中于右下角。随着高频区域逐渐缩小(黑色),图像逐渐变得清晰。
4.讨论不同的图像内容与FFT、DCT频谱之间的对应关系
频谱中的一个点,不是对应图像的一个点,而是一种对于图像的全局信息,反映的是原图像中具有该灰度变化快慢规律的图像区域(可能不止一个)及其灰度峰值(亮暗)信息。
图像频谱图上的高频部分表示原图像上灰度发生急剧变化的区域,意味着该区域可能出现了边缘、轮廓、细节或噪声信息;低频部分则表示原图像上灰度基本不变或变化很小的区域,代表图片中大片图像区域。
在FFT的二维频谱图中,经过中心化移动后,最中间的点表示低频,向外频率逐渐增加,一般来说具有对称性,以中心点为圆心,做一个圆,这个圆上的每个点频率相同,而相位不一样。而图中的亮点可以理解为表示该点所在频率下对应的灰度变化曲线的幅值(灰度峰值)的大小。然后一般来说,原图像平移,对应的频谱图不会变化;而原图像旋转,则频谱图也会随之相同的角度进行旋转。
而在DCT的频谱图中,低频主要集中于左上角,高频集中于右下角。
🧡🧡全部代码🧡🧡
import cv2
import numpy as np
import matplotlib.pyplot as plt
"""
4-1-a 绘制一个二值图像矩阵,并将其傅立叶函数可视化
"""
# 创建一个30x30的零矩阵
f = np.zeros((30, 30))
# 在指定位置添加矩形
f[4:24, 12:18] = 1
# 显示原始图像
plt.imshow(f, 'gray', interpolation='nearest')
plt.title('Original Image')
plt.show()
# 计算二维FFT
F = np.fft.fft2(f)
F2 = np.log(np.abs(F)+1e-8)# 计算FFT的幅度谱,并取对数
plt.imshow(F2, cmap='jet') # 显示FFT的幅度谱
plt.title('FFT Magnitude Spectrum')
plt.colorbar()
plt.clim(-1, 5) # 设置颜色条范围为 -1 到 5
plt.show()
# 进行零填充至256x256
F = np.fft.fft2(f, (256, 256))
F2 = np.log(np.abs(F)+1e-8)# 计算FFT的幅度谱,并取对数
plt.imshow(F2, cmap='jet') # 显示零填充后的FFT幅度谱
plt.title('Zero-Padded FFT Magnitude Spectrum')
plt.colorbar()
plt.clim(-1, 5) # 设置颜色条范围为 -1 到 5
plt.show()
# 对FFT进行频率中心移动
F2 = np.fft.fftshift(F)
F2 = np.log(np.abs(F2)+1e-8)# 计算FFT的幅度谱,并取对数
plt.imshow(F2, cmap='jet') # 显示移动中心后的FFT幅度谱
plt.title('Shifted FFT Magnitude Spectrum')
plt.colorbar()
plt.clim(-1, 5) # 设置颜色条范围为 -1 到 5
plt.show()
"""
4-1-b 利用傅立叶变换分析两幅图像的相关性,定位图像特征。读入图像‘text.png',抽取其中的字母‘a’
"""
# 读取图像并转换为灰度图像
bw = cv2.imread('img/tes1_text.png', cv2.IMREAD_GRAYSCALE)
a = bw[31:45, 87:98] # 提取感兴趣区域
# 显示原始图像
plt.imshow(bw, cmap='gray')
plt.title('Original Image')
plt.show()
# 显示感兴趣区域
plt.imshow(a, cmap='gray')
plt.title('Region of Interest')
plt.show()
# 计算相关性
C = np.real(np.fft.ifft2(np.fft.fft2(bw) * np.fft.fft2(np.rot90(a, 2), bw.shape)))
# 显示相关性矩阵
plt.imshow(C, cmap='gray')
plt.title('Cross-correlation Matrix')
plt.colorbar()
plt.show()
# 使用阈值对相关性矩阵进行二值化并显示结果
thresh = np.max(C)
binary_image1 = C > thresh - 10
binary_image2 = C > thresh - 15
plt.imshow(binary_image1, cmap='gray')
plt.title('Binary Image (Threshold - 10)')
plt.show()
plt.imshow(binary_image2, cmap='gray')
plt.title('Binary Image (Threshold - 15)')
plt.show()
"""
4-2-a 离散余弦变换:使用dct2对图像‘autumn.tif’进行DCT变换
"""
from skimage import io, color
# 读取图像
RGB = io.imread('img/test1_autumn.tif')
plt.imshow(RGB)
plt.title('Original Image')
plt.show()
# 转换为灰度图像
I = color.rgb2gray(RGB)
plt.imshow(I, cmap='gray')
plt.title('Grayscale Image')
plt.show()
# 进行二维离散余弦变换(DCT)
J = np.fft.fft2(I)
plt.imshow(np.log(np.abs(J)), cmap='jet')
plt.colorbar()
plt.clim(-10, 10)
plt.title('DCT of Grayscale Image')
plt.show()
"""
4-2-b 将上述DCT变换结果中绝对值小于10的系数舍弃,使用idct2重构图像并与原图像比较。
"""
from skimage import io, color
from scipy.fftpack import dctn, idctn
# 读取图像
RGB = io.imread('img/test1_autumn.tif')
I = color.rgb2gray(RGB) # 转换为灰度图像
plt.imshow(I, cmap='gray')
plt.title('Original Gray Image')
plt.show()
# 进行二维离散余弦变换(DCT)
J = dctn(I, type=2)
# 进行反变换
K = idctn(J, type=2)
plt.imshow(K, cmap='gray')
plt.title('Reconstructed Image from DCT')
plt.show()
# 舍弃系数
threshold = 10
J[np.abs(J) < threshold] = 0
# 反变换舍弃系数后的结果
K2 = idctn(J, type=2)
plt.imshow(K2, cmap='gray')
plt.title('Reconstructed Image after Coefficient Thresholding')
plt.show()
"""
4-2-c 利用DCT变换进行图像压缩
"""
from scipy.fftpack import dct, idct
from skimage.io import imread, imshow
# 读取图像
I = imread('img/test1_cameraman.tif')
I = I.astype(float) / 255.0 # 将图像转换为双精度,范围从[0,255]转换为[0,1]
# 定义DCT变换矩阵
T = dct(np.eye(8), axis=0, norm='ortho')
# 对图像进行8x8块DCT变换
B = np.zeros_like(I)
for i in range(0, I.shape[0], 8):
for j in range(0, I.shape[1], 8):
B[i:i+8, j:j+8] = dct(dct(I[i:i+8, j:j+8], axis=0, norm='ortho'), axis=1, norm='ortho')
# 定义掩码
mask = np.array([[1, 1, 1, 1, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0],
[1, 1, 0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0]])
# 对每个块应用掩码
B2 = np.zeros_like(B)
for i in range(0, B.shape[0], 8):
for j in range(0, B.shape[1], 8):
B2[i:i+8, j:j+8] = B[i:i+8, j:j+8] * mask
# 对图像进行反DCT变换
I2 = np.zeros_like(I)
for i in range(0, I.shape[0], 8):
for j in range(0, I.shape[1], 8):
I2[i:i+8, j:j+8] = idct(idct(B2[i:i+8, j:j+8], axis=0, norm='ortho'), axis=1, norm='ortho')
# 显示原始图像和处理后的图像
plt.imshow(I, cmap='gray')
plt.title('Original Image')
plt.show()
plt.imshow(I2, cmap='gray')
plt.title('Processed Image')
plt.show()
"""
4-3 对(1)中经过FFT和DCT的图像进行反变换
"""
# 创建一个30x30的零矩阵
f = np.zeros((30, 30))
# 在指定位置添加矩形
f[4:24, 12:18] = 1
# 计算二维FFT
F = np.fft.fft2(f)
# 进行频率中心移动
F_shifted = np.fft.fftshift(F)
# 定义不同维度下保留的低频信息范围
dimensions = [0,5,10, 13]
# 显示保留不同维度下的低频信息反变换后的图像
for dim in dimensions:
# 将中心周围的高频部分设置为零
F2 = F_shifted.copy()
rows, cols = F2.shape
F2[0:30, 0:dim] = 0
F2[0:dim, 0:30] = 0
F2[30-dim:30, 0:30] = 0
F2[0:30, 30-dim:30] = 0
F2_copy=F2.copy()
# 显示频谱图
F2=np.log(np.abs(F2)+1e-8)
plt.imshow(F2,'gray')
plt.title(f"Spectrogram (Dimensions = {dim})")
plt.show()
# 进行逆FFT
f_filtered = np.fft.ifft2(np.fft.ifftshift(F2_copy)).real
# 显示反变换后的图像
plt.imshow(f_filtered, 'gray')
plt.title(f'Reconstructed Image (Dimensions = {dim})')
plt.colorbar()
plt.show()
"""
4-3 对(2)中经过FFT和DCT的图像进行反变换
"""
from skimage import io, color
RGB = io.imread('img/test1_autumn.tif')
I = color.rgb2gray(RGB) # 转换为灰度图像
J = np.fft.fft2(I) # 进行二维离散余弦变换(DCT)
# 设置要保留的低频信息的维度
dimensions_to_keep = [10, 30, 100] # 可以根据需要调整
reconstructed_images = []
spectrogram_images=[]
# 对每个维度进行反变换并保留低频信息
for dim in dimensions_to_keep:
# 将高频成分设置为0
J_reduced = J.copy()
J_reduced[dim:, :] = 0
J_reduced[:, dim:] = 0
J_reduced_copy=J_reduced.copy()
J_reduced=np.log(np.abs(J_reduced)+1e-8)
spectrogram_images.append(J_reduced)
# 进行逆离散余弦变换(IDCT)
I_reconstructed = np.fft.ifft2(J_reduced_copy).real
reconstructed_images.append(I_reconstructed)
# 显示不同维度下的频谱图
plt.figure(figsize=(15, 5))
for i, dim in enumerate(dimensions_to_keep):
plt.subplot(1, len(dimensions_to_keep), i + 1)
plt.imshow(spectrogram_images[i],cmap='gray')
plt.title(f"Spectrogram (Dimensions = {dim})")
plt.axis('off')
plt.show()
# 显示保留不同维度下反变换图像
plt.figure(figsize=(15, 5))
for i, dim in enumerate(dimensions_to_keep):
plt.subplot(1, len(dimensions_to_keep), i + 1)
plt.imshow(reconstructed_images[i], cmap='gray')
plt.title(f'Dimension {dim} Kept')
plt.axis('off')
plt.show()