6.2 Python图像处理之图像编码技术和标准-余弦变换编码
(6)图像编码技术和标准,包括预测编码(DPCM编码、余弦变换编码、小波变换编码)
1 算法原理
图像处理中常用的正交变换除了傅里叶变换外,还有其他一些有用的正交变换,其中离散余弦就是一种。离散余弦变换表示为 DCT( Discrete Cosine Transformation),常用于图像处理和图像识别等。
二维离散余弦变换正变换公式:
其中 f(x,y)是空间域二维向量之元素, x,y=0,1,2,…N-1;F(u,v)是变换系数阵列之元素。式中表示的阵列为 N×N。反变换公式:
符号意义同正变换式一样。求二维图像的离散余弦变换要进行以下步骤:
- 1获得图像的二维数据矩阵 f(x,y);
- 2求离散余弦变换的系数矩阵[A];
- 3求系数矩阵对应的转置矩阵[A]T;
- 4根据公式公式计算离散余弦变换;
利用DCT压缩图像数据,主要是根据图像信号在频率域的统计特性。在空间域看来,图像内容千差万别;但在频率域上,经过对大量图像的统计分析发现,图像经过DCT变换后,其频率系数的主要成分集中于比较小的范围,且主要位于低频部分。利用DCT变换揭示出这种规律后,可以再采取一些措施把频谱中能量较小的部分舍弃,尽量保留传输频谱中主要的频率分量,就能够达到图像数据压缩目的。
2 代码
运行代码说明
1.要改变代码中的图片地址(地址不能有中文)
最后一行代码,更改
put(path)
函数中的路径put(r'../image/image3.jpg')
2.注意最后的
plt.savefig('1.new.jpg')
是保存plt图像,如果不使用可以注释掉代码依赖包:
matplotlib 3.4.2 numpy 1.20.3 opencv-python 4.1.2.30
# pip安装 pip install matplotlib numpy opencv-python
import cv2
import numpy as np
import matplotlib.pyplot as plt
def put(path):
# 读取图片
img = cv2.imread(path)
b, g, r = cv2.split(img)
img2 = cv2.merge([r, g, b]) # 转rgb
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转灰度图
rows, cols = img.shape[:2] # img_h, img_w
if (rows % 2) != 0:
rows = rows + 1
if (cols % 2) != 0:
cols = cols + 1
img = cv2.resize(img, (int(cols), int(rows))) # 需要的输入格式是(宽img_w,高img_h),和之前的获取的img.shape相反
img1 = img.astype('float') # 将uint8转化为float类型
img_dct = cv2.dct(img1) # 进行离散余弦变换
img_dct_log = np.log(abs(img_dct)) # 进行log处理 方便用plt显示
# 在频域矩阵位置,对大于100,小于的行和列都置零(相当于低通滤波)后, 反变换后图像有点模糊, 但还能还原大致效果.这样进行压缩
for i in range(0, rows):
for j in range(0, cols):
if i > 100 or j > 100:
img_dct[i, j] = 0
img_dct_log[i, j] = 0
# cv2.imshow("Dct",img_dct) # 使用cv2可以显示dct频域图像
# cv2.waitKey(0)
img_recor = cv2.idct(img_dct) # 进行离散余弦反变换
# 结果显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.subplot(221)
plt.imshow(img2, cmap='gray') # cmap='gray' 和plt.cm.gray用法一样
plt.title('原始图像')
plt.axis('off')
plt.subplot(222)
plt.imshow(img, cmap='gray')
plt.title('灰度图像')
plt.axis('off')
plt.subplot(223)
plt.imshow(img_dct_log, cmap='gray')
plt.title('余弦变换log形式')
plt.axis('off')
plt.subplot(224)
plt.imshow(img_recor, plt.cm.gray)
plt.title('图像还原')
plt.axis('off')
# plt.savefig('2.new-img.jpg')
plt.show()
# 图像处理函数,要传入路径
put(r'../image/image3.jpg')