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
00024
00025
00026 void
00027 MINDIST (IMAGE * in,
00028 short option,
00029
00030
00031
00032 short nlev,
00033
00034 double *mean,
00035 double *cov,
00036 IMAGE ** out
00037
00038 )
00039 {
00040 register short i, j, k, m, n, l1, l2, ll, nl, np;
00041 char msg[SLEN];
00042 PIXEL *dist = 0, mindist;
00043 double *inv = 0;
00044
00045 if (TIMES)
00046 TIMING (T_MINDIST);
00047 if (NAMES)
00048 {
00049 MESSAGE ('I', "");
00050 MESSAGE ('I', "MINDIST");
00051 MESSAGE ('I', "");
00052 sprintf (msg, " Input image: %s", in->text);
00053 MESSAGE ('I', msg);
00054 if (option == CITYBLOCK)
00055 {
00056 MESSAGE ('I', " Classifier: City-block");
00057 }
00058 else if (option == EUCLIDEAN)
00059 {
00060 MESSAGE ('I', " Classifier: Euclidean");
00061 }
00062 else if (option == MAHALANOBIS)
00063 {
00064 MESSAGE ('I', " Classifier: Mahalanobis");
00065 }
00066 sprintf (msg, " Number of classes: %d", nlev);
00067 MESSAGE ('I', msg);
00068 sprintf (msg, " Mean graylevels:");
00069 MESSAGE ('I', msg);
00070 for (n = j = 0; j < nlev; j++)
00071 {
00072 sprintf (msg, " Class%3d: ", j + 1);
00073 for (k = 0, m = strlen (msg); k < in->nbnd; k++, m = strlen (msg))
00074 {
00075 sprintf (msg + m, "%12.4e", mean[n++]);
00076 }
00077 MESSAGE ('I', msg);
00078 }
00079 MESSAGE ('I', " Covariance matrix:");
00080 for (n = j = 0; j < in->nbnd; j++)
00081 {
00082 sprintf (msg, " Band%4d: ", j + 1);
00083 for (k = 0, m = strlen (msg); k < in->nbnd; k++, m = strlen (msg))
00084 {
00085 sprintf (msg + m, "%12.4e", cov[n++]);
00086 }
00087 MESSAGE ('I', msg);
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 (option != CITYBLOCK && option != EUCLIDEAN
00099 && option != MAHALANOBIS)
00100 {
00101 MESSAGE ('E',
00102 " Option must be one of CITYBLOCK, EUCLIDEAN, or MAHALANOBIS.");
00103 goto the_end;
00104 }
00105 else if (nlev <= 0)
00106 {
00107 MESSAGE ('E', "Number of classes must be greater than zero.");
00108 goto the_end;
00109 }
00110
00111
00112 if (!CHECKIMG (*out))
00113 GETMEM (1, in->nlin, in->npix, out);
00114 if (!*out)
00115 goto the_end;
00116
00117
00118 if (!(dist = (PIXEL *) malloc (nlev * sizeof (PIXEL))))
00119 {
00120 MESSAGE ('E', "Memory request failed.");
00121 goto the_end;
00122 }
00123
00124
00125 if (option == CITYBLOCK)
00126 {
00127 for (nl = 0; nl < in->nlin; nl++)
00128 {
00129 for (np = 0; np < in->npix; np++)
00130 {
00131 for (k = 0; k < nlev; k++)
00132 {
00133 dist[k] = 0.0;
00134 for (i = 0; i < in->nbnd; i++)
00135 {
00136 l1 = k * in->nbnd + i;
00137 dist[k] += fabs (in->data[i][nl][np] - mean[l1]);
00138 }
00139 }
00140 mindist = dist[0];
00141 for (i = 0; i < nlev; i++)
00142 {
00143 if (dist[i] <= mindist)
00144 {
00145 (*out)->data[0][nl][np] = (PIXEL) (i + 1);
00146 }
00147 }
00148 }
00149 }
00150
00151
00152 }
00153 else if (option == EUCLIDEAN)
00154 {
00155 for (nl = 0; nl < in->nlin; nl++)
00156 {
00157 for (np = 0; np < in->npix; np++)
00158 {
00159 for (k = 0; k < nlev; k++)
00160 {
00161 dist[k] = 0.0;
00162 for (i = 0; i < in->nbnd; i++)
00163 {
00164 l1 = k * in->nbnd + i;
00165 dist[k] +=
00166 (in->data[i][nl][np] -
00167 mean[l1]) * (in->data[i][nl][np] - mean[l1]);
00168 }
00169 }
00170 mindist = dist[0];
00171 for (i = 0; i < nlev; i++)
00172 {
00173 if (dist[i] <= mindist)
00174 {
00175 (*out)->data[0][nl][np] = (PIXEL) (i + 1);
00176 }
00177 }
00178 }
00179 }
00180
00181
00182 }
00183 else if (option == MAHALANOBIS)
00184 {
00185
00186
00187 if (!(inv = (double *) malloc (in->nbnd * in->nbnd * sizeof (double))))
00188 {
00189 MESSAGE ('E', "Memory request failed.");
00190 goto the_end;
00191 }
00192 if (!(dist = (PIXEL *) malloc (nlev * sizeof (PIXEL))))
00193 {
00194 MESSAGE ('E', "Memory request failed.");
00195 goto the_end;
00196 }
00197 MATRIX_INVERT (cov, in->nbnd, inv);
00198
00199 for (nl = 0; nl < in->nlin; nl++)
00200 {
00201 for (np = 0; np < in->npix; np++)
00202 {
00203 for (k = 0; k < nlev; k++)
00204 {
00205 dist[k] = 0.0;
00206 for (i = 0; i < in->nbnd; i++)
00207 {
00208 for (j = 0; j < in->nbnd; j++)
00209 {
00210 l1 = k * in->nbnd + i;
00211 l2 = k * in->nbnd + j;
00212 ll = i * in->nbnd + j;
00213 dist[k] +=
00214 (in->data[i][nl][np] -
00215 mean[l1]) * inv[ll] * (in->data[j][nl][np] -
00216 mean[l2]);
00217 }
00218 }
00219 }
00220 mindist = dist[0];
00221 for (i = 0; i < nlev; i++)
00222 {
00223 if (dist[i] <= mindist)
00224 {
00225 (*out)->data[0][nl][np] = (PIXEL) (i + 1);
00226 }
00227 }
00228 }
00229 }
00230 }
00231
00232 the_end:
00233 if (inv)
00234 free (inv);
00235 if (dist)
00236 free (dist);
00237 if (TIMES)
00238 TIMING (T_EXIT);
00239 }