207 bộ lọc 2-D. Ví dụ để thiết kế bộ lọc IIR bạn cần có IMPULSE.EXE và IIRD.EXE theo tên của file lấy từ chương trình này. Để chạy chương trình này bạn cần tách các đường biên dùng một trong các chương trình hoặc biểu đồ đã mô tả ở trong chương 5. Chương trình bắt nguồn từ tên của file chứa ảnh mờ và độ đậm đường biên ảnh. Độ đậm đường biên ảnh là file chứa ảnh sau khi đã tách ra các đường biên. Chương trình 10.1 :DEBLUR.C” Tính độ lớn của đáp ứng /*ProgramlO.1 "DEBLUR.C".Calculating the magnitude response of the deblurring function.*/ /* This program calculates the inverse magnitude response of the extracted blurring function.Theprogram requires the file names of the blurred imageand the edge strength image for the blurred image.To obtain the edge strength image you can use Kirsh.exe or Sobel.exe. */ #include <stdio.h> #include <math.h> #include <stdlib.h> #include <io.h> #include <conio.h> #include <ctype.h> #define pi 3.1414 void main() { FILE *fptr1,*fptr2,*fptr; char file_name1[12],file_name2[12]; unsigned char *buff; int M,M1,z,i,j,*wv,*wh,x0,y0,sign_max; float sum,A,*cv,*ch,mu1,mu2,pi2; float sigmax,sigmay,sx2,sy2,u,v,du,dv; float H[32][32],G,x; double nsq; char file_name[14],ch1; clrscr(); printf ("Enter file name for blurred image before obtaining edges >"); 208 scanf("%s",file_name1); fptr1=fopen(file_name1,"rb"); if(fptr1=NULL) { printf("File does not exist."); exit(1); } printf("Enter file name for edge strength image >"); scanf("%s",file_name2); fptr2=fopen(file_name2,"rb"); if(fptr2=NULL) { printf("File does not exist."); exit(1); } nsq=filelength(fileno(fptr1)); M=sqrt(nsq); M1=M/4; buff=(char *)malloc(M); wv=(int *)malloc(11*sizeof(int)); wh=(int *)malloc(11*sizeof(int)); ch=(float *)malloc(11*sizeof(float)); cv-(float *)malloc(11*sizeof(float)); fseek(fptr2,(long)(M*M1),0); for(i-M/4;i<(3*M/4);i++) { fread(buff,M,1,fptr2); for(j=M/4;j<(3*M/4);j++) { z=(int)(buff[j]-buff[j-1]); if(abs(z)>(int)30) { printf("\An edge has been detected at (%d, %d)",j,i); x0=j; y0=i; goto one; } } } printf("\nNo edges has been located."); fclose(fptr2); exit(1); one: 209 fclose(fptr2); fseek(fptr1,(long)(M*(y0-5)),0); for(i=0;i<11;i++) { fread(buff,M,1,fptr1); wv[i]=buff[x0]; if(i==5) { for(j=0;j<11;j++) wh[j]=buff[j+x0-5]; } } /* Obtaining the derivatives of the image about the edge. */ for(j=1;j<11;j++) { ch[j]=(float)(abs((wh[j]-wh[j-1]))); cv[j]=(float)(abs((wv[j]-wv[j-1]))); } ch[0]=ch[1]; cv[0]=cv[1]; fclose(fptr1); printf("\nDo you wish to store horizontal and vertical difference"); printf("\n data for plotting (y or n) >"); while(((ch1=tolower(getch()))=='y')&&(ch1=='n')); putch(ch1); if(ch1== 'y') { /* Preparing data for plotting. */ printf("\nEnter file name for storing data"); printf("\n taken along a horizontal line >"); scanf ( "%s", file_name1); printf("Enter file name for storing data "); printf("\n taken along a vertical line >"); scanf("%s " , file_name2); fptr1=fopen(file_name1,"w"); fptr2=fopen(file_name2,"w"); fprintf(fptr1,"%d %d\n",11,2); fprintf(fptr2, "%d %d\n",11,2); for(i=0;i<11;i++) { fprintf(fptr1,"%e %e\n",(float)i,ch[i]); fprintf(fptr2,"%e %e\n",(float)i,cv[i]); 210 } fclose(fptr1); fclose(fptr2); } A=(ch[0]+ch[10])/2.0; for (i=1;i<10; i++) A+=ch[i]; for(i=0;i<11;i++) ch[i]/=A; mu1=0.0; for(i=0;i<11;i++) mu1+=(float)i*ch[i]; sum=0.0; for(i=0;i<11;i++) sum+=(i-mu1)*(i-mu1)*ch[i]; sigmax=sqrt((double)sum); printf("\n mul=%f sigmax=%f\n",mu1,sigmax); A=(cv[0]+cv[10])/2.0; for(i=1;i<10;i++) A+=cv[i]; for(i=0;i<11;i++) cv[i]/=A; mu2=0.0; for(i=0;i<11;i++) mu2+=(float)i*cv[i]; sum=0.0; for(i=0;i<11;i++) sum+=(i-mu2)*(i-mu2)*cv[i]; sigmay=sqrt((double)sum); printf("\n mu2=%f sigmay=%f\n",mu2,sigmay); sx2=sigmax*sigmax; sy2=sigmay*sigmay; printf("\n Does the source of the blur imposes equal extent \n"); printf(" of blurs in both the x and y directions?(y or n) >"); while(((ch1=getche())!='y')&&(ch1!='n')); if(ch1=='y') sx2=sy2=sx2+sy2; printf("\nEnter name of file for storing magnitude- frequency"); printf("\nresponse in a form suitable for plotting >"); scanf("%s",file_name); 211 fptr=fopen(file_name,"w"); u=-pi; pi2=2.0*pi*sigmax*sigmay;; du=dv=(2.0*pi)/32.0; Hình 10.3 Hàm khôi phục ảnh mờ. for(i=0;i<32;i++) { v=-pi; for(j=0;j<32;j++) { x=(u*u*sx2+v*v*sy2)/2.0; if(x>=20.0) G=(float)0.0; else G=(float)exp((double)(-x)); H[i][j]=1.0/(pi2*G+1.0); v+=dv; } u+=du ; } fprintf(fptr,"%d %d\n",32,32); fprintf(fptr,"%e ",0.0); v=-pi; for(i=0;i<32;i++) 212 { fprintf(fptr,"%e ",v); v+=dv; } fprintf(fptr,"\n"); u=-pi; for(i=0;i<32;i++) { fprintf (fptr, "%e " , u) ; for(j=0;j<32;j++) fprintf(fptr,"%e ",H[i][j]); fprintf(fptr, " \n "); u+=du; } fclose(fptr); printf("\nEnter file name for storing mag . -freq . response in a"); printf ( "\nformat that can be used by IMPULSE. C or FIRD.C > " ); scanf ( "%s " , file_name); fptr=fopen(file_name,"w"); fprintf(fptr , "%d %d ", 32, 32); for(i=0;i<32;i++) for (j=0 ;j<32 ; j++) fprintf(fptr,"%f ", H[i][j]); fclose(fptr) ; } Bài tập 10.1 Kiểm tra thủ tục trên đây với ảnh "CAMEL.IMG" (hình 7.7a) đã được phóng to, dùng hàm nội suy chốt B bậc ba. Kết quả được cho trong hình 7.9 đó là ảnh hơi mờ. Với yêu cầu nhận dạng đường biên ảnh mà tại đó phạm vi vết mờ theo cả hai hướng ngang và dọc có thể đánh giá được, chương trình trên đã cho ra một đường biên ảnh rõ nét trên cả hai hướng ngang và dọc. Kết quả này có thể thu được khi sử dụng toán tử Kirsh (chương 5, chương trình 5.3). So sánh kết quả đó với hình 7.7b, 8.5, và 8.6 trong các chương trước. Hình 10.3 chỉ ra hàm giảm mờ, đó là kết quả từ bài tập này. Vết mờ được xem như tròn trong trường hợp này. Hình 7.9 là ảnh kết quả của chương trình trên với x 2.9 và x 2.6, hoặc 3.89. Hình 10.4 đưa ra đáp ứng tần số- biên độ của bộ lọc IIR 2 2 được thiết kế để xấp xỉ hàm giảm mờ. Đầu tiên bộ 213 lọc được thiết kế với phương pháp Shanks và sau đó là phương pháp lặp của chương 9. Kết quả áp dụng bộ lọc IIR 2-D với ảnh đã nói ở trên có sự cải thiện đáng chú ý so với ảnh gốc. Tuy nhiên, phương pháp lọc thông thấp mô tả trong chương 9 cho kết quả gần với phương pháp FFT hơn, so với cách tiếp cận này. Các hệ số thu được của bộ lọc IIR trong ví dụ này được ghi trong bảng 10.1. Bây giờ chúng ta tăng cường ảnh sao hoả thu được qua kính thiên văn được cho trên hình 10.5. Nguyên nhân của vết mờ này là do hệ số khúc xạ thay đổi theo áp xuất khí quyển, và cũng có thể là do mở ống kính trong khoảng thời gian dài. áp dụng thủ tục đường biên trong phần này, chúng ta thu được ảnh chỉ ra trên hình 10.6. Mặt dù ảnh nét hơn, nhưng nó không cung cấp cho ta nhiều chi tiết mới. Chúng ta cần chỉ ra rằng đây là một ảnh của toàn bộ sao hoả với độ phân giải chỉ có 256 256 điểm ảnh. Đây là một ảnh dưới mẫu, và không có thông tin nào về ảnh được rút ra ở đây mà lại không rút ra được từ ảnh gốc. Hình 10.7 chỉ ra một ảnh mờ là kết quả của ảnh của vật nằm ngoài tiêu cự. Áp dụng cùng thủ tục và dùng bộ lọc FIR 7 7 thiết kế sử dụng cửa sổ Blackmann chúng ta thu được ảnh chỉ trên hình 10.8. Bảng 10.1 các hệ số của bộ lọc khôi phục -0.034139 1.000000 -0.014686 - 0.650127 -0.012220 0.007701 -0.014683 - 0.650224 0.991926 0.474917 -0.655115 0.005353 -0.012214 0.007699 -0.655211 0.005351 0.468586 0.005273 214 Hình 10.4 Đáp ứng biên độ của bộ lọc 2-D IIR được xấp xỉ bởi hàm khôi phục ảnh mờ. Bài tập 10.2 1. "MARS.IMG" và "YOSSRA.IMG" là các tên file tương ứng của các ảnh trong hình 10.5 và 10.7. Thực hiện quá trình khôi phục. Để làm bài tập này chúng ta cần chạy các chương trình sau theo thứ tự: a. KIRSH để có được đường biên rõ nét của ảnh. b. DEBLUR để tính hàm chuyển đổi giảm mờ. c. IMPULSE để thu được đáp ứng không gian của hàm giảm mờ. d. IIRD để thiết kế bộ lọc IIR từ đáp ứng không gian. e. IIRDITER để tăng cường bộ lọc được thiết kế (dùng một hoặc hai bước lặp). Bạn cần phải tự viết chương trình cho bạn. 2. Lặp lại phần 1 dùng các bộ lọc kiểu FIR. 3. áp dụng lọc trung bình để khôi phục ảnh "YOSSRA.IMG". 4. áp dụng bộ lọc thống kê Wallis với ảnh "YOSSRA.IMG".` . *fptr1,*fptr2,*fptr; char file_name1[ 12] ,file_name2[ 12] ; unsigned char *buff; int M,M1,z,i,j,*wv,*wh,x0 ,y0 ,sign_max; float sum,A,*cv,*ch,mu1,mu2,pi2; float sigmax,sigmay,sx2,sy2,u,v,du,dv;. pi2 =2. 0*pi*sigmax*sigmay;; du=dv= (2. 0*pi)/ 32. 0; Hình 10.3 Hàm khôi phục ảnh mờ. for(i=0;i< 32; i++) { v=-pi; for(j=0;j< 32; j++) { x=(u*u*sx2+v*v*sy2) /2. 0; if(x> =20 .0) G=(float)0.0;. blurs in both the x and y directions? (y or n) >"); while(((ch1=getche())!=&apos ;y& apos;)&&(ch1!='n')); if(ch1==&apos ;y& apos;) sx2=sy2=sx2+sy2; printf("
Enter