Main Page   Data Structures   File List   Data Fields   Globals  

gradient.c

Go to the documentation of this file.
00001 #include "trees.h"
00002 
00003 
00004 /*-Copyright Information------------------------------------------------------*/
00005 /* Copyright (c) 1988 by the University of Arizona Digital Image Analysis Lab */
00006 /*----------------------------------------------------------------------------*/
00007 /*-General Information--------------------------------------------------------*/
00008 /*                                                                            */
00009 /*   This function computes a two-dimensional gradient (magnitude and         */
00010 /*   direction) of an image, using two user-supplied convolution kernels.     */
00011 /*   The magnitude is computed as the vector magnitude of the output          */
00012 /*   of the two kernels, and the direction is computed as the angle           */
00013 /*   between the two orthogonal gradient vectors.                             */
00014 /*                                                                            */
00015 /*----------------------------------------------------------------------------*/
00016 /*-Background Information-----------------------------------------------------*/
00017 /*                                                                            */
00018 /*   Robinson, G.S.:                                                          */
00019 /*   "Detection and Coding of Edges Using Directional Masks."                 */
00020 /*   Optical Engineering, Vol. 16, No. 6 (Nov/Dec 1977), pp. 580-585          */
00021 /*                                                                            */
00022 /*----------------------------------------------------------------------------*/
00023 /*-Interface Information------------------------------------------------------*/
00024 void TREES_GRADIENT (
00025 IMAGE *in,      /*  I   Pointer to the input image.                           */
00026 LOCAL_INDEX *localindex,                   
00027 PIXEL *vert,    /*  I   Pointer to a square convolution kernel[size][size] for*/
00028                 /*      the y-derivative. It should return positive values    */
00029                 /*      for gradients increasing to the "top" of the image.   */
00030 PIXEL *horz,    /*  I   Pointer to a square convolution kernel[size][size] for*/
00031                 /*      the x-derivative. It should return positive values    */
00032                 /*      for gradients increasing to the "right" of the image. */
00033 short size,     /*  I   Kernel size in lines and pixels/line.                 */
00034 IMAGE **out1,   /*  O   Address of a pointer to the output image              */
00035                 /*      containing the gradient magnitude.                    */
00036 IMAGE **out2    /*  O   Address of a pointer to the output image              */
00037                 /*      containing the gradient direction.                    */
00038 /*----------------------------------------------------------------------------*/
00039 ) { register int i, j, k, l, m, n=size/2;
00040     char   msg[SLEN];
00041     double dv, dh, pinc, psum;
00042     
00043     int progmeter;
00044     double progress;
00045     int progcount, progtotal, progincr;
00046     int cancel=0;
00047 
00048     progmeter = ProgMeter_Create("Gradient");
00049     progress = 0.0;
00050 
00051 
00052     if (TIMES) TIMING(T_GRADIENT);
00053     if (NAMES) {
00054         MESSAGE('I',"");
00055         MESSAGE('I',"GRADIENT");
00056         MESSAGE('I',"");
00057         sprintf(msg," Input image:                    %s",in->text);
00058         MESSAGE('I',msg);
00059         sprintf(msg," Kernel size: lines and pixels:  %d",size);
00060         MESSAGE('I',msg);
00061         if (size <= SLEN/16) {
00062             MESSAGE('I'," Horizontal kernel:");
00063             for (i=0; i<size; i++) {
00064                 for (j=k=0,msg[k++]=' '; j<size; j+=1,k=strlen(msg)) {
00065                     sprintf(msg+k,"%12.4e",(double)horz[i*size+j]);
00066                 }
00067                 MESSAGE('I',msg);
00068             }
00069             MESSAGE('I'," Vertical kernel:");
00070             for (i=0; i<size; i++) {
00071                 for (j=k=0,msg[k++]=' '; j<size; j+=1,k=strlen(msg)) {
00072                     sprintf(msg+k,"%12.4e",(double)vert[i*size+j]);
00073                 }
00074                 MESSAGE('I',msg);
00075             }
00076         } else {
00077             MESSAGE('I'," Kernels too large to list.");
00078         }
00079         MESSAGE('I'," ...............");
00080     }
00081 
00082     /* check input */
00083     if (!CHECKIMG(in)) {
00084         MESSAGE('E'," Can't identify image.");
00085         goto the_end;
00086     } else if (size < 2  ||  size%2 == 0) {
00087         MESSAGE('E'," Size of convolution mask must be an odd number greater than two.");
00088         goto the_end;
00089     } else if (size > in->nlin  ||  size > in->npix) {
00090         MESSAGE('E'," Image size must be equal to or greater than convolution mask size.");
00091         goto the_end;
00092     }
00093 
00094 
00095     /* create images of appropriate size */
00096     if (!CHECKIMG(*out1)) GETMEM(in->nbnd,in->nlin,in->npix,out1);
00097     if (!*out1) goto the_end;
00098     if (!CHECKIMG(*out2)) GETMEM(in->nbnd,in->nlin,in->npix,out2);
00099     if (!*out2) goto the_end;
00100 
00101     /* Initialize output image */
00102     for(j = 0; j < in->nlin; j++) {
00103         for(k = 0; k < in->npix; k++) {
00104             (*out1)->data[0][j][k] = (PIXEL)0;
00105             (*out2)->data[0][j][k] = (PIXEL)0;
00106         }
00107     }
00108 
00109     /* initialize progress indicator */
00110     if (LINES  &&  !PROGRESS(psum=0.0)) goto the_end;
00111     pinc = 1.0/(double)in->nbnd/(double)(in->nlin-2*n);
00112     progtotal = in->nbnd * (in->nlin-2*n);
00113     progcount = 0;
00114     progincr = rint((double)progtotal/20.0);
00115 
00116     /* Compute convolution */
00117     for (k = localindex->hstart+n; k <= localindex->hend-n; k++) {
00118         for (j = localindex->vstart[k]+n; j <= localindex->vend[k]-n; j++) {
00119             dv = dh = 0.0;
00120             for (l=0; l<size; l++) {
00121                 for (m=0; m<size; m++) {
00122                     dv += (double)vert[l*size+m]*(double)in->data[0][j-n+l][k-n+m];
00123                     dh += (double)horz[l*size+m]*(double)in->data[0][j-n+l][k-n+m];
00124                 }
00125             }
00126             (*out1)->data[0][j][k] = (PIXEL)sqrt(dv*dv+dh*dh)/1443.0*255.0;
00127             if (dh == 0.0) {
00128                 if (dv > 0.0) {
00129                     (*out2)->data[0][j][k] = (PIXEL)(PI/2.0);
00130                 } else if (dv < 0.0) {
00131                     (*out2)->data[0][j][k] = (PIXEL)(-PI/2.0);
00132                 } else /* (dv == 0.0 ) */ {
00133                     (*out2)->data[0][j][k] = (PIXEL)0.0;
00134                 }
00135             } else {
00136                 (*out2)->data[0][j][k] = (PIXEL)atan2(dv,dh);
00137             }
00138             (*out2)->data[0][j][k] = (unsigned char)(128 + (int)(127.0*(*out2)->data[0][j][k]/PI));
00139         }
00140         if (LINES  &&  !PROGRESS(psum+=pinc)) goto the_end;
00141         if (progmeter) {
00142             progcount++;
00143             if ((progcount%progincr) == 0) {
00144                 progress = ((double)progcount/(double)progtotal)*100.0;
00145                 cancel = ProgMeter_Update(progmeter,progress);
00146                 if (cancel != 0) goto the_end;
00147             }
00148         }
00149     }
00150 
00151 
00152     the_end:
00153     if (TIMES) TIMING(T_EXIT);
00154 
00155     if (progmeter) {
00156         ProgMeter_Destroy(progmeter);
00157     }
00158 
00159     if (cancel != 0) {
00160         if (*out1) RELMEM(*out1);
00161         *out1 = NULL;
00162         if (*out2) RELMEM(*out2);
00163         *out2 = NULL;
00164     }
00165 }

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