从“零”开始学习一下DCT

  • 回忆傅里叶频率分析,DTFT
    • 信号的频率分析
      • 连续时间周期信号的傅里叶级数
      • 连续时间非周期信号的傅里叶变换
      • 离散时间周期信号的频率分析
      • 离散时间非周期信号的频率分析
    • 四种变换的关系
    • 离散时间信号傅里叶变换的对称性,离DCT又近了一步
  • 主角登场:DFT和DCT
    • 频率采样和时域重建
    • 实值偶序列的DFT到DCT
      • 实值偶序列的DFT
      • 原型DCT
      • 归一化DCT
      • 矩阵表达DCT
  • TDAC修正的type-IV型DCT孕育了MDCT
    • type-IV DCT
    • MDCT
    • TDAC-Time-Domain Aliasing Cancellation
  • 小结
  • 参考文献

回忆傅里叶频率分析,DTFT

“汝果欲学诗,工夫在诗外”,这两句诗来形容对DCT的学习最贴切不过了,因为这个DCT是从DTFT技术衍生出来,具体实现又大量借鉴了FFT的蝶形运算,所以想搞懂DCT,先要拾起久违的傅里叶频率分析理论。BTW举的例子大都是声音相关的信号。

信号的频率分析

从1672年牛顿使用术语“频谱”来描述白光折射出的有色光开始,到十九世纪法国数学家傅里叶(1672-1830)用三角级数扩展来描述物体的热传导和温度分布,又经历了100年的发展,20世纪这项数学技术应用于基于时间信号的分析当中,形成了信号频率分析的一个共识:大多数有实际意义的信号都可以分解成正弦信号成分之和。对于周期信号,这样的分解成为傅里叶级数。而对于有限能量信号,这样的分解成为傅里叶变换。LTI系统的对输入为正弦信号的响应仍然是一个频率相同,但是幅度和相位产生差异的正弦信号,这意味着正弦曲线成分的线性组合输入,将在LTI系统中产生类似频率组合的线性输出,而变化的只是这些组合分量的幅度和相位,LTI系统的这个特性令正弦分解变得如此重要,而对应的傅里叶频率分析方法也成为了数字信号处理的基石【1】。

连续时间周期信号的傅里叶级数

连续时间周期信号的复指数信号表达形式:
x(t)=∑k=−∞∞ckej2πkF0tx(t) = \sum_{k=-\infty}^{\infty}c_ke^{j2\pi kF_0t} x(t)=k=−∞∑∞​ck​ej2πkF0​t
其中系数ckc_kck​的计算公式(分析等式)为

ck=1Tp∫t0t0+Tpx(t)e−j2πkF0tdtc_k =\frac{1}{T_p} \int_{t_0}^{t_0+T_p}x(t)e^{-j2\pi kF_0t}\,{\rm d}t ck​=Tp​1​∫t0​t0​+Tp​​x(t)e−j2πkF0​tdt
理想情况下,典型的乐音就是连续时间周期信号,基音的频率是F0F_0F0​,决定了乐音的声调,泛音是基音的倍频,决定了乐音的音色,不同幅值和相位的基音+泛音的组合就形成了丰富的乐音。
ck\qquad c_kck​是复值,而自然界中大部分信号是实数(我就没见过虚数),这样的话ckc_kck​和c−kc_{-k}c−k​是共轭的,将ckc_kck​写成复指数表达式:
ck=∣ck∣ejθk,c−k=∣ck∣e−jθkc_k=|c_k|e^{j\theta_k}, c_{-k}=|c_k|e^{-j\theta_k} ck​=∣ck​∣ejθk​,c−k​=∣ck​∣e−jθk​
可以将上面的公式改写为实数的傅里叶级数表达:
x(t)=c0+2∑k=1∞∣ck∣cos(j2πkF0t+θk)x(t) =c_0 + 2\sum_{k=1}^{\infty}|c_k|cos(j2\pi kF_0t+\theta_k) x(t)=c0​+2k=1∑∞​∣ck​∣cos(j2πkF0​t+θk​)
联系到本文的题目,有那味儿吧。。。。。

连续时间非周期信号的傅里叶变换

\qquad乐音的确很美,我们无法探求其原因,从频谱上可以窥见固定间隔的离散谱,简洁而和谐。但世界中不能只有乐音,有很多声音无规律可循,比如机器的“隆隆声”,刹车的声音,还有我们的语音,这些信号很显然是非周期的,那么从频率分析的角度,他们的频谱是什么样的呢?答案就是连续的,连续到你觉得都不靠谱,但现实世界就是很多连续谱信号组成的,如乐音那样魅力和谐的线状谱只是凤毛麟角。省去推导,直接列出公式:
X(F)=∫−∞∞x(t)e−j2πFtdtX(F) = \int_{-\infty}^{\infty}x(t)e^{-j2\pi Ft}\,{\rm d}t X(F)=∫−∞∞​x(t)e−j2πFtdt
x(t)=∫−∞∞X(F)ej2πFtdFx(t) = \int_{-\infty}^{\infty}X(F)e^{j2\pi Ft}\,{\rm d}F x(t)=∫−∞∞​X(F)ej2πFtdF
而从线性频率F直接映射到弧度频率Ω\OmegaΩ的方法是dF=dΩ/2π{\rm d}F = {\rm d}\Omega/2\pidF=dΩ/2π,就会得到另外一个常见的傅里叶变换形式
X(Ω)=∫−∞∞x(t)e−jΩtdtX(\Omega) = \int_{-\infty}^{\infty}x(t)e^{-j\Omega t}\,{\rm d}t X(Ω)=∫−∞∞​x(t)e−jΩtdt
x(t)=∫−∞∞X(Ω)ejΩtdΩx(t) = \int_{-\infty}^{\infty}X(\Omega)e^{j\Omega t}\,{\rm d}\Omega x(t)=∫−∞∞​X(Ω)ejΩtdΩ
以上都是基于连续时间信号来分析的,但计算机是数字的,是离散的,最痛苦的是数字的和离散的不是一回事,所以产生了两个概念DTFT-Discrete Time Fourier Transform和DFT-Discrete Fourier Transform。

离散时间周期信号的频率分析

基本周期为N的离散时间信号,频率范围被展开在0−2π0-2\pi0−2π范围,由2π/N2\pi/N2π/N弧度,或者f=1/Nf=1/Nf=1/N的周期成分组成。傅里叶级数是包含最多N个频率成分的复指数展开,公式如下:
x(n)=∑k=0N−1ckej2πkn/Nx(n) = \sum_{k=0}^{N-1}c_ke^{j2\pi kn/N} x(n)=k=0∑N−1​ck​ej2πkn/N
ck=1N∑n=0N−1x(n)e−j2πkn/Nc_k =\frac{1}{N} \sum_{n=0}^{N-1}x(n)e^{-j2\pi kn/N} ck​=N1​n=0∑N−1​x(n)e−j2πkn/N
这个叫做DTFS-Discrete Time Fourier Series。

离散时间非周期信号的频率分析

这就是开头提到的DTFT-Discrete Time Fourier Transform了。
x(n)=∫−ππX(ω)ejωdωx(n) = \int_{-\pi}^{\pi}X(\omega)e^{j\omega}\,{\rm d}\omega x(n)=∫−ππ​X(ω)ejωdω
X(ω)=∑n=−∞∞x(n)e−jωnX(\omega) = \sum_{n=-\infty}^{\infty}x(n)e^{-j\omega n} X(ω)=n=−∞∑∞​x(n)e−jωn

四种变换的关系

  • 连续时间信号具有非周期行频谱
  • 离散时间信号具有周期性频谱
  • 周期信号具有离散谱
  • 非周期信号具有连续谱

离散时间信号傅里叶变换的对称性,离DCT又近了一步

非周期的有限能量信号傅里叶变换有很多性质,有些性质能减少复杂度和计算量。先贴图,整体性质在图中总结的很详细
而实信号偶对称(实偶信号)的时候,其傅里叶变换也表现为实偶性,并且只需要余弦函数就能得出所有的公式:

X(ω)=XR(ω)=x(0)+2∑n=1∞x(n)cosωnX(\omega)=X_R(\omega) = x(0)+2\sum_{n=1}^{\infty}x(n)cos{\omega n} X(ω)=XR​(ω)=x(0)+2n=1∑∞​x(n)cosωn
因为
XI(ω)=0X_I(\omega) = 0 XI​(ω)=0
逆运算
x(n)=1π∫−ππXR(ω)cosωndωx(n) = \frac{1}{\pi}\int_{-\pi}^{\pi}X_R(\omega)cos{\omega n}\,{\rm d}\omega x(n)=π1​∫−ππ​XR​(ω)cosωndω
这个就是DCT的初始版本。

主角登场:DFT和DCT

DFT的登场是因为上一章DTFT的最后一张图,图中显示非周期离散时间信号的频域分析是一个连续函数,但是连续函数对于计算机处理来说是灾难性的,如果能将连续函数进行采样,变成离散的,计算机处理就变成简单的加乘运算,DFT就是来打通最后一关的,DCT则是DFT对于实偶性信号的快速运算。

频率采样和时域重建

DFT是对傅里叶变换X(ω)X(\omega)X(ω)一组N个离散频率值的抽样序列,而满足N>L,L是原始信号x(n)的时域长度N>L, L是原始信号x(n)的时域长度N>L,L是原始信号x(n)的时域长度之后,又可以利用一个逆变换来重建这个时域信号x(n)x(n)x(n):
DFT:X(k)=∑n=0N−1x(n)e−j2πkn/Nk=0,1,2,...,N−1DFT:X(k) = \sum_{n=0}^{N-1}x(n)e^{-j2\pi kn/N}\,\,\,k=0,1,2,...,N-1 DFT:X(k)=n=0∑N−1​x(n)e−j2πkn/Nk=0,1,2,...,N−1
IDFT:x(n)=1N∑n=0N−1X(k)ej2πkn/NIDFT:x(n) =\frac{1}{N} \sum_{n=0}^{N-1}X(k)e^{j2\pi kn/N} IDFT:x(n)=N1​n=0∑N−1​X(k)ej2πkn/N

实值偶序列的DFT到DCT

实值偶序列的DFT

如果序列x(n)是实值的偶对称序列,即x(n)=x(N−n),0⩽n⩽N−1x(n)=x(N-n)\,\,,0\leqslant n \leqslant N-1x(n)=x(N−n),0⩽n⩽N−1,那么DFT可利用对称性得出XI(k)=0X_I(k)=0XI​(k)=0,DFT简化为:

DFT:X(k)=∑n=0N−1x(n)cos(2πkn/N)k=0,1,2,...,N−1DFT:X(k) = \sum_{n=0}^{N-1}x(n)cos(2\pi kn/N)\,\,\,k=0,1,2,...,N-1 DFT:X(k)=n=0∑N−1​x(n)cos(2πkn/N)k=0,1,2,...,N−1
IDFT:x(n)=1N∑n=0N−1X(k)cos(j2πkn/N)IDFT:x(n) =\frac{1}{N} \sum_{n=0}^{N-1}X(k)cos(j2\pi kn/N) IDFT:x(n)=N1​n=0∑N−1​X(k)cos(j2πkn/N)

原型DCT

根据这个特性,对任何序列进行时域偶延拓之后,就可以利用cosine函数来实现序列的时频转换,运算效率和复杂度将大大减小。算法推导之后(太难不愿意啃了)得出基本的DCT公式:
DCT:V(k)=2∑n=0N−1x(n)cos[πN(n+12)k]k=0,1,2,...,N−1DCT:V(k) = 2\sum_{n=0}^{N-1}x(n)cos\left[ \frac{\pi}{N}(n+\frac{1}{2})k\right]\,\,\,k=0,1,2,...,N-1 DCT:V(k)=2n=0∑N−1​x(n)cos[Nπ​(n+21​)k]k=0,1,2,...,N−1
IDCT:x(n)=1N[V(0)2+∑k=0N−1V(k)cos[πN(n+12)k]]IDCT:x(n) =\frac{1}{N}\left[ \frac{V(0)}{2} + \sum_{k=0}^{N-1}V(k)cos\left[ \frac{\pi}{N}(n+\frac{1}{2})k\right]\right] IDCT:x(n)=N1​[2V(0)​+k=0∑N−1​V(k)cos[Nπ​(n+21​)k]]

归一化DCT

而为了归一化的考虑定义了一个归一化因子α(k)\alpha(k)α(k)如下:
α(k)={1N,k=02N,1⩽k ⩽N-1\alpha(k)= \begin{cases} \sqrt{\frac{1}{N}}, & \text {k=0} \\ \sqrt{\frac{2}{N}}, & \text {1$\leqslant$ k $\leqslant$ N-1} \end{cases} α(k)=⎩⎨⎧​N1​​,N2​​,​k=01⩽ k ⩽ N-1​
得到归一化的FDCT:
FDCT:C(k)=α(k)∑n=0N−1x(n)cos[πN(n+12)k]k=0,1,2,...,N−1FDCT:C(k) = \alpha(k)\sum_{n=0}^{N-1}x(n)cos\left[ \frac{\pi}{N}(n+\frac{1}{2})k\right]\,\,\,k=0,1,2,...,N-1 FDCT:C(k)=α(k)n=0∑N−1​x(n)cos[Nπ​(n+21​)k]k=0,1,2,...,N−1
IFDCT:x(n)=∑k=0N−1α(k)C(k)cos[πN(n+12)k]IFDCT:x(n) = \sum_{k=0}^{N-1}\alpha(k)C(k)cos\left[ \frac{\pi}{N}(n+\frac{1}{2})k\right] IFDCT:x(n)=k=0∑N−1​α(k)C(k)cos[Nπ​(n+21​)k]

矩阵表达DCT

归一化的表达式可以进一步提取系数矩阵CNC_NCN​,定义矩阵CNC_NCN​元素为:
Ckn={1N,k=0, 0⩽n⩽N-1 2Ncos[πN(n+12)k],1⩽k⩽N-1, , 0⩽n⩽N-1C_{kn}= \begin{cases} \sqrt{\frac{1}{N}}, & \text {k=0, 0$\leqslant$n$\leqslant$ N-1 } \\ \sqrt{\frac{2}{N}}cos\left[ \frac{\pi}{N}(n+\frac{1}{2})k\right], & \text {1$\leqslant$k$\leqslant$ N-1, , 0$\leqslant$n$\leqslant$ N-1} \end{cases} Ckn​=⎩⎨⎧​N1​​,N2​​cos[Nπ​(n+21​)k],​k=0, 0⩽n⩽ N-1 1⩽k⩽ N-1, , 0⩽n⩽ N-1​
这是一个N*N方阵。将x(n)定义为矢量表示:
xN=[x(0)x(1)...x(N−1)]Tx_N= [x(0) x(1) ... x(N-1)]^T xN​=[x(0)x(1)...x(N−1)]T
变换输出的矢量定义为c(n)
cN=[C(0)C(1)...C(N−1)]Tc_N= [C(0) C(1) ... C(N-1)]^T cN​=[C(0)C(1)...C(N−1)]T
那么我们将得到DCT的矩阵表达:
cN=CNxNxN=CNTcN\bold {c_N}=\bold {C_N}\bold {x_N}\\ \bold {x_N}=\bold {C_N^T}\bold {c_N} cN​=CN​xN​xN​=CNT​cN​
这个表达式是一个求逆运算,暗示了矩阵是正交的,即:CNT=CN−1\bold {C_N^T}=\bold {C_N^{-1}}CNT​=CN−1​,正交变换具有能量聚集特性,趋向于将平均能量的大部分转移到相对较少的变换系数分量上,这为信息压缩提供了一个非常有效的变换工具。推导的例子是type-II型,type-IV型衍生的MDCT被大量用于多媒体压缩编码当中,下一章继续推导。

TDAC修正的type-IV型DCT孕育了MDCT

type-IV DCT

X(k)=∑n=0N−1x(n)cos[πN(n+12)(k+12)]k=0,1,2,...,N−1X(k) = \sum_{n=0}^{N-1}x(n)cos\left[ \frac{\pi}{N}(n+\frac{1}{2})(k+\frac{1}{2})\right]\,\,\,k=0,1,2,...,N-1 X(k)=n=0∑N−1​x(n)cos[Nπ​(n+21​)(k+21​)]k=0,1,2,...,N−1

MDCT

X(k)=∑n=02N−1x(n)cos[πN(n+12+N2)(k+12)]k=0,1,2,...,N−1X(k) = \sum_{n=0}^{2N-1}x(n)cos\left[ \frac{\pi}{N}(n+\frac{1}{2}+\frac{N}{2})(k+\frac{1}{2})\right]\,\,\,k=0,1,2,...,N-1 X(k)=n=0∑2N−1​x(n)cos[Nπ​(n+21​+2N​)(k+21​)]k=0,1,2,...,N−1

TDAC-Time-Domain Aliasing Cancellation

小结

离散余弦变换。

参考文献

  1. 《数字信号处理》 (第四版), John G. Proakis, Dinitris G.Manolakis 著,方艳梅等译,电子工业出版社
  2. 《Discrete Cosine and Sine Transforms: General properties, Fast algorithms andInteger》,V. Britanak, P. Yip, K. R. Rao
  3. 《低功耗MP3解码器设计及其可测性分析》博士论文,周锦锋,中科院计算所
  4. 改進的離散餘弦變換 ,https://zh.wikipedia.org/wiki

从“零”开始学习一下DCT相关推荐

  1. ue5新手零基础学习教程 Unreal Engine 5 Beginner Tutorial - UE5 Starter Course

    ue5新手零基础学习教程 Unreal Engine 5 Beginner Tutorial - UE5 Starter Course! 教程大小解压后:4.96G 语言:英语+中英文字幕(机译)时长 ...

  2. 0基础学好python难不难_零基础学习Python难不难?Python有什么优势?

    原标题:零基础学习Python难不难?Python有什么优势? Python是一种计算机程序设计语言.首先,我们普及一下编程语言的基础知识.用任何编程语言来开发程序,都是为了让计算机干活,比如下载一个 ...

  3. Java零基础学习难吗

    java编程是入行互联网的小伙伴们大多数的选择,那么对于零基础的小伙伴来说Java零基础学习难吗?如果你是初学者,你可以很好的理解java编程语言.并不困难.如果你的学习能力比较高,那么你对Java的 ...

  4. 零基础学习java,这些书一定要看!

    学习java技术除了看视频,看书也是非常重要的,尤其是零基础同学,本文包含学习Java各个阶段的书籍推荐,史上最全,学习Java,没有书籍怎么行,就好比出征没带兵器一个道理,这些书籍整理出来给大家作为 ...

  5. 零基础学习UI设计有哪些简单有效的方法

    UI设计的普及让越来越多的人对UI有了重新的认识,很多企业对UI设计这个岗位都是非常重视的,如今很多零基础学员都想要转行做UI设计,那么针对零基础学习UI设计有哪些简单有效的方法呢?来看看下面的详细介 ...

  6. 零基础学习Java培训有什么攻略

    零基础学习Java培训有什么攻略?java是主流编程语言之一,我们在学习Java的时候需要制定Java学习路线图,Java涉及到的知识点非常的多,我们该从何学起呢?怎么系统的学习呢?来看看下面的详细介 ...

  7. 近期必读的6篇NeurIPS 2019零样本学习论文

    来源 | 专知(ID:Quan_Zhuanzhi) [导读]NeurIPS 是全球最受瞩目的AI.机器学习顶级学术会议之一,每年全球的人工智能爱好者和科学家都会在这里聚集,发布最新研究.NIPS 20 ...

  8. 谷歌发布最新看图说话模型,可实现零样本学习,多类型任务也能直接上手

    点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 兴坤 发自 凹非寺 量子位 报道 | 公众号 QbitAI 谷歌新推 ...

  9. 现代NLP中的零样本学习

    2020-07-01 11:19:35 作者:Joe Davison 编译:ronghuaiyang 导读 使用最新的NLP技术来进行零样本学习的一些进展和工作. 自然语言处理现在是一个非常令人兴奋的 ...

最新文章

  1. java 一些常用的代码(转载)
  2. muxer、demuxer muxer是什么?视频封装、解封装(逆封装)
  3. childactor movable
  4. 格密码教程(五):Babai‘s algorithm和求解apprCVP算法
  5. 移卡科技java_聊一聊Java垃圾回收与卡表技术
  6. mysql 插入数据会执行事务吗_在代码中,插入数据到数据库时,如果不使用事务,将会导致速度极慢...
  7. 平方根函数sqrt和牛顿迭代法
  8. ajax帝国cms自动加载分页,帝国CMS7.0版ajax无刷新添加评论插件
  9. 虚拟机 linux无法与本地计算机互通的处理办法
  10. 使用helm部署kubeapps
  11. iOS 3级滚动地址
  12. 安卓手机数据备份与恢复方法汇总和操作详解
  13. 三维投影总结:数学原理、投影几何、OpenGL教程、我的方法
  14. initramfs模式介绍及解决方法
  15. ios应用数据存储方式(偏好设置)-转
  16. ACC自适应巡航控制系统介绍
  17. THE ADVENTURE BEGINS
  18. 输出一个由*组成的三角形图案_一文带你读懂集成电路的组成与封装形式
  19. 基于python实现利用DEM数据计算坡度、坡向
  20. 手机的android版本怎么升级,华为HarmonyOS 2.0将于6月2日发布,华为手机可一键升级...

热门文章

  1. Python3处理HTTP请求
  2. 寻找250(非数组求法)
  3. JAP的类关系 @OneToMany 和 @ManyToManys
  4. 2-4 第18次课 高项之沟通管理与干系人管理
  5. 【python学习】如何将字典添加到字典
  6. 配置:以爱普生TM-T81热敏打印机为例:小票打印驱动安装配置
  7. php简单后台,ThinkPHP简单网站后台
  8. Android高德地图线优化,Android 接入高德地图SDK模块的优化点点滴滴
  9. onbeforeunload, 浏览器关闭和刷新提示
  10. caffe.bin caffe的框架