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
00024 GRADIENT (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 )
00038 {
00039 register short 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 if (TIMES)
00052 TIMING (T_GRADIENT);
00053 if (NAMES)
00054 {
00055 MESSAGE ('I', "");
00056 MESSAGE ('I', "GRADIENT");
00057 MESSAGE ('I', "");
00058 sprintf (msg, " Input image: %s", in->text);
00059 MESSAGE ('I', msg);
00060 sprintf (msg, " Kernel size: lines and pixels: %d", size);
00061 MESSAGE ('I', msg);
00062 if (size <= SLEN / 16)
00063 {
00064 MESSAGE ('I', " Horizontal kernel:");
00065 for (i = 0; i < size; i++)
00066 {
00067 for (j = k = 0, msg[k++] = ' '; j < size;
00068 j += 1, k = strlen (msg))
00069 {
00070 sprintf (msg + k, "%12.4e", (double) horz[i * size + j]);
00071 }
00072 MESSAGE ('I', msg);
00073 }
00074 MESSAGE ('I', " Vertical kernel:");
00075 for (i = 0; i < size; i++)
00076 {
00077 for (j = k = 0, msg[k++] = ' '; j < size;
00078 j += 1, k = strlen (msg))
00079 {
00080 sprintf (msg + k, "%12.4e", (double) vert[i * size + j]);
00081 }
00082 MESSAGE ('I', msg);
00083 }
00084 }
00085 else
00086 {
00087 MESSAGE ('I', " Kernels too large to list.");
00088 }
00089 MESSAGE ('I', " ...............");
00090 }
00091
00092
00093 if (!CHECKIMG (in))
00094 {
00095 MESSAGE ('E', " Can't identify image.");
00096 goto the_end;
00097 }
00098 else if (size < 2 || size % 2 == 0)
00099 {
00100 MESSAGE ('E',
00101 " Size of convolution mask must be an odd number greater than two.");
00102 goto the_end;
00103 }
00104 else if (size > in->nlin || size > in->npix)
00105 {
00106 MESSAGE ('E',
00107 " Image size must be equal to or greater than convolution mask size.");
00108 goto the_end;
00109 }
00110
00111
00112 if (!CHECKIMG (*out1))
00113 GETMEM (in->nbnd, in->nlin, in->npix, out1);
00114 if (!*out1)
00115 goto the_end;
00116 if (!CHECKIMG (*out2))
00117 GETMEM (in->nbnd, in->nlin, in->npix, out2);
00118 if (!*out2)
00119 goto the_end;
00120
00121
00122 if (LINES && !PROGRESS (psum = 0.0))
00123 goto the_end;
00124 pinc = 1.0 / (double) in->nbnd / (double) (in->nlin - 2 * n);
00125 progtotal = in->nbnd * (in->nlin - 2 * n);
00126 progcount = 0;
00127 progincr = rint ((double) progtotal / 20.0);
00128
00129 for (i = 0; i < in->nbnd; i++)
00130 {
00131
00132
00133 for (j = n; j < in->nlin - n; j++)
00134 {
00135 for (k = n; k < in->npix - n; k++)
00136 {
00137 dv = dh = 0.0;
00138 for (l = 0; l < size; l++)
00139 {
00140 for (m = 0; m < size; m++)
00141 {
00142 dv +=
00143 (double) vert[l * size + m] * (double) in->data[i][j -
00144 n +
00145 l]
00146 [k - n + m];
00147 dh +=
00148 (double) horz[l * size + m] * (double) in->data[i][j -
00149 n +
00150 l]
00151 [k - n + m];
00152 }
00153 }
00154 (*out1)->data[i][j][k] = (PIXEL) sqrt ((dv * dv + dh * dh));
00155 if (dh == 0.0)
00156 {
00157 if (dv > 0.0)
00158 {
00159 (*out2)->data[i][j][k] = (PIXEL) (PI / 2.0);
00160 }
00161 else if (dv < 0.0)
00162 {
00163 (*out2)->data[i][j][k] = (PIXEL) (-PI / 2.0);
00164 }
00165 else
00166 {
00167 (*out2)->data[i][j][k] = (PIXEL) 0.0;
00168 }
00169 }
00170 else
00171 {
00172 (*out2)->data[i][j][k] = (PIXEL) atan2 (dv, dh);
00173 }
00174 }
00175 if (LINES && !PROGRESS (psum += pinc))
00176 goto the_end;
00177 if (progmeter)
00178 {
00179 progcount++;
00180 if ((progcount % progincr) == 0)
00181 {
00182 progress =
00183 ((double) progcount / (double) progtotal) * 100.0;
00184 cancel = ProgMeter_Update (progmeter, progress);
00185 if (cancel != 0)
00186 goto the_end;
00187 }
00188 }
00189 }
00190
00191
00192 for (j = 0; j < n; j++)
00193 {
00194 for (k = n; k < in->npix - n; k++)
00195 {
00196 (*out1)->data[i][j][k] = (*out1)->data[i][n][k];
00197 (*out1)->data[i][in->nlin - j - 1][k] =
00198 (*out1)->data[i][in->nlin - n - 1][k];
00199 (*out2)->data[i][j][k] = (*out2)->data[i][n][k];
00200 (*out2)->data[i][in->nlin - j - 1][k] =
00201 (*out2)->data[i][in->nlin - n - 1][k];
00202 }
00203 }
00204
00205
00206 for (j = 0; j < in->nlin; j++)
00207 {
00208 for (k = 0; k < n; k++)
00209 {
00210 (*out1)->data[i][j][k] = (*out1)->data[i][j][n];
00211 (*out1)->data[i][j][in->npix - k - 1] =
00212 (*out1)->data[i][j][in->npix - n - 1];
00213 (*out2)->data[i][j][k] = (*out2)->data[i][j][n];
00214 (*out2)->data[i][j][in->npix - k - 1] =
00215 (*out2)->data[i][j][in->npix - n - 1];
00216 }
00217 }
00218 }
00219
00220 the_end:
00221 if (TIMES)
00222 TIMING (T_EXIT);
00223
00224 if (progmeter)
00225 {
00226 ProgMeter_Destroy (progmeter);
00227 }
00228
00229 if (cancel != 0)
00230 {
00231 if (*out1)
00232 RELMEM (*out1);
00233 *out1 = NULL;
00234 if (*out2)
00235 RELMEM (*out2);
00236 *out2 = NULL;
00237 }
00238 }