sandipan

C program to implement Optimum Thresholding (binarize image)

Sep 6th, 2018
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.12 KB | None | 0 0
  1. /*
  2.  C program to implement Optimum Thresholding to binarize an image
  3.  Sandipan Dey
  4.  BCSE, JU, Kolkata
  5.  2003
  6. */
  7.  
  8. //MUST USE MEDIUM MEMORY MODEL
  9. //USE 256 COLOR BITMAP FILE (WIDTH%4=0)
  10. // Input image files: RABBIT.BMP, BIRD.BMP
  11.  
  12. #include <math.h>
  13. #include <stdio.h>
  14. #include <conio.h>
  15. #include <stdlib.h>
  16. #include <graphics.h>
  17. #include <string.h>
  18. #define DEFAULT "output.bmp"
  19. #define MAX 256
  20. #define PI 3.14159
  21. #define VAL 1
  22.  
  23. struct Point {
  24.     int x,y;
  25. };
  26.  
  27. struct SE {
  28.     Point p[4];
  29. };
  30.  
  31. double ln(double x) {
  32.     return (x>0?log(x):0);
  33. }
  34.  
  35. void main(int argc,char* argv[]) {
  36.  
  37.     FILE* fp=NULL,*fo=NULL;
  38.     long int n[MAX]={0};
  39.     double p[MAX]={0};
  40.     int c,type;
  41.     char INPUTFILE[100],OUTPUTFILE[100],s[100];
  42.     long int imgoffset=0;
  43.     double sum=0;
  44.     strcpy(OUTPUTFILE,DEFAULT);
  45.     clrscr();
  46.     if(argc<=1) {
  47.         printf("\nNo Input File!");
  48.         getch();
  49.         exit(0);
  50.     }
  51.     strcpy(INPUTFILE,argv[1]);
  52.     if(argc>2 && strcmp(argv[2],"\0"))
  53.     strcpy(OUTPUTFILE,argv[2]);
  54.     if((fp=fopen(INPUTFILE,"rb"))==NULL) {
  55.         printf("\n File Not Found!");
  56.         fclose(fp);
  57.         getch();
  58.         exit(0);
  59.     }    // File Not Found
  60.     fo=fopen(OUTPUTFILE,"wb");
  61.     if(fgetc(fp)!='B' || fgetc(fp)!='M') {      // Check Signature
  62.         printf("\n Not a valid BMP File!!!");
  63.         fclose(fp);
  64.         fclose(fo);
  65.         getch();
  66.         exit(0);
  67.     }
  68.     fseek(fp,10,0);         // Find Offset of Data
  69.     imgoffset=fgetc(fp)+(fgetc(fp)<<8)+(fgetc(fp)<<16)+(fgetc(fp)<<24);  // Data Offset
  70.     fseek(fp,28,0);         // Find No. of Bits to Represent a Pixel of the Bitmap
  71.     type=fgetc(fp);
  72.     switch(type) {
  73.         case 1:printf("\n A Monochrome (1-Bit) Bitmap!");break;
  74.         case 4:printf("\n A 16-Color (4-Bit) Bitmap!");break;
  75.         case 8:printf("\n A 256-Color (8-Bit) Bitmap");break;
  76.         default:printf("\n Not a 1,4 Or 8-Bit Bitmap!");break;
  77.     }
  78.     if(type!=8){
  79.         fclose(fp);
  80.         printf("\nAn 8-bit Bitmap expected!!!");
  81.         fclose(fo);
  82.         exit(0);
  83.     }
  84.     long int w,h;
  85.     fseek(fp,18,0);
  86.     w=fgetc(fp)+(fgetc(fp)<<8)+(fgetc(fp)<<16)+(fgetc(fp)<<24);
  87.     h=fgetc(fp)+(fgetc(fp)<<8)+(fgetc(fp)<<16)+(fgetc(fp)<<24);
  88.     int threshold=0;
  89.     double minH=1000000.01,q1,q2,m1,m2,v1,v2,H,sumsq=0;
  90.     for(int i=0;i<MAX;++i){n[i]=p[i]=0;}
  91.     int gd=VGA,gm=VGAHI,x=0,y=h;
  92.     struct palettetype pal;
  93.     initgraph(&gd,&gm,"");
  94.     getpalette(&pal);
  95.     for(i=0;i<16;i++)
  96.     setrgbpalette(pal.colors[i],i*4,i*4,i*4);
  97.     fp=fopen(INPUTFILE,"rb");
  98.     fo=fopen(OUTPUTFILE,"wb");
  99.     fseek(fp,0,0);
  100.     while(!feof(fp)) {
  101.         fputc(fgetc(fp),fo);
  102.     }
  103.     fseek(fp,imgoffset,0);
  104.     while(!feof(fp)) {
  105.         c=fgetc(fp);
  106.         putpixel(x,y,c/16);
  107.         x=(x+1)%w;
  108.         if(!x){--y;}
  109.         ++n[c%MAX];
  110.     }
  111.     getch();
  112.     cleardevice();
  113.     for(i=0;i<MAX;++i)sum+=n[i];
  114.     for(i=0;i<MAX;++i)p[i]=n[i]/(sum*1.0);
  115.     threshold=0;
  116.     for(unsigned int t=1;t<MAX-1;++t) {
  117.         q1=sum=0;
  118.         for(i=0;i<t;++i){q1+=p[i];sum+=i*p[i];}
  119.         m1=q1?sum/q1:0;sumsq=0;
  120.         for(i=0;i<t;++i){sumsq+=(i-m1)*(i-m1)*p[i];}
  121.         v1=q1?sumsq/q1:0;
  122.         q2=sum=0;
  123.         for(i=t;i<MAX;++i){q2+=p[i];sum+=i*p[i];}
  124.         m2=q2?sum/q2:0;sumsq=0;
  125.         for(i=t;i<MAX;++i){sumsq+=(i-m2)*(i-m2)*p[i];}
  126.         v2=q2?sumsq/q2:02;
  127.         //printf("%lf %lf %lf %lf\n", q1, q2, v1, v2);
  128.         H=(1+ln(2*PI))/2-q1*ln(q1)-q2*ln(q2)+(q1*ln(v1)+q2*ln(v2))/2;
  129.         if(H<minH){minH=H;threshold=t;}
  130.     }
  131.     int xstart=10,ystart=470;
  132.     line(xstart,ystart,620,ystart);
  133.     line(xstart,ystart-470,xstart,ystart);
  134.     setcolor(14);
  135.     for(i=0;i<MAX;++i)  {
  136.         line(xstart+2*i,ystart-5000*p[i],xstart+2*i,ystart);
  137.         if(!(i%15)){
  138.             setcolor(getmaxcolor());
  139.             line(xstart+2*i,ystart-5,xstart+2*i,ystart+1);
  140.             sprintf(s,"%d",i);
  141.             outtextxy(xstart+2*i-7,ystart+2,s);
  142.             setcolor(14);
  143.         }
  144.     }
  145.     setcolor(4);
  146.     outtextxy(xstart+2*threshold+7,ystart-200,"Threshold");
  147.     line(xstart+2*threshold,ystart,xstart+2*threshold,ystart-470);
  148.     setcolor(14);
  149.     fflush(stdin);
  150.     getch();
  151.     cleardevice();
  152.     sprintf(s,"Threshold=%d",threshold);
  153.     outtextxy(520,421,s);
  154.     outtextxy(520,445,"Sandipan Dey");
  155.     outtextxy(520,455,"BCSE-IV");
  156.     outtextxy(520,465,"Roll-99710");
  157.     fseek(fp,imgoffset,0);
  158.     fseek(fo,imgoffset,0);
  159.     x=0;y=h;
  160.     int c1;
  161.     while(!feof(fp)) {
  162.         c=fgetc(fp);
  163.         c1=(c<threshold)?0:15;
  164.         fputc(c1,fo);
  165.         putpixel(x,y,c1);
  166.         x=(x+1)%w;
  167.         if(!x){--y;}
  168.     }
  169.     fclose(fo);
  170.     fclose(fp);
  171.     getch();
  172.     closegraph();
  173. }
Add Comment
Please, Sign In to add comment