文章目录

离散余弦变换(DCT)、离散小波变换(DWT)和离散傅立叶变换(DFT)

离散余弦变换(DCT)

离散余弦变换(Discrete Cosine Transform,DCT)是图像频域变换的一种,它类似于离散傅里叶变换(DFT for Discrete Fourier Transform,DFT),离散余弦变换相当于一个长度大概是它两倍的离散傅里叶变换,但是离散余弦变换只使用实数。在傅里叶级数中,如果被展开的函数是实偶函数,那么在傅里叶级数中则只包含余弦项,再将其离散化,由此便可导出离散余弦变化。

高频系数(AC系数):一般保存的是图像的边界、纹理信息丰富
低频信息(DC系数)。主要是保存的图像中平坦区域信息。

变换后DCT系数能量主要集中在左上角,其余大部分系数接近于零,因此DCT具有适用于图像压缩的特性,用于对信号和图像(包括静止图像和运动图像)进行有损数据压缩。

Python 离散余弦变换(DCT)_信号处理


关于离散余弦变换理论:【点击查看】 演示示例:

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


# 整张图 DCT 变换
def whole_img_dct(img_f32):
img_dct = cv2.dct(img_f32) # 进行离散余弦变换
img_dct_log = np.log(abs(img_dct)) # 进行log处理
img_idct = cv2.idct(img_dct) # 进行离散余弦反变换
return img_dct_log, img_idct

# 分块图 DCT 变换
def block_img_dct(img_f32):
height,width = img_f32.shape[:2]
block_y = height // 8
block_x = width // 8
height_ = block_y * 8
width_ = block_x * 8
img_f32_cut = img_f32[:height_, :width_]
img_dct = np.zeros((height_, width_), dtype=np.float32)
new_img = img_dct.copy()
for h in range(block_y):
for w in range(block_x):
# 对图像块进行dct变换
img_block = img_f32_cut[8*h: 8*(h+1), 8*w: 8*(w+1)]
img_dct[8*h: 8*(h+1), 8*w: 8*(w+1)] = cv2.dct(img_block)

# 进行 idct 反变换
dct_block = img_dct[8*h: 8*(h+1), 8*w: 8*(w+1)]
img_block = cv2.idct(dct_block)
new_img[8*h: 8*(h+1), 8*w: 8*(w+1)] = img_block
img_dct_log2 = np.log(abs(img_dct))
return img_dct_log2, new_img


if __name__ == '__main__':
img_u8 = cv2.imread("len_std.jpg", 0)
img_f32 = img_u8.astype(np.float) # 数据类型转换 转换为浮点型
img_dct_log, img_idct = whole_img_dct(img_f32)
img_dct_log2, new_img = block_img_dct(img_f32.copy())

plt.figure(6, figsize=(12, 8))
plt.subplot(231)
plt.imshow(img_u8, 'gray')
plt.title('original image'), plt.xticks([]), plt.yticks([])
plt.subplot(232)
plt.imshow(img_dct_log)
plt.title('DCT'), plt.xticks([]), plt.yticks([])
plt.subplot(233)
plt.imshow(img_idct, 'gray')
plt.title('IDCT'), plt.xticks([]), plt.yticks([])
plt.subplot(234)
plt.imshow(img_dct_log2)
plt.title('block_DCT'), plt.xticks([]), plt.yticks([])
plt.subplot(235)
plt.imshow(new_img, 'gray')
plt.title('block_IDCT'), plt.xticks([]), plt.yticks([])
plt.show()

Python 离散余弦变换(DCT)_傅里叶级数_02