未经博主允许,禁止转载!

离散余弦变换(DCT for Discrete Cosine Transform)是与傅里叶变换相关的一种变换,它与离散傅里叶变换类似,但是只使用实数。

这种变化经常被信号处理和图像处理使用,用于对信号和图像(包括静止图像和运动图像)进行有损压缩。在压缩算法中,现将输入图像划分为8*8或16*16的图像块,对每个图像块作DCT变换;然后舍弃高频的系数,并对余下的系数进行量化以进一步减少数据量;最后使用无失真编码来完成压缩任务。解压缩时首先对每个图像块作DCT反变换,然后将图像拼接成一副完整的图像。

大多数自然信号(包括声音和图像)的能量都集中在余弦变换后的低频部分。由于人眼对于细节信息不是很敏感,因此信息含量更少的高频部分可以直接去掉,从而在后续的压缩操作中获得较高的压缩比。

  • 1. 一维DCT变换
  • 2. 二维DCT变换
  • 3. DCT反变换
  • 4. 怎样提高二维DCT变换的速度

1. 一维DCT变换

一维DCT变换共有8种,最实用的一种公式如下:

其中N是一维数据的元素总数,c(u)系数使得DCT变换矩阵成为正交矩阵,正交特性在二维DCT变换中更能体现其优势。一维DCT变换的复杂度是O(n^2)

2. 二维DCT变换

二维DCT变换公式如下:

我们将公式变换一下:

可以发现,二维DCT变换其实是在一维DCT变换的基础上,再做一次一维DCT变换。二维DCT也可以写成矩阵相乘的形式:

矩阵A和f必须为长宽均为N的方阵,f不是方阵的情况可以补零再对其做DCT变换。生成矩阵A的matlab代码如下:

A=zeros(N);for i=0:Nfor j=0:Nif i==0a=sqrt(1/N);elsea=sqrt(2/N);end            A(i+1,j+1)=a*cos(pi*(2*j+1)*i/(2*N));end
end

二维DCT变换的复杂度达到O(n^4),所以进行DCT变换的矩阵不宜过大。在实际处理图片的过程中,需要先把矩阵分块,一般分为8*8或16*16大小,这样DCT变换不至于耗费过多的时间。

3. DCT反变换

DCT变换是无损并可逆的,反变换的公式如下:

同样,DCT反变换也可以写成矩阵相乘的形式:

DCT反变换的时间复杂度与DCT变换相同。

4. 怎样提高DCT变换的速度

由于DCT变换的高效,这种变换方法已经广泛应用于信号处理和图像处理,成为许多图像编码国际标准的核心。但随着信息时代的来临和信息量的飞速增长,人们对图像处理的速度要求越来越高,虽然离散余弦变换已经比较高效了,但是能否在DCT变换的基础上,继续提升其速度呢?

我们考虑用并行计算的方法提升速度。并行计算指的是同时使用多种计算资源解决计算问题的一种高效的计算手段。图形处理器(Graphics Processing Unit,缩写GPU)非常擅长大规模并发计算,所以我考虑在GPU上实现并行的二维DCT变换,看能否有效提升二维DCT变换的速度。

我们观察二维DCT变换的公式,不难发现每一个DCT系数的计算,不依赖于任何一个DCT系数,也就是说,任意多个DCT系数的计算,都可以独立进行。所以我考虑对整个矩阵分线程块计算,线程块内再以每一个系数为单位分为线程,每一个DCT系数由一个线程来完成。记矩阵的大小为length*length,块大小为block_len* block_len。

DCT算法的CUDA代码如下,环境为ubuntu 14.04,CUDA版本8.0:

int tidy = blockIdx.x * blockDim.x + threadIdx.x;int tidx = blockIdx.y * blockDim.y + threadIdx.y;int index = tidx * length + tidy;int i;float tmp;float beta, alfa;if (tidx == 0)beta = sqrt(1.0 / length);elsebeta = sqrt(2.0 / length);if (tidy == 0)alfa = sqrt(1.0 / length);elsealfa = sqrt(2.0 / length);if (tidx < length && tidy < length) {for (i = 0; i < length * length; i++) {int x = i / length;int y = i % length;tmp += ((double) f[i])* cos((2 * x + 1) * tidx * PI / (2.0 * length))* cos((2 * y + 1) * tidy * PI / (2.0 * length));}F[index] = (double) alfa * beta * tmp;}__syncthreads();
}

由于GPU的控制单元可以把多个访问合并成少的访问,同时,计算每个系数需要访问的数据都完全相同,导致同一个块内的线程对于原矩阵的访问可以达到非常高的效率,所以我直接将块数设置为1,让所有计算系数的线程处于一个块内。

通过实验发现,基于CPU实现的DCT算法随着矩阵的增大,处理时间急剧的上升,而基于GPU实现的并行二维DCT变换算法,耗时非常短,计算速度惊人。

Matrix Length DCT Based on GPU(ms) DCT Based on CPU(ms) speedup
8 2.111 0.111 0.053
16 5.503 0.336 0.061
32 35.1296 2.844 0.081
64 1.105 16.338 14.785
128 2.312 218.512 94.291
256 2.151 1534.86 213.556
320 1.961 3034.05 1547.195

从上表中我们发现,当矩阵比较小的时候,GPU并行计算没有带来优势,反而让DCT变换时间更长了。通过CUDA提供的程序性能分析工具,观察到GPU并行程序的大部分时间不是花在了计算上面,而是CUDA任务的创建上。当矩阵增大之后,CUDA程序的运行时间不再主要取决于Event的创建。而基于CPU的DCT变换的时间基本来自于计算,所以随着矩阵的增大,时间基本呈指数增长。

通过以上内容,我完整的了解了一维和二维DCT变换的详细过程,并且通过GPU并行计算为二维DCT变换加速,实验结果显示,对于比较大的矩阵,基于GPU的二维DCT变换速度得到了巨大的提升,但是在矩阵比较小的应用场景下,CPU更有优势。

DCT算法的原理和优化相关推荐

  1. DCT算法的原理及实现简介

    DCT算法的原理及实现简介 DCT算法: DCT变换的全称是离散余弦变换(Discrete Cosine Transform),离散余弦变换相当于一个长度大概是它两倍的离散傅里叶变换,这个离散傅里叶变 ...

  2. 做diff_Vue3.0时代你必须了解的:diff算法原理和优化

    关注前端公众号 [前端每日一博] 前言 面试官: 你知道 Vue3.0 Object.difineProperty和vue3.0的proxy的区别吗? 你知道 Vue3.0 diff算法原理和它有什么 ...

  3. 【优化算法】简述灰狼优化算法(GWO)原理

    [优化算法]简述遗传算法(GA)原理 [优化算法]简述灰狼优化算法(GWO)原理 前言: 灰狼优化算法(Grey Wolf Optimizer,GWO)由澳大利亚格里菲斯大学学者 Mirjalili ...

  4. 基于人工鱼群算法的路径优化,鱼群算法的原理

    目录 摘要 参数优化的方法 鱼群算法的原理 基于人工鱼群算法的参数优化 基本参数 代码 效果图 结果分析 展望 摘要 详细介绍了人工鱼群算法的原理,并MATLAB编程实现基于人工鱼群算法的参数优化,对 ...

  5. java寻优算法_模拟退火算法SA原理及python、java、php、c++语言代码实现TSP旅行商问题,智能优化算法,随机寻优算法,全局最短路径...

    模拟退火算法SA原理及python.java.php.c++语言代码实现TSP旅行商问题,智能优化算法,随机寻优算法,全局最短路径 模拟退火算法(Simulated Annealing,SA)最早的思 ...

  6. 萤火虫算法_40多种智能优化算法原理和代码分享

    40多种智能优化算法原理和代码分享 <智能优化算法讲解>PDF下载地址: <智能优化算法原理讲解>PDF​mianbaoduo.com 包括: 1.海鸥算法SOA 智能优化算法 ...

  7. GC的三种收集方法:标记清除、标记整理、复制算法的原理与特点,分别用在什么地方,优化收集方法的思路

    面试java中,jvm中的垃圾收集算法一般都会问一下,下面来总结一下这个经常提到的问题. 第一种:标记清除 它是最基础的收集算法. 原理:分为标记和清除两个阶段:首先标记出所有的需要回收的对象,在标记 ...

  8. 差分进化算法原理及优化应用

    目录 一.差分进化(differential evolution)算法的起源 二.差分进化算法的原理 (一)初始化参数

  9. jpg图片与jpeg图片格式的区别(没有区别,.jpg只是扩展名.jpeg的缩写)JPEG图像压缩(YUV4:2:0 缩减采样、缩减取样)(离散余弦变换 DCT算法)(量化)(熵编码)(霍夫曼哈夫曼)

    文章目录 20191026 20220414 更新,更系统去了解里面的编码压缩流程 科普:关于图像格式JPG和JPEG你知多少? 一.前言 二.JPEG和JPG的关系 三.色彩空间转换 缩减取样 离散 ...

  10. 视觉SLAM开源算法ORB-SLAM3 原理与代码解析

    来源:深蓝学院,文稿整理者:何常鑫,审核&修改:刘国庆 本文总结于上交感知与导航研究所科研助理--刘国庆关于[视觉SLAM开源算法ORB-SLAM3 原理与代码解析]的公开课. ORB-SLA ...

最新文章

  1. 对象名和函数名同名引起的莫名错误
  2. 【Leetcode】62. 不同路径
  3. JadClipse eclipse反编译插件
  4. 调研了2000位CEO,67%的企业都在数字化转型,想做的无非这3点
  5. android 手电筒电量低于15%,Android 手电筒(最强适配版)
  6. linux中 centos6 文件误删如何恢复
  7. IIS Express介绍与使用
  8. 你必须知道的C#的25个基础概念(附演示)
  9. Cobbler安装指南
  10. IDEA出现Module ** must not contain source root **. The root already belongs to module **这类错误的解决方法
  11. Win7 64位中文旗舰版上Cocos2d-x 3.0的Android开发调试环境架设
  12. 浅谈串口DCB流控制设置
  13. (转)深入剖析ASP.NET的编译原理
  14. vmware workstation 12 打开vm14 不兼容问题解决
  15. 怎么在windows文件资源管理器中打开ftp
  16. public static void main解释
  17. 论文学习笔记——弱监督语义分割(Learning Integral Objects with Intra-Class Discriminator for Weakly-Supervised Sema)
  18. 在VS Code中t把分支写的代码合并到master中并提交到远程仓库github上
  19. mysql老司机之路
  20. 纯真ip php,PHP利用纯真数据库获取访客IP物理地址

热门文章

  1. leetcode电话号码java_【LeetCode(Java) - 379】电话目录管理系统
  2. 【YOLOV5-5.x 源码解读】datasets.py
  3. 神奇的泡泡java游戏,神奇的泡泡作文400字
  4. python字符串去掉特殊符号_python去特殊字符_python 去字符串中特殊符号 - CSDN
  5. python为什么是蛇的天敌_青蛙和蛇一直是天敌,只知道蛇会吃青蛙,你知不知道青蛙也吃蛇...
  6. Day01-python编程基础
  7. Elasticearch 搜索引擎(1
  8. 【java导出PDF】
  9. linux ata4 serror,linux – 如何将kern.log错误消息中的ataX.0标识符映射到实际的/ dev / sdY设备?...
  10. 关于word粘贴图片显示不全的解决办法