基于DCT变换的图像编解码matlab代码.docx
《基于DCT变换的图像编解码matlab代码.docx》由会员分享,可在线阅读,更多相关《基于DCT变换的图像编解码matlab代码.docx(8页珍藏版)》请在冰豆网上搜索。
基于DCT变换的图像编解码matlab代码
//////////////////////////////////////////////////////////////////////////////////////////////////////
//基于块的变换编码
//读入灰度图像数据,完成8*8像素块余弦变换并进行DCT系数矩阵量化,把得到的量化矩阵游程编码
//////////////////////////////////////////////////////////////////////////////////////////////////////
#include
#include
#include
#include
#include
#include
#definePI3.1415926
#defineWIDTH256
#defineHEIGHT256
usingnamespacestd;
doublearr[WIDTH][HEIGHT]={0};//自定义数组保存文件二进制数据
doubledct2[8][8]={100};//自定义数组保存待变换8*8像素块二进制数据
intx(14),y(22);//任意设定开始选定数据坐标
voidDCT(int,int,doubledct2[8][8]);//余弦变换算法函实现数
doubleCuCv(int);//中间函数C(u),C(v)
voidQuant(doubledct2[8][8]);//均匀量化函数
voidRun_level(doubledct2[8][8]);//游程编码函数
//*******************************************************************************************************
voidmain()
{
charch;
intdata[8][8]={0};
FILE*fp=NULL;//创建文件指针并初始化
//----------------------------------------------------------以二进制只读形式打开待处理IMG文件
fp=fopen("LENA256.IMG","rb");
if(fp==NULL)//如果失败了
{
printf("Buffererror!
Programterminated!
!
\n\n");
}
ofstreamoutfile("源文件二进制数据.txt");//建立文件
charbuf[24];
intcount=0;
//----------------------------------------------------------将读入文件的数据保存在自定义数组中
for(inti(0);i{
for(intj(0);j{
intc=fgetc(fp);
arr[i][j]=c;
}
}
fclose(fp);//关闭文件
cout<<"256*256选定8*8像素块开始坐标:
"<<//----------------------------------------------------------选定8*8像素块,并保存数据到文本文件中
for(inti(x);i{
for(intj(y);j{
outfile<}
outfile<}
outfile.close();
DCT(x,y,dct2);//余弦变换
Quant(dct2);//均匀量化
for(inti=0;i<8;i++)//变换结果输出到文本文件中
{
for(intj=0;j<8;j++)
{
cout<}
}cout<Run_level(dct2);//zig-zag游程编码
system("pause");
}
//*******************************************************************************************************
voidDCT(intm,intn,doubledct2[8][8])//余弦变换算法实现函数
{
for(intu(0);u<8;u++)
{
for(intv(0);v<8;v++)
{
doublesum=0;
for(inti(0);i<8;i++)
{
for(intj(0);j<8;j++)
{
sum=sum+(arr[m+i][n+j]*cos((2*i+1)*u*PI/16)*cos((2*j+1)*v*PI/16));
}
}
doubletemp=CuCv(u)*CuCv(v);
dct2[u][v]=int(temp*sum/4+0.5);//余弦变换后的值,四舍五入取整
}
}
ofstreamoutfile2("余弦变换取整后数据.txt");
for(inti=0;i<8;i++)//变换结果输出到文本文件中
{
for(intj=0;j<8;j++)
{
outfile2<}
outfile2<}
outfile2.close();
}
//*******************************************************************************************************
doubleCuCv(inta)//中间函数C(u),C(v)
{
if(a==0)
{
return1/pow(2,0.5);
}
else
{
return1;
}
}
//*******************************************************************************************************
voidQuant(doubledct2[8][8])//均匀量化函数
{
intQS[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,113,92,
49,64,78,87,103,121,120,101,
72,92,95,98,112,100,103,99
};
for(inti(0);i<8;i++)
{
for(intj(0);j<8;j++)
{
dct2[i][j]=int(double(dct2[i][j])/QS[i][j]+0.5);
}
}
ofstreamoutfile3("均匀量化后数据.txt");
for(inti=0;i<8;i++)//变换结果输出到文本文件中
{
for(intj=0;j<8;j++)
{
outfile3<}
outfile3<}
outfile3.close();
}
//*******************************************************************************************************
voidRun_level(doubledct2[8][8])//游程编码函数
{
intk(0),a[8][8]={0};
inti(0),j(0),s(0);//i=行----j=列----s=总行/列数
intdir(0);//扫描方向,0:
右方,1:
左下,2:
下方,3:
右上
ofstreamoutfile4("游程符号.txt");
while(s<8*8)
{
a[i][j]=dct2[i][j];//初始化zig-zag扫描位置
inttemp0=i,temp1=j;
switch(dir)//下一个扫描位置
{
case0:
j++;//行进方向
if(i==0)
dir=1;
if(i==7)
dir=3;
break;
case1:
i++;
j--;
if(i==7)
dir=0;
elseif(j==0)
dir=2;
break;
case2:
i++;
if(j==0)
dir=3;
if(j==7)
dir=1;
break;
case3:
i--;
j++;
if(j==7)
dir=2;
elseif(i==0)
dir=0;
break;
default:
break;
}
if(a[temp0][temp1]!
=dct2[i][j])
{//输出游程符号到文件
if(a[temp0][temp1]!
=0)
{
if(k!
=0)k++;
outfile4<<"("<k=0;
}
}
elsek++;
s++;
}
outfile4.close();
}