数据压缩第四次作业魔人俊.docx
《数据压缩第四次作业魔人俊.docx》由会员分享,可在线阅读,更多相关《数据压缩第四次作业魔人俊.docx(11页珍藏版)》请在冰豆网上搜索。
![数据压缩第四次作业魔人俊.docx](https://file1.bdocx.com/fileroot1/2022-12/1/62e62655-3d55-488b-9dec-150c19d1ec1f/62e62655-3d55-488b-9dec-150c19d1ec1f1.gif)
数据压缩第四次作业魔人俊
数据压缩第四次大作业
班级:
学号:
姓名:
魔人俊
一、实验目的:
通过编写DCT的C语言程序,实现对raw格式图片的编码压缩,从而更深入的理解DCT编码这一经典实用的数据压缩方法。
二、实验内容:
编写基于DCT的C语言图像压缩程序DCT_Code和解压缩程序DCT_Decode。
三、算法流程:
DCT编码属于正交变换编码。
这类算法通常是将空间域上的图像经过正交变换映射到系数空间,使变换后的系数直接相关性降低。
图像变换本身并不能压缩数据,但变换后图像大部分能量集中到了少数几个变换系数上,再采用适当的量化和熵编码便可以有效地压缩图像。
在目前的多数图像和视频压缩标准中都用到了DCT技术。
基于DCT的编码压缩过程框图:
二维DCT变换公式:
正变换:
反变换:
其中变换矩阵C如下所示:
在DCT变换域中,低频系数的能量远大于高频系数的能量,变换系数的相关性将大大减小,通过去除高频分量来实现压缩。
四、程序设计说明:
程序分为两部分,第一部分为编码程序;第二部分为解码程序;
这里我们用8阶的dct矩阵压缩一个256*256的raw文件。
原图像如下:
将256*256的图像分成32*32的8*8的矩阵,对每个矩阵进行8*8的dct变换。
经过dct变换后,所得的系数为
以10为量化步长对数据进行量化;
由此看出非0系数很少,据统计占1/6左右。
然后我们将非0的系数和坐标位置压在一个int中。
若系数为正则公式为i*256*256+j*256+x/10+1;否则公式为i*256*256+j*256-x/10+0。
输出压缩文件code.txt。
再根据code.txt还原系数矩阵,再进行dct反变换,得还原图像如下:
五、程序压缩性能评价:
对于测试文件“compress.raw”进行编码和解码,分别输出“code.txt”和“restore.raw”,其中code.txt为压缩后的编码,restore.raw为解压的图像。
压缩比为35%左右。
六、程序源代码:
/*
*dct.c
*
*Createdon:
2015-7-8
*Author:
smalljun
*/
#include
#include
#include
#include
#defineN8
#defineP3.141593
floatcof[8][8],dof[8][8];
floatc[8][8]={0};
floaty[256][256]={0};
charz[256][256]={0};
charx[256][256]={0};
//变换矩阵及其转置的赋值
voidCt()
{
intx,y,i,j,k;
//变换矩阵
for(i=0;i<8;i++)
{
cof[0][i]=1.0/sqrt(N);
}
for(j=1;j{
for(k=0;k{
cof[j][k]=(sqrt(2.0)/sqrt(N))*cos((j*(2*k+1))*P/(2*N));
}
}
//变换矩阵的转置
for(x=0;xfor(y=0;ydof[y][x]=cof[x][y];
}
//DCT编码
voidDCT(intdx,intdy){
inti,j;
for(i=0;ifor(j=0;j{
floats=0;
intk;
for(k=0;ks+=cof[i][k]*x[k+dx][j+dy];
c[i][j]=s;
}
for(i=0;ifor(j=0;j{
floats=0;
intk;
for(k=0;ks+=c[i][k]*dof[k][j];
y[i+dx][j+dy]=s;
}
}
//DCT的逆变换
voidIDCT(intdx,intdy)
{
inti,j;
for(i=0;ifor(j=0;j{
floats=0;
intk;
for(k=0;ks+=dof[i][k]*y[k+dx][j+dy];
c[i][j]=s;
}
for(i=0;ifor(j=0;j{
floats=0;
intk;
for(k=0;ks+=c[i][k]*cof[k][j];
z[i+dx][j+dy]=(int)s;//f[i][j]=(int)s;
}
}
intmain()
{
Ct();
inti,j;
FILE*fp;
fp=fopen("compress.raw","rb");
if(!
fp)
{
printf("ERROR!
\n");
}
fread(x,sizeof(char),(256*256),fp);
fclose(fp);
for(i=0;i<256;i=i+8)
for(j=0;j<256;j=j+8)
DCT(i,j);
fp=fopen("result.txt","wb");
for(i=0;i<256;i=i+1)
{
for(j=0;j<256;j=j+1)
{
fprintf(fp,"%f",y[i][j]);
}
fprintf(fp,"\n");
}
fclose(fp);
inttemp;
fp=fopen("result1.txt","wb");//量化压缩
for(i=0;i<256;i=i+1)
{
for(j=0;j<256;j=j+1)
{
temp=((int)(y[i][j]/10+0.5))*10;
y[i][j]=temp;
fprintf(fp,"%4d",temp);
}
fprintf(fp,"\n");
}
fclose(fp);
inttot=0;
fp=fopen("code.txt","wb");
for(i=0;i<256;i=i+1)
{
for(j=0;j<256;j=j+1)
{
temp=(int)y[i][j];
if(temp!
=0)
{
intnew1=i*256*256+j*256+y[i][j];
fprintf(fp,"%d",new1);
}
if(temp==0)
tot++;
}
}
fclose(fp);
printf("%d",tot);
for(i=0;i<256;i=i+8)
for(j=0;j<256;j=j+8)
IDCT(i,j);
fp=fopen("restore.raw","wb");//生成raw
for(i=0;i<256;i=i+1)
for(j=0;j<256;j=j+1)
{
fputc((z[i][j]),fp);
}
fclose(fp);
return0;
}