00001 #include "sadie.h"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 void GRADIENT (
00024 IMAGE *in,
00025 PIXEL *vert,
00026
00027
00028 PIXEL *horz,
00029
00030
00031 short size,
00032 IMAGE **out1,
00033
00034 IMAGE **out2
00035
00036
00037 ) { register short i, j, k, l, m, n=size/2;
00038 char msg[SLEN];
00039 double dv, dh, pinc, psum;
00040
00041 int progmeter;
00042 double progress;
00043 int progcount, progtotal, progincr;
00044 int cancel=0;
00045
00046 progmeter = ProgMeter_Create("Gradient");
00047 progress = 0.0;
00048
00049
00050 if (TIMES) TIMING(T_GRADIENT);
00051 if (NAMES) {
00052 MESSAGE('I',"");
00053 MESSAGE('I',"GRADIENT");
00054 MESSAGE('I',"");
00055 sprintf(msg," Input image: %s",in->text);
00056 MESSAGE('I',msg);
00057 sprintf(msg," Kernel size: lines and pixels: %d",size);
00058 MESSAGE('I',msg);
00059 if (size <= SLEN/16) {
00060 MESSAGE('I'," Horizontal kernel:");
00061 for (i=0; i<size; i++) {
00062 for (j=k=0,msg[k++]=' '; j<size; j+=1,k=strlen(msg)) {
00063 sprintf(msg+k,"%12.4e",(double)horz[i*size+j]);
00064 }
00065 MESSAGE('I',msg);
00066 }
00067 MESSAGE('I'," Vertical kernel:");
00068 for (i=0; i<size; i++) {
00069 for (j=k=0,msg[k++]=' '; j<size; j+=1,k=strlen(msg)) {
00070 sprintf(msg+k,"%12.4e",(double)vert[i*size+j]);
00071 }
00072 MESSAGE('I',msg);
00073 }
00074 } else {
00075 MESSAGE('I'," Kernels too large to list.");
00076 }
00077 MESSAGE('I'," ...............");
00078 }
00079
00080
00081 if (!CHECKIMG(in)) {
00082 MESSAGE('E'," Can't identify image.");
00083 goto the_end;
00084 } else if (size < 2 || size%2 == 0) {
00085 MESSAGE('E'," Size of convolution mask must be an odd number greater than two.");
00086 goto the_end;
00087 } else if (size > in->nlin || size > in->npix) {
00088 MESSAGE('E'," Image size must be equal to or greater than convolution mask size.");
00089 goto the_end;
00090 }
00091
00092
00093 if (!CHECKIMG(*out1)) GETMEM(in->nbnd,in->nlin,in->npix,out1);
00094 if (!*out1) goto the_end;
00095 if (!CHECKIMG(*out2)) GETMEM(in->nbnd,in->nlin,in->npix,out2);
00096 if (!*out2) goto the_end;
00097
00098
00099 if (LINES && !PROGRESS(psum=0.0)) goto the_end;
00100 pinc = 1.0/(double)in->nbnd/(double)(in->nlin-2*n);
00101 progtotal = in->nbnd * (in->nlin-2*n);
00102 progcount = 0;
00103 progincr = rint((double)progtotal/20.0);
00104
00105 for (i=0; i<in->nbnd; i++) {
00106
00107
00108 for (j=n; j<in->nlin-n; j++) {
00109 for (k=n; k<in->npix-n; k++) {
00110 dv = dh = 0.0;
00111 for (l=0; l<size; l++) {
00112 for (m=0; m<size; m++) {
00113 dv += (double)vert[l*size+m]*(double)in->data[i][j-n+l][k-n+m];
00114 dh += (double)horz[l*size+m]*(double)in->data[i][j-n+l][k-n+m];
00115 }
00116 }
00117 (*out1)->data[i][j][k] = (PIXEL)sqrt((dv*dv+dh*dh));
00118 if (dh == 0.0) {
00119 if (dv > 0.0) {
00120 (*out2)->data[i][j][k] = (PIXEL)(PI/2.0);
00121 } else if (dv < 0.0) {
00122 (*out2)->data[i][j][k] = (PIXEL)(-PI/2.0);
00123 } else {
00124 (*out2)->data[i][j][k] = (PIXEL)0.0;
00125 }
00126 } else {
00127 (*out2)->data[i][j][k] = (PIXEL)atan2(dv,dh);
00128 }
00129 }
00130 if (LINES && !PROGRESS(psum+=pinc)) goto the_end;
00131 if (progmeter) {
00132 progcount++;
00133 if ((progcount%progincr) == 0) {
00134 progress = ((double)progcount/(double)progtotal)*100.0;
00135 cancel = ProgMeter_Update(progmeter,progress);
00136 if (cancel != 0) goto the_end;
00137 }
00138 }
00139 }
00140
00141
00142 for (j=0; j<n; j++) {
00143 for (k=n; k<in->npix-n; k++) {
00144 (*out1)->data[i][j][k] = (*out1)->data[i][n][k];
00145 (*out1)->data[i][in->nlin-j-1][k] = (*out1)->data[i][in->nlin-n-1][k];
00146 (*out2)->data[i][j][k] = (*out2)->data[i][n][k];
00147 (*out2)->data[i][in->nlin-j-1][k] = (*out2)->data[i][in->nlin-n-1][k];
00148 }
00149 }
00150
00151
00152 for (j=0; j<in->nlin; j++) {
00153 for (k=0; k<n; k++) {
00154 (*out1)->data[i][j][k] = (*out1)->data[i][j][n];
00155 (*out1)->data[i][j][in->npix-k-1] = (*out1)->data[i][j][in->npix-n-1];
00156 (*out2)->data[i][j][k] = (*out2)->data[i][j][n];
00157 (*out2)->data[i][j][in->npix-k-1] = (*out2)->data[i][j][in->npix-n-1];
00158 }
00159 }
00160 }
00161
00162 the_end:
00163 if (TIMES) TIMING(T_EXIT);
00164
00165 if (progmeter) {
00166 ProgMeter_Destroy(progmeter);
00167 }
00168
00169 if (cancel != 0) {
00170 if (*out1) RELMEM(*out1);
00171 *out1 = NULL;
00172 if (*out2) RELMEM(*out2);
00173 *out2 = NULL;
00174 }
00175 }