图像二维整数离散余弦变换DCT 变换算法和DSP实现课程设计.docx

上传人:b****8 文档编号:11075869 上传时间:2023-02-24 格式:DOCX 页数:16 大小:216.25KB
下载 相关 举报
图像二维整数离散余弦变换DCT 变换算法和DSP实现课程设计.docx_第1页
第1页 / 共16页
图像二维整数离散余弦变换DCT 变换算法和DSP实现课程设计.docx_第2页
第2页 / 共16页
图像二维整数离散余弦变换DCT 变换算法和DSP实现课程设计.docx_第3页
第3页 / 共16页
图像二维整数离散余弦变换DCT 变换算法和DSP实现课程设计.docx_第4页
第4页 / 共16页
图像二维整数离散余弦变换DCT 变换算法和DSP实现课程设计.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

图像二维整数离散余弦变换DCT 变换算法和DSP实现课程设计.docx

《图像二维整数离散余弦变换DCT 变换算法和DSP实现课程设计.docx》由会员分享,可在线阅读,更多相关《图像二维整数离散余弦变换DCT 变换算法和DSP实现课程设计.docx(16页珍藏版)》请在冰豆网上搜索。

图像二维整数离散余弦变换DCT 变换算法和DSP实现课程设计.docx

图像二维整数离散余弦变换DCT变换算法和DSP实现课程设计

课程设计

课程名称光电图像处理综合课程设计

题目名称图像二维整数离散余弦变换

(DCT)变换算法和DSP实现

 

2013年11月26日

 

 

 

一、离散余弦变换

1、概念

离散余弦变换(DCTforDiscreteCosineTransform)是与傅里叶变换相关的一种变换,它类似于离散傅里叶变换(DFTforDiscreteFourierTransform),但是只使用实数。

离散余弦变换相当于一个长度大概是它两倍的离散傅里叶变换,这个离散傅里叶变换是对一个实偶函数进行的(因为一个实偶函数的傅里叶变换仍然是一个实偶函数),在有些变形里面需要将输入或者输出的位置移动半个单位(DCT有8种标准类型,其中4种是常见的)。

最常用的一种离散余弦变换的类型是下面给出的第二种类型,通常我们所说的离散余弦变换指的就是这种。

它的逆,也就是下面给出的第三种类型,通常相应的被称为"反离散余弦变换","逆离散余弦变换"或者"IDCT"。

有两个相关的变换,一个是离散正弦变换(DSTforDiscreteSineTransform),它相当于一个长度大概是它两倍的实奇函数的离散傅里叶变换;另一个是改进的离散余弦变换(MDCTforModifiedDiscreteCosineTransform),它相当于对交叠的数据进行离散余弦变换。

离散余弦变换,尤其是它的第二种类型,经常被信号处理和图像处理使用,用于对信号和图像(包括静止图像和运动图像)进行有损数据压缩。

这是由于离散余弦变换具有很强的"能量集中"特性:

大多数的自然信号(包括声音和图像)的能量都集中在离散余弦变换后的低频部分,而且当信号具有接近马尔科夫过程(Markovprocesses)的统计特性时,离散余弦变换的去相关性接近于K-L变换(Karhunen-Loève变换--它具有最优的去相关性)的性能。

2、离散余弦变换用于图像处理:

图像数据一般有较强的相关性,若所选用的正交矢量空间的基矢量与图像本身的主要特征相近,在该正交矢量空间中描述图像数据则会变得更简单。

经过正交变换,会把原来分散在原空间的图像数据在新的坐标空间中得到集中。

对于大多数图像,大量变换系数很小,只要删除接近于零的系数,并且对较小的系数进行粗量化,而保留包含图像主要信息的系数,以此进行压缩编码。

在重建图像进行解码时,所损失的将是一些不重要的信息,几乎不会引起图像的失真。

在变换编码中,首先要将图像数据分割成子图像,然后对子图像数据块实施某种变换,如DCT变换,那么子图像尺寸取多少好呢?

根据实践证明子图像尺寸取4×4、8×8、16×16适合作图像的压缩,这是因为:

<1>如果子图像尺寸取得太小,虽然计算速度快,实现简单,但压缩能力有一定的限制。

<2>如果子图像尺寸取得太大,虽然去相关效果变好,因为象DFT、DCT等正弦型变换均具有渐近最佳性,但也渐趋饱和。

若尺寸太大,由于图像本身的相关性很小,反而使其压缩效果不显示,而且增加了计算的复杂性。

8*8FDCT和IDCT的普通算法如下:

其中:

离散余弦变换(DiscreteCosineTranform,简称DCT)是一种与傅立叶变换紧密相关的数学运算。

在傅立叶级数展开式中,如果被展开的函数式是偶函数,那么其傅立叶级数中只包含余弦项,再将其离散化可导出余弦变换,因此称之为离散余弦变换。

时间域中信号需要许多数据点表示;在x轴表示时间,在y轴表示幅度。

信号一旦用傅立叶变换转换到频率域,就只需要几点就可以表示这个相同的信号。

如我们已经看到的那样,原因就是信号只含有少量的频率成分。

这允许在频率域中只用几个数据点就可以表示信号,而在时间域中表示则需要大量数据点。

这一技术可以应用到彩色图像上。

彩色图像有像素组成,这些像素具有RGB彩色值。

每个像素都带有x,y坐标,对每种原色使用8x8或者16x16矩阵。

在灰度图像中像素具有灰度值,它的x,y坐标由灰色的幅度组成。

为了在JPEG中压缩灰度图像,每个像素被翻译为亮度或灰度值。

为了压缩RGB彩色图像,这项工作必须进行三遍,因为JPEG分别得处理每个颜色成分,R成分第一个被压缩,然后是G成分,最后是B成分。

而一个8x8矩阵的64个值,每个值都带有各自的x,y坐标,这样我们就有了一个像素的三维表示法,称作控件表达式或空间域。

通过DCT变换,空间表达式就转化为频谱表达式或频率域。

从而到达了数据压缩的目的。

DCT式目前最佳的图像变换,它有很多优点。

DCT是正交变换,它可以将8x8图像空间表达式转换为频率域,只需要用少量的数据点表示图像;DCT产生的系数很容易被量化,因此能获得好的块压缩;DCT算法的性能很好,它有快速算法,如采用快速傅立叶变换可以进行高效的运算,因此它在硬件和软件中都容易实现;而且DCT算法是对称的,所以利用逆DCT算法可以用来解压缩图像。

为什么采用8x8的图像块,其原因是由于计算量和像素之间关系的数量,许多研究表明,在15或20个像素之后,像素间的相关性开始下降。

就是说,一列相似的像素通常会持续15到20个像素那么长,在此之后,像素就会改变幅度水平(或反向)。

模拟图像经采样后成为离散化的亮度值然后分成一个个宏块,而一个宏块有分成8x8大小的块,可以用一个矩阵来表示这个块。

在这里,N=8,矩阵中元素f(i,j)表示块中第i行、第j列像素的亮度值。

把该矩阵看作一个空间域,显然,块中这些亮度值的大小有一定的随机性,无序性,或者说亮度值的分布没有什么特征;DCT变换就是来解决这个问题的,把这些随机的数据变的有序,便于对数据进行编码压缩。

3、量化

量化过程实际上就是对DCT系数的一个优化过程。

它是利用了人眼对高频部分不敏感的特性来实现数据的大幅简化。

  量化过程实际上是简单地把频率领域上每个成份,除以一个对于该成份的常数,且接着四舍五入取最接近的整数。

  这是整个过程中的主要有损运算。

以这个结果来说,经常会把很多高频率的成份四舍五入而接近0,且剩下很多会变成小的正或负数。

  整个量化的目的是减小非“0”系数的幅度以及增加“0”值系数的数目。

  量化是图像质量下降的最主要原因。

因为人眼对亮度信号比对色差信号更敏感,因此使用了两种量化表:

亮度量化值和色差量化值。

总体上来说,DCT变换实际是空间域的低通滤波器。

对Y分量采用细量化,对UV采用粗量化。

量化表是控制JPEG压缩比的关键,这个步骤除掉了一些高频量;另一个重要原因是所有图片的点与点之间会有一个色彩过渡的过程,大量的图像信息被包含在低频率中,经过量化处理后,在高频率段,将出现大量连续的零。

二、流程图

基于DCT的图像压缩编码的程序实现的流程图如图3-1所示。

 

图3-1程序流程图

三、程序中实现

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

/*学号:

姓名:

*/

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

#include

#include

#defineN8

#definePI3.1415926

intf1[N][N]=

{

{139,144,149,153,155,155,155,155},

{144,151,153,156,159,156,156,156},

{150,155,160,163,158,156,156,156},

{159,161,162,160,160,159,159,159},

{159,160,161,162,162,155,155,155},

{161,161,161,161,160,157,157,157},

{162,162,161,163,162,157,157,157},

{162,162,161,161,163,158,158,158},

};

intq1[N][N]=//定义色度量化系数

{

{17,18,24,47,99,99,99,99},

{18,21,26,66,99,99,99,99},

{24,26,56,99,99,99,99,99},

{47,66,99,99,99,99,99,99},

{99,99,99,99,99,99,99,99},

{99,99,99,99,99,99,99,99},

{99,99,99,99,99,99,99,99},

{99,99,99,99,99,99,99,99},

};

intq2[N][N]=//定义亮度量化系数

{

{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}

};

voidshowMat_d(double**matShow);

voidshowMat_i(int**matShow);//显示函数,输出为整形数据

voidDCT(int**f,double**F);//经过FDCT变换,f为输入数据,F为输出数据

voidIDCT(int**f,int**F);//经过逆变换,f为输入数据,F为输出数据

voidquant(double**f,int**F);//量化过程,f为传进的DCT数据,F为量化后的数据

voidiQuant(int**f,int**F);//逆量化过程,f为量化后的数据,F为消除了量化的数据

voidmain()

{

doubleF[N][N]={0};//初始化输出数组

intf_1[N][N]={0};//初始化逆变换的输出数组

intf2[N][N]={0};//自定义输入数组的数据

intfq[N][N]={0};//定义量化后的数组。

intfq_1[N][N]={0};//定义经过逆变化后的数组

inti=0,j=0;

//////////////////////////////////////////////////////////////////////////

printf("输入数据f(x,y)为:

\n");

showMat_i((int**)f1);//输出原始数据

for(i=0;i

for(j=0;j

f1[i][j]-=128;//减128

printf("\nDCT之后,数据F(u,v)为:

\n");

DCT((int**)f1,(double**)F);//DCT变换

showMat_d((double**)F);//输出DCT数据

quant((double**)F,(int**)fq);//量化

printf("\n量化后的DCT为:

\n");

showMat_i((int**)fq);//输出量化后的DCT数据

iQuant((int**)fq,(int**)fq_1);//经过逆量化处理

printf("\n逆量化后的数为:

\n");

showMat_i((int**)fq_1);

printf("\nIDCT之后,数据f'(x,y)为:

\n");

IDCT((int**)fq_1,(int**)f_1);//IDCT变换

for(i=0;i

for(j=0;j

f_1[i][j]+=128;//加128

showMat_i((int**)f_1);//输出数据

//////////////////////////////////////////////////////////////////////////

}

voidshowMat_d(double**matShow)

{

inti=0;

intj=0;

for(i=0;i

{

for(j=0;j

{

printf("%5.1f",((*((double*)matShow+i*N+j))));

}

printf("\n");

}

}

voidshowMat_i(int**matShow)

{

inti=0;

intj=0;

for(i=0;i

{

for(j=0;j

{

printf("%3d",((*((int*)matShow+i*N+j))));

}

printf("\n");

}

}

voidquant(double**f,int**F)

{

inti=0;

intj=0;

doubletemp[N][N]={0.0};

for(i=0;i

for(j=0;j

{

*((double*)temp+i*N+j)=(*((double*)f+i*N+j)/((*((int*)q2+i*N+j))));

if(((*((double*)temp+i*N+j))<0))

{

*((int*)F+i*N+j)=(int)((*((double*)temp+i*N+j))-0.5);//-0.5为四舍五入取整

}

else

*((int*)F+i*N+j)=(int)((*((double*)temp+i*N+j))+0.5);//+0.5为四舍五入取整

}

}

voidiQuant(int**f,int**F)

{

inti=0;

intj=0;

doubletemp[N][N]={0.0};

for(i=0;i

for(j=0;j

{

*((double*)temp+i*N+j)=(double)*((int*)f+i*N+j)*(*((int*)q2+i*N+j));

if(((*((double*)temp+i*N+j))<0))

{

*((int*)F+i*N+j)=(int)((*((double*)temp+i*N+j))-0.5);//-0.5为四舍五入取整

}

else

*((int*)F+i*N+j)=(int)((*((double*)temp+i*N+j))+0.5);//+0.5为四舍五入取整

}

}

voidDCT(int**f,double**F)//DCT转换

{

intx,m,n;

doubledTemp[N][N]={0.0};//中间矩阵

doubletemp[N][N]={0.0};

doublecoff[N]={0.0};//变换系数

coff[0]=1/sqrt(N);

for(m=1;m

{

coff[m]=sqrt

(2)/sqrt(N);

}

//一维变换,,,,对列进行一维DCT变换。

for(n=0;n

for(m=0;m

for(x=0;x

(*((double*)temp+m*N+n))+=(double)(*((int*)f+x*N+n))*coff[m]*cos((2*x+1)*PI*m/(2*N));

//二维变换,,对行进行以为DCT变换

for(m=0;m

for(n=0;n

for(x=0;x

}

voidIDCT(int**f,int**F)//逆变换

{

inty,m,x;

doubledTemp[N][N]={0.0};//中间矩阵

doubletemp[N][N]={0.0};

doublecoff[N]={0.0};//变换系数

coff[0]=1.0/sqrt(N);

for(m=1;m

{

coff[m]=sqrt

(2)/sqrt(N);

}

//一维变换

for(x=0;x

for(y=0;y

for(m=0;m

(*((double*)temp+x*N+y))+=(*((int*)f+x*N+m))*coff[m]*cos((2*y+1)*PI*m/(2*N));

//二维变换

for(y=0;y

for(x=0;x

{

for(m=0;m

(*((double*)dTemp+x*N+y))+=(*((double*)temp+m*N+y))*coff[m]*cos((2*x+1)*PI*m/(2*N));

if((*((double*)dTemp+x*N+y))<0)

{

(*((int*)F+x*N+y))=(int)((*((double*)dTemp+x*N+y))-0.5);//-0.5为四舍五入取整

}

else

(*((int*)F+x*N+y))=(int)((*((double*)dTemp+x*N+y))+0.5);//+0.5为四舍五入取整

}

四、输出结果

亮度量化输出结果:

色度量化结果为:

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 外语学习 > 英语学习

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1