原理:
离散余弦变换(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=0; i <dimX;i++){ m[i] = &p[i*dimY]; } return m; } void free_mat(float **m){ free(m[0]); free(m); } void write_mat(FILE *fp, float **m, int N, int M){ int i, j; for(i =0; i< N; i++){ fprintf(fp, "%f", m[i][0]); for(j = 1; 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 = 0; u < N; ++u) { for (v = 0; v < M; ++v) { DCTMatrix[u][v] = 0; for (i = 0; i < N; i++) { for (j = 0; j < M; j++) { DCTMatrix[u][v] += Matrix[i][j] * cos(M_PI/((float)N)*(i+1./2.)*u)*cos(M_PI/((float)M)*(j+1./2.)*v); } } } } } void idct(float **Matrix, float **DCTMatrix, int N, int M){ int i, j, u, v; for (u = 0; u < N; ++u) { for (v = 0; v < M; ++v) { Matrix[u][v] = 1/4.*DCTMatrix[0][0]; for(i = 1; i < N; i++){ Matrix[u][v] += 1/2.*DCTMatrix[i][0]; } for(j = 1; j < M; j++){ Matrix[u][v] += 1/2.*DCTMatrix[0][j]; } for (i = 1; i < N; i++) { for (j = 1; j < M; j++) { Matrix[u][v] += DCTMatrix[i][j] * cos(M_PI/((float)N)*(u+1./2.)*i)*cos(M_PI/((float)M)*(v+1./2.)*j); } } Matrix[u][v] *= 2./((float)N)*2./((float)M); } } } int main() { float testBlockA[8][8] = { {255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255} }, testBlockB[8][8] = {{255, 0, 255, 0, 255, 0, 255, 0}, {0, 255, 0, 255, 0, 255, 0, 255}, {255, 0, 255, 0, 255, 0, 255, 0}, {0, 255, 0, 255, 0, 255, 0, 255}, {255, 0, 255, 0, 255, 0, 255, 0}, {0, 255, 0, 255, 0, 255, 0, 255}, {255, 0, 255, 0, 255, 0, 255, 0}, {0, 255, 0, 255, 0, 255, 0, 255} }; FILE * fp = fopen("mydata.csv", "w"); int dimX = 8, dimY = 8; int i, j; float **testBlock = calloc_mat(dimX, dimY); float **testDCT = calloc_mat(dimX, dimY); float **testiDCT = calloc_mat(dimX, dimY); for(i = 0; i<dimX; i++){ for(j = 0; 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 0; }
代码路径: https://github.com/DyLanCao/DCT.git
参考文档:
1 https://stackoverflow.com/questions/8310749/discrete-cosine-transform-dct-implementation-c
作者:虚生 出处:https://www.cnblogs.com/dylancao/ 以音频和传感器算法为核心的智能可穿戴产品解决方案提供商 ,提供可穿戴智能软硬件解决方案的设计,开发和咨询服务。 勾搭热线:邮箱:1173496664@qq.com weixin:18019245820 市场技术对接群:347609188 |
![]() |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战