压缩编码之变换的选择之离散余弦变换(DCT)和离散傅立叶变换(DFT)——数字图像处理

原理

变换的选择是一个关键的考量因素,它决定了数据是如何被压缩的。选择变换时考虑以下几个重要原则:

数据去关联性:变换的目的之一是减少数据中的相关性。例如,在图像压缩中,像素间往往高度相关。通过适当的变换,如离散余弦变换(DCT),可以将这些相关性转化为更加独立的形式,从而提高压缩效率。

能量集中:理想的变换应该能将数据的能量(或信息)集中到尽可能少的系数中。这样,通过仅编码这些主要系数,就可以在保留大部分信息的同时实现有效的压缩。

可逆性:对于无损压缩,变换必须是可逆的,这意味着从压缩数据中可以完全恢复原始数据。对于有损压缩,这一要求可以放宽,允许在接受某种程度信息损失的前提下获得更高的压缩比。

计算效率:变换过程应该足够高效,以便于在实际应用中快速处理大量数据。这通常意味着变换算法需要能够被有效地实现,且计算复杂度可接受。

适应性:在某些情况下,变换应该具有适应性,能够根据数据的特性进行调整。例如,在音频和视频压缩中,根据内容的不同,可能需要使用不同的变换策略。

编码后的数据特性:变换应该产生便于编码的数据。例如,高效的压缩算法通常会生成具有高峰值和长尾分布的数据,这使得熵编码等技术更加有效。
变换的选择取决于特定应用的需求和特性。

以下是几种常用于数据压缩的变换:

离散余弦变换(DCT):这种变换广泛用于图像和视频压缩,例如在JPEG图像格式中。DCT能有效地将图像数据从空间域转换到频率域,使得图像中的高频信息(通常是细节部分)和低频信息(图像的主要部分)得以分离,从而便于进行更高效的压缩。

小波变换:小波变换在图像和视频压缩中也很流行,特别是在JPEG 2000图像格式中。与DCT相比,小波变换提供了更好的尺度和位置控制,使其在处理具有不同尺度特征的图像时更加有效。

离散傅立叶变换(DFT):虽然DFT在图像压缩中不如DCT常用,但它在音频压缩和通信系统中非常重要。DFT可以将时域信号转换为频域信号,使得频域中的能量分布更加明显,从而便于压缩。

Karhunen-Loève变换(KLT):这种变换在理论上可以提供最佳的数据压缩,但由于其高计算复杂性和数据依赖性,它在实际应用中不太常用。

**奇异值分解(**SVD):虽然SVD的计算成本较高,但它在某些特定应用中,如图像压缩的特定场景中,能提供优秀的压缩效果。

选择哪种变换取决于多种因素,包括压缩的目标(无损或有损)、数据类型(图像、视频、音频等)、处理速度要求、以及最终压缩数据的预期用途。在实际应用中,这些变换通常与其他压缩技术(如量化和熵编码)结合使用,以达到最优的压缩效果。

python实现下图

在这里插入图片描述

提示

结果显示了原图的两种变换后近似。先将原图分割为大小为8×8的子图像,并对每个子图像进行DCT和DFT变换,之后保留幅值最大的32个系数,最后对截尾后的系数阵列进行反变换得到近似图像,并计算原图与近似图之间的误差图像。
注意:dct变换可以通过函数cv2.dct(img)来实现,需要注意img在做dct变换之前需要转换为float类型。此外,为了增加误差图像的对比度,可用如下语句显示误差图像axs[i, j].imshow(img, vmin=img.min()*0.1, vmax=img.max()*0.1, cmap=‘gray’)

python代码

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

img=cv2.imread("lena_gray_512.tif",0)
img=img.astype(np.float)
rows,cols=img.shape
dct_inv_img = np.zeros(img.shape)
dft_inv_img = np.zeros(img.shape)
dct_dif_img = np.zeros(img.shape)
dft_dif_img = np.zeros(img.shape)
for i in range(0, rows, 8):
    for j in range(0, cols, 8):
        dct = cv2.dct(img[i:i+8, j:j+8])
        dft = np.fft.fft2(img[i:i+8, j:j+8])
        # idx = np.argpartition(dct.ravel(), 32)[:32]
        # idx2d = np.unravel_index(idx, dct.shape)
        # dct[idx2d] = 0
        med = np.median(np.abs(dct))
        dct[np.abs(dct) < med] = 0
        med = np.median(np.abs(dft))
        dft[np.abs(dft) < med] = 0

        dct_inv_img[i:i+8, j:j+8] = cv2.idct(dct)
        dft_inv_img[i:i+8, j:j+8] = np.abs(np.fft.ifft2(dft))
dct_dif_img=img-dct_inv_img
dft_dif_img=img-dft_inv_img


img_list = [img, dct_inv_img, dct_dif_img, img, dft_inv_img, dft_dif_img]
img_name_list = ['original', 'dct', 'dct_diff', 'original', 'dft', 'dft_diff']
_,axs=plt.subplots(2,3)

for i in range(2):
    for j in range(3):
        if j==2:
            axs[i, j].imshow(img_list[i*3+j], vmin=img_list[i*3+j].min()*0.1, vmax=img_list[i*3+j].max()*0.1, cmap='gray')
        else:
            axs[i, j].imshow(img_list[i*3+j], cmap='gray')
        axs[i, j].set_title(img_name_list[i*3+j])
        axs[i, j].axis('off')

plt.show()

结果展示

在这里插入图片描述

总结

在变化编码中,其性能与所选用的正交变换类型,图像类型,变化块的大小,压缩方式和压缩程度等因素有关。在变换方式确定之后,变换块的大小选择就显得尤为重要,因为大多数图像统计结果显示,大多数图像仅在约20个相邻像素间有较大的相关性,而且一般当子图像尺寸n>16(像素)时,其性能已经改善不大。同时,如果子图像块过大,其中所包含的像素就越多,变换时所需要的计算量也就越大,因此一般子图像块的大小选为8像素8像素或16像素16像素。对图像进行字块划分的好处是:小块图像的变换计算容易,它可以将传输误差造成的图像损伤限制在子图像的范围之内,从而避免误码的扩散。


http://www.niftyadmin.cn/n/5317639.html

相关文章

Tomcat 的 work 目录缓存导致的JSP页面图片更新问题

一、问题分析 1. 修改后重新部署没有变化 笔者之前部署了一个后台管理项目&#xff0c;通过它来发布课程内容&#xff0c;其中有一个 JSP 课程页面&#xff0c;在该 JSP 页面里也引用了类文件 Constant.java 里的一个变量&#xff08;ALIYUN_OSS_PATH&#xff09;&#xff0c;…

虚拟主机 如何上传大于100M的文件 php网站程序

问题 虚拟主机上传文件大小限制100m&#xff0c; 有时会遇到非常大的文件上传&#xff0c;上传过程中耗时非常久&#xff0c; 可能服务器的限制设置了上传文件尺寸&#xff0c;返回“413 request entity too large” 整体逻辑 前端&#xff1a;上传文件时&#xff0c;进行文…

Maven之多环境配置与应用

多环境配置与应用 1. 多环境配置作用 maven提供配置多种环境的设定&#xff0c;帮助开发者使用过程中快速切换环境 2. 多环境配置步骤 2.1 定义多环境 <!--定义多环境--> <profiles><!--定义具体的环境&#xff1a;生产环境--><profile><!--定义…

【LeetCode】2626. 数组归约运算

数组归约运算 题目题解 题目 给定一个整数数组 nums、一个 reducer 函数 fn 和一个初始值 init&#xff0c;返回通过依次对数组的每个元素执行 fn 函数得到的最终结果。 通过以下操作实现这个结果&#xff1a;val fn(init, nums[0])&#xff0c;val fn(val, nums[1])&#…

JS中垃圾数据是如何自动回收的

JS中垃圾数据是如何自动回收的 背景垃圾回收机制调用栈中的数据回收堆空间中数据回收垃圾回收器的工作流程副垃圾回收器主垃圾回收器 全停顿 背景 在JS栈和堆&#xff1a;数据是如何存储的一文中提到了 JavaScript 中的数据是如何存储的&#xff0c;并通过示例代码分析了原始数…

软件测试|深入理解SQL CROSS JOIN:交叉连接

简介 在SQL查询中&#xff0c;CROSS JOIN是一种用于从两个或多个表中获取所有可能组合的连接方式。它不依赖于任何关联条件&#xff0c;而是返回两个表中的每一行与另一个表中的每一行的所有组合。CROSS JOIN可以用于生成笛卡尔积&#xff0c;它在某些情况下非常有用&#xff…

美国证券交易委员会 X 账户被黑,引发比特币市场震荡

Bleeping Computer 网站消息&#xff0c;威胁攻击者成功“占领”了美国证券交易委员会的 X 账户&#xff0c;并发布一条关于批准比特币 ETF 在证券交易所上市的虚假公告。 帖子原文&#xff1a;今天&#xff0c;美国证券交易委员会批准比特币 ETF 在注册的国家证券交易所上市&a…

2019年认证杯SPSSPRO杯数学建模B题(第一阶段)外星语词典全过程文档及程序

2019年认证杯SPSSPRO杯数学建模 基于方差分布的方法对未知语言文本中重复片段的自动搜索问题的研究 B题 外星语词典 原题再现&#xff1a; 我们发现了一种未知的语言&#xff0c;现只知道其文字是以 20 个字母构成的。我们已经获取了许多段由该语言写成的文本&#xff0c;但…