/* Lightness computation - Andrew Blake, Dept. CS, Edinburgh University. adjusted by Gavin Brelstaff 16/11/84. Altered to allow for a SQUARE GRID OF SKEWED TRIANGLES rather than equilaterals. DISCARDED 16/9/85 WITH NON-FLOATING POINT VARIATION OF THE OVERRELAXTION PARAMETER, implemented by Gavin Brelstaff 21/11/84. Extended to pictures greater than 128x128 by Gavin Brelstaff 14/12/84. WITH LOGARITHMIC INPUT CONVERSION WITH OUTPUT OF MEAN ZERO both by Gavin Brelstaff 14/1/85 With threshold percentage option 4/2/85 Gavin Brelstaff. DEVELOPMENT CANNY THRESHOLD FILE INPUT OPTION 27/2/85 Gavin Brelstaff MORE DEVELOPMENT OF CANNY 19/3/85 picture format: first byte is image size (square image) if less than 128, else use -x option, then image grey data in left to right, top to bottom format. to run, see vision:light.doc */ #include #include /* for log function */ #define progname "light" #define flagU 0100 #define flagD 0200 #define MAXSIZE 256 /* max. image size */ #define MAXAREA MAXSIZE*MAXSIZE #define MAXCHAR 255 #define EOS '\0' short nbits = 0; /* picture scaling: nbits +8 bits */ long x[MAXAREA], rij[MAXAREA] ; /* pics: relaxing, initial */ char conflag[MAXAREA]; /* flags indicating existence of triangles and results of thresholding (top 2 bits) uij & dij */ char Mij[MAXAREA]; /* number of surrounding triangles*/ short asize ; /* pic dimensions */ long area; short header=1;/* set if pic file contains a header char */ float th_percentage=6.0; /* input parameter the threshold percentage*/ int th=100; /* threshold value for (gradient*gradient) */ #define MAXCHANGE 0 #define MAXITER 10000 int iter=0; /* maximum no of iterations */ int minchange=MAXCHANGE; /* min max-change for one iteration: stops */ /* program if max-change is less */ short freq=10; /* number of iters per reported change */ int prec=16; /* constant specifying precision of integer computation */ FILE *fp, *fq = NULL; /* input,output picture channels */ char canny_file_name[32]; /* name file containing canny results */ #define CANNYFILE "canny.hyst" /* default canny file name */ char funcflag=0;/* set if Functional is to be computed */ char cflag=0; /* set if canny operator file is used as thresholding */ char gflag=0; /* set if canny operator file is used to guide thresholding */ char tflag=0; /* set if threshold specified */ char mflag=1; /* set if mean zero option for output */ char bflag=0; /* set if beeps for attention */ char sflag=0; /* set if output to screen is to be supressed */ char lflag=1; /* set if log conversion used */ char wflag=0; /* set if writing threshold flags to file */ char fflag=0; /* set if reading threshold flags from file */ char edge_file_name[32]; /* file name to send edge results to if wflag=1 */ char flag_file_name[32]; /* file name to get edges from if fflag=1 */ #define EDGEFILE "edgeU" /* default edge file name */ #define FLAGFILE "flagU" /* default flag file name */ main(argc,argv) char **argv; { argv++; while ((argc>1)&&((*argv)[0] == '-')) { switch((*argv)[1]) { case 'j': error("SOR always 0.5"); break; case 'x': sscanf(*argv+2,"%hd",&asize); if(asize<0||asize>MAXSIZE) error("picture to big"); header=0; break; case 'F': sscanf(*argv+2,"%hd",&freq); if(freq<1) error("bad reporting frequency"); break; case 'c': sscanf(*argv+2,"%s",canny_file_name); cflag=1; break; case 'g': sscanf(*argv+2,"%s",canny_file_name); gflag=1; break; case 's': /* supress output to screen flag */ sflag=1; break; case 'w': /* write threshold flag files */ sscanf(*argv+2,"%s",edge_file_name); wflag=1; break; case 'f': /* read threshold flag files */ sscanf(*argv+2,"%s",flag_file_name); fflag=1; break; case 'l': /* turn off logarithmic input conversion option */ lflag=0; break; case 'm': /* turn off mean-zero output option */ mflag=0; break; case 't': sscanf(*argv+2,"%f",&th_percentage); if(th_percentage<0.0) error("bad threshold percentage"); tflag=1; break; case 'i': sscanf(*argv+2,"%d",&iter); if(iter<0||MAXITER max) max = (*p); if (*p < min) min = (*p); } for (p=y,pend=y+area; pMAXCHAR) { scale(nbits-1); max = ((max+1)>>1); } } #define TMAX 256 #define TOP_INPUT_INTENSITY 256 log_scale(lflag,tflag) char lflag,tflag; { long log_table[TMAX]; /* temporary log conversion look up table */ double CONST; register long *p; register long i; if(!lflag){ nbits=0; if(tflag) th = ((int) th_percentage); /* set threshold option */ return(0); } /* 2^11 constant ensures discrimination between log values */ /* obtained from adjacent input levels: because without */ /* any mult-factor range would be 0 .. 8 */ nbits = 6; /* 11 + 3 - 8 */ /* global variable */ if(tflag) th=((int) ( (TOP_INPUT_INTENSITY<MAXSIZE) error("picture to big"); area = asize*asize; for (p=x,pend=x+area; p127) *p = 127; else if(*p<-128) *p = -128; } } scale(n) /* scale x,rij to n+8 bits */ { register long s, *ptop; register long *p,*q; s=n-nbits; nbits=n; if (s>0) { for (p=x,q=rij,ptop=x+area; p>s); *q++ = (*q>>s); } } } /* constants for connect threshold make_Rij and adjust*/ #define dirNNE 01 #define dirNEE 02 #define dirES 04 #define dirSSW 010 #define dirSWW 020 #define dirWN 040 #define bearN (dirWN|dirNNE) #define bearE (dirNEE|dirES) #define bearS (dirES|dirSSW) #define bearW (dirSSW|dirWN) #define bearNE (dirNNE|dirNEE) #define bearSW (dirSSW|dirSWW) #define offN (-asize) #define offNE (1-asize) #define offE 1 #define offS asize #define offSW (asize-1) #define offW (-1) connect() { register char *conp; long i; /* initialise conflag. all 6 adjacent exist. */ for (i=0,conp=conflag;i++th) #define gd ((g_down) >th) functional() { long *p; register char *conp; long i; float F=0,G=0; /* Functional and sigma |E|^2 */ for (i=0,p=x,conp=conflag;i++> (*d++)); /* (Sum + rij)/Mij */ /* over relaxation */ /* N.B. pointer to function used */ inc = (inc>>1); /* (w)(Sum + Rij)/Mij */ *p = (v>>1) + inc; /* (1-w)*lij + (w)(Sum+Rij)/Mij) */ inc = (*p) - v; /* new lij - old lij */ if (inc<0) inc = -inc; if (changeminchange); i++) { a=adjust(); if ((!sflag)&&!(i % freq)) fprintf(stderr,"%9ld%1s", a, (i%(5*freq) ? " " : "\n")); } if((!sflag)&&(i % (5*freq))) fprintf(stderr,"\n"); if(!sflag) fprintf(stderr,"total iterations: %d\n\n",i-1); }