离散余弦变换的改进

离散余弦变换的改进 fficeffice" />[/B]
邓景仁(sgdjr2003)
2004年11月12日星期五
摘要:[/B]
关键词:[/B]



1 前言[/B]
由于我还是高一新丁,文学底子很薄弱,对于一些技术方面的知识,我是有口说不出,无法用文字表达出来,因此这里提供的知识只是我 所知道的1/4左右,还有3/4我不知该如何表达,特别是第三节“ 深入研究DCT”,我个人认为简直是浅入!
此文适合于那些对DCT或对Haar小波的Mallat算法有一定了解的人。
如果你只是菜鸟,不但想看懂此文,而且还要看懂其他的类似文章,那么我教你一个最快的学习方法:
设 X={10,20}
分解的方法:低频=10+20=30,高频=10-20=-10,
即 Y={30,-10}
合并的方法:X(0)=(低频+高频)/2=(30+(-10))/2=10,X(1)=X(0)-高频=10-(-10)=20
即 X={10,20}
只要搞清楚低频和高频是怎么来的和如何合并的即可。
2 [/B]DCT[/B]简介[/B]
DCT全名为Discrete Cosine Transform,中文名为离散余弦变换。在众人皆知的JPEG编码中,就是使用了DCT来压缩图像的。为什么DCT可以压缩图像?我想这个问题有很多人都想知道,但其实这是错误的说法!因为DCT在图像压缩中仅仅起到扶助的作用,给它n个数据,经变换后仍然会得出n个数据,DCT只不过消除了这n个数据的冗余性和相关性。
即,用很少的数据就能大致还原出这n个数据,其他的一些DCT系数只起到修正的作用,可有可无。
DCT有一个缺点,就是计算量很大!因为如果按照DCT的标准变换公式(二维)来实现8x8点阵的变换需要将近上万次计算!后来提出了一种优化方法,即将二维的DCT分解为两个一维的DCT,这样一来计算量就可以减少为原来的1/4。但是计算量依然巨大,不具有使用价值,后来在1988年有人提出了一种快速算法叫AAN,它也是将二维的DCT分解成一维的形式,但是二维计算量已减少到只有600来次了,JPG和MPEG编码中的DCT就是使用AAN算法实现的。
DCT还有一个缺点,就是不能无损变换,因为DCT系数都是一些无理数,目前为止,依然无法解决。
3 [/B]深入研究[/B]DCT[/B]
首先让我们来看看AAN算法的第一阶级变换代码:
For I = 0 To 3
J = 7 - I
Y(I) = X(I) + X(J)
Y(J) = X(I) - X(J)
Next I
设X={10,20,30,40,50,60,70,80}
那么Y={90,90,90,90,-10,-30,-50,-70}
可以看出,这一阶级的低频部分(相加得出的数据)全部相等,而高频部分则呈线性或者是有规律的。DCT 之所以能以较少的数据大致还原图像,就是因为通过预测高频部分而达到的。那么为何高频部分可以预测呢?请仔细看上面的代码,可以 看出DCT 是由外到内来进行处理的,由于像素与像素间有一定的关联性,所以靠的越近的像素之间的差就应该越小,越远就因该越大,但也并不是 说所有的数据都具有这种规律,因此DCT 预测出来的高频数据就会和原高频数据不大相同,它们之间的差便是第二节提出的修正数据。第二阶级变换则是在第一阶级变换的基础上 再次分解出低、高频,和预测高频,得出修正值。第三阶级……。最后,再将DCT系数按照重要程度由大到小,由左到右,重排列即可。
例:X={10, 20, 30, 40, 50, 60, 70, 80}
经过FDCT后:Y={127,-64,0,-7,-0,-2,0,-1}
其中127是最最重要的,而-64次之,以此类推。可以发现,-7,-2,-1的能量都很小,说明这三个修正值可以忽略,当忽略后,
得Y={127,-64,0,0,0,0,0,0}
经过IDCT后:X={ 14, 18, 27, 39, 51, 63, 72,76}
这与原始数据:X={10, 20, 30, 40, 50, 60, 70, 80}
是非常接近的,肉眼很难发觉。
4 [/B]为何[/B]JPEG2000[/B]放弃[/B]DCT[/B]
[/B]在JPEG2000里,放弃了基于块的DCT,而改为了小波变换。为何要放弃DCT呢?我认为最根本的原因还是跟DCT的计算量有关,第二节已经指出,为了减少计算量,我们不得不使用只能处理8X8点阵的AAN快速算法(目前,也只有基于8X8点阵的),对于一幅图像,必须将其分割成无数个8X8大小的“块”,对块进行变换。在低码率下,就会产生方块效应,要解决这个问题,唯有不使用基于区块的AAN 快速算法,而是使用直接变换法,但计算量惊人!由于小波变换计算量很少,便于直接处理图像数据,因此就不会产生块效应,但假如用 小波也进行基于8X8点阵的块变换,在低码率下,同样也会有块效应!只要是基于块变换的,那么在低码率下就会出现块效应,无论是DCT还是小波。因此,如果忽略DCT直接处理的计算量问题的话,我认为压缩效率会比JPEG2000更好!(具体原因暂不讨论)
5 DCT[/B]的改进[/B][/B]
下面的代码是我对DCT变换的改进,它具有以下特性
l 无损变换
l 计算量少
l 原位计算
经改进后,它已不再叫作DCT了,可以认为是一种新的算法,只不过是在DCT的基础上修改而来。
以下是正变换:X为输入端,Y为输出端
设X={10,20,30,40,50,60,70,80}
那么Y={45,40,0,0,0,0,0,0}
'----------------------------------第一阶级
For I = 0 To 3
J = 7 - I
Y(J) = X(J) - X(I)
Y(I) = X(I) + Fix(Y(J) / 2)
Next I
'-----------------------------------第二阶级
For H = 0 To 4 Step 4
For I = 0 To 1
J = 3 - I
X(J + H) = Y(J + H) - Y(I + H)
X(I + H) = Y(I + H) + Fix(X(J + H) / 2)
Next I
Next H
'-----------------------------------第三阶级
For I = 0 To 6 Step 2
Y(I + 1) = X(I + 1) - X(I)
Y(I) = X(I) + Fix(Y(I + 1) / 2)
Next I
'-----------------------------------预测
Y(3) = Y(3) - Y(2)
Y(6) = Y(6) - Y(7)
Y(7) = Y(7) - Y(4)
'重要性排序与AAN一样,皆为{0,4,2,6,1,5,7,3},此略

为何能无损?为何能原位?和具体实现原理暂时略,以后我会补上
6 [/B]参考[/B][/B]
[1]丁贵广,计文平,郭宝龙 Visual C++6.0数字图像编码 p44,p57,p170
 
我又写了一个改进算法,可以无损或有损变换


详见:host.bluexp.net/vbgood/forum/forum_posts.asp?TID=20672&PN=1&20672.html


我最近由图像编码改为视频编码 但在这方面我还是新手,急需高手指点。。。

还有就是我想自己制订编码算法(即自创算法)。。

在此附上我在图像处理上,设计的仿DCT一维变换的算法。原理很简单,就是基于数据的相关性。。。,如果稍加改动,是可以无损变 换的,即不存在小数的精度问题。反变换就是本代码的逆代码。

Sub FT(Dat() As Integer, K As Integer, L As Integer)
Dim X(7) As Single, Y(7) As Single
Dim Pos As Integer, I As Integer, J As Integer
'0.125, 0.25, 0.5, 0.75, 0.875 比例系数
'1 / 8, 2 / 8, 4 / 8, 6 / 8, 7 / 8 比例系数的分数表达
' = Array(0, 4, 2, 6, 1, 5, 7, 3)
Pos = L
For I = 0 To 7
X(I) = Dat(Pos + K * I)
Next I

For I = 0 To 3
J = 7 - I
Y(I) = X(I) + X(J)
Y(J) = X(J) - X(I)
Next I

X(0) = Y(0) + Y(3)
X(1) = Y(1) + Y(2)
X(2) = Y(2) - Y(1)
X(3) = Y(3) - Y(0)
X(4) = Y(4)
X(5) = (Y(6) - Y(5)) * 0.5
X(6) = (Y(6) + Y(5)) * 0.875
X(7) = Y(7)

Y(0) = X(0) + X(1)
Y(1) = X(1) - Y(0) * 0.5
Y(2) = X(2) * 0.25 + X(3) * 0.75
Y(3) = X(3) * 0.25 - X(2) * 0.75

X(4) = X(5) + X(4): X(5) = X(5) - X(4) * 0.5
X(6) = X(7) + X(6): X(7) = X(7) - X(6) * 0.5

Y(4) = X(4) * 0.125 + X(6) * 0.875
Y(5) = X(6) * 0.125 - X(4) * 0.875
Y(6) = X(5) * 0.25 + X(7) * 0.75
Y(7) = X(7) * 0.25 - X(5) * 0.75

For I = 0 To 7
Dat(Pos + K * I) = Y(P(I))
Next I
End Sub


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值