DCTb變換

Contents

1.       DCT變換編碼C語言

2.     MPEG4中逆DCT變換

3.     DCT變換探究

4.     快速DCT變換

 

 

 

DCT變換編碼C語言

#include <memory.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#define PI 3.1415926
#define CLK_TCK CLOCKS_PER_SEC
int N;
void DCT(double *f,double *F)
{
  int n,m,x;
 double *dTemp = new double[N*N];//中間矩陣
 double *coff = new double[N*N];//變換系數
 coff[0] = 1/sqrt(N);
 for( m=1; m<N; m++ )
  coff

­ = sqrt(2)/sqrt(N);
 memset( dTemp, 0, sizeof(double)*N*N );
 memset( F, 0, sizeof(double)*N*N );

 //一維變換
 for(n=0;n<N;n++)
  for(m=0;m<N;m++)
   for(x=0;x<N;x++)
    dTemp[m*N+n] += f[x*N+n] * coff

­ * cos( (2*x+1) * PI * m/(2*N) );

 //第二次一維變換
 for(m=0;m<N;m++)c
  for(n=0;n<N;n++)
   for(x=0;x<N;x++)
    F[m*N+n] += dTemp[m*N+x] * coff[n] * cos( (2*x+1) * PI * n/(2*N) );

 delete []dTemp;
 delete []coff;
}

void iDCT(double *f,double *F)
{
 int m,y,x;
 double *dTemp=new double[N*N];//中間矩陣
 double *coff=new double[N*N];//變換系數
 coff[0]=1/sqrt(N);
 for(m=1;m<N;m++)
  coff

­=sqrt(2)/sqrt(N);
 memset(dTemp,0,sizeof(double)*N*N);
 memset(F,0,sizeof(double)*N*N);

 //一維變換
 for(x=0;x<N;x++)
  for(y=0;y<N;y++)
   for(m=0;m<N;m++)
    dTemp[x*N+y]+=F[x*N+m]*coff

­*cos((2*y+1)*PI*m/(2*N));

 //第二次一維變換
 for(y=0;y<N;y++)
  for(x=0;x<N;x++)
   for(m=0;m<N;m++)
    F[x*N+y]+=dTemp[m*N+y]*coff

­*cos((2*x+1)*PI*m/(2*N));

 delete []dTemp;
 delete []coff;

}

int main()

  clock_t start,end;
 start=clock();
 int i;
 long L;
 
 printf("變換維數:");
 scanf("%d",&N);
 
 double *f=new double[N*N];//初始矩陣
 double *F=new double[N*N];//變換後輸出矩陣 

memset(F,0,sizeof(double)*N*N);//初始化爲0

 for(i=0;i<N*N;i++)
 {
  printf("f[%d][%d]:",i/N,i%N);
  scanf("%lf",&f[i]);
 }

 printf("循環次數:");
 scanf("%d",&L);

//輸出初始矩陣
 printf("變換前:\n");
 for(i=1;i<=N*N;i++)
 {
  printf("%f\t",f[i-1]);
  if(i%N==0)
   printf("\n");
 }

 for(i=0;i<L;i++)
  DCT(f,F);//變換
//輸出變換後矩陣
 printf("變換後:\n");

 for(i=1;i<=N*N;i++)
 {
  printf("%f\t",F[i-1]);
  if(i%N==0)
   printf("\n");
 } 

for(i=0;i<L;i++)
 iDCT(f,F);
 //輸出反變換後矩陣
 printf("反變換後:\n");
 for(i=1;i<=N*N;i++)
 {  printf("%f\t",f[i-1]);
  if(i%N==0)
   printf("\n");
 }
 //printf("\n");

 delete []f;
 delete []F;
 end=clock();
 printf("耗時:%f\n",(double)(end-start)/CLK_TCK);
 return 0; 
}

 

===================================================================

MPEG4中逆DCT變換

一旦DCT係數F[u][v]被恢復,那麼就可以用逆DCT變換來獲得逆變換值f[y][x],這些只要被飽和到-256f[y][x]255

對短頭格式,由於不存在隔行模式,因此全部用幀 DCT變換,就是一般的情況。

非短頭格式時,如果使用隔行模式,並且dct_type等於1,此時使用場DCT變換,場DCT變換的算法同幀DCT變換完全一樣,只是輸出的時候需要將按場組織的宏塊轉換爲按幀組織的宏塊。

下面簡單介紹一下DCT變換和逆變換的過程。

矩陣大小爲NxN的二維DCT變換爲:

                       

                                    u, v, x, y = 0, 1, 2, ¼ N-1

                        其中     x, y 是原始域中的空間座標

                                    u, v 是變換域中的空間座標

                       

DCT變換定義爲:

                       

如果每個像素爲n比特,則DCT變換的輸入爲n+1比特,逆DCT變換的輸出爲n+1比特。DCT變換後的DCT係數的長度爲n+4比特,動態範圍爲[-2n+3:+2n+3-1]。對我們來說這裏的n等於8

NxN的逆DCT變換的實現必須符合IEEE的關於8x8的逆DCT變換的實現的標準,即IEEE Standard Specification for the Implementations of 8 by 8 Inverse Discrete Cosine Transform, Std 1180-1990, December 6, 1990,不過有下列修改:

1)                IEEE規範中的3.2小節的item(1)中最後一句話被替換爲:<<Data sets of 1 000 000 (one million) blocks each should be generated for (L=256, H=255), (L=H=5) and (L=384, H=383). >>

2)                IEEE規範中的3.3小節的text被替換爲:<<For any pixel location, the peak error shall not exceed 2 in magnitude.  There is no other accuracy requirement  for this test.>>

3)                Let F be the set of 4096 blocks Bi[y][x] (i=0..4095) defined as follows :

a) Bi[0][0] = i - 2048

                                   b) Bi[7][7] = 1 if  Bi[0][0] is even, Bi[7][7] = 0 if  Bi[0][0] is odd

c) All other coefficients Bi[y][x] other than Bi[0][0] and Bi[7][7] are equal to 0

For each block Bi[y][x] that belongs to set F defined above, an IDCT that claims to be compliant shall output a block f[y][x] that as a peak error of 1 or less compared to the reference saturated mathematical integer-number IDCT fíí(x,y).  In other words, | f[y][x] - fíí(x,y)| shall be <= 1 for all x and y.

NOTE 1  lause  2.3 Std 1180-1990 “Considerations of Specifying IDCT Mismatch Errors” requires the specification of periodic intra-picture coding in order to control the accumulation of mismatch errors. Every macroblock is required to be refreshed before it is coded 132 times as predictive macroblocks. Macroblocks in B-pictures (and skipped macroblocks in P-pictures) are excluded from the counting because they do not lead to the accumulation of mismatch errors. This requirement is the same as indicated in 1180-1990 for visual telephony according to ITU-T Recommendation H.261.

NOTE 2  Whilst the IEEE IDCT standard mentioned above is a necessary condition for the satisfactory implementation of the IDCT function it should be understood that this is not sufficient. In particular attention is drawn to the following sentence from subclause 5.4: “Where arithmetic precision is not specified, such as the calculation of the IDCT, the precision shall be sufficient so that significant errors do not occur in the final integer values.”

DCT變換的過程這裏不再詳述,需要實現這個的可以去參考這個標準。

在實際應用中一般通過兩次1-D IDCT變換來完成2-D IDCT變換,這種方法通常被稱爲行-列法。

一般來說,後者在結構上的對稱性更好,並且可以重複使用硬件資源,所以在我們的芯片設計選用一種行-列法來進行IDCT單元的結構研究。

二維IDCT可以分解成二次一維IDCT運算,如以下公式。

          

在結構上,上兩式所定義的運算使用了相同的運算“核”(如以下公式所示), 它們具有相似性。因此利用三角函數的各種關係,可以得到“核”的快速算法。

            其中,

爲了便於理解,可將快速算法表示成蝶形圖,如下圖。

將對模塊進行一維IDCT變換的結果存儲起來,轉置輸出,再進行一次IDCT變換,即爲相應的二維IDCT變換。

              

4-8  摺疊結構的二維IDCT單元 

一行數據 ( 一行有8個像素數據 ) 在該單元中的處理流程是:1—>2—>3—>4—>5—>6—>7—>8。

 

 

 

DCT變換探究

1 前言
此文適合於那些對DCT或對Haar小波的Mallat算法有一定了解的人。
由於我還是高一新丁,文學底子很薄弱,對於一些技術方面的知識,我是有口說不出,無法用文字表達出來,因此這裏提供的知識只是我 所知道的1/4左右,還有3/4我不知該如何表達,特別是第三節“ 深入研究DCT”,我個人認爲簡直是淺入!
如果你只是菜鳥,不但想看懂此文,而且還要看懂其他的類似文章,那麼我教你一個最快的學習方法:
設 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 DCT簡介
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 深入研究

首先讓我們來看看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爲何JPEG2000放棄DCT
在JPEG2000裏,放棄了基於塊的DCT,而改爲了小波變換。爲何要放棄DCT呢?我認爲最根本的原因還是跟DCT的計算量有關,第二節已經指出,爲了減少計算量,我們不得不使用只能處理8X8點陣的AAN快速算法(目前,也只有基於8X8點陣的),對於一幅圖像,必須將其分割成無數個8X8大小的“塊”,對塊進行變換。在低碼率下,就會產生方塊效應,要解決這個問題,唯有不使用基於區塊的AAN 快速算法,而是使用直接變換法,但計算量驚人!由於小波變換計算量很少,便於直接處理圖像數據,因此就不會產生塊效應,但假如用小波也進行基於8X8點陣的塊變換,在低碼率下,同樣也會有塊效應!只要是基於塊變換的,那麼在低碼率下就會出現塊效應,無論是DCT還是小波。因此,如果忽略DCT直接處理的計算量問題的話,我認爲壓縮效率會比JPEG2000更好!(具體原因暫不討論)

5 DCT的改進
下面的代碼是我對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參考
[1]丁貴廣,計文平,郭寶龍 Visual C++6.0數字圖像編碼 p44,p57,p170

 

 

快速DCT變換

 

仿效FFT的FDCT方法有與DCT無關的複數運算部分,選用代數分解法可以降低運

算量,達到高速運算的目的。代數分解法實現如下:對一維DCT表達式直接展開,

尋找各點表達式中共同項,仿FFT蝶形關係,將表達式中的共同項作爲下一級節

點,依次進行多次,最後得到變換結果。

一、DCT部分

例子:

Define cos(n*pi/16) Cn

F(0
,v)=0.5*C(0)*[x(0)+x(1)+x(2)+x(3)+x(4)+x(5)+x(6)+x(7)]

F(1,v)=0.5*C(0)*[x(0)*C1+x(1)*C3+x(2)*C5+x(3)*C7+x(4)*C9

              +x(5)*C11+x(6)*C13+x(7)*C15]

           =0.5*{[x(0)-X(7)]C1+[X(1)-X(6)]*C3+[X(2)-x(5)]*C5

              +[x(3)-x(4)]*C7]

從上面的式子可以看到07,16,25,34可以作爲第一次運算的相加節點,將所有節點

的表達式列出後,可發現一個規律,得到一蝶形圖,按之編程,如下:

#define  C1 0.9808
#define  C2 0.9239
#define  C3 0.8315
#define  C4 0.7071
#define  C5 0.5556
#define  C6 0.3827
#define  C7 0.1951

//先做行DCT
void fdctrow(double *blk)

double S07,S16,S25,S34,S0734,S1625;
double D07,D16,D25,D34,D0734,D1625;

S07=blk[0]+blk[7];
S16=blk[1]+blk[6];
S25=blk[2]+blk[5];
S34=blk[3]+blk[4];
S0734=S07+S34;
S1625=S16+S25;

D07=blk[0]-blk[7];
D16=blk[1]-blk[6];
D25=blk[2]-blk[5];
D34=blk[3]-blk[4];
D0734=S07-S34;
D1625=S16-S25;

blk[0]=0.5*(C4*(S0734+S1625));
blk[1]=0.5*(C1*D07+C3*D16+C5*D25+C7*D34);
blk[2]=0.5*(C2*D0734+C6*D1625);
blk[3]=0.5*(C3*D07-C7*D16-C1*D25-C5*D34);
blk[4]=0.5*(C4*(S0734-S1625));
blk[5]=0.5*(C5*D07-C1*D16+C7*D25+C3*D34);
blk[6]=0.5*(C6*D0734-C2*D1625);
blk[7]=0.5*(C7*D07-C5*D16+C3*D25-C1*D34);

}

//再做列DCT

void fdctcol(double *blk)
{
double S07,S16,S25,S34,S0734,S1625;
double D07,D16,D25,D34,D0734,D1625;

S07=blk[0*8]+blk[7*8];
S16=blk[1*8]+blk[6*8];
S25=blk[2*8]+blk[5*8];
S34=blk[3*8]+blk[4*8];
S0734=S07+S34;
S1625=S16+S25;

D07=blk[0*8]-blk[7*8];
D16=blk[1*8]-blk[6*8];
D25=blk[2*8]-blk[5*8];
D34=blk[3*8]-blk[4*8];
D0734=S07-S34;
D1625=S16-S25;

blk[0*8]=0.5*(C4*(S0734+S1625));
blk[1*8]=0.5*(C1*D07+C3*D16+C5*D25+C7*D34);
blk[2*8]=0.5*(C2*D0734+C6*D1625);
blk[3*8]=0.5*(C3*D07-C7*D16-C1*D25-C5*D34);
blk[4*8]=0.5*(C4*(S0734-S1625));
blk[5*8]=0.5*(C5*D07-C1*D16+C7*D25+C3*D34);
blk[6*8]=0.5*(C6*D0734-C2*D1625);
blk[7*8]=0.5*(C7*D07-C5*D16+C3*D25-C1*D34);

}

void fdct(double *block)
{
  int i;

  for (i=0; i<8; i++)
    fdctrow(block+8*i);

  for (i=0; i<8; i++)
    fdctcol(block+i);
}

二、IDCT部分



圖片來源:G. G. Pechanek, C. W. Kurak, C. J. Glossner, C. H. L. Moller, and S. J. Walsh IBM Microelectronics Division, Research Triangle Park, N.C. "M.F.A.S.T.: A HIGHLY PARALLEL SINGLE CHIP DSP WITH A 2D IDCT EXAMPLE"

圖中未給出係數,需自行算出,仿上述DCT方法直接展開表達式搜尋規律即可。

編程如下:

#define  C1 0.9808
#define  C2 0.9239
#define  C3 0.8315
#define  C4 0.7071
#define  C5 0.5556
#define  C6 0.3827
#define  C7 0.1951

//對行做DCT

void idctrow(double *blk)
{ double tmp[16];

 //first step
 tmp[0]=blk[0]*C4+blk[2]*C2;
 tmp[1]=blk[4]*C4+blk[6]*C6;
 tmp[2]=blk[0]*C4+blk[2]*C6;
 tmp[3]=-blk[4]*C4-blk[6]*C2;
 tmp[4]=blk[0]*C4-blk[2]*C6;
 tmp[5]=-blk[4]*C4+blk[6]*C2;
 tmp[6]=blk[0]*C4-blk[2]*C2;
 tmp[7]=blk[4]*C4-blk[6]*C6;

 tmp[8]=blk[1]*C7-blk[3]*C5;
 tmp[9]=blk[5]*C3-blk[7]*C1;
 tmp[10]=blk[1]*C5-blk[3]*C1;
 tmp[11]=blk[5]*C7+blk[7]*C3;
 tmp[12]=blk[1]*C3-blk[3]*C7;
 tmp[13]=-blk[5]*C1-blk[7]*C5;
 tmp[14]=blk[1]*C1+blk[3]*C3;
 tmp[15]=blk[5]*C5+blk[7]*C7;


 //second step
 tmp[0]=0.5*(tmp[0]+tmp[1]);
 tmp[1]=0.5*(tmp[2]+tmp[3]);
 tmp[2]=0.5*(tmp[4]+tmp[5]);
 tmp[3]=0.5*(tmp[6]+tmp[7]);
 tmp[4]=0.5*(tmp[8]+tmp[9]);
 tmp[5]=0.5*(tmp[10]+tmp[11]);
 tmp[6]=0.5*(tmp[12]+tmp[13]);
 tmp[7]=0.5*(tmp[14]+tmp[15]);

 //third step
 blk[0]=tmp[0]+tmp[7];
 blk[1]=tmp[1]+tmp[6];
 blk[2]=tmp[2]+tmp[5];
 blk[3]=tmp[3]+tmp[4];
 blk[4]=tmp[3]-tmp[4];
 blk[5]=tmp[2]-tmp[5];
 blk[6]=tmp[1]-tmp[6];
 blk[7]=tmp[0]-tmp[7];

 /*
 blk[0]=0.5*(Y0C4+Y2C2+Y4C4+Y6C6+Y1C1+Y3C3+Y5C5+Y7C7);
 blk[1]=0.5*(Y0C4+Y2C6-Y4C4-Y6C2+Y1C3-Y3C7-Y5C1-Y7C5);
 blk[2]=0.5*(Y0C4-Y2C6-Y4C4+Y6C2+Y1C5-Y3C1+Y5C7+Y7C3);
 blk[3]=0.5*(Y0C4-Y2C2+Y4C4-Y6C6+Y1C7-Y3C5+Y5C3-Y7C1);

 blk[4]=0.5*(Y0C4-Y2C2+Y4C4-Y6C6-Y1C7+Y3C5-Y5C3+Y7C1);
 blk[5]=0.5*(Y0C4-Y2C6-Y4C4+Y6C2-Y1C5+Y3C1-Y5C7-Y7C3);
 blk[6]=0.5*(Y0C4+Y2C6-Y4C4-Y6C2-Y1C3+Y3C7+Y5C1+Y7C5);
 blk[7]=0.5*(Y0C4+Y2C2+Y4C4+Y6C6-Y1C1-Y3C3-Y5C5-Y7C7);
 */

}

//在對列做DCT

void idctcol(double *blk)
{
 double tmp[16];

 //first step
 tmp[0]=blk[0*8]*C4+blk[2*8]*C2;
 tmp[1]=blk[4*8]*C4+blk[6*8]*C6;
 tmp[2]=blk[0*8]*C4+blk[2*8]*C6;
 tmp[3]=-blk[4*8]*C4-blk[6*8]*C2;
 tmp[4]=blk[0*8]*C4-blk[2*8]*C6;
 tmp[5]=-blk[4*8]*C4+blk[6*8]*C2;
 tmp[6]=blk[0*8]*C4-blk[2*8]*C2;
 tmp[7]=blk[4*8]*C4-blk[6*8]*C6;

 tmp[8]=blk[1*8]*C7-blk[3*8]*C5;
 tmp[9]=blk[5*8]*C3-blk[7*8]*C1;
 tmp[10]=blk[1*8]*C5-blk[3*8]*C1;
 tmp[11]=blk[5*8]*C7+blk[7*8]*C3;
 tmp[12]=blk[1*8]*C3-blk[3*8]*C7;
 tmp[13]=-blk[5*8]*C1-blk[7*8]*C5;
 tmp[14]=blk[1*8]*C1+blk[3*8]*C3;
 tmp[15]=blk[5*8]*C5+blk[7*8]*C7;


 //second step
 tmp[0]=0.5*(tmp[0]+tmp[1]);
 tmp[1]=0.5*(tmp[2]+tmp[3]);
 tmp[2]=0.5*(tmp[4]+tmp[5]);
 tmp[3]=0.5*(tmp[6]+tmp[7]);
 tmp[4]=0.5*(tmp[8]+tmp[9]);
 tmp[5]=0.5*(tmp[10]+tmp[11]);
 tmp[6]=0.5*(tmp[12]+tmp[13]);
 tmp[7]=0.5*(tmp[14]+tmp[15]);

 //third step
 blk[0*8]=tmp[0]+tmp[7];
 blk[1*8]=tmp[1]+tmp[6];
 blk[2*8]=tmp[2]+tmp[5];
 blk[3*8]=tmp[3]+tmp[4];
 blk[4*8]=tmp[3]-tmp[4];
 blk[5*8]=tmp[2]-tmp[5];
 blk[6*8]=tmp[1]-tmp[6];
 blk[7*8]=tmp[0]-tmp[7];

 /*
 blk[0*8]=0.5*(Y0C4+Y2C2+Y4C4+Y6C6+Y1C1+Y3C3+Y5C5+Y7C7);
 blk[1*8]=0.5*(Y0C4+Y2C6-Y4C4-Y6C2+Y1C3-Y3C7-Y5C1-Y7C5);
 blk[2*8]=0.5*(Y0C4-Y2C6-Y4C4+Y6C2+Y1C5-Y3C1+Y5C7+Y7C3);
 blk[3*8]=0.5*(Y0C4-Y2C2+Y4C4-Y6C6+Y1C7-Y3C5+Y5C3-Y7C1);

 blk[4*8]=0.5*(Y0C4-Y2C2+Y4C4-Y6C6-Y1C7+Y3C5-Y5C3+Y7C1);
 blk[5*8]=0.5*(Y0C4-Y2C6-Y4C4+Y6C2-Y1C5+Y3C1-Y5C7-Y7C3);
 blk[6*8]=0.5*(Y0C4+Y2C6-Y4C4-Y6C2-Y1C3+Y3C7+Y5C1+Y7C5);
 blk[7*8]=0.5*(Y0C4+Y2C2+Y4C4+Y6C6-Y1C1-Y3C3-Y5C5-Y7C7);
 */

}


void idct(double *block)
{
  int i;

  for (i=0; i<8; i++)
    idctrow(block+8*i);

  for (i=0; i<8; i++)
    idctcol(block+i);
}

經簡單測試,上面兩種算法是簡單矩陣實現DCT速度的100倍以上。

 

個人日記 |公開 |原創:神劍俠

簽名檔

編輯簽名檔
 

取消

我的熱評日誌

還沒有人發表評論  來坐第一個沙發

提示QQ空間鄭重承諾:致力於爲用戶提供綠色、健康的網絡空間!堅決杜絕低俗、惡意、反動等不良信息,在此願每位QQ空間用戶共同參與維護!對您的舉報信息我們將第一時間覈查處理,請點擊:瞭解QQ空間舉報入口
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章