Chơng
7
Các thuộc tính của ảnh số
7.1 Chỉ dẫn
Trong chơng này chúng ta sẽ nghiên cứu các vấn đề sau:
Tầm quan trọng của pha trong các ảnh số.
Các giả thiết lấy mẫu 2-D với các ứng dụng trên các ảnh.
Nhân đôi độ phân giải trên ảnh.
7.2 Tầm quan trọng của pha
Trong chơng 6, phần 6.4.2, tầm quan trọng của đặc tính tuyến tính hoặc đặc tính
pha zero cho các bộ lọc 2-D đã đợc đề cập. Tuy nhiên, chúng ta cha kiểm tra tác
dụng phân bố đặc tính pha của các ảnh số đối với các nội dung thông tin có trên ảnh.
Để làm vậy, chúng ta sẽ đa ra hai thử nghiệm.
Thử nghiệm 1:
1. Rút ra 2-D FFT của một ảnh đợc cho.
2. Tính đặc tuyến pha:
=
)(
)(
tan
kx
kx
r
i
k
ở đây x
i
(k) biểu diễn cho các phần giá trị ảo và x
r
(k) biểu diễn các giá trị thực của
FFT.
3. Tính toán và lu trong một file các giá trị phức
cos( ) sin( ),
k k
i+ i = -1
4. Rút ra biến đổi ngợc FFT của file cuối cùng.
Để đa các bớc trên, chơng trình 7.1 đợc cung cấp. Chơng trình thực hiện trên ảnh
IKRAM.IMG của hình 3.2a (Chơng 3). Kết quả đợc đa ra trên hình 7.1.
Chơng trình 7.1 "PHASE.C". Kiểm tra tầm quan trọng của pha.
125
/* Program for testing the importance of phase in digital images.*/
#define pi 3.141592654
#include <stdio.h>
#include <math.h>
#include <alloc.h>
#include <stdlib.h>
#include <io.h>
#include <string.h>
#include <conio.h>
void bit_reversal(unsigned int *, int , int);
void WTS(float *, float *, int, int);
void FFT(float *xr, float *xi, float *, float *,int, int);
void transpose(FILE *, int, int);
void FFT2D(FILE *, FILE *, float *, float *, unsigned int *,
int,int,int);
H×nh 7.1 T¸ch riªng pha ®èi víi ¶nh "IKRAM.IMG".
void main()
{
int N,n2,m,i,j,NT;
unsigned int *L;
float *wr,*wi ;
126
double nsq,xr,xi,theta;
FILE *fptri,*fptro,*fptrt,*fptrr;
float *buffi,*buffo, max,min,scale;
unsigned char file_name[14], *buff,file_name2[14];
clrscr() ;
printf("Enter name of file containing FFT data >");
scanf("%s",file_name);
fptri=fopen(file_name,"rb");
if(fptri==NULL)
{
printf("\nFile does not exist.");
exit(1);
}
fptrt=fopen("temp.img","wb+");
again :
gotoxy(1,2);
printf(" ");
gotoxy(1,2);
printf("Enter File for storing display IFFT data->");
scanf("%s",file_name);
if(((stricmp("temp.img",file_name2))==0)||
((stricmp("temp2.img",file_name2))==0))
printf("This is a reserved file name. Use some other name.");
goto again;
fptrr=fopen(file_name,"wb");
nsq=(double)filelength(fileno(fptri))/(2*sizeof(float));
N=(int)sqrt(nsq);
m=(int)(log10((double)N)/log10((double)2));
clrscr( ) ;
NT=2*N*sizeof(float);
buffi=(float *)malloc(NT*sizeof(float));
buffo=(float *)malloc(NT*sizeof(float));
buff=(char *)malloc(N*sizeof(char));
for(i=0;i<N;i++)
{
fread(buffi,NT,1,fptri);
for(j=0;j<N;j++)
{
xr=(double)buffi[2*j];
xi=(double)buffi[2*j+1];
theta=atan2(xi,xr);
buffo[2*j]=100.0*(float)cos(theta);
buffo[2*j+1]=100.0*(float)sin(theta);
}
fwrite(buffo,NT,1,fptrt);
}
fclose(fptri);
127
rewind(fptrt);
/* Allocating memory for bit reversal LUT.*/
L=(unsigned int *)malloc(N*sizeof(unsigned int));
/* Generate Look-up table for bit reversal.*/
bit_reversal(L,m,N);
/* Allocating memory for twiddle factors.*/
n2=(N>>1)-1;
wr=(float *)malloc(n2*sizeof(float));
wi=(float *)malloc(n2*sizeof(float));
fptro=fopen("temp2.img","wb+"),
WTS(wr,wi,N,1);
FFT2D(fptrt,fptro,wr,wi,L,N,m,1);
fptro=fopen("temp2.img","rb");
max=0.0; min=1.e10;
for(i=0;i<(N-30);i++)
{
fread(buffi,NT,1,fptro);
if(i<11) continue;
for(j=0;j<N;j++)
H×nh 7.2 T¸ch riªng biªn ®é cña ¶nh "IKRAM.IMG".
{
if(buffi[2*j]>max) max=buffi[2*j];
if(buffi[2*j]<min) min=buffi[2*j];
}
128
}
rewind(fptro);
scale=255.0/(max-min);
for(i=0;i<N;i++)
{
fread(buffi,NT,1,fptro);
for(j=0;j<N;j++)
buff[j]=(char)((buffi[2*j]-min)*scale);
fwrite(buff,N,1,fptrr);
}
fcloseall();
remove("temp.jmq");
remove("tempLimg");
}
Thử nghiệm 2:
1. Rút ra FFT của một ảnh.
2. Rút ra đặc tính biên độ
| | ( ) ( )H x k x k
k
r i
= +
2 2
3. Chứa trong một file dữ liệu phức
(| | . )H i
k
+ 0 0
4. Rút ra biến đổi ngợc FFT của file cuối cùng.
Chơng trình 7.1 có thể dễ dàng thay đổi lại để kết hợp với các bớc trên. Kết quả
chạy thử nghiệm 2 trên ảnh IKRAM.IMG đợc cho hình 7.2.
Có thể thấy rõ ràng từ hai thử nghiệm trên rằng đặc tính pha mang gần hết các
thông tin trong ảnh. Điều này đúng với hầu hết các ảnh, bởi vậy khi thực hiện các
phép toán nh lọc 2-D với mục đích tăng cờng ảnh ta nên tránh làm biến dạng pha.
Điều này cho thấy sự cần thiết của các toán tử 2-D tuyến tính hoặc có pha zero.
7.3 Định lý lấy mẫu Whittaker-Shannon
Chúng ta sẽ bắt đầu bằng xem xét định lý lấy mẫu trong trờng hợp 1-D. Sau đây
chúng ta sẽ nghiên cứu trờng hợp các tín hiệu 2-D.
Định lý: Nếu một hàm x(t) không chứa tần số cao hơn W, có thể xác định một
cách hoàn toàn bằng một toạ độ mà dãy các điểm chia cách nhau 1/(2W). Chu kỳ
lấy mẫu đợc cho bởi
T
W
1
2
ở đây T tính theo giây và W tính theo herzt.
129
Chứng minh. Xem xét biểu diễn Fourier của một dãy các tín hiệu liên tục x
a
(t)
= dejXtx
tj
aa
)(
2
1
)(
(7.1a)
= dtetxjX
tj
aa
)()(
(7.1b)
Nếu x(n) biểu diễn một dãy đợc rút ra từ việc lấy mẫu x
a
(t) tại các khoảng bằng nhau
T, chúng ta có thể dùng biểu thức (7.1a) để viết:
== dejXnTxnx
nTj
aa
)(
2
1
)()(
(7.2)
Từ biến đổi rời rạc Fourier chúng ta cũng rút ra
=
deeXnx
njj
)(
2
1
)(
(7.3)
ở đây
X e
j
( )
là biến đổi Fourier rời rạc của x(n). Bây giờ cần tính mối quan hệ
)( jX
a
theo
X e
j
( )
.
Để xem xét mối quan hệ giữa các biểu thức (7.2) và (7.3) ta cần xem xét biểu
thức (7.2) nh một tổng của các tích phân trong các khoảng có độ dài 2
/T.
=
+
=
r
T
r
T
r
nTj
a
dejXnx
)12(
)12(
)(
2
1
)(
(7.4)
Mỗi phần trong tổng có thể quy về tích phân trong khoảng từ
T
đến
T
bằng
cách thay đổi biến để rút ra
=
+=
r
T
T
rnjnTj
a
dee
T
r
jjXnx
2
)
2
(
2
1
)(
(7.5)
Nếu thay đổi thứ tự của tích phân và tính tổng và chú ý rằng
1
2
=
rnj
e
với mọi
giá trị nguyên của r và n, thì chúng ta rút ra
+=
=
de
T
r
jjXnx
nTj
T
T
r
a
)
2
(
2
1
)(
(7.6)
130
Với thay thế , biểu thức (7.6) trở thành
de
T
r
j
T
jX
T
nx
nj
r
a
=
+= )
2
(
1
2
1
)(
(7.7)
có cùng dạng với biểu thức (7.3). Vì vậy, chúng ta có thể xác định
=
+=
r
a
j
T
r
j
T
jX
T
eX )
2
(
1
)(
(7.8)
Tơng tự, chúng ta có thể biểu diễn biểu thức (7.8) theo biến tần số tơng tự nh
=
+=
r
a
Tj
T
r
jjX
T
eX )
2
(
1
)(
(7.9)
Biểu thức (7.8) và (7.9) cung cấp mối quan hệ giữa biến đổi Fourier thời gian liên
tục và biến đổi Fourier của một dãy các mẫu. Cho ví dụ, nếu
X j
a
( )
đợc giới thiệu
trong hình 7.3a, thì
X e
j
( )
sẽ đợc giới thiệu trong hình 7.3b nếu W (/T) (hoặc T
(2/2W)), cụ thể, nếu W tính theo hezt
)2/1( WT
. Vì thế, nếu lấy mẫu tại tốc
độ tối thiểu gấp đôi tần số cao nhất trong
x j
a
( )
, thì
X e
j
( )
đợc xác định thành
X j
a
( )
trong khoảng
TT
. Tần số lấy mẫu này thờng đợc gọi là tần số
Nyquist. Nếu T 1/(2W), thì các bản dịch của
X j
a
( )
sẽ bị chồng lên nhau nh trong
hình 7.3c. Vấn đề này gọi là hiện tợng trùm phổ (aliasing).
Nếu T 1/(2W) (W tính theo hezt), thì có khả năng khôi phục x
a
(t) từ x(nT) bởi
một phép nội suy xấp xỉ, mà sẽ đợc chúng ta đề cập đến phần tiếp theo.
Từ phép biến đổi Fourier thời gian liên tục:
=
T
T
tj
aa
dejXtx
)(
2
1
)(
131
(7.10)
132
ω
ω
Ω
wΩ
-w
X
a
(jΩ)
BiÕn ®æi Fourier cña tÝn
hiÖu liªn tôc
(a)
w
T
>
π
-w
w
X(e
jω
)
(b)
T
π
T
π
−
w
w
T
<
π
-w
(c)
T
π
T
π
−
Hình 7.3 Phổ tần số của trạng thái liên tục và trạng thái đã lấy mẫu của một tín hiệu.
Nếu
TT
- )(
1
)(
=
jX
T
eX
a
Tj
(7.11)
và
=
=
k
kTj
a
Tj
ekTxeX )()(
Kết hợp biểu thức (7.10) và (7.11)
=
T
T
tj
a
dejX
T
tx
)(
2
)(
Vì vậy
=
=
deekTx
T
tx
tj
T
T
k
Tkj
aa
)(
2
)(
Thay đổi thứ tự tính tổng và tích phân,
=
=
k
T
T
kTtj
aa
de
T
kTxtx
/
/
)(
2
)()(
Tính giá trị của tích phân chúng ta đợc
=
=
k
aa
kTt
T
kTt
T
kTxtx
)(
)(sin
)()(
(7.12)
Biểu thức (7.12) là phép nội suy cho phép khôi phục các tín hiệu liên tục theo thời
gian x
a
(t) từ các mẫu của nó.
Trờng hợp 2-D: Các định lý lấy mẫu 2-D giả thiết rằng hàm giới hạn băng f
a
(x,y)
có thể khôi phục một cách hoàn toàn từ các mẫu mà thoả mãn
T
W
H
H
1
2
T
W
V
V
1
2
(7.13)
ở đây W
H
và W
V
biểu diễn giải thông theo hezt của tín hiệu 2-D theo chiều dọc và
theo chiều ngang. Nếu biểu thức (7.13) đợc thoả mãn, và f
a
(k
1
T
V
,k
2
T
H
) biểu diễn tín
hiệu lấy mẫu 2-D, thì f
a
(x,y) có thể khôi phục từ f
a
(k
1
T
V
,k
2
T
H
) dùng biểu thức nội suy:
133
(7.14)
Chứng minh của các biểu thức (7.13) và (7.14) tơng tự nh trờng hợp 1-D và đợc
để lại nh một bài tập. Một chú ý là phổ tần số của một tín hiệu lấy mẫu 2-D tuần
hoàn trong miền tần số, nh trong hình 7.4. Tín hiệu tơng tự có thể đợc khôi phục
bằng cách tách ra một chu kỳ từ phổ tín hiệu mẫu.
7.4 Định lý lấy mẫu áp dụng lên các ảnh
Một ảnh đợc tạo nên bằng cách chiếu một cảnh 3-D lên mặt phẳng 2-D. Phép
chiếu này biểu diễn một phép biến đổi từ nhiều vào một. Có nghĩa là một điểm ảnh
không tơng ứng duy nhất với một điểm trong cảnh 3-D. Điều này đợc minh hoạ qua
hình 7.5. Giả sử rằng ảnh này chứa N điểm ảnh theo hớng x. Sau đó cho các vật thể
S
1
và S
2
trong hình 7.5 chúng ta có
x
N
1
10
=
mét (7.15)
và
N
x
3
2
=
mét (7.16)
Định lý lấy mẫu đòi hỏi:
1
1
2
1
W
x
134
)(
)(sin
2
2
H
H
H
H
Tky
T
Tky
T
(7.17)
Hình 7.4 Phổ tần số của một tín hiệu lấy mẫu 2-D.
và
2
2
2
1
W
x
(7.18)
ở đây, W
1
là tần số cao nhất theo hớng x cho ảnh đợc tạo bởi một mình vật thể S
1
, và
W
2
là tần số cao nhất theo hớng x cho ảnh đợc tạo bởi một mình vật thể S
2
. Bởi vì
chúng ta chỉ có một ảnh bao gồm S
1
và S
2
nên W
1
= W
2
và N đợc xác định theo
x
N W
2
2
3 1
2
= =
(7.19)
Vì thế N = 6W
2
(7.20)
135
1
2
H
T
H
T
V
T
V
T
H
W
V
W
Hình 7.5 ánh xạ một cảnh 3-D lên mặt phẳng ảnh 2-D.
Thay N trong biểu thức (7.15) chúng ta đợc
112
1
2
1
6
10
6
10
WWW
x >==
Vì thế, giả thiết lấy mẫu không thoả mãn cho vật thể S
1
, và ở đây các thông tin của
miền này trên ảnh không thể khôi phục qua phép nội suy. Nói một cách khác, các vật
thể gần camera có khả năng tốt hơn khi lấy mẫu, trong khi các vật thể xa camera thì
dễ dàng khi khôi phục mẫu.
7.5 Nhân đôi độ phân giải trên ảnh
Kết quả của định lý lấy mẫu có thể dùng để tăng độ phân giải trên ảnh. Dù sao
chăng nữa, dựa vào kết quả đã đạt đợc chúng ta có thể kết luận rằng nói chung thì
không thể tăng độ phân giải của ảnh lên đợc. Trong các ảnh, các vật thể đáng quan
tâm thông thờng đợc che hết bề mặt của ảnh. Vì thế, nếu các đối tợng trong nền
không đợc cho độ phân giải d thừa, các vật thể cận cảnh thông thờng có đủ mẫu để
cho phép dùng các định lý lấy mẫu.
7.5.1 Nhân đôi độ phân giải dùng sự thể hiện tần số của lý thuyết lấy mẫu
Chúng ta đã chú ý ở trong chơng 6 rằng phổ tần số của một ảnh giảm nhanh cùng
với sự tăng của tần số. Chúng ta có thể dùng nhận xét này và định lý lấy mẫu
Whittaker-Shannon để tăng độ phân giải. Giải thuật này theo các bớc sau:
1. Rút ra FFT của ảnh có kích thớc N ì N, cụ thể
I k k FFT i n n
n n
( , ) { ( , )( ) }
1 2 1 2
1
1 2
=
+
136
phổ tần số sẽ phải có gốc toạ độ ở trung tâm của mảng FFT.
2. Thêm các điểm 0 vào FFT nh giới thiệu trong hình 7.6 để tăng kích thớc của nó
lên 2N ì 2N.
3. Rút ra biến đổi ngợc FFT của biến đổi tần số mở rộng. Kết quả thu đợc là ảnh
gốc với độ phân giải tăng gấp đôi. Cần chú ý là các vật thể không lấy đủ mẫu
trong ảnh gốc thì không cung cấp một sự phát triển trong độ phân giải.
Để thực hiện các phơng pháp trên chúng ta sẽ bắt đầu với ảnh kích thớc 128 ì
128 điểm và 256 mức xám trong hình 7.7a. ảnh đã có sẵn trên đĩa với file có tên là
CAMEL.IMG. Thực hiện thuật toán trên đợc cho trong Chơng trình 7.2. Kết quả áp
dụng trên ảnh đợc cho trong hình 7.7b. Rõ ràng là rất khó khăn để nhận ra ngời cỡi
trên lạc đà, nếu ảnh gốc mặt ngời đó cha đợc lấy đủ mẫu.
Chơng trình 7.2 ENLQFFT.C nhân đôi độ phân giải của một ảnh qua FFT.
/*This program utilizes 2-D FFT to double the size of an image.*/
#define pi 3.141592654
#include <stdio.h>
#include <math.h>
#include <alloc.h>
#include <stdlib.h>
#include <io.h>
#include <string.h>
#include <ctype.h>
#include <conio.h>
void bit_reversal(unsigned int *, int , int);
void WTS(float *, float *, int, int);
void FFT(float *xr , float *xi, float *, float *, int , int) ;
void transpose(FILE *, int, int);
void FFT2D(FILE *, FILE *, float *, float *, unsigned int *,
int,int,int);
void main()
{
int N,m,i,j,N2,N4,m2,n2,ind;
unsigned int *L;
float *wr,*wi;
FILE *fptri,*fptro,*fptrt;
double nsq;
float *buffo,*buffi;
unsigned char file_name[14],ch,*buffr;
float max,min,scale;
clrscr();
printf("Enter file name for image to be enlarged -> ");
scanf("%s", file_name);
137
fptri=fopen(file_name,"rb");
if(fptri==NULL)
{
printf("\n File does not exist.");
exit(1);
}
nsq=filelength(fileno(fptri));
N=(int)sqrt(nsq);
m=(int)(log10((double)N)/log10((double)2));
fptro=fopen("FFT1.img","wb+");
/* file for storing FFT of image.*/
again :
gotoxy(1,2);
printf ( " ");
gotoxy(1,2);
printf("Enter file-name for enlarged image -> ");
scanf("%s",file_name);
if(((stricmp("FFT1.img",file_name))==0)||
((stricmp("temp.img",file_name))==0)||
((stricmp("IFFT2.img",file_name))==0))
{
printf("This is a reserved file name. Use some other name.");
Hình 7.6 Thêm các số 0 vào FFT thu đợc ảnh có tần số mở rộng.
goto again;
}
138
FFT của ảnh
N
N
2
1
2
2
T
T
=
T
0s 0s
0s
0s
2
N
2
N
gotoxy(1,2);
printf ( " ");
ind=access(file_name,0);
while(!ind)
{
gotoxy(1,3);
printf("File exists. Wish to overwrite? (y or n) >");
while(((ch=tolower(getch()))!='y')&&(ch!='n'));
putch(ch);
switch(ch)
{
case 'y' :
ind=1 ;
break ;
case 'n' :
gotoxy(1,3);
printf(" ");
gotoxy(1,2);
printf (" ");
gotoxy(1,2);
printf("Enter file name >");
scanf("%s",file_name);
ind=access(file_name,0);
}
}
139
H×nh 7.7 "CAMEL.IMG" vµ ¶nh ®· ®îc phãng to.
N2=N<<1;
/* Allocating memory for bit reversal LUT.*/
L=(unsigned int *)malloc(N2*sizeof(unsigned int));
/* Generate Look-up table for bit reversal.*/
bit_reversal(L,m,N);
/* Allocating memory for twiddle factors. n2=N- 1 */
wr=(float *)malloc(n2*sizeof(float));
wi=(float *)malloc(n2*sizeof(float));
/*Generating LUT for twiddle factors.*/
WTS(wr,wi,N,-1);
/* Taking 2-D FFT. */
FFT2D(fptri,fptro,wr,wi,L,N,m,-1);
140
clrscr() ;
printf(" Adding zeros to FFT of image. \n");
/* Adding zeros to double the size of the FFT.*/
N4=N2<<1 ;
buffi=(float *)malloc(N2*sizeof(float));
buffo=(float *)malloc(N4*sizeof(float));
fptri=fopen("FFT1.img","rb");
fptrt=fopen("temp.img","wb+");
fptro=fopen("TFFT2.jmg","wb+");
for(i=0; i<N4; i++)
buffo[i]=(float)0.0;
/* store O's in the first N/2 lines.*/
for(i=0; i<(N>>1); i++)
fwrite(buffo,N4,sizeof(float),fptrt);
/* Store O's in the first and last N/2 rows.*/
for(i=0; i<N; i++)
fread(buffi,N2,sizeof(float),fptri);
for(j=0;j<N;j++)
buffo[j]=(float)0.0;
for(j=0;j<N2;j++)
buffo[j+N]=buffi[j];
for(j=(N2+N);j<N4;j++)
buffo[j]=(float)0.0;
fwrite(buffo,N4,sizeof(float),fptrt);
for(i=0; i<N4; i++)
buffo[i]=(float)0.0;
for(i=0;i<(N>>1);i++)
fwrite(buffo,N4,sizeof(float),fptrt);
fclose(fptri);
rewind(fptrt);
/* Taking the inverse FFT.*/
printf("Taking the inverse FFT.\n");
m2=m+1 ;
/* Generating bit reversal I(JT.*/
bit_reversal(L,m2,N2);
WTS(wr,wi,N2,1);
FFT2D(fptrt,fptro,wr,wi,L,N2,m2,1);
clrscr() ;
printf("Last stage in forming enlarged image.");
fptri=fopen("IFFT2.img","rb");
fptro=fopen(file_name,"wb");
buffr=(unsigned char *)malloc(N2*sizeof(char));
max=0; min=1.0e7;
for(i=0;i<N2;i++)
{
fread(buffo,N4,sizeof(float),fptri);
141
for(j=0;j<N2;j++)
{
scale=buffo[j<<1];
if(scale>max) max=scale;
if(scale<min) min=scale;
}
}
scale=(float)255.0/(max-min);
rewind(fptri);
for(i=0;i<N2;i++)
{
fread(buffo,N4,sizeof(float),fptri);
for(j=0;j<N2;j++)
buffr[j]=(unsigned char)((buffo[j<<1]-min)*scale);
fwrite(buffr,N2,sizeof(char),fptro);
}
fcloseall();
remove("FFT1.img");
remove("temp.img");
remove("IFFT2.img");
printf("\nDone.");
}
7.5.2 Nhân đôi độ phân giải trên ảnh dùng phép nội suy không gian
Trong phơng pháp này ảnh đầu tiên đợc chứa lên một mảng có kích thớc 2N
ì
2N với tất cả các hàng và các cột đợc xoá về không. ảnh đợc chiếu lần lợt với các
phép nội suy. Hình 7.8 liệt kê các phần của các phép nội suy phổ biến nhất. Giải
thuật nội suy vuông là thao tác sao chép trong đó những điểm ảnh về cơ bản đợc sao
chép vào những vị trí rỗng. Có thể thu đợc toán tử nội suy tam giác nhờ sự kết hợp
hai toán tử nội suy vuông, vì vậy ta có thể thu đợc cùng kết quả nếu ta áp dụng liên
tiếp hai phép nội suy vuông. Giải thuật chuyển đổi những sao chép cơ bản theo bộ
lọc thông thấp sang ảnh để có đợc ảnh trơn hơn. Kết hợp thực hiện ba lần liên tục
trên ảnh với toán tử nội suy vuông tơng đơng với áp dụng toán tử nội suy Bell. Toán
tử nội suy bậc 3 có thể thu đợc nhờ kết hợp phép nội suy vuông và Bell hoặc kết hợp
toán tử nội suy vuông bốn lần. Sử dụng cùng khái niệm đó, chúng ta có thể dễ dàng
có đợc nội suy cao hơn.
142
Hình vuông: 1 1
1 1
Tam giác: 1 2 1
2 4 2
1 2 1
Bell 1 3 3 1
3 9 9 3
3 9 9 3
1 3 3 1
Cubic B-Spline 1 4 6 4 1
4 16 24 16 4
6 24 36 24 6
4 16 24 16 4
1 4 6 4 1
Hình 7.8 Các phép nội suy thông thờng.
Những khái niệm trên có thể đợc thực hiện trong phần mềm tơng tự với việc thực
hiện lọc FIR. Bộ đệm chuyển đổi ảnh kích thớc N ì (2 ì độ rộng của ảnh) đợc tận
dụng, ở đó N = 2 cho toán tử nội suy vuông, N = 3 cho toán tử nội suy tam giác, v.v
Một hàng của ảnh đợc chuyển thành hàng cuối cùng của bộ đệm chuyển đổi ảnh và
lu trữ tại các vị trí khác với các vị trí ở giữa đặt bằng không. Tơng quan của phép nội
suy với bộ đệm truyền tới ảnh và dịch chuyển hàng nh trong phơng pháp trong bộ
lọc FIR, một hàng của các giá trị 0 đợc chuyển đổi thành hàng cuối cùng của bộ đệm
chuyển đổi ảnh. Những bớc này đợc lặp đi lặp lại cho những phần còn lại của ảnh,
bằng cách lựa chọn sự chuyển đổi một hàng từ ảnh theo một hàng của các giá trị 0.
Thủ tục thực hiện thuật toán này đợc cho trong chơng trình 7.3.
Chơng trình 7.3 ENLARGE.C.
/* This program doubles the dimensions of an
image by interpolation. */
#include <stdio.h>
#include <math.h>
#include <alloc.h>
#include <conio.h>
#include <io.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int SQUARE[2][2]={ { 1, 1 },
{ 1, 1 }};
int TRIANGLE[3][3]= { { 1, 2, 1 },
{ 2, 4, 2 },
{ 1, 2, 1 } };
int BELL[4][4]={ { 1, 3, 3, 1 },
{ 3, 9, 9, 3},
{ 3, 9, 9, 3},
{ 1, 3, 3, 1} } ;
int CUBIC_B_SPLINE[5][5]={ { 1, 4, 6, 4, 1 },
143
{ 4, 16, 24, 16, 4 },
{ 6, 24, 36, 24, 6 },
{ 4, 16, 24, 16, 4 } };
void main()
{
char file_name[14],ch;
FILE *fptri,*fptro,*fptrt;
double nsq;
int image_length,image_width, N, N1,image_length2,
image_width2,i,j,ind,xt,yt;
unsigned int **a,n1,n2,k1,k2,sum,max,min,*bufft;
unsigned char **w,*buffi,*buffo,*temp;
float scale;
clrscr();
printf("Enter file name for input image >");
scanf("%s",file_name);
fptri=fopen(file_name,"rb");
if(fptri==NULL)
{
printf("%s does not exist.",file_name);
printf("\nPress any key to exit. ");
getch() ;
exit(1);
}
nsq=filelength(fileno(fptri));
printf("Is this a square image ?");
printf("\n i.e. Is image length =image width (y or no) ? >");
while(((ch=tolower(getch()))!='y')&&(ch!='n'));
putch(ch);
switch(ch)
{
case 'y' :
image_length=image_width=sqrt(nsq);
printf("\n Image size = %d x %d",image_length,
image_width);
break;
case 'n':
printf("\nEnter image_width >");
scanf("%d",&image_width);
image_length=nsq/image_width;
printf("Image length is %d", image_length);
break;
again :
gotoxy(1,5);
printf(" ");
gotoxy(1,5);
printf("Enter file name for enlarged image >");
144
scanf("%s",file_name);
if((stricmp("temp.img",file_name))==0)
{
printf("This is a reserved file name. Use some other name.");
goto again;
}
gotoxy(1,6);
printf ( " ");
ind=access(file_name,0);
while(!ind)
{
gotoxy(1,6);
printf("File exists. Wish to overwrite? (y or n) >");
while(((ch=tolower(getch()))!='y')&&(ch!='n'));
putch(ch);
switch(ch)
{
case 'y' :
ind=1;
break;
case 'n' :
gotoxy(1,6);
printf ( " ");
gotoxy(1,5);
printf ( " ");
gotoxy(1,5);
printf("Enter file name >");
scanf("%s",file_name);
ind=access(file_name,0);
}
}
fptro=fopen(file_name,"wb");
printf("\nEnter choice for interpolation \n");
printf(" 1.SQUARE. \n");
printf(" 2.TRIANGLE. \n");
printf(" 3.BELL. \n");
printf(" 4.CUBIC B-SPLINE. \n");
printf(" Enter choice (1,2,3 or 4) ");
while(((ch=getche())!='l')&&(ch!='2')
&&(ch!='3')&&(ch!='4'));
N1=ch-48;
N=N1+1 ;
a=(unsigned int **)malloc(N*sizeof(int *));
for(i=0;i<N;i++)
*(a+i)=(unsigned int *)malloc(N*sizeof(int));
switch(N1)
145
{
case 1: for(i=0;j<N;i++)
for(j=0;j<N;j++)
a[i][j]=SQUARE[i][j];
break;
case 2: for(i=0;i<N;i++)
for(j=0;j<N;j++)
a[i][j]=TRIANGLE[i][j];
break;
case 3: for(i=0;i<N;i++)
for(j=0;j<N;j++)
a[i][j]=BELL[i][j];
break ;
case 4: for(i=0;i<N;i++)
for(j=0;j<N;j++)
a[i][j]=CUBIC_B_SPLINE[i][j];
}
image_width2=2*image_width;
image_length2=2*image_length;
/*Allocating memory for image transfer buffer.*/
w=(unsigned char **)malloc(N*sizeof(char *));
for(i=0;i<N;i++)
*(w+i)=(char *)calloc(image_width2,sizeof(char));
/*Clear image transfer buffer.*/
for(i=0;i<N;i++)
for(j=0;j<image_width2;j++)
w[i][j]=(unsigned char)0;
/*Allocating memory for input and output buffers.*/
buffi=(char *)malloc(image_width*sizeof(char));
buffo=(char *)malloc(image_width2*sizeof(char));
bufft=(unsigned int *)malloc(image_width2*sizeof(int));
fptrt=fopen("temp.img","wb+");
max=0; min=20000;
xt=wherex();
yt=wherey();
gotoxy(70,25);
textattr(WHITE+(GREEN<<4)+BLINK);
cputs("WAIT");
/*Interpolation.*/
for(n1=0;n1<image_length2;n1++)
{
if((n1%2)==0)
fread(buffi,image_width,sizeof(char),fptri);
else /* Every other row is set to zero. */
for(j=0;j<image_width;j++)
buffi[j]=(unsigned char)0;
146
for(j=0;j<image_width;j++)
w[N1][j<<1]=buffi[j];/*Every other location is set to zero. */
for(n2=0;n2<image_width2;n2++)
{
sum=(int)0;
for(k1=0;k1<N;k1++)
for(k2=0;k2<N;k2++)
{
if((n2+k2-N1)<(int)0) continue;
sum+=a[k1][k2]*w[k1][n2+k2-N1];
}
bufft[n2]=sum;
if(sum>max) max=sum;
if(sum<min) min=sum;
}
fwrite(bufft,image_width2,sizeof(int),fptrt);
/* Shift rows of w. */
temp=*w;
for(j=0;j<N1;j++)
*(w+j)=*(w+j+1);
*(w+N1)=temp;
}
rewind(fptrt);
scale=(float)255.0/((float)(max-min));
for(i=0;i<image_length2;i++)
{
fread(bufft,image_width2,sizeof(int),fptrt);
for(j=0;j<image_width2;j++)
buffo[j]=(unsigned char)((float)(bufft[j]-min)*scale);
fwrite(buffo,image_width2,sizeof(char),fptro);
}
fclose(fptrt);
fclose(fptri);
fclose(fptro);
remove("temp.img");
gotoxy(70,25);
textattr(WHITE+(BLACK<<4));
cputs(" ");
gotoxy(xt,yt);
}
Để kiểm tra chơng trình 7.3 chúng ta sẽ sử dụng ảnh "CAMEL.IMG" mà ta đã sử
dụng để kiểm tra trong phơng pháp tần số. Kết quả sử dụng nội suy bậc 3 đợc thể
hiện trên hình 7.9. Nh đã mong đợi, ảnh hơi mờ, và chất lợng thấp hơn ảnh thu đợc
qua việc ứng dụng định lý lấy mẫu. Tuy nhiên, có thể khôi phục ảnh mờ bằng cách
sử dụng kỹ thuật không gian thông qua việc sử dụng trực tiếp bộ lọc thông cao.
Chúng ta sẽ đề cập nhiều hơn về vấn đề này trong chơng 8. Tổng quan về ảnh mờ sẽ
đợc thảo luận trong chơng 10.
147
7.6 Bộ lọc sai phân thống kê Wallis
Bởi vì phóng đại ảnh là một dạng của tăng cờng ảnh, sẽ là thích hợp khi giới thiệu
bộ lọc sai phân thống kê tại thời điểm này. Kiểu lọc này đợc phát triển bởi Wallis là
đặc biệt hữu ích trong việc tăng cờng các chi tiết trong vùng tối. Vấn đề này nảy
sinh trong ảnh x-quang nh chỉ trên hình 7.10. Trong giải thuật lọc Wallis mỗi điểm
đợc điều chỉnh bằng phép trừ giá trị trung bình của các điểm lân cận và chia với độ
lệch chuẩn của các điểm lân cận của nó. ảnh lọc Wallis thờng đợc trung bình với
ảnh gốc. Nguyên nhân phải thực hiện việc trung bình ảnh này là để ngăn cản việc
loại bỏ toàn bộ nền. Kích thớc của vùng lân cận thờng đợc nói đến nh bậc của bộ
lọc. Kết quả của áp dụng bộ lọc Wallis bậc 5 đợc chỉ trên hình 7.11.
Hình 7.9 Phóng to ảnh "CAMEL.IMG" dùng phơng pháp gần đúng.
Bài tập 7.1
1.Tìm kiếm và phân tích tài liệu của H.S.Hou và H.C.Andrews. Trên cơ sở đó, viết
chơng trình C cho phép phóng to, thu nhỏ ảnh dùng các toán tử bậc 3.
2.Vấn đề về miền tần số cũng đợc đề cập bởi T.C.Chen và R.J.P.De Figueiredo.
Đọc và phân tích tài liệu đó.
148
H×nh 7.10 ¶nh cña tia x.
H×nh 7.11 Xö lý ¶nh h×nh 7.10 víi bé läc Wallis.
Bµi tËp 7.2
149