#include<math.h>
#include<stdio.h>
#define PI 3.1415926
#define N 8
void yuanshi(int a[][8])//输出原始数据
{
int i,j;
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
{
printf("%d",a[i][j]);
}
}
}
void DCT(int f[8][8],float m[8][8])//DCT变换子程序
{
int x,y,i,j,l;
float coff[8][8],doff[8][8],D[8][8]={0};
for(y=0;y<N;y++) //计算第一行的coff
coff[0][y]=(sqrt(2.0)/sqrt(N))*(sqrt(1.0)/sqrt(2.0));
for(x=1;x<N;x++) //计算后面N-1行的coff
{
for(y=0;y<N;y++)
{
coff[x][y]=(sqrt(2.0)/sqrt(N))*cos((2*(y+1)-1)*x*PI/(2*N));
}
}
printf("COFF: \n"); //输出矩阵coff
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
{
printf("%f",coff[i][j]);
}
}
for(x=0;x<N;x++) //求coff的转置矩阵doff
{
for(y=0;y<N;y++)
{
doff[x][y]=coff[y][x];
}
}
for(i=0;i<N;i++) //矩阵doff和f矩阵相乘,结果为矩阵D
{
for(l=0;l<N;l++)
{
D[i][l]=0;
for(j=0;j<N;j++)
{
D[i][l]=D[i][l]+doff[i][j]*(1.0*f[j][l]);
}
}
}
printf("\n");
for(i=0;i<N;i++) //矩阵D和矩阵coff相乘,结果为矩阵m,即经过DCT变换//得到的矩阵
{
for(l=0;l<N;l++)
{
m[i][l]=0;
for(j=0;j<N;j++)
{
m[i][l]=m[i][l]+D[i][j]*coff[j][l];
}
}
}
printf("输出DCT矩阵\n");
for(i=0;i<N;i++) //输出经过DCT变换的结果矩阵m
{
for(l=0;l<N;l++)
{
printf("%f",m[i][l]);
printf("\n");
}
}
}
void sch(int te[8][8],float m[8][8],int n[8][8])//量化子程
{
int x,y;
int tr[8][8] ;
for(x=0;x<N;x++)
{
for(y=0;y<N;y++)
{
tr[x][y]=(int)(m[x][y]/te[x][y]);
n[x][y]=tr[x][y];
printf("%d",tr[x][y]);
}
}
}
int bianma(int n[8][8],int c[]) //一维行程编码
{
int k[64],a[128],i,j,t=0,e=1,d=0,l;
for(i=0;i<N;i++)//把二维的编码数组转换成一维数组
{
for(j=0;j<N;j++)
{
k[t++]=n[i][j];
}
}
for(i=0;i<N;i++)//计算编码后的数据,将其存在数组a中
{
l=i+1;
if(k[i]==k[l])e++;
else
{
a[d++]=e;
a[d++]=k[i];
e=1;
}
}
printf("编码输出:\n");
for(i=0;i<N;i++)//输出编码后的数据
{
printf("%d",a[i]);
c[i]=a[i];//把得到的编码后的数组a的值复制到数组c中
}
printf("\n");
return d;//返回数组c的长度
}
void main()
{ /*8*8图像块数据如下*/
float m[8][8],b[8][8];
int Y=128,i=0,j=0,s,number,n[8][8],c[52],data;
int a[][8]={{130,130,130,129,134,133,129,130},{130,130,130,129,134,133,130,130},{130,130,130,129,132,132,130,130},{129,130,130,129,130,130,129,129},{127,128,127,129,131,129,131,130},{127,128,127,128,127,128,132,132},{125,126,129,129,127,129,133,132},{127,125,128,128,126,130,131,131}};
int Fy[8][8]={{16,11,10,16,24,40,51,61},{12,12,14,19,26,58,60,55},{14,13,16,24,40,57,69,56},{14,17,22,29,51,87,80,62},{18,22,37,56,68,109,103,77},{24,35,55,64,81,104,103,77},{49,64,78,87,103,121,120,101},{72,92,95,98,112,100,103,99}};
printf("8*8图像块数据:\n");//输出需要处理的图象数据块的数据
yuanshi(a); //调用原始图像模块程序
printf("变换系数矩阵:\n");
DCT(a,m); //调用DCT变换函数
printf("输出量化后的矩阵:\n");
sch(Fy,m,n); //调用量化函数
number=bianma(n,c); //调用编码函数
printf("原始数据量:\n");
printf("%d \n",s=8*64); //输出原始数据量
printf("编码后的数据总量:\n");
data=number/2*3+number/2*8;
printf("%d \n",data); //输出编码后的数据总量
printf("压缩率: \n");
printf("%f%% \n",data*1.0/s*100); //输出压缩率
}