开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第27天,点击查看活动详情
前言
离散余弦变换 (Discrete Cosine Transform, DCT) 以不同频率振幅的余弦函数组合表示图像,而离散傅里叶变换 (Discrete Fourier Transform, DFT) 则以复杂指数的形式使用正弦和余弦函数。以下方程式显示了如何计算 图像 的 DCT 的第 项(系数):
其中 ,对于块大小为 的 DCT, 。
利用离散余弦变换 (DCT) 执行图像压缩
DCT 算法用途广泛,通常用于实现图像 JPEG 压缩,在本节中,我们将学习如何使用 Python 执行图像重建操作。
(1) 首先,导入所需库,关键在于从 scipy.fftpack 模块导入所需的函数 dct() 和 idct():
import scipy.fftpack as fp
from skimage.io import imread
from skimage.color import rgb2gray, gray2rgb
from skimage.draw import rectangle_perimeter
import numpy as np
import matplotlib.pylab as plt
from mpl_toolkits.mplot3d import Axes3D # noqa: F401 unused import
from mpl_toolkits.axes_grid1 import make_axes_locatable
from matplotlib.ticker import LinearLocator, FormatStrFormatter
from scipy.fftpack import dct, idct
(2) 使用 scipy.fftpack 的 dct() 和 idct() 函数分别定义函数 dct2() 和 idct2() 以实现 2D-DCT 和 IDCT。其中,函数 dct() 的调用方式如下,而 idct() 函数的调用方式类似:
scipy.fftpack.dct(x, type=2, n=None, axis=-1, norm=None, overwrite_x=False)
该返回任意类型序列x的离散余弦变换。
根据在前言中介绍的 DCT 方程,并使用通过使用参数 norm ='ortho' 应用归一化:
def dct2(a):
return dct(dct(a, axis=0, norm='ortho'), axis=1, norm='ortho')
def idct2(a):
return idct(idct(a, axis=0, norm='ortho'), axis=1, norm='ortho')
(3) 读取输入 RGB 图像并将其转换为灰度。计算图像的 2D-DCT,然后利用 IDCT 使用前面定义的函数重建图像:
im = rgb2gray(imread('1.png'))
imF = dct2(im)
im1 = idct2(imF)
(4) 检查重建的图像,观察其与原始图像之间的差别,查看其是否与原始图像相同,在这里使用函数 np.callclose() 评估图像间的差距:
print(np.allclose(im, im1))
(5) 使用 matplotlib.pyplot 绘制原始图像和重建图像,得到结果如下所示:
plt.figure(figsize=(10,5))
plt.gray()
plt.subplot(121), plt.imshow(im), plt.axis('off'), plt.title('original image', size=10)
plt.subplot(122), plt.imshow(im1), plt.axis('off'), plt.title('reconstructed image (DCT+IDCT)', size=10)
plt.tight_layout()
plt.show()
在以上结果图像中可以看到,重建后的图像与原始图像在视觉效果上类似,证明了可以使用 DCT 进行图像压缩,使用 IDCT 对压缩后的图像进行重建。