Skip to content

MATLAB - 二维离散余弦逆变换

MATLAB - 二维逆离散余弦变换 (IDCT)

Section titled “MATLAB - 二维逆离散余弦变换 (IDCT)”

二维逆离散余弦变换(2-D Inverse Discrete Cosine Transform,简称 IDCT)是数字信号和图像处理中的一项基本操作。它逆转了二维离散余弦变换(2-D Discrete Cosine Transform,简称 DCT)的过程,将图像从频域表示转换回空间域(即像素)。

其最著名的应用是在 JPEG 图像压缩标准中。在计算并量化(quantized,一种丢弃不重要频率信息以节省空间的步骤)图像的 DCT 系数后,解码器使用 IDCT 来重建图像。MATLAB 中实现此功能的函数是 idct2。

在 MATLAB 中,idct2 函数计算矩阵的二维逆离散余弦变换。它接受一个 DCT 系数矩阵作为输入,并返回空间域中的重建矩阵。

B = idct2(A)
B = idct2(A, m, n)
B = idct2(A, [m n])
  • B = idct2(A):计算矩阵 A 的 IDCT。输出矩阵 B 将与 A 具有相同的维度。
  • B = idct2(A, m, n) 或 B = idct2(A, [m n]):计算 IDCT,但将输出矩阵 B 的大小调整为 m 行 n 列。如果 A 大于 m 行 n 列,则会裁剪;如果 A 小于,则在变换前用零填充。这在已知原始尺寸的重建场景中很有用。

让我们通过一些实际示例来探讨 idct2 的用法。

实际应用:通过频域进行图像滤波

Section titled “实际应用:通过频域进行图像滤波”

DCT/IDCT 的一个常见用途是在频域中执行滤波。通过操作 DCT 系数,我们可以改变图像的特性。在此示例中,我们将通过将高频系数清零来创建一个简单的低通滤波器,这有效地模糊了图像。

%% 现代 MATLAB 最佳实践示例:图像滤波
% --- 1. 设置与图像加载 ---
% 使用内置的 MATLAB 图像以保证可复现性。
originalImage = imread('cameraman.tif');
% 最佳实践:确保图像为灰度图以便进行 2D DCT。
% 'cameraman.tif' 已经是灰度图,但此检查更健壮。
if size(originalImage, 3) > 1
grayImage = rgb2gray(originalImage);
else
grayImage = originalImage;
end
% --- 2. 前向 DCT ---
% 最佳实践:在执行傅里叶族变换之前,将图像转换为浮点类型(例如 double),以确保数值精度。
doubleImage = double(grayImage);
dctCoeffs = dct2(doubleImage);
% --- 3. 频域滤波 ---
% DCT 矩阵的左上角包含低频分量。
% 我们定义一个截止频率,只保留最低的 30x30 频率。
cutoff = 30;
dctCoeffsFiltered = dctCoeffs;
% 将高频分量清零。
dctCoeffsFiltered(cutoff+1:end, :) = 0;
dctCoeffsFiltered(:, cutoff+1:end) = 0;
% --- 4. 逆 DCT ---
% 使用逆 DCT 重建图像。
reconstructedImage = idct2(dctCoeffsFiltered);
% --- 5. 显示结果 ---
% 最佳实践:转换回 uint8 以正确显示图像。
figure;
subplot(1, 2, 1);
imshow(grayImage);
title('原始图像');
subplot(1, 2, 2);
imshow(uint8(reconstructedImage));
title('滤波后的图像(低通)');
  • 加载与准备:我们加载图像并确保它是灰度图。然后将其转换为 double 类型,以防止 DCT 计算(涉及浮点运算)期间的数据丢失或裁剪。
  • 变换:dct2 将图像转换为其频率表示。dctCoeffs 中的系数代表图像中不同频率模式的幅度。
  • 滤波:我们将所有高频系数设置为零。高频对应于锐利的过渡,如边缘和噪声。低频代表平滑的颜色渐变。通过去除高频,我们实际上是在去除细节。
  • 逆变换:idct2 接收修改后的系数,并将它们转换回空间图像。
  • 显示:最终图像在显示前转换回 uint8,这是灰度图像的标准 8 位整数格式。结果是原始图像的模糊版本,因为锐利的细节已被过滤掉。

将出现一个图像窗口,其中包含两幅图像。左侧将显示原始的、清晰的“摄影师”图像。右侧的“滤波图像”将显得明显更平滑、细节更少,这展示了低通滤波器的效果。

  • 忘记数据类型转换:对 uint8 图像执行 dct2 可能会导致不准确的结果,因为变换运算可能超出 0-255 的范围。始终先转换为 double 或 single。
  • 不正确的显示范围:如果您对 idct2 的 double 结果调用 imshow,它很可能会显示为白色矩形。这是因为 imshow 期望 double 值在 [0, 1] 范围内。重建后的图像值将在 [0, 255] 范围内。正确的方法是在显示前使用 uint8(reconstructedImage) 转换回 uint8。
  • 不正确的裁剪/填充:当使用 idct2(A, m, n) 时,请注意用零填充可能会在重建图像的边缘引入伪影,而裁剪则会丢失信息。