--- */ buffi=float *mallocNT*sizeoffloat; buffo=unsigned char *mallocNT*sizeofchar; x=float *mallocNB*sizeoffloat; L=unsigned int *mallocNB*sizeofint; C=float *mallocNB-1*sizeoffloat; w=
Trang 1printf ("\nEnter block size (e.g 8x8, 16x 16,
etc.) > ");
scanf ( "%dx%d", &NB,&NB);
m=(int)(log10((double)NB)/log10((double)2.0));
NT=N*NB;
/* -
Blocks of NBxNB will be considered
-*/
/* -
Assigning memory
- */
buffi=(float *)malloc(NT*sizeof(float));
buffo=(unsigned char *)malloc(NT*sizeof(char));
x=(float *)malloc(NB*sizeof(float));
L=(unsigned int *)malloc(NB*sizeof(int));
C=(float *)malloc((NB-1)*sizeof(float));
w=(float **)malloc(NB*sizeof(float *));
for(i=0;i<NB;i++)
*(w+i)=(float *)malloc(NB*sizeof(float));
bit_reversal(L,m,NB);
WTS(C,m,NB);
NS=(N>>m);
/* -
2-D FCT using the row-column approach
- */
for(i=0;i<NS;i++)
{
fread(buffi,NT,1,fptri);
for(j=0;j<NS;j++)
{
for(k1=0;k1<NB;k1++)
for(k2=0;k2<NB;k2++)
w[k1][k2]=buffi[k1*N+k2+j*NB];
for(k1=0;k1<NB;k1++)
{
for(k2=0;k2<NB;k2++)
x[k2]=w[k1][k2];
FCT(x,L,C,m,NB);
for(k2=0;k2<NB;k2++)
w[k1][k2]=x[k2];
}
for(k2=0;k2<NB;k2++)
{
for(k1=0;k1<NB;k1++)
Trang 2x[k1]=w[k1][k2];
FCT(x,L,C,m,NB);
for(k1=0;k1<NB;k1++)
w[k1][k2]=x[k1];
}
for(k1=0;k1<NB;k1++)
for(k2=0;k2<NB;k2++)
buffo[k1*N+k2+j*NB]=w[k1][k2];
}
fwrite(buffo,NT,sizeof(float),fptro);
}
fcloseall();
}
Hình 13.10 Biểu đồ chuyển đổi cosin nhanh
void FCT(float *x, unsigned int *L,
float *C, int m, int N) {
int NK1,NK2,i,j,k,kk,ip,incr,L1,k1,k2,iter;
float T;
/*Rearranging the order of the input sequence.*/ NK1=N>>1;
T=x[2];
x[2]=x[1];
x[1]=T;
k1=2;
k2=4;
16
2C
2 1 2 1 2 1
-1 -1 -1 -1
-1 -1
-1 -1
-1 -1 -1 -1
-1
-1 -1 -1 -1
C4
C 4
C 4
C 4
X(0) X(1) X(2)
X(7)
X(3) X(4) X(5) X(6)
)
0
(
~x
)
1
(
~
x
)
2
(
~x
)
3
(
~x
)
4
(
~x
)
5
(
~x
)
6
(
~x
)
7
(
~x
8
2C
8
2C
5
2C
5
2C
5 16
2C
9 16
2C
13
2C
Trang 3for(i=1;i<(NK1-1);i++)
{
T=x[k2];
for(j=0;j<=(k2-k1);j++)
{
x[k2-j]=x[k2-j-1];
}
x[k1]=T;
k1++;
k2+=2;
}
NK2=N-1;
for(i=0; i<(NK1>>1);i++)
{
T=x[NK2-i];
x[NK2-i]=x[NK1+i];
x[NK1+i]=T;
}
/*Forward operation */
ip=NK1;
kk=0;
incr=N;
for(iter=0;iter<m;iter++)
{
for(k=0;k<ip;k++)
{
for(j=k;j<N;j+=incr)
{
i=j+ip;
T=x[j];
x[j]=T+x[i];
x[i]=T-x[i];
x[i]*=C[kk];
}
kk++;
}
ip>>=1;
incr>>=1;
}
/*Bit reversal */
for(i=0; i<(N-1); i++)
{
Trang 4if(i<=L[i]) continue;
else
{
T=x[i];
x[i]=x[L[i]];
x[L[i]]=T;
}
}
/*Recursive subtraction */
for(i=1;i<NK1;i++)
x[i]*=0.5;
NK1=(N>>2);
NK2=(N>>1);
kk=1;
for(iter=1;iter<m;iter++)
{
kk<<=1;
L1=kk-1; /*L1=2^iter-1*/
for(k=1;k<=L1;k++)
for(i=0;i<NK1;i++)
x[NK1+k*NK2+i]=x[NK1+k*NK2+i]-x[NK1+(k-1)*NK2+i]; NK1>>=1;
NK2>>=1;
}
x[0]*=1.414/(float)N;
for(i=1;i<N;i++)
x[i]*=2.0/(float)N;
}
void bit_reversal(unsigned int *L, int m, int N) {
unsigned int MASK,C,A,j,k,i;
for(k=0;k<N;k++)
{
MASK=1;
C=0;
for(i=0,j=m-1;i<m;i++,j )
{
A=(k&MASK)>>i;
A<<=j;
Trang 5C|=A;
MASK<<=1;
}
L[k]=C;
}
}
void WTS(float *C,int m, int N)
{
int NK1,NK2,i,k,iter;
NK1=N>>1;
NK2=N<<1;
k=0;
for(iter=0;iter<m;iter++)
{
for(i=0;i<NK1;i++)
{
C[k]=
(float)cos((double)((PI*(float)(4*i+1))/(float)N K2));
k++;
}
NK1>>=1;
NK2>>=1;
}
for(i=0;i<(k-1);i++)
C[i]*=2.0;
}
Biến đổi ngược DCT được cho bỏi
1
) 1 2 ( cos ) ( )
(
N k
k
N
n k k
X n
ở đây
1 -N , 1,2,
= k cho 1
0
= k cho 2
1
k
Thay vì lập lại cả một chương trình để tính biến đổi ngược FCT, chúng ta sẽ dùng lưu đồ của FCT tiến (forward) Để rút ra FCT ngược, tất cả các việc mà chúng ta cần làm là đảo ngược biểu đồ ở hình 13.10 Hình 13.11 giới thiệu
Trang 6phép biến đổi ngược của một bướm Kết quả của thuật toán biến đổi ngược của lưu đồ FCT cho trong hình 13.12 Từ lưu đồ của hình 13.11 biến đổi ngược của FCT có thể phát triển bình thường từ FCT tiến Chương trình tính 2-D FCT ngược cho trong chương trình 13.6 Giá trị của khối ảnh gốc phải được cho trước bởi người dùng
Hình 13.11 Phép đổi ngược của một bướm
Hình 13.12 Biểu đồ đảo ngược giải thuật FCT
Chương trình 13.6 "IFCT2D.C" Đảo ngược FCT Kích thước khối sử dụng trên ảnh gốc
/*Program 13.6 "IFCT2D.C" Inverse FCT Block size used on the original image should be known to the user.*/
/* This program is for carrying out
the inverse of the 2-D Fast Cosine Transform */
#define PI 3.14159
#include <stdio.h>
#include <math.h>
1/2CX
0.5
A
B
C
-1 A=C+D
B=(C-D)CX
C
D
A
B
-1 C=0.5A+B/(2CX) D=0.5A-B/(2CX)
13
1
C
9 16
1
C
0.
-1
-1
-1 -1 -1
-1 -1
-1 -1
5 16
1
C
16
1
C
8
4
1
C
5
4
1
C
8
4
1
C
8
4
1
C
4 2 1
C
4 2 1
C
4 2 1
C
4 2 1
C
0.
5
0.
5
0.
5
0.
5
0.
0.
0.
5
0.
5
0.
0.
0.
+ +
+ +
+
X(0
)
X(1
X(2
)
X(3
)
X(4
X(6
X(7
)
(0) x
~ (1) x
~ (2) x
~
(3) x
~
(4) x
~
(6) x
~ (7) x
~
X(5
)
(5) x
~
Trang 7#include <alloc.h>
#include <conio.h>
#include <io.h>
#include <process.h>
void IFCT(float *, unsigned int *, float *, int , int );
void bit_reversal(unsigned int *, int , int );
void WTSINV(float *,int, int);
void main()
{
int m,N,i,j,k1,k2,NB,NT,NS,k;
float *x,*C,**w;
unsigned int *L;
double nsq;
FILE *fptri, *fptro;
char file_name[14] ;
float *buffi ;
unsigned char *buffo;
clrscr();
printf ( "This program is for the inverse 2-D FCT
\n" ) ;
printf ( "Enter name of input file ->") ;
scanf ("%s " , file_name) ;
fptri=fopen(file_name, " rb");
if( fptri ==NULL)
{
printf("\nNo such file exists.\n");
exit(1);
}
nsq=(double)filelength(fileno(fptri));
/* -
Assume image is square,
-*/
N=(int)sqrt(nsq/sizeof(float));
m=(int)(log10((double)N)/log10((double)2.0));
k=1;
for(i=0; i<m;i++)
k<<=1;
if(k!=N)
{
printf("\nTransform image must have dimensions");
Trang 8printf(" which are multiples of 2 \n ");
exit(1);
}
printf("Enter name for Output file - - -> " ) ; scanf("%s", file_name);
fptro=fopen(file_name,"wb");
printf("\nEnter block size used (e.g
8x8,16xI6,etc.) >");
scanf("%dx%d",&NB,&NB);
m=(int)(log10((double)NB)/log10((double)2.0));
NT=N*NB;
/* -
Blocks of NBxNB were considered
-*/
/* -
Assigning memory
- */
buffi=(float *)malloc(NT*sizeof(float));
buffo=(unsigned char *)malloc(NT*sizeof(char));
x=(float *)malloc(NB*sizeof(float));
L=(unsigned int *)malloc(NB*sizeof(int));
C=(float *)malloc((NB-1)*sizeof(float));
w=(float **)malloc(NB*sizeof(float *));
for(i=0;i<NB;i++)
*(w+i)=(float *)malloc(NB*sizeof(float));
bit_reversal(L,m,NB);
WTSINV(C,m,NB);
NS=(N>>m) ;
/* -
2-D inverse FCT using the row-column approach
- */
for(i=0;i<NS;i++)
{
fread(buffi,NT,sizeof(float),fptri);
for(j=0;j<NS;j++)
{
for(k1=0;k1<NB;k1++)
for(k2=0;k2<NB;k2++)
w[k1][k2]=buffi[k1*N+k2+j*NB];
for(k1=0;k1<NB;k1++)
{
for(k2=0;k2<NB;k2++)
x[k2]=w[k1][k2];
Trang 9IFCT(x,L,C,m,NB);
for(k2=0;k2<NB;k2++)
w[k1][k2]=x[k2];
}
for(k2=0;k2<NB;k2++)
{
for(k1=0;k1<NB;k1++)
x[k1]=w[k1][k2];
IFCT(x,L,C,m,NB);
for(k1=0;k1<NB;k1++)
w[k1][k2]=x[k1];
}
for(k1=0;k1<NB;k1++)
for(k2=0;k2<NB;k2++)
buffo[k1*N+k2+j*NB]=(char)fabs((double)w[k1][k2]);
}
fwrite(buffo,NT,1,fptro);
}
fcloseall();
}
void bit_reversal(unsigned int *L, int m, int N) {
unsigned int MASK,C,A,j,k,i;
for(k=0;k<N;k++)
{
MASK=1;
C=0;
for(i=0,j=m-1;i<m;i++,j )
{
A=(k&MASK)>>i;
A<<=j;
C|=A;
MASK<<=1;
}
L[k]=C;
}
}
void WTSINV(float *C,int m,int N)
{
int NK,k,i,iter,LK;
NK=4;