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

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

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 (248.92 KB, 8 trang )

201

/* This program is for eN1arging images using 2-D
iir filters. The filter's coefficients can be obtained
from iird.exe or iirditer.exe. */

#include <stdio.h>
#include <math.h>
#include <conio.h>
#include <io.h>
#include <stdlib.h>
#include <alloc.h>
#include <ctype.h>
#include <string.h>

void main()
{
FILE *fptri,*fptro,*fptrt;
unsigned char *buff,**wx,ch,*temp1;
double nsq;
float **wy,**a,**b,*temp2,*bufft;
float max,min,scale,tt;
int n,m,image_length,image_width,i,j,N,N1,ind;
int true_length,true_width,yt,k;
char file_name[14];

clrscr();
printf("Enter file name for image >");
scanf("%s",file_name);
fptri=fopen(file_name, "rb");
if(fptri==NULL)


{
printf("No such image file exists.\n");
exit(1);
}
nsq=(double)filelength(fileno(fptri));
printf("Is image length equal to image width ? (y or n) >");
while(((ch=getche())!='y')&&(ch!='n'));
switch(ch)
{
case 'y' :
image_length=image_width=(int)sqrt(nsq);
break;
case 'n':
printf("\nEnter image_width >");
scanf("%d",&image_width);
202

image_length=(int)(nsq/(float)image_width);
}
printf("\n Image size %dx%d. " , image_length, image_width);
printf ( "\nEnter file name for filter's coefficients >" ) ;
scanf("%s",file_name);
fptro=fopen(file_name,"r");
if(fptro==NULL)
{
printf("\nNo such file exists.\n");
exit(1);
}



Hình 9.12 Bộ lọc nội suy đáp ứng tần số kích thước 2  2 thiết kế từ đáp ứng
vuông với miền chuyển tiếp dốc và 
c
= 1.4.
fscanf(fptro," %d",&N);
printf("IIR filter has an order of %dx%d.",N,N);
N1=N+1;

/* Allocating memory space. */
a=(float **)malloc(N1*sizeof(float *));
for(i=0;i<N1;i++)
*(a+i)=(float *)malloc(N1*sizeof(float)),

b=(float **)malloc(N1*sizeof(float *));
203

for(i=0;i<N1;i++)
*(b+i)=(float *)malloc(N1*sizeof(float));

wx=(unsigned char **)malloc(N1*sizeof(char *));
for(i=0;i<N1;i++)
*(wx+i)=(unsigned char *)malloc(2*image_width*sizeof(char));

wy=(float **)malloc(N1*sizeof(float *));
for(i=0;i<N1;i++)
*(wy+i)=(float *)malloc(2*image_width*sizeof(float));

buff=(unsigned char *)malloc(image_width*sizeof(char));
bufft=(float *)malloc(2*image_width*sizeof(float));


for(i=0;i<=N;i++)
for(j=0;j<=N;j++)
fscanf(fptro," %f %f",&a[i][j],&b[i][j]);
fclose(fptro);

yt=wherey()+1;
again:
gotoxy(1,yt);
printf ( " ");
gotoxy(1,yt);
printf("Enter file name for eN1arged image ->");
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,yt+1);
printf ( " ");
ind=access(file_name,0);
while(!ind)
{
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;

204

break;
case 'n':
gotoxy(1,yt+1);
printf(" ");
gotoxy(1,yt);
printf(" ");
gotoxy(1,yt);
printf("Enter file name >");
scanf("%s",file_name);
ind=access(file_name,0);
}
}
fptro=fopen(file_name,"wb");
fptrt=fopen("temp.imq","wb+");

/* Clearing input and output image transfer buffers. */
for(i=0;i<N1;i++)
for(j=0;j<(2*image_width);j++)
{
wx[i][j]=(char)0;
wy[i][j]=(float)0.0;
}
max=(float)0.0;
min=(float)1000.0;
true_width=2*image_width-N1;
true_length=2*image_length*0.9;

for(n=0; n<(2*image_length); n++)

{
if((n%2)==0)
fread(buff,image_width,1,fptri);

/* Read the same line for odd or even pixels.*/
gotoxy(1,yt+4);
printf("Transferred line %d to input buffer.",n);
k=0;
for(j=0;j<(2*image_width);j++)
{
if((j%2)==0)
wx[0][j]=buff[k++];
else
wx[0][j]=wx[0][j-1];
}
for(m=0;m<(2*image_width);m++)
205

{
wy[0][m]=(float)0.0;
for(i=0;i<=N;i++)
for(j=0;j<=N;j++)
{
if((m-j)<0) continue;
wy[0][m]+=a[i][j]*(float)wx[i][m-i];
if((i+j)==0) continue;
wy[0][m]-=b[i][j]*(float)wy[i][m-i];
}
bufft[m]=wy[0][m];
if((m>N1)&&(m<true_width)&&(n>N1)&&(n<true_length))

{
if(bufft[m]>max) max=wy[0][m];
if(bufft[m]<min) min=wy[0][m];
}
}
fwrite(bufft,2*image_width,sizeof(float),fptrt);

/* Shifting. */
temp1=*(wx+N);
for(i=0;i<N;i++)
*(wx+N-i)=*(wx+(N-1)-i);
*wx=temp1;
temp2=*(wy+N);
for(i=0;i<N;i++)
*(wy+N-i)=*(wy+(N-1)-i);
*wy=temp2;
}
printf("\n\n Scaling ");
yt=wherey();
rewind(fptrt);
scale=(float)250.0/(max-min);
for(n=0;n<(2*image_length);n++)
{
gotoxy(1,yt+2);
printf("Scaling line %d.",n);
fread(bufft,2*image_width,sizeof(float),fptrt);
for(m=0;m<(2*image_width);m++)
{
tt=(bufft[m]-min)*scale;
if(tt>255.0) tt=255.0;

if(tt<0.0) tt=0.0;
buff[m]=(unsigned char)tt;
206

}
fwrite(buff,2*image_width,1,fptro);
}
fclose(fptri);
fclose(fptro);
fclose(fptrt),
remove("temp.img");
}


Bài tập 9.4
Chạy thử chương trình 9.4 trên ảnh "CAMEL.IMG" và "MAHER.IMG" sử
dụng:
1. Bộ lọc IIR thông thấp đáp ứng vuông với 
c
= /2.0.
2. Bộ lọc thông thấp đối xứng tuần hoàn với 
c
= /2.0.

Đầu tiên dùng đáp ứng có miền chuyển tiếp dốc, và sau đó dùng hàm
Butterworth. So sánh kết quả với phương pháp FFT được mô tả trong chương
7.
Chú ý: Để thiết kế được bộ lọc trước tiên bạn cần chạy "IMPULSE.EXE"
theo "IIRD.EXE". Với đáp ứng vuông bạn sẽ cần phải hoặc là thêm một số
thay đổi vào chương trình hoặc là viết một chương trình riêng để sinh và lưu

trữ dữ liệu biên độ tần số trong một file. Chương trình IMPULSE.C cho phép
đọc dữ liệu được sinh ra từ bên ngoài. Một chương trình mẫu để sinh ra dữ liệu
phù hợp với IMPULSE.C được cho trong chương trình 9.5.

Chương trình 9.5 “GEN-DATA.C”. Chương trình mẫu tạo tạo dữ liệu
đáp ứng tần số cho “IMPULSE.C”.

/* Program 9.5 "GEN-DATA.C". Sample program for generating frequency-
response data for "IMPULSE.C". */

#define pi 3.141592654

#include <stdio.h>
#include <conio.h>

main()
{
int i,j,ii,jj,N,N1,kk;
float Do,H;
FILE *fptr;
207

char file_name[14];
clrscr();
printf
("\nEnter number of data points to be generated (e.g. 32x32) >");
scanf("%dx%d",&N1,&N1);
printf("Enter file name for storing mag. response >");
scanf("%s",file_name);
fptr=fopen(file_name,"w");

N=N1/2;
printf ( "Enter cut-off ( less than pi ) >");
scanf("%f",&Do);
kk=(int)((Do/pi)*(float)N);
kk*=kk;

Hình 9.13 Đáp ứng tần số của bộ lọc nội suy 2  2 từ đáp ứng hình vuông với
miền chuyển tiếp dốc và 
c
= 1.4.
fprintf(fptr,"%d %d ",N1,N1);
for(i=0;i<N1;i++)
{
ii=(i-N)*(i-N);
for(j=0;j<N1;j++)
{
jj=(j-N)*(j-N);
if((ii<=kk)&&(jj<=kk)) H=1.0;
208

else H=0.0;
fprintf(fptr,"%f ",H);
}
}
fclose(fptr);
}


Trước khi kết thúc chương này chúng ta sẽ thiết kế lại bộ lọc của hình 9.12
sử dụng thay cho bộ lọc FIR. Đáp ứng biên độ tần số của bộ lọc FIR kích

thước 5  5 sử dụng cửa sổ Blackmann được chỉ trên hình 9.13. Rõ ràng là giải
chuyển đổi có độ dốc hơn nhiều so với hình 9.12. Bộ lọc FIR 5  5 có 25 hệ số
so với 17 hệ số của bộ lọc FIR kích thước 2  2. Mặc dù vậy bộ lọc FIR có
nhiều lợi thế so với bộ lọc IIR, chúng linh động hơn và có bậc cao hơn nhiều.
Vấn đề khó khăn của bộ IIR là độ ổn định không được bảo đảm, và pha tuyến
tính thực sự là không có thể. Tuy nhiên, phương pháp được mô tả trong
chương này, mặc dù không đảm bảo tính ổn định, nhưng dường như ổn định
với pha gần tuyến tính.


Bài tập 9.5
Viết chương trình để nhân đôi độ phân giải ảnh sử dụng bộ kiểu lọc FIR,
dùng phương pháp được mô tả trong mục 9.8.

Bài tập 9.6
Lặp lại bài tập 9.4 dùng bộ lọc FIR để thay thế. Thử những hàm cửa sổ khác
nhau.

Bài tập 9.7
Đảo ngược từng bước giải thích trong phần này để thu được sự thay đổi
ảnh. Điều này rất hữu ích cho ứng dụng TV trong đó chúng được biết như ảnh
trong ảnh, ở đó một ảnh nhỏ đặt lên trên một ảnh lớn trên màn hình hiển thị
của một kênh khác. Bạn sẽ cần phải đảo lọc, và bộ lọc đảo có thể không ổn
định. Nếu đây là một vấn đề bạn cần phải thiết kế một bộ lọc mới để xấp xỉ bộ
lọc thông cao miền chuyển tiếp dốc với đối xứng vuông, và một vài kết quả ở
tần số 0,0. Sau khi lọc, các điểm khác và các dòng khác được sử dụng để hiển
thị ảnh.

Bài tập 9.8
Tham khảo 5 (trang 482- 483) cung cấp bộ lọc nội suy 2-D cho việc phóng

đại ảnh. Tận dụng bộ lọc IIR trình bày trên trang đó và so sánh kết quả. Tác
giả cũng đề nghị rằng bộ lọc nội suy theo bộ lọc thông cao. Thực hiện lời đề

×