C语言DCT图像,任意长度DCT变换C语言实现方法

我是在Matlab上找到灵感

先去网站

http://www.fftw.org/

下载

然后调用实现fftw以及ifftw

然后在Matlab里面找到dct 以及idct的文件

把那几行Matlab改成c语言就行了

DCT变换代码:

// AnyLengFDCT.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#include "fftw3.h"//引用库文件

#include

#define PI 3.1415926

static double *as = NULL;

static double *ax = NULL;

static fftw_complex *in, *out;

static int n = 4;

void InitData();

void dft(int dn);

void fft_dct(double *a, int dn);

int _tmain(int argc, _TCHAR* argv[])

{

double a[4] = {1, 2, 3, 4};

InitData();

dft(n);

fft_dct(a, n);

return 0;

}

void InitData(){

in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * 2*n); //FFT变换前数据

out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * 2*n);//FFT变换后数据

as = (double*)malloc(n*sizeof(double));

ax = (double*)malloc(n*sizeof(double));

}

//*******************************************************************

//方法名称:dft

//说明:对所变幻的数据的长度进行DFT,因为每次变换的数据长度一致,所以单独拿出来,防止重复计算

//日期:2012.4.19

//参数说明:

//as: DFT变换后数据的实数

//ax:DFT变换后数据的虚部

//dn:DFT变换数据的个数

//*******************************************************************

void dft(int dn){

int i;

double x = 0.0;

double y;

//Compute weights to multiply DFT coefficients

for(i = 0; i < dn; i++){

y = -i*PI/(2*dn);

as[i] = exp(x)*cos(y)/sqrt(2.0*dn);

ax[i] = exp(x)*sin(y)/sqrt(2.0*dn);

}

as[0] = as[0]/sqrt(2.0);

for(i = 0; i < dn; i++){

printf("%f, %f\n", as[i], ax[i]);

}

}

//*******************************************************************

//方法名称:fft_dct

//说明:任意长度的快速DCT变换

//日期:2012.4.19

//参数说明:

//a: 数据

//dn:变换数据的大小

//*******************************************************************

void fft_dct(double *a, int dn){

int l;

int j;

int k;

fftw_plan p;

if(dn%2 == 1){

//奇数的DCT变换

for(l = 0; l < dn; l++){

in[l][0] = a[l];

in[dn+l][0] = a[dn-1-l];

}

p=fftw_plan_dft_1d(2*dn,in,out, FFTW_FORWARD, FFTW_ESTIMATE);

fftw_execute(p); /* repeat as needed*/

}else{

//偶数的DCT变换

for(l = 0; l < dn; l++){

as[l] = as[l]*2;

ax[l] = ax[l]*2;

//printf("%f, %f\n", as[i], ax[i]);

}

for(l = 0, j = 0,k = dn-1; l < dn; l++){

if(l%2){

in[k][0] = a[l];

--k;

}else{

in[j][0] = a[l];

++j;

}

}

p=fftw_plan_dft_1d(dn,in,out, FFTW_FORWARD, FFTW_ESTIMATE);

fftw_execute(p); /* repeat as needed*/

}

for(l = 0; l < dn; l++){

a[l] = as[l]*out[l][0] - ax[l]*out[l][1];

//printf("%f\n", a[l]);

}

fftw_destroy_plan(p);

fftw_free(in);

fftw_free(out);

free(as);

free(ax);

}

反DCT变换:

// AnyLengFIDCT.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#include "fftw3.h"//引用库文件

#include

#define PI 3.1415926

//static double *ias = NULL;

//static double *iax = NULL;

//static fftw_complex *in, *out;

//static int n = 6;

//void InitData();

//void idft(int dn);

//void ifft_idct(double *a, int dn);

void idft(int dn, double *ias, double *iax);

void ifft_idct(int dn, fftw_plan p, double *a, double *data, double *ias, double *iax, fftw_complex *in, fftw_complex *out);

int _tmain(int argc, _TCHAR* argv[])

{

int n = 6;

//double a[5] = {6.708204, -3.1495, 0, -0.283990, 0};

double a[6] = {8.573214, -4.162562, 0, -0.408248, 0, -0.080079};

double *ias = (double*)malloc(n*sizeof(double));

double *iax = (double*)malloc(n*sizeof(double));

double *data = (double*)malloc(n*sizeof(double));

fftw_plan p = NULL;

fftw_complex *in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * 2*n); //IFFT变换前数据

fftw_complex *out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * 2*n);//IFFT变换后数据

idft(n, ias, iax);

ifft_idct(n, p, a, data, ias, iax, in, out);

for(int i = 0; i < n; i++)

printf("%d %f\n", i+1, data[i]);

return 0;

}

//*******************************************************************

//方法名称:idft

//说明:对所变幻的数据的长度进行IDFT,因为每次变换的数据长度一致,所以单独拿出来,防止重复计算

//日期:2012.4.19

//参数说明:

//as: DFT变换后数据的实数

//ax:DFT变换后数据的虚部

//dn:DFT变换数据的个数

//*******************************************************************

void idft(int dn, double *ias, double *iax){

int i;

double x = 0.0;

double y;

//Compute weights to multiply IDFT coefficients

for(i = 0; i < dn; i++){

y = i*PI/(2*dn);

ias[i] = exp(x)*cos(y)*sqrt(2.0*dn);

iax[i] = exp(x)*sin(y)*sqrt(2.0*dn);

}

// for(i =0; i < dn; i++){

// printf("%f, %f\n", ias[i], iax[i]);

// }

}

//*******************************************************************

//方法名称:fft_dct

//说明:任意长度的快速IDCT变换

//日期:2012.4.19

//参数说明:

//a: 数据

//dn:变换数据的大小

//*******************************************************************

void ifft_idct(int dn, fftw_plan p, double *a, double *data, double *ias, double *iax, fftw_complex *in, fftw_complex *out){

int l;

int j;

int k;

double ias_0;

if(dn%2 == 1){

//奇数的DCT变换

ias_0 = ias[0] * sqrt(2.0);

in[0][0] = ias_0*a[0];

in[0][1] = iax[0]*a[0];

for(l = 1; l < dn; l++){

in[l][0] = ias[l]*a[l];

in[l][1] = iax[l]*a[l];

//printf("1==%f, 2==%f\n", in[l][0], in[l][1]);

in[dn+l][0] = iax[l]*a[dn-l];

in[dn+l][1] = -ias[l]*a[dn-l];

//printf("a==%f, b==%f\n", in[dn+l][0], in[dn+l][1]);

}

p=fftw_plan_dft_1d(2*dn,in,out, FFTW_BACKWARD, FFTW_ESTIMATE);

fftw_execute(p); /* repeat as needed*/

for(l = 0; l < dn; l++){

data[l] = out[l][0] / dn/2;

//out[l][1] = out[l][1] / dn;

//data[l] = out[l][0];

//printf("data == %f\n", data[l]);

}

}else{

//偶数的DCT变换

ias_0 = ias[0] / sqrt(2.0);

in[0][0] = ias_0*a[0];

in[0][1] = iax[0]*a[0];

for(l = 1; l < dn; l++){

in[l][0] = ias[l]*a[l];

in[l][1] = iax[l]*a[l];

//printf("%f, %f\n", in[l][0], in[l][1]);

}

p=fftw_plan_dft_1d(dn,in,out, FFTW_BACKWARD, FFTW_ESTIMATE);

fftw_execute(p); /* repeat as needed*/

for(l = 0; l < dn; l++){

out[l][0] = out[l][0] / dn;

out[l][1] = out[l][1] / dn;

//printf("out == %f\n", out[l][0]);

}

for(l = 0, j = 0, k = dn-1; l < dn; l++){

if(l%2){

data[l] = out[k][0];

k--;

}else{

data[l] = out[j][0];

++j;

}

//printf("data == %f\n", data[l]);

}

}

}

注:记得下载FFTW以及IFFTW

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值