00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <stdio.h>
00013 #include <stdlib.h>
00014
00015 #define VERBOSE 0
00016
00017 #define NOEDGE 0
00018 #define POSSIBLE_EDGE 128
00019 #define EDGE 255
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 int follow_edges(unsigned char *edgemapptr, short *edgemagptr, short lowval,
00030 int cols)
00031 {
00032 short *tempmagptr;
00033 unsigned char *tempmapptr;
00034 int i;
00035 int x[8] = {1,1,0,-1,-1,-1,0,1},
00036 y[8] = {0,1,1,1,0,-1,-1,-1};
00037
00038
00039 for(i=0;i<8;i++){
00040 tempmapptr = edgemapptr - y[i]*cols + x[i];
00041 tempmagptr = edgemagptr - y[i]*cols + x[i];
00042
00043 if((*tempmapptr == POSSIBLE_EDGE) && (*tempmagptr > lowval)){
00044 *tempmapptr = (unsigned char) EDGE;
00045 follow_edges(tempmapptr,tempmagptr, lowval, cols);
00046 }
00047 }
00048
00049 return 0;
00050 }
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 int apply_hysteresis(short int *mag, unsigned char *nms, int rows, int cols,
00061 float tlow, float thigh, unsigned char *edge)
00062 {
00063 int r, c, pos, numedges, highcount, lowthreshold, highthreshold,
00064 hist[32768];
00065 short int maximum_mag = 0 ;
00066
00067
00068
00069
00070
00071
00072
00073
00074 for(r=0,pos=0;r<rows;r++){
00075 for(c=0;c<cols;c++,pos++){
00076 if(nms[pos] == POSSIBLE_EDGE) edge[pos] = POSSIBLE_EDGE;
00077 else edge[pos] = NOEDGE;
00078 }
00079 }
00080
00081 for(r=0,pos=0;r<rows;r++,pos+=cols){
00082 edge[pos] = NOEDGE;
00083 edge[pos+cols-1] = NOEDGE;
00084 }
00085 pos = (rows-1) * cols;
00086 for(c=0;c<cols;c++,pos++){
00087 edge[c] = NOEDGE;
00088 edge[pos] = NOEDGE;
00089 }
00090
00091
00092
00093
00094
00095 for(r=0;r<32768;r++) hist[r] = 0;
00096 for(r=0,pos=0;r<rows;r++){
00097 for(c=0;c<cols;c++,pos++){
00098 if(edge[pos] == POSSIBLE_EDGE) hist[mag[pos]]++;
00099 }
00100 }
00101
00102
00103
00104
00105 for(r=1,numedges=0;r<32768;r++){
00106 if(hist[r] != 0) maximum_mag = r;
00107 numedges += hist[r];
00108 }
00109
00110 highcount = (int)(numedges * thigh + 0.5);
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 r = 1;
00123 numedges = hist[1];
00124 while((r<(maximum_mag-1)) && (numedges < highcount)){
00125 r++;
00126 numedges += hist[r];
00127 }
00128 highthreshold = r;
00129 lowthreshold = (int)(highthreshold * tlow + 0.5);
00130
00131 if(VERBOSE){
00132 printf("The input low and high fractions of %f and %f computed to\n",
00133 tlow, thigh);
00134 printf("magnitude of the gradient threshold values of: %d %d\n",
00135 lowthreshold, highthreshold);
00136 }
00137
00138
00139
00140
00141
00142 for(r=0,pos=0;r<rows;r++){
00143 for(c=0;c<cols;c++,pos++){
00144 if((edge[pos] == POSSIBLE_EDGE) && (mag[pos] >= highthreshold)){
00145 edge[pos] = EDGE;
00146 follow_edges((edge+pos), (mag+pos), lowthreshold, cols);
00147 }
00148 }
00149 }
00150
00151
00152
00153
00154 int centroid = 0;
00155 int numEdgePts = 0;
00156 for(r=0,pos=0;r<rows;r++){
00157 for(c=0;c<cols;c++,pos++)
00158 if(edge[pos] != EDGE) edge[pos] = NOEDGE;
00159 else {
00160 centroid += pos;
00161 numEdgePts++;
00162 }
00163 }
00164 if(numEdgePts != 0){
00165 centroid = centroid/numEdgePts;
00166 }
00167 else{
00168 centroid = 0;
00169 }
00170 return centroid;
00171 }
00172
00173
00174
00175
00176
00177
00178
00179
00180 void non_max_supp(short *mag, short *gradx, short *grady, int nrows, int ncols,
00181 unsigned char *result)
00182 {
00183 int rowcount, colcount,count;
00184 short *magrowptr,*magptr;
00185 short *gxrowptr,*gxptr;
00186 short *gyrowptr,*gyptr,z1,z2;
00187 short m00,gx=0,gy=0;
00188 float mag1,mag2,xperp=0.0f,yperp=0.0f;
00189 unsigned char *resultrowptr, *resultptr;
00190
00191
00192
00193
00194
00195 for(count=0,resultrowptr=result,resultptr=result+ncols*(nrows-1);
00196 count<ncols; resultptr++,resultrowptr++,count++){
00197 *resultrowptr = *resultptr = (unsigned char) 0;
00198 }
00199
00200 for(count=0,resultptr=result,resultrowptr=result+ncols-1;
00201 count<nrows; count++,resultptr+=ncols,resultrowptr+=ncols){
00202 *resultptr = *resultrowptr = (unsigned char) 0;
00203 }
00204
00205
00206
00207
00208 for(rowcount=1,magrowptr=mag+ncols+1,gxrowptr=gradx+ncols+1,
00209 gyrowptr=grady+ncols+1,resultrowptr=result+ncols+1;
00210 rowcount<nrows-2;
00211 rowcount++,magrowptr+=ncols,gyrowptr+=ncols,gxrowptr+=ncols,
00212 resultrowptr+=ncols){
00213 for(colcount=1,magptr=magrowptr,gxptr=gxrowptr,gyptr=gyrowptr,
00214 resultptr=resultrowptr;colcount<ncols-2;
00215 colcount++,magptr++,gxptr++,gyptr++,resultptr++){
00216 m00 = *magptr;
00217 if(m00 == 0){
00218 *resultptr = (unsigned char) NOEDGE;
00219 }
00220 else{
00221 xperp = -(gx = *gxptr)/((float)m00);
00222 yperp = (gy = *gyptr)/((float)m00);
00223 }
00224
00225 if(gx >= 0){
00226 if(gy >= 0){
00227 if (gx >= gy)
00228 {
00229
00230
00231 z1 = *(magptr - 1);
00232 z2 = *(magptr - ncols - 1);
00233
00234 mag1 = (m00 - z1)*xperp + (z2 - z1)*yperp;
00235
00236
00237 z1 = *(magptr + 1);
00238 z2 = *(magptr + ncols + 1);
00239
00240 mag2 = (m00 - z1)*xperp + (z2 - z1)*yperp;
00241 }
00242 else
00243 {
00244
00245
00246 z1 = *(magptr - ncols);
00247 z2 = *(magptr - ncols - 1);
00248
00249 mag1 = (z1 - z2)*xperp + (z1 - m00)*yperp;
00250
00251
00252 z1 = *(magptr + ncols);
00253 z2 = *(magptr + ncols + 1);
00254
00255 mag2 = (z1 - z2)*xperp + (z1 - m00)*yperp;
00256 }
00257 }
00258 else
00259 {
00260 if (gx >= -gy)
00261 {
00262
00263
00264 z1 = *(magptr - 1);
00265 z2 = *(magptr + ncols - 1);
00266
00267 mag1 = (m00 - z1)*xperp + (z1 - z2)*yperp;
00268
00269
00270 z1 = *(magptr + 1);
00271 z2 = *(magptr - ncols + 1);
00272
00273 mag2 = (m00 - z1)*xperp + (z1 - z2)*yperp;
00274 }
00275 else
00276 {
00277
00278
00279 z1 = *(magptr + ncols);
00280 z2 = *(magptr + ncols - 1);
00281
00282 mag1 = (z1 - z2)*xperp + (m00 - z1)*yperp;
00283
00284
00285 z1 = *(magptr - ncols);
00286 z2 = *(magptr - ncols + 1);
00287
00288 mag2 = (z1 - z2)*xperp + (m00 - z1)*yperp;
00289 }
00290 }
00291 }
00292 else
00293 {
00294 if ((gy = *gyptr) >= 0)
00295 {
00296 if (-gx >= gy)
00297 {
00298
00299
00300 z1 = *(magptr + 1);
00301 z2 = *(magptr - ncols + 1);
00302
00303 mag1 = (z1 - m00)*xperp + (z2 - z1)*yperp;
00304
00305
00306 z1 = *(magptr - 1);
00307 z2 = *(magptr + ncols - 1);
00308
00309 mag2 = (z1 - m00)*xperp + (z2 - z1)*yperp;
00310 }
00311 else
00312 {
00313
00314
00315 z1 = *(magptr - ncols);
00316 z2 = *(magptr - ncols + 1);
00317
00318 mag1 = (z2 - z1)*xperp + (z1 - m00)*yperp;
00319
00320
00321 z1 = *(magptr + ncols);
00322 z2 = *(magptr + ncols - 1);
00323
00324 mag2 = (z2 - z1)*xperp + (z1 - m00)*yperp;
00325 }
00326 }
00327 else
00328 {
00329 if (-gx > -gy)
00330 {
00331
00332
00333 z1 = *(magptr + 1);
00334 z2 = *(magptr + ncols + 1);
00335
00336 mag1 = (z1 - m00)*xperp + (z1 - z2)*yperp;
00337
00338
00339 z1 = *(magptr - 1);
00340 z2 = *(magptr - ncols - 1);
00341
00342 mag2 = (z1 - m00)*xperp + (z1 - z2)*yperp;
00343 }
00344 else
00345 {
00346
00347
00348 z1 = *(magptr + ncols);
00349 z2 = *(magptr + ncols + 1);
00350
00351 mag1 = (z2 - z1)*xperp + (m00 - z1)*yperp;
00352
00353
00354 z1 = *(magptr - ncols);
00355 z2 = *(magptr - ncols - 1);
00356
00357 mag2 = (z2 - z1)*xperp + (m00 - z1)*yperp;
00358 }
00359 }
00360 }
00361
00362
00363
00364 if ((mag1 > 0.0) || (mag2 > 0.0))
00365 {
00366 *resultptr = (unsigned char) NOEDGE;
00367 }
00368 else
00369 {
00370 if (mag2 == 0.0)
00371 *resultptr = (unsigned char) NOEDGE;
00372 else
00373 *resultptr = (unsigned char) POSSIBLE_EDGE;
00374 }
00375 }
00376 }
00377 }