Main Page   Data Structures   File List   Data Fields   Globals  

histeq.c

Go to the documentation of this file.
00001 #include        "sadie.h"
00002 
00003 /*-Copyright Information------------------------------------------------------*/
00004 /* Copyright (c) 1988 by the University of Arizona Digital Image Analysis Lab */
00005 /*----------------------------------------------------------------------------*/
00006 /*-General Information--------------------------------------------------------*/
00007 /*                                                                            */
00008 /*   This function performs histogram equalization on an image.               */
00009 /*                                                                            */
00010 /*----------------------------------------------------------------------------*/
00011 /*-Interface Information------------------------------------------------------*/
00012 void HISTEQ (
00013 IMAGE *in,      /*  I   Pointer to the input image.                           */
00014 short nlev,     /*  I   Histogram resolution                                  */
00015                 /*      (and number of graylevels in the output image).       */
00016 short inc,      /*  I   Line and pixel subsample increment.                   */
00017 IMAGE **out     /*  O   Address of a pointer to the output image.             */
00018                 /*      The input image may be overwritten (out = &in).       */
00019 /*----------------------------------------------------------------------------*/
00020 ) { register short i, j, k;
00021     char   msg[SLEN];
00022     long   *hist=0;
00023     double *dist=0, factor, width;
00024 
00025     if (TIMES) TIMING(T_HISTEQ);
00026     if (NAMES) {
00027         MESSAGE('I',"");
00028         MESSAGE('I',"HISTEQ");
00029         MESSAGE('I',"");
00030         sprintf(msg," Input image:                          %s",in->text);
00031         MESSAGE('I',msg);
00032         sprintf(msg," Histogram resolution:                 %d",nlev);
00033         MESSAGE('I',msg);
00034         sprintf(msg," Line and pixel subsample increment:   %d",inc);
00035         MESSAGE('I',msg);
00036         MESSAGE('I'," ...............");
00037     }
00038 
00039     /* check input */
00040     if (!CHECKIMG(in)) {
00041         MESSAGE('E'," Can't identify image.");
00042         goto the_end;
00043     } else if (inc <= 0) {
00044         MESSAGE('E'," Subsample increment must be greater than zero.");
00045         goto the_end;
00046     } else if (nlev <= 0) {
00047         MESSAGE('E'," Number of histogram bins must be greater than zero.");
00048         goto the_end;
00049     }
00050 
00051     /* create image of appropriate size */
00052     if (!CHECKIMG(*out)) GETMEM(in->nbnd,in->nlin,in->npix,out);
00053     if (!*out) goto the_end;
00054 
00055     /* allocate space for histogram and distribution arrays */
00056     if (!(hist=(long *)malloc(in->nbnd*nlev*sizeof(long))))  {
00057         MESSAGE('E'," Memory request failed.");
00058         goto the_end;
00059     }
00060     if (!(dist=(double *)malloc(in->nbnd*nlev*sizeof(double))))  {
00061         MESSAGE('E'," Memory request failed.");
00062         goto the_end;
00063     }
00064 
00065     /* compute distribution function and scaling factor */
00066     RANGE(in);
00067     HISTOGRM(in,inc,in->gmin,in->gmax,nlev,hist);
00068     for (i=0; i<in->nbnd; i++) {
00069         for (j=1; j<nlev; j++) {
00070             hist[i*nlev+j] += hist[i*nlev+j-1];
00071         }
00072     }
00073     factor = (double)(in->gmax-in->gmin)/(double)hist[nlev-1];
00074     for (i=0; i<in->nbnd; i++) {
00075         for (j=0; j<nlev; j++) {
00076             dist[i*nlev+j] = hist[i*nlev+j]*factor;
00077         }
00078     }
00079     width  = (double)(in->gmax-in->gmin)/(double)(nlev-1);
00080 
00081     /* perform histogram equalization */
00082     for (i=0; i<in->nbnd; i++) {
00083         for (j=0; j<in->nlin; j++) {
00084             for (k=0; k<in->npix; k++) {
00085                 (*out)->data[i][j][k] = (PIXEL)(dist[i*nlev+(short)((double)(in->data[i][j][k]-in->gmin)/width)] + (double)in->gmin);
00086             }
00087         }
00088     }
00089     (*out)->gmin = (PIXEL)((double)in->gmin+dist[0]);
00090     (*out)->gmax = (PIXEL)((double)in->gmin+dist[nlev-1]);
00091 
00092     the_end:
00093     if (hist)  free(hist);
00094     if (dist)  free(dist);
00095     if (TIMES) TIMING(T_EXIT);
00096 }

Generated on Wed Apr 9 08:56:06 2003 for TREES by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002