原理:

  离散余弦变换(DCT for Discrete Cosine Transform)是与傅里叶变换相关的一种变换,它类似于离散傅里叶变换(DFT for Discrete Fourier Transform),但是只使用实数。离散余弦变换相当于一个长度大概是它两倍的离散傅里叶变换,这个离散傅里叶变换是对一个实偶函数进行的(因为一个实偶函数的傅里叶变换仍然是一个实偶函数),在有些变形里面需要将输入或者输出的位置移动半个单位(DCT有8种标准类型,其中4种是常见的)。

  使用场景:

  离散余弦变换,尤其是它的第二种类型,经常被信号处理和图像处理使用,用于对信号和图像(包括静止图像和运动图像)进行有损数据压缩。一个类似的变换, 改进的离散余弦变换被用在高级音频编码(AAC for Advanced Audio Coding),Vorbis 和 MP3 音频压缩当中。

  python源码实现:  

# import numpy
import numpy as np # import dct
from scipy.fftpack import dct # numpy array
x = np.array([1.0, 2.0, 1.0, 2.0, -1.0])
print("x : ",x) # apply dct function on array
y = dct(x)
print("dct(x) : ",y)

  C源码实现:

#include <stdio.h>
#include <math.h>
#include <stdlib.h> void dct(float **DCTMatrix, float **Matrix, int N, int M);
void write_mat(FILE *fp, float **testRes, int N, int M);
void idct(float **Matrix, float **DCTMatrix, int N, int M);
float **calloc_mat(int dimX, int dimY);
void free_mat(float **p); float **calloc_mat(int dimX, int dimY){
float **m = calloc(dimX, sizeof(float*));
float *p = calloc(dimX*dimY, sizeof(float));
int i;
for(i=; i <dimX;i++){
m[i] = &p[i*dimY]; }
return m;
} void free_mat(float **m){
free(m[]);
free(m);
} void write_mat(FILE *fp, float **m, int N, int M){ int i, j;
for(i =; i< N; i++){
fprintf(fp, "%f", m[i][]);
for(j = ; j < M; j++){
fprintf(fp, "\t%f", m[i][j]);
}
fprintf(fp, "\n");
}
fprintf(fp, "\n");
} void dct(float **DCTMatrix, float **Matrix, int N, int M){ int i, j, u, v;
for (u = ; u < N; ++u) {
for (v = ; v < M; ++v) {
DCTMatrix[u][v] = ;
for (i = ; i < N; i++) {
for (j = ; j < M; j++) {
DCTMatrix[u][v] += Matrix[i][j] * cos(M_PI/((float)N)*(i+./.)*u)*cos(M_PI/((float)M)*(j+./.)*v);
}
}
}
}
} void idct(float **Matrix, float **DCTMatrix, int N, int M){
int i, j, u, v; for (u = ; u < N; ++u) {
for (v = ; v < M; ++v) {
Matrix[u][v] = /.*DCTMatrix[][];
for(i = ; i < N; i++){
Matrix[u][v] += /.*DCTMatrix[i][];
}
for(j = ; j < M; j++){
Matrix[u][v] += /.*DCTMatrix[][j];
} for (i = ; i < N; i++) {
for (j = ; j < M; j++) {
Matrix[u][v] += DCTMatrix[i][j] * cos(M_PI/((float)N)*(u+./.)*i)*cos(M_PI/((float)M)*(v+./.)*j);
}
}
Matrix[u][v] *= ./((float)N)*./((float)M);
}
}
} int main() { float
testBlockA[][] = { {, , , , , , , },
{, , , , , , , },
{, , , , , , , },
{, , , , , , , },
{, , , , , , , },
{, , , , , , , },
{, , , , , , , },
{, , , , , , , } }, testBlockB[][] = {{, , , , , , , },
{, , , , , , , },
{, , , , , , , },
{, , , , , , , },
{, , , , , , , },
{, , , , , , , },
{, , , , , , , },
{, , , , , , , } }; FILE * fp = fopen("mydata.csv", "w");
int dimX = , dimY = ;
int i, j; float **testBlock = calloc_mat(dimX, dimY);
float **testDCT = calloc_mat(dimX, dimY);
float **testiDCT = calloc_mat(dimX, dimY); for(i = ; i<dimX; i++){
for(j = ; j<dimY; j++){
testBlock[i][j] = testBlockB[i][j];
}
} dct(testDCT, testBlock, dimX, dimY);
write_mat(fp, testDCT, dimX, dimY); idct(testiDCT, testDCT, dimX, dimY);
write_mat(fp, testiDCT, dimX, dimY); fclose(fp);
free_mat(testBlock);
free_mat(testDCT);
free_mat(testiDCT); return ;
}

  代码路径: https://github.com/DyLanCao/DCT.git

参考文档:

https://stackoverflow.com/questions/8310749/discrete-cosine-transform-dct-implementation-c

DCT(离散余弦变换)算法原理和源码(python)的更多相关文章

  1. Java并发编程(七)ConcurrentLinkedQueue的实现原理和源码分析

    相关文章 Java并发编程(一)线程定义.状态和属性 Java并发编程(二)同步 Java并发编程(三)volatile域 Java并发编程(四)Java内存模型 Java并发编程(五)Concurr ...

  2. [Spark内核] 第32课:Spark Worker原理和源码剖析解密:Worker工作流程图、Worker启动Driver源码解密、Worker启动Executor源码解密等

    本課主題 Spark Worker 原理 Worker 启动 Driver 源码鉴赏 Worker 启动 Executor 源码鉴赏 Worker 与 Master 的交互关系 [引言部份:你希望读者 ...

  3. [Spark內核] 第41课:Checkpoint彻底解密:Checkpoint的运行原理和源码实现彻底详解

    本课主题 Checkpoint 运行原理图 Checkpoint 源码解析 引言 Checkpoint 到底是什么和需要用 Checkpoint 解决什么问题: Spark 在生产环境下经常会面临 T ...

  4. Dubbo原理和源码解析之服务引用

    一.框架设计 在官方<Dubbo 开发指南>框架设计部分,给出了引用服务时序图: 另外,在官方<Dubbo 用户指南>集群容错部分,给出了服务引用的各功能组件关系图: 本文将根 ...

  5. Dubbo原理和源码解析之标签解析

    一.Dubbo 配置方式 Dubbo 支持多种配置方式: XML 配置:基于 Spring 的 Schema 和 XML 扩展机制实现 属性配置:加载 classpath 根目录下的 dubbo.pr ...

  6. Dubbo原理和源码解析之“微内核+插件”机制

    github新增仓库 "dubbo-read"(点此查看),集合所有<Dubbo原理和源码解析>系列文章,后续将继续补充该系列,同时将针对Dubbo所做的功能扩展也进行 ...

  7. Dubbo原理和源码解析之服务暴露

    github新增仓库 "dubbo-read"(点此查看),集合所有<Dubbo原理和源码解析>系列文章,后续将继续补充该系列,同时将针对Dubbo所做的功能扩展也进行 ...

  8. DStream-05 updateStateByKey函数的原理和源码

    Demo updateState 可以到达将每次 word count 计算的结果进行累加. object SocketDstream { def main(args: Array[String]): ...

  9. 我是如何在短期内快速掌握Dubbo的原理和源码的(纯干货)?

    写在前面 上周,在[Dubbo系列专题]中更新了两篇文章<冰河开始对Dubbo下手了!>和<俯瞰Dubbo全局,阅读源码前必须掌握这些!!>,收到了很多小伙伴的微信私聊消息,大 ...

随机推荐

  1. 获取Control请求路径

    对于多个uri映射到同一个control方法时,需根据不同的uri返回的数据结构进行区分,因此需要再方法体内获取到RequestUri,再对其做相应的判断实现对应的业务逻辑 @Resource pri ...

  2. js处理日期

    /Date(-62135596800000)/ 如何用js转化为日期时间格式 2015-11-20 14:33:20像这样 var a = '/Date(-62135596800000)/' Date ...

  3. List Leave

    本次作业是建立二叉树并输出叶结点 (1)首先是定义结点,包括左孩子,右孩子 typedef struct { int lch;//左孩子 int rch;//右孩子 }Node; (2)建立二叉树 c ...

  4. javaMail的使用以及trying to connect to host "1xxx@163.com", port 25, isSSL false异常

    最近项目用到邮件系统,开始了解javaMail...话不多说先上代码: pom依赖: <!--    邮件  https://mvnrepository.com/artifact/javax.m ...

  5. 【NIFI】 Apache NiFI 集群搭建

    NiFI 集群介绍 NiFi集群架构 NiFi采用Zero-Master Clustering范例.集群中的每个节点对数据执行相同的任务,但每个节点都在不同的数据集上运行.其中一个节点自动选择(通过A ...

  6. H5新特性-canvas绘图--渐变对象路径(最复杂)--图片--变形操作

    今天的目标 3.1:canvas绘图--(重点掌握:渐变对象.路径.图片.变形) 3.2:canvas绘图--渐变对象 线性渐变: linearGradient 径向渐变: var g = ctx.c ...

  7. MyEclipse has detected that less than 5% of

      选择Windows->Preferences; 2 选择MyEclipse->Servers->Integrated Sandbox->MyEclispe Tomcat 6 ...

  8. python语言相关语法基础

    numpy系列import numpya = numpy.array([[1,2], [3,4]])b = numpy.array([[5,6], [7,8]])a*b>>>arra ...

  9. 走进JDK(十二)------TreeMap

    一.类定义 TreeMap的类结构: public class TreeMap<K,V> extends AbstractMap<K,V> implements Navigab ...

  10. 线程中的setDaemon方法

    setDaemon方法必须在start方法前定义.t1.setDaemon(True),该语句的意思是:将主线程A设置为子线程t1的守护线程.也就是在执行程序时,t1会随着主线程A的退出而退出,不论t ...