Tải bản đầy đủ (.pdf) (8 trang)

Giáo trình xử lý ảnh y tế Tập 2 P8 ppsx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (154.66 KB, 8 trang )

169


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,N1,m,n2,i,j,ii,jj,N2,k,norder,j1,ind,yt;
unsigned int *L;
float *wr,*wi,Do,theta,nsqrt,beta,alpha,sum1,sum2,T;
FILE *fptri,*fptro,*fptr;
float *buffi,*buffo,R2,H,nsq,win,slope,gamal,gamah;
unsigned char file_name[14], ch,ch1,file_name1[14];
clrscr() ;
printf("Freq response can be calculated using standard\n");
printf(" functions available to you if your reply to the\n");
printf(" following question is negative.\n");
printf("Is freq. response provided in a file? (y or n) >");
while(((ch1=getche())!='y')&&(ch1!='n'));
switch(ch1)
{
case 'n':
case 'N':
printf("\nEnter # of points to be generated (e.g. 32x32) >");
scanf("%d%c%d",&N1,&ch,&N1);
break;


case 'y' :
case 'Y ':
printf("\nEnter name of file storing magnitude response >");
scanf("%s",file_name1);
fptr=fopen(file_name1,"r");
fscanf(fptr,"%d %d ",&N1,&N1);
}
N=N1>>1;
yt=wherey();
again :
gotoxy(1,yt);
printf(" ");
gotoxy(1,yt);
printf("Enter file name for storing impulse response >");
scanf("%s",file_name);
170

if(((stricmp("FFT.DAT",file_name))==0)||
((stricmp("TEMP.DAT",file_name))==0)||
((stricmp("IFFT.DAT",file_name))==0))
{
printf("This is a reserved file name. Use some other name.");
goto again;
}
gotoxy(1,yt);
printf( " ");
ind=access(file_name,0);
while(!ind)
{
gotoxy(1,yt+1);

printf ( " ");
gotoxy(1,yt+1);
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,yt+1);
printf ( " ");
printf ( " ");
gotoxy(1,yt);
gotoxy(1,yt);
printf("Enter file name >");
scanf("%s",file_name);
ind=access(file_name,0);
}
}
fptri=fopen("FFT.DAT","wb+");
fptro=fopen("IFFT.DAT","wb+");
buffi=(float *)malloc((N1<<1)*sizeof(float));
switch(ch1)
{
case 'n' :
case 'N' :
/*Generating data for IFFT. */
printf

("\nEnter cut-off freq. in rad./sec. ( cut-off <= n.)->");
171

scanf("%f",&Do);
Do=(Do/pi)*(float)N;
printf("Enter choice (1,2,3,4 or 5):\n");
printf(" 1. Low-pass with abrupt transition.\n");
printf(" 2. High-pass with abrupt transition.\n");
printf(" 3. Low-pass Butterworth.\n");
printf(" 4. High-pass Butterworth.\n");
printf(" 5. Homomorphic characteristcs >");
while(((ch=getche())!='l')&&(ch!='2')
&&(ch!=13)&&(ch!='4')&&(ch!='5'));
if(ch=='5')
{
printf("\nEnter gain at không freq >");
scanf("%f",&gamah);
printf("Enter gain at high frequencies >");
scanf("%f",&gamah);
slope=(gamah-gamal)/Do;
}
Do*=Do;
if((ch=='3')||(ch=='4'))
{
printf("\n Enter order of Butterworth >");
scanf("%d",&norder);
for(i=0;i<norder;i++)
Do*=Do;
}
printf("\n");

for(i=0;i<N1;i++)
{
ii=(i-N)*(i-N);
for(j=0;j<N1;j++)
{
R2=(float)((j-N)*(j-N)+ii);
if((ch=='3')||(ch=='4'))
{
for(j1=0;j1<norder;j1++)
R2*=R2;
}
switch(ch)
{
case '1': /* low-pass abrupt transition.*/
if(R2<Do) H=(float)1.0;
else H=(float)0.0;
break;
172

case '2': /* high-pass abrupt transition*/
if(R2<Do) H=(float)0.0;
else H=(float)1.0;
break;
case '3': /* low-order Butterworth */
H=Do/(Do+0.414*R2);
break;
case '4': /* high-order Butterworth. */
H=R2/(R2+0.414-Do);
break;
case '5': /* homomorphic characteristics. */

if ( R2<Do)
H=slope*sqrt((double)R2)+gamal;
else
H=gamah ;
}
jj=j<<1;
buffi[jj]=H;
buffi[jj+1]=0.0;
}
fwrite(buffi,N1,2*sizeof(float),fptri);
}
break;
case 'y':
case 'Y' :
for(i=0;i<N1;i++)
{
for(j=0;j<N1;j++)
{
fscanf(fptr,"%f ",&H);
jj=j <<1 ;
buffi[jj]=H;
buffi[jj+1]=(float)0.0;
}
fwrite(buffi,N1,2*sizeof(float),fptri);
}
fclose(fptr);
}
rewind(fptri);
m=(int)(log10((double)N1)/log10((double)2));


/* Allocating memory for bit reversal LUT. */
L=(unsigned int *)malloc(N1*sizeof(unsigned int));

173

/* Generate Look-up table for bit reversal. */
bit_reversal(L,m,N1);

/* Allocating memory for twiddle factors. */
n2=N1-1;
wr=(float *)malloc(n2*sizeof(float));
wi=(float *)malloc(n2*sizeof(float));

/* Generating twiddle factor. */
WTS(wr,wi,N1,1);
clrscr() ;
FFT2D(fptri,fptro,wr,wi,L,N1,m,1);
remove("FFT.DAT");
clrscr() ;
fptri=fopen("IFFT.DAT","rb");
fptro=fopen(file_name,"wb+");
nsq=(float)(N1*N1);
buffo=(float *)malloc(N1*sizeof(float));
for(i=0;i<N1;i++)
{
fread(buffi,N1,2*sizeof(float),fptri);
for(j=0;j<N1;j++)
buffo[j]=buffi[2*j]/nsq;
fwrite(buffo,N1,sizeof(float),fptro);
}

fclose(fptri);
remove("IFFT.DAT");
rewind(fptro);
printf("Enter selection of window function:");
printf("\n 1.Rectangular.");
printf("\n 2.Hann.");
printf("\n 3.Hamming.");
printf("\n 4.Blackmann.");
printf("\n 5.Kaiser.");
printf("\nEnter (1,2 etc.) >");
while(((ch=getche())!='I')&&(ch!='2')&&
(ch!='3')&&(ch!='4')&&(ch!='5'));
printf("\n");
if(ch!='1')
{
N2=N1/2 ;
theta=pi/((float)N2*sqrt((double)2.0));
for(i=0;i<N1;i++)
{
174

ii=(i-N2)*(i-N2);
fread(buffo,N1,sizeof(float),fptro);
for(j=0;j<N1;j++)
{
jj=(j-N2)*(j-N2);
nsq=(float)(ii+jj);
nsqrt=sqrt((double)nsq)/sqrt((double)2.0);
switch(ch)
{

case '2':
win=0.5+0.5*cos((double)(theta*nsqrt));
buffo[j]*=win;
break;
case '3' :
win=0.54+0.46*cos((double)(theta*nsqrt));
buffo[j]*=win;
break;
case '4' :
win=0.42+0.5*cos((double)(theta*nsqrt))
+0.08*cos((double)(2.0*theta*nsqrt));
buffo[j]*=win;
break;
case '5':
if((i+j)==0)
{
printf("\n\nEnter a value for alpha (1 to 8) >");
scanf("%f",&alpha);
alpha/=2.0;
}
beta=nsqrt/(float)N2;
beta*=beta;
beta=alpha*sqrt(fabs((double)(1.0-beta)));
T=alpha;
sum1+=1.0+T*T;
for(k=2;k<11;k++)
{
T=(1.0/(float)k)*alpha*T;
sum1+=T*T;
}

T=beta;
sum2=1.0+T*T;
for(k=2;k<11;k++)
{
T=(1.0/(float)k)*alpha*T;
175

sum2+=T*T;
}
win=sum2/sum1;
buffo[j]*=win;
break;
}
}
fwrite(buffo,N1,sizeof(float),fptro);
}
}
printf
("\nDo you wish to store data for 3-D plotting? (y or n) >");
while(((ch=getche())!='y')&&(ch!='n'));
switch(ch)
{
case 'n':
fclose(fptro);
exit(1);
case 'y':
rewind(fptro);
}
printf("\nEnter file name for storing data for 3-D plotting ->");
scanf("%s",file_name);

fptri=fopen(file_name,"w");
fprintf(fptri,"%d %d\n",N1,N1);
fprintf(fptri,"%e",(float)0.0);
for(i=0;i<N1;i++)
fprintf(fptri,"%e",(float)i);
for(i=0;i<N1;i++)
{
fprintf(fptri,"\n");
fread(buffo,N1,sizeof(float),fptro);
fprintf(fptri,"%e",(float)i);
for(j=0;j<N1;j++)
fprintf(fptri," %e",buffo[j]);
}
fclose(fptri);
fclose(fptro);
}
9.5 Thiết kế bộ lọc IIR
Hình 9.3 biểu diễn miền không gian của đáp ứng xung. Vòng tròn xẫm màu
nằm ở trung tâm chứa những biên độ lớn nhất của h
d
(m,n). Trong phần tiếp
176

theo này, chúng ta sẽ nghiên cứu cách sử dụng tốt nhất đáp ứng xung trong
thiết kế bộ lọc IIR dùng các phương pháp Shanks. Rõ ràng chúng ta có khả
năng được chọn từ:

1. Dùng bốn góc phần tư của đáp ứng xung với điểm (0,0) nằm ở tại trung
tâm của miền.
2. Dịch chuyển các trục để (0,0) nằm ở góc cao bên trái. (Hình 9.3a)

3. Tính đáp ứng xung từ góc phần tư nằm ở bên phải phía dưới. (Hình 9.3a)
4. Dịch chuyển các trục một đoạn đủ lớn để bao khối lớn nhất của đáp ứng
xung. (Hình 9.3b).

Đáp ứng xung mong muốn được trích ra từ miền gạch chéo trong hình
9.3b. Lựa chọn đầu tiên yêu cầu chúng ta phải chuyển hàm truyền đạt dưới
dạng :

















Hình 9.3 (a) Chọn một phần tư hay góc phần tư thứ tư. (b) Chọn miền lớn hơn
bao gồm những giá trị trội trong đáp ứng xung.

j
i
ij

N
Nj
N
Ni
ji
ij
N
Nj
N
Ni
zzb
zza
zzH








2
1
2
1
21
),( (9.24)
Chú ý rằng nếu bạn nhân biểu thức (9.24)với z
1
N

z
2
N
, chúng ta sẽ chuyển
hàm truyền đạt thành một hệ thống nhân quả. Dù thế nào đi chăng nữa tính
không nhân quả có nghĩa là điều kiện khởi đầu khác 0 và điều này cũng chỉ ra
(0,0)

Một phần tư
mặt phẳng .
M
M

offset

offset

m’
m
n’

n
(a)
n’

n
offset

(0,0)


m’
m
(b)
offset

×