/* Imager2 Documentation Scott Langley, 3/4/93, for IE 592 Computer Vision Program name is imager2.exe It requires the svga256.bgi driver to run. Editing structuring elements is most easily done by using a keyboard with a numeric pad with Num_Lock engaged, so that the keys 4, 8, 6, and 2 act as direction keys. ************************************** Roberts_Gradient offset=180-45.0; scale1=360/(2*3.14159); scale2=255/360.0; G_45=before_image(origin+num_columns+1)-before_image(origin); N_G_45=before_image(origin+1)-before_image(origin+num_columns); Magnitude first_image(origin)=abs(G_45)+abs(N_G_45); Angle second_image(origin)=(atan2(G_45,N_G_45)*scale1+offset)*scale2+.49; /*************************************************************/ Soebel_Gradient offset=180.0; scale1=360/(2*3.14159); scale2=255/360.0; GX=before_image(origin-num_columns+1)+2*before_image(origin+1) +before_image(origin+num_columns+1)-before_image(origin-num_columns-1) -2*before_image(origin-1)-before_image(origin+num_columns-1); GY=before_image(origin+num_columns-1)+2*before_image(origin+num_columns) +before_image(origin+num_columns+1)-before_image(origin-num_columns-1) -2*before_image(origin-num_columns)-before_image(origin-num_columns+1); Magnitude first_image(origin)=abs(GX)+abs(GY)+.49; Angle second_image(origin)=(atan2(GY,GX)*scale1+offset)*scale2; /*************************************************************/ Laplacian first_image(origin)=4*before_image(origin)-(before_image(origin-num_columns) +before_image(origin-1)+before_image(origin+1) +before_image(origin+num_columns)); /*************************************************************/ Convert_to_Binary NOTE: Since most of the we were using showed beetles and they showed up as low pixel values (tending toward 0), I operated on the assumption that the binary operations acted on images were a pixel value of 0 was considered part of the object and a pixel vale of 255 was considered not part of the object. int threshold; printf("\nType number for thresholding (0 - 255): "); scanf("%d",&threshold); for(i=0;ithreshold) before_image(i)=255; else before_image(i)=0; } *************************************************************8 Dilation for(i=0;iend)!=1) { row_temp=i+(current_block->row); column_temp=j+(current_block->column); if((row_temp>=0)&&(row_temp=0)&&(column_tempnext; } row_temp=i+(current_block->row); column_temp=j+(current_block->column); if((row_temp>=0)&&(row_temp=0)&&(column_tempend)!=1)&&(match==1)) { row_temp=i+(current_block->row); column_temp=j+(current_block->column); if((row_temp>0)&&(row_temp0)&&(column_tempnext; } row_temp=i+(current_block->row); column_temp=j+(current_block->column); if((row_temp>0)&&(row_temp0)&&(column_temp #include #include #include #include #include #include #include #include "svga256.h" #include "largearr.h" #define FALSE 0 #define TRUE !FALSE #define MAXIMAGE 69120 #define before_image(x) *((unsigned char *)pointer_add(BEFORE_IMAGE,x)) #define first_image(x) *((int *)pointer_add(FIRST_IMAGE,x<<1)) #define second_image(x) *((unsigned char *)pointer_add(SECOND_IMAGE,x)) #define temp_image(x) *((unsigned char *)pointer_add(TEMP_IMAGE,x)) #define original_image(x) *((unsigned char *)pointer_add(ORIGINAL_IMAGE,x)) void *BEFORE_IMAGE,*FIRST_IMAGE,*SECOND_IMAGE,*ORIGINAL_IMAGE,*TEMP_IMAGE; FILE *get_i_file(char *i_prompt, char *in_type); FILE *get_o_file(char *prompt, char *out_type); FILE *in_file, *out_file; void Roberts_Gradient(void); void Soebel_Gradient(void); void Laplacian(void); void Convert_to_Binary(void); void Get_Structuring_Block(void); void Dilation(void); void Erosion(void); void Opening(void); void Closing(void); void Morphological_Filtering(void); void Morphological_Skeletonizing(void); void Load_Image(void); void Save_Image(void); void Revert_to_Image(void); void Display_Image(void); void Scale_Image(void); void Handle_Gradient(void); struct unit{ int row; int column; char end; struct unit *next;}; typedef struct unit BLOCK; typedef BLOCK *BLOCKLINK; BLOCKLINK pointer_to_first_block, current_block; char structure_exists=0,binary=0, pad[41][21]; int ask(char *prompt), length, delta, origin_x,origin_y; long int num_rows,num_columns,i,j,k,l,row_temp,column_temp,origin; double max,min,scale; unsigned long int total_pixels=0; extern unsigned _stklen = 8432; int huge DetectVGA256() {return 1;} /*************************************************************/ main() { int menu_choice='0'; int errorcode, a, b, mode=0; int Gd = DETECT, Gm=2; installuserdriver("Svga256",DetectVGA256); initgraph(&Gd,&Gm,""); errorcode = graphresult(); if (errorcode != grOk) /* an error occurred */ { printf("Graphics error: %s\n", grapherrormsg(errorcode)); printf("Press any key to halt:"); getch(); exit(1); /* terminate with an error code */ } restorecrtmode(); origin_x=origin_y=0; pointer_to_first_block=(BLOCKLINK)malloc(sizeof(BLOCK)); current_block=pointer_to_first_block; for(i=1;i<41;i++) for(j=1;j<21;j++) { pad[i][j]=0; current_block->row=current_block->column=0; current_block->end=1; current_block->next=(BLOCKLINK)malloc(sizeof(BLOCK)); current_block=current_block->next; } ORIGINAL_IMAGE=char_array(MAXIMAGE); BEFORE_IMAGE=char_array(MAXIMAGE); FIRST_IMAGE=int_array(MAXIMAGE); SECOND_IMAGE=char_array(MAXIMAGE); TEMP_IMAGE=char_array(MAXIMAGE); while(TRUE) { if(mode==0) { printf("\n\n\nSCOTT LANGLEY'S IMAGE PROCESSOR\n\n"); printf("MENU\n-----------------------------\n"); printf("1 Roberts Gradient Approximation\n\n"); printf("2 Sobel Gradient Approximation\n\n"); printf("3 Laplacian Approximation\n\n"); printf("4 Binary Functions\n----------"); printf("------------------------------------------------------\n"); printf("L Load Image File\n\n"); printf("S Save Image File\n\n"); printf("R Revert to Image Last Loaded\n\n"); printf("D Display Image\n\n"); printf("X Exit Program\n----------"); printf("------------------------------------------------------\n"); printf("Enter Menu Selection:"); menu_choice=toupper(getche()); printf("\n"); switch(menu_choice) { case '1': Roberts_Gradient(); Handle_Gradient(); break; case '2': Soebel_Gradient(); Handle_Gradient(); break; case '3': Laplacian(); break; case '4': mode=1; break; case 'L': Load_Image(); break; case 'S': for(i=0;i<(total_pixels);i++) temp_image(i)=before_image(i); Save_Image(); break; case 'R': Revert_to_Image(); break; case 'D': for(i=0;i<(total_pixels);i++) temp_image(i)=before_image(i); Display_Image(); break; case 'X': exit(0); closegraph(); break; } } else { printf("1 Convert to Binary Image\n"); printf("2 Enter Structuring Element\n\n"); printf("3 Dilation\n"); printf("4 Erosion\n\n"); printf("5 Opening\n"); printf("6 Closing\n\n"); printf("7 Morphological Filtering\n"); printf("8 Morphological Skeletonizing\n\n"); printf("9 Gradient Functions\n"); printf("------------------------------------------------------\n"); printf("L Load Image File\n\n"); printf("S Save Image File\n\n"); printf("R Revert to Image Last Loaded\n\n"); printf("D Display Image\n\n"); printf("X Exit Program\n----------"); printf("------------------------------------------------------\n"); printf("Enter Menu Selection:"); menu_choice=toupper(getche()); printf("\n"); switch(menu_choice) { case '1': Convert_to_Binary(); break; case '2': Get_Structuring_Block(); break; case '3': Dilation(); for(i=0;imax) max=magnitude; else if(magnitudemax) max=magnitude; else if(magnitudemax) max=magnitude; else if(magnitudethreshold) before_image(i)=255; else before_image(i)=0; printf("\n"); } /*************************************************************/ void Get_Structuring_Block(void){ char choice='r',x,y; textmode(1); textattr(BLACK); textbackground(CYAN); clrscr(); gotoxy(1,22); cprintf("Enter Your Structuring Element"); gotoxy(1,23); cprintf(" Black=Structure; Yellow=Origin;"); gotoxy(1,24); cprintf("Movement: (4,8,6,2); 5 toggles block"); gotoxy(1,25); cprintf("(C)lear screen; set (O)rigin; (D)one"); window(1,1,40,20); gotoxy(20,10); textattr(BLACK+BLINK); _setcursortype(_SOLIDCURSOR); if(structure_exists==1) { for(i=1;i<41;i++) for(j=1;j<21;j++) if(pad[i][j]==1) { gotoxy(i,j); textbackground(LIGHTGRAY); textcolor(BLACK); putch('*'); } else{ if(pad[i][j]==2) { gotoxy(i,j); textbackground(LIGHTGRAY); textcolor(YELLOW); putch('*'); } } } while(choice!='q') { choice=toupper(getch()); x=wherex(); y=wherey(); textcolor(RED); switch(choice) { case '5': if(pad[x][y]==2) origin_x=origin_y=0; if(pad[x][y]==0) { pad[x][y]=1; textbackground(LIGHTGRAY); textcolor(BLACK); putch('*'); gotoxy(x,y); } else { pad[x][y]=0; textbackground(CYAN); textcolor(RED); putch(32); gotoxy(x,y); } break; case 'O': if(pad[x][y]!=2) { pad[x][y]=2; pad[origin_x][origin_y]=1; gotoxy(origin_x,origin_y); textbackground(LIGHTGRAY); textcolor(BLACK); putch('*'); textcolor(RED); gotoxy(x,y); origin_x=x; origin_y=y; textbackground(LIGHTGRAY); textcolor(YELLOW); putch('*'); gotoxy(x,y); } else { origin_x=origin_y=0; pad[x][y]=1; textbackground(LIGHTGRAY); textcolor(BLACK); putch('*'); gotoxy(x,y); } break; case 'C': textbackground(CYAN); clrscr(); for(i=1;i<41;i++) for(j=1;j<21;j++) pad[i][j]=0; origin_x=origin_y=0; break; case 'D': if(origin_x==0) { window(1,22,40,25); gotoxy(1,1); textattr(BLACK); textbackground(CYAN); clrscr(); textcolor(BLACK); cprintf("Structuring Element Doesn't Have an Origin"); gotoxy(1,2); cprintf("Ending now will cancel structuring block"); gotoxy(1,3); cprintf("Do you really want do end editing"); if(ask("?")==TRUE) { choice='q'; structure_exists=0; for(i=1;i<41;i++) for(j=1;j<21;j++) pad[i][j]=0; } else { textattr(BLACK); textbackground(CYAN); clrscr(); gotoxy(1,1); cprintf("Enter Your Structuring Element"); gotoxy(1,2); cprintf(" Black=Structure; Yellow=Origin;"); gotoxy(1,3); cprintf("Movement: (4,8,6,2); 5 toggles block"); gotoxy(1,4); cprintf("(C)lear screen; set (O)rigin; (D)one"); window(1,1,40,20); gotoxy(20,10); textattr(BLACK+BLINK); _setcursortype(_SOLIDCURSOR); } } else { current_block=pointer_to_first_block; for(i=1;i<41;i++) for(j=1;j<21;j++) if(pad[i][j]!=0) { current_block->end=0; current_block=current_block->next; current_block->row=origin_y-j; current_block->column=origin_x-i; current_block->end=1; } choice='q'; structure_exists=1; } break; case '4': gotoxy(x-1,y); break; case '8': gotoxy(x,y-1); break; case '6': gotoxy(x+1,y); break; case '2': gotoxy(x,y+1); break; } } textmode(3); } /*************************************************************/ void Dilation(void){ if(structure_exists==0) { printf("\n\You should enter a structuring element first\n"); getch(); return; } else { for(i=0;iend)!=1) { row_temp=i+(current_block->row); column_temp=j+(current_block->column); if((row_temp>=0)&&(row_temp=0)&&(column_tempnext; } row_temp=i+(current_block->row); column_temp=j+(current_block->column); if((row_temp>=0)&&(row_temp=0)&&(column_tempend)!=1)&&(match==1)) { row_temp=i+(current_block->row); column_temp=j+(current_block->column); if((row_temp>0)&&(row_temp0)&&(column_tempnext; } row_temp=i+(current_block->row); column_temp=j+(current_block->column); if((row_temp>0)&&(row_temp0)&&(column_tempend=0; current_block=current_block->next; current_block->row=origin_y-j; current_block->column=origin_x-i; current_block->end=1; } structure_exists=1; for(i=0;i'7')) { printf("\n\n\nWhat to do with gradient result:\n"); printf("---------------------------------\n"); printf("\n"); printf("Magnitude Image\n\n"); printf(" 1 Display\n\n"); printf(" 2 Save Image to Disk\n\n"); printf(" 3 Make this the current image\n\n\n"); printf("Direction Image\n\n"); printf(" 4 Display\n\n"); printf(" 5 Save Image to Disk\n\n"); printf(" 6 Make this the current image\n\n"); printf("---------------------------------\n"); printf("7 Return to main menu\n\n"); printf("Enter Menu Selection:"); menu_choice=toupper(getche()); } printf("\n"); switch(menu_choice) { case '1': for(i=0;i<(total_pixels);i++) temp_image(i)=first_image(i); Display_Image(); break; case '2': for(i=0;i<(total_pixels);i++) temp_image(i)=first_image(i); Save_Image(); break; case '3': for(i=0;i<(total_pixels);i++) before_image(i)=first_image(i); break; case '4': for(i=0;i<(total_pixels);i++) temp_image(i)=second_image(i); Display_Image(); break; case '5': for(i=0;i<(total_pixels);i++) temp_image(i)=second_image(i); Save_Image(); break; case '6': for(i=0;i<(total_pixels);i++) before_image(i)=second_image(i); break; case '7': break; } } }