Thread: Histogram Equalization

  1. #1
    Registered User
    Join Date
    Nov 2009
    Posts
    21

    Histogram Equalization

    Greetings everybody.
    i have an assigment on image proccesing and amongst other question one of them specifies:calculate the equalized histogram of a grayscale
    image and show statistical data of your choice between the input and output images.
    I am having trouble equalizing the histogram.I have googled around for a couple of days now and i think i could use some help, either im missing the whole picture or minor details that cause problems.
    my code is below:
    Code:
    //                          original histogram
        for (i=0; i<lines; i++)
          for (j=0; j<columns; j++)       
                  hist[image_in[i][j]]++;
           
        
    
    
    //histogram max and min
    int hmax=-1,hmin=257;
    for(int i=0;i<256;i++)
    {
    if (hist[i]>hmax)
    hmax=hist[i];
    if (hist[i]<hmin)
    hmin=hist[i];
    }
    
    //                    Probability table
    float prt[256];
    int pixels=lines*columns;
    for(int i=0;i<256;i++);
    prt[i]=hist[i]/pixels;
    
    
    //                            CumulativeDistributionFunction
    float cdfmax=-1,cdfmin=257;
    float cdf[256];
    cdf[0]=prt[0];
    for(int i=1;i<256;i++)
    {
            cdf[i]=prt[i]+cdf[i-1];
            if(cdf[i]>cdfmax)
            cdfmax=cdf[i];
            if(cdf[i]<cdfmin)
            cdfmin=cdf[i];
    }
    
    
    // final image
    for (int i=0;i<lines;i++)
    {
        for(int j=0;j<columns;j++)
        {
        image_out[i][j]=(unsigned char)(((cdf[image_in[i][j]]-cdfmin)/(pixels-cdfmin))*255);
        }
    }
    can anyone point out anything that might help?
    im thinking that my equalization formula is wrong, i might have incorrectly translated the mathematical formula from wikipedia to C code but i cant figure out why.
    Thanks in advance
    Last edited by Cursius; 05-14-2013 at 08:32 AM.

  2. #2
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    you don't show us all your data types. what types are hmax,hmin,hist[]? it looks like all variables should be floats except the images themselves.

    is the loop computing cfg[i] supposed to go 0..255 or 0..number of pixels. wikipedia isn't clear

  3. #3
    Registered User
    Join Date
    Nov 2009
    Posts
    21
    hmax hmin and hist are integers. as for the later i am not sure...

  4. #4
    Registered User
    Join Date
    May 2012
    Posts
    505
    A greyscale image has 256 separate greyscale levels. So that trivially gives you a 256 bin histogram of colour counts.
    Now we want to reassign colour values to the histogram so that all the levels are as equally occupied as possible. There's no way of doing this without losing some information (assuming that every bin is occupied). Basically we want to unite low-occupied regions of the histogram, and spread out the highly-occupied regions.

    An easy way to do it is to define a cumulative distribution function, between 0 and 1, for each greyscale value 0-255. This represents the proportion of pixels in the range 0-x for that value.

    When we've got 256 cdf values (all incrementing) for the original histogram, the new value becomes cdf * 255. Because we round to the nearest integer, some bins will now have equal values, whilst other values won't be represented at all.

    histogram - very easy to write, just declare an array of 256 integers, set to zero to begin with, and go through the image summing.
    cumulative distribution function - again very easy to write. decare an array of 256 floats. Then step through the histogram keeping a running sum, and divide by the total number of pixels.
    equalisation step - very easy to write. Simply go throught he 256 cdf values and assign the new value to the old value.

    Histogram equalisation function - not easy to write in one go, but
    very easy once you have those three functions debugged and working.
    I'm the author of MiniBasic: How to write a script interpreter and Basic Algorithms
    Visit my website for lots of associated C programming resources.
    https://github.com/MalcolmMcLean


  5. #5
    Registered User
    Join Date
    Nov 2009
    Posts
    21
    after some testing i see that prt[i] values are 0.000000 for all indexes. am i doing something wrong? hist[i] is an int, pixels are int and prt is float.
    hist is full of values, theyr sum is equal to pixels so everything is fine with that. Why
    hist[i]/pixels gives no result to prt[i]?
    Last edited by Cursius; 05-14-2013 at 11:12 AM.

  6. #6
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Quote Originally Posted by Cursius View Post
    after some testing i see that prt[i] values are 0.000000 for all indexes. am i doing something wrong? hist[i] is an int, pixels are int and prt is float.
    hist is full of values, theyr sum is equal to pixels so everything is fine with that. Why
    hist[i]/pixels gives no result to prt[i]?
    C-FAQ - Question 3.15

    Bye, Andreas

  7. #7
    Registered User
    Join Date
    Nov 2009
    Posts
    21
    i have already tried casting and i still dont get any results

  8. #8
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Code:
    //                    Probability table
    float prt[256];
    int pixels=lines*columns;
    for(int i=0;i<256;i++);
    prt[i]=hist[i]/pixels;
    Do you know how to use a debugger?
    Single stepping through the code would have shown you that your loop doesn't do anything except incrementing "i";

    Bye, Andreas

  9. #9
    Registered User
    Join Date
    Nov 2009
    Posts
    21
    aaahh thank you mate, i had gone through the code a million times and i never noticed that ;....

  10. #10
    Registered User
    Join Date
    Nov 2009
    Posts
    21
    as my first contribution to this site i present you the code.It needs an input of a grayscale image and it will produce an output of the enchanced image, along with basic statistical values such as average color and dispersion of both images.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    main()
    {	
    	int i,j,k,l, lines, columns;
        
        
    
    	unsigned char	*image_in[2048], *image_out[2048];
    	int hist[256];
    
    	char	inp_fn[30], 
    			out_fn[30];
    
    	
    	FILE *inp, *out;
    
    	printf ("Enter input file name : ");
    	gets( inp_fn );
    
    	printf ("Enter output file name : ");
    	gets( out_fn );
    
    	printf ("Enter no. of lines : ");
    	scanf("%d", &lines);
    
    	printf ("Enter no. of columns : ");
    	scanf("%d", &columns);
    
    	for  (i=0;i<lines;i++)
    		image_in[i]=(unsigned char*)malloc((columns) * sizeof(unsigned char));
    
    	for  (i=0;i<lines;i++)
    		image_out[i]=(unsigned char*)malloc((columns) * sizeof(unsigned char));
    
        for(int i=0;i<256;i++)
                hist[i]=0;
        
        
        int pixels=lines*columns;
        printf("\nTotal pixels: %d",pixels);
    /**********************READ IMAGE ****************************************************/
    	if ( ((inp=fopen (inp_fn,"rb")) == NULL))
    		printf ("Not a valid input file\n");
    	else
    	{
    
    	for  (i=0;i<lines;i++)
    		fread(image_in[i], sizeof(unsigned char), columns, inp);
    
    	fclose(inp);
    	}
    //************************************************************************************/	
      
      //                          original histogram
        for (i=0; i<lines; i++)
        {  for (j=0; j<columns; j++)
           {
                  hist[image_in[i][j]]++;
           }
        }
        
        //                          Histogram stats
        // min max avg
        
        int hsum=0;
        float avg;
        int hmax=-1,hmin=257;
        for(int i=0;i<256;i++)
          {
             if (hist[i]>hmax)
             hmax=hist[i];
             if (hist[i]<hmin)
             hmin=hist[i];
          }
    
        for(int i=0;i<256;i++)
             hsum+=hist[i]*i;
            
            avg=(float)hsum/pixels;
            //                   Dispersion of data for original image (Standar Deviation)
        float cSum=0;
        float cTable[256];
        float avgDev=0;
        for(int i=0;i<256;i++)
        {
                cTable[i]=(abs((i-(int)avg)))*(abs((i-(int)avg)));
                cTable[i]=hist[i]*cTable[i];
                cSum+=cTable[i];
        }        
        cSum=cSum/pixels;
        
        
        avgDev=sqrt(cSum);
            
            
            printf("\nOriginal Histogram statistics");
            printf("\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
            printf("\nHistogram sum: %d \n Histogram Max: %d\n Histogram Min: %d \n Histogram Avg: %f \n Standar Deviation: %f",hsum,hmax,hmin,avg,avgDev);
     
    //                                           Probability table
    
        float prt[256];
                   for(int i=0;i<256;i++)
                   prt[i]=(float)hist[i]/pixels;     
    
    
    //                                 Cumulative Distribution Function
    float cdfmax=-1,cdfmin=257;
    float cdf[256];
    cdf[0]=prt[0];
    for(int i=1;i<256;i++)
    {
            cdf[i]=prt[i]+cdf[i-1];
            if(cdf[i]>cdfmax)
            cdfmax=cdf[i];
            if(cdf[i]<cdfmin)
            cdfmin=cdf[i];
    }
    
    //                                            Final Image
    for (int i=0;i<lines;i++)
    {
        for(int j=0;j<columns;j++)
        {
        image_out[i][j]=cdf[image_in[i][j]]*255;
        }
    }
    
    //                                       Equalized Histogram
    int eHist[256];
    for(int i=0;i<256;i++)
    for(int j=0;j<256;j++)
    eHist[image_out[i][j]]++;
    
    //                                 Equalized Histogram stats
        int ehsum=0;
        float eavg;
        int ehmax=-1,ehmin=257;
        for(int i=0;i<256;i++)
          {
             if (eHist[i]>ehmax)
             ehmax=eHist[i];
             if (eHist[i]<ehmin)
             ehmin=eHist[i];
          }
    
        for(int i=0;i<256;i++)
                ehsum+=eHist[i]*i;
    
            eavg=(float)ehsum/pixels;
    //                             Dispersion of data for Equalised Histogram  
        float ecSum=0;
        float ecTable[256];
        float eavgDev=0;
        for(int i=0;i<256;i++)
        {
                ecTable[i]=(abs((i-(int)eavg)))*(abs((i-(int)eavg)));
                ecTable[i]=eHist[i]*ecTable[i];
                ecSum+=ecTable[i];
        }        
        ecSum=ecSum/pixels;
        
        
        eavgDev=sqrt(ecSum);
        
            
            
            
            
            
            printf("\n\n Equalised Histogram statistics");
            printf("\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
            printf("\n EqHistogram sum: %d \n EqHistogram Max: %d \n EqHistogram Min: %d \n EqHistogram Avg: %f \n Standar Deviation: %f",ehsum,ehmax,ehmin,eavg,eavgDev);
        
    
    
    
    
    
    
    
    //*********************WRITE IMAGE ****************************************************
    	out=fopen (out_fn, "wb");
    
    	for  (i=0;i<lines;i++)
    		fwrite(image_out[i], sizeof(unsigned char), columns, out);
    
    	fclose(out);
    
    
    	for (i=0;i<lines;i++)
    		free(image_in[i]);
    	for (i=0;i<lines;i++)
    		free(image_out[i]);
    printf("\n");
    system("pause");
    }
    it is not really refined or optimized as i have more work to do for an other project.there are basic comments that should be enough though

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Histogram
    By SpecKROELLchen in forum C Programming
    Replies: 9
    Last Post: 08-02-2012, 03:10 AM
  2. Histogram issues
    By enimgaterror in forum C++ Programming
    Replies: 1
    Last Post: 01-09-2011, 09:17 PM
  3. Histogram help
    By Fixxxer in forum C Programming
    Replies: 4
    Last Post: 11-12-2010, 02:15 AM
  4. histogram
    By bazzano in forum C Programming
    Replies: 3
    Last Post: 04-04-2007, 12:25 PM
  5. Histogram
    By fjf314 in forum C++ Programming
    Replies: 1
    Last Post: 01-15-2004, 11:39 PM