home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / TARFILE.GZ / tarfile / ch_3.5 / bcd / hyst.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-11  |  5.4 KB  |  202 lines

  1. /*
  2.  * This program is used with permission from I. Cox.
  3.  * Please reference:
  4.  * R. A. Boie, I. Cox, Proc. IEEE 1st Int. Conf. Computer Vision,
  5.  * London, 1987, pp. 450-456.
  6.  */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <math.h>
  10. #include <malloc.h>
  11. #include "edge_finder.h"
  12.  
  13. extern struct image *my_image;
  14. void image_neighbor_fwd ();
  15. void image_neighbor_bwd ();
  16.  
  17. static nx, ny;
  18. int nxXny;
  19.  
  20. unsigned char *
  21. image_hysteresis (int lo_thld)
  22. {
  23.   register int iy, ix;
  24.   register unsigned char *lmapP, *lmap_hiP, *mapP;
  25.  
  26.   nx = my_image->nx;
  27.   ny = my_image->ny;
  28.   nxXny = nx * ny;
  29.   my_image->lo_threshold = lo_thld;
  30.   my_image->edge_map_hi = my_image->edge_map;
  31.   my_image->edge_map = (unsigned char *) malloc (nx * ny * sizeof (unsigned char));
  32.  
  33.   lmap_hiP = &my_image->edge_map_hi[0];
  34.   lmapP = &my_image->edge_map[0];
  35.  
  36.   mapP = lmapP;
  37.   for (ix = nx * ny; --ix >= 0;)
  38.     *mapP++ = 0;
  39.  
  40.   for (iy = 0; iy < ny; iy++, lmap_hiP += nx, lmapP += nx) {
  41.     mapP = lmapP;
  42.     for (ix = 0; ix < nx; ix++, mapP++) {
  43.       if (lmap_hiP[ix] != 0) {
  44.         *mapP = lmap_hiP[ix];
  45.         image_neighbor_fwd (iy, ix, mapP);
  46.         image_neighbor_bwd (iy, ix, mapP);
  47.       }
  48.     }
  49.   }
  50.   return (my_image->edge_map);
  51. }
  52.  
  53. void
  54. image_neighbor_fwd (register int iy, register int ix, register unsigned char *mapP)
  55. {
  56.   switch (*mapP) {
  57.   case 5:
  58.     return;
  59.  
  60.   case EDGE_Y:                 /*0 */
  61.     if (!Fcontour (iy, ix + 1) && Fcontour (iy, ix + 2))
  62.       goto L_EDGE_Y;
  63.     else if (!(Fcontour (iy - 1, ix + 1) || Fcontour (iy + 1, ix + 1)) &&
  64.              (Fcontour (iy - 1, ix + 2) || Fcontour (iy + 1, ix + 2))) {
  65.     L_EDGE_Y:if (ix + 1 < nx)
  66.         *(mapP + 1) = 5;
  67.     }
  68.     break;
  69.   case EDGE_135:               /*45 */
  70.     if (!Fcontour (iy - 1, ix + 1) && Fcontour (iy - 2, ix + 2))
  71.       goto L_EDGE_135;
  72.     else if (!(Fcontour (iy, ix + 1) || Fcontour (iy - 1, ix)) &&
  73.              (Fcontour (iy - 2, ix + 1) || Fcontour (iy - 1, ix + 2))) {
  74.     L_EDGE_135:if ((iy - 1 >= 0) && (ix + 1 < nx))
  75.         *(mapP - nx + 1) = 5;
  76.     }
  77.     break;
  78.   case EDGE_X:                 /*90 */
  79.     if (!Fcontour (iy - 1, ix) && Fcontour (iy - 2, ix))
  80.       goto L_EDGE_X;
  81.     else if (!(Fcontour (iy - 1, ix - 1) || Fcontour (iy - 1, ix + 1)) &&
  82.              (Fcontour (iy - 2, ix - 1) || Fcontour (iy - 2, ix + 1))) {
  83.     L_EDGE_X:if (iy - 1 >= 0)
  84.         *(mapP - nx) = 5;
  85.     }
  86.     break;
  87.   case EDGE_45:                /*135 */
  88.     if (!Fcontour (iy + 1, ix + 1) && Fcontour (iy + 2, ix + 2))
  89.       goto L_EDGE_45;
  90.     else if (!(Fcontour (iy, ix + 1) || Fcontour (iy + 1, ix)) &&
  91.              (Fcontour (iy + 1, ix + 2) || Fcontour (iy + 2, ix + 1))) {
  92.     L_EDGE_45:if ((iy + 1 < ny) && (ix + 1 < nx))
  93.         *(mapP + nx + 1) = 5;
  94.     }
  95.     break;
  96.   default:
  97.     fprintf (stderr, "error in case statements\n");
  98.     fprintf (stderr, "x=%d y=%d\n", ix, iy);
  99.     exit (1);
  100.     break;
  101.   }
  102. }
  103.  
  104. void
  105. image_neighbor_bwd (register int iy, register int ix, register unsigned char *mapP)
  106. {
  107.   switch (*mapP) {
  108.   case 5:
  109.     return;
  110.  
  111.   case EDGE_Y:                 /*0 */
  112.     if (!Bcontour (iy, ix - 1) && Bcontour (iy, ix - 2))
  113.       goto L_EDGE_Y;
  114.     else if (!(Bcontour (iy - 1, ix - 1) || Bcontour (iy + 1, ix - 1)) &&
  115.              (Bcontour (iy - 1, ix - 2) || Bcontour (iy + 1, ix - 2))) {
  116.     L_EDGE_Y:if (ix - 1 >= 0)
  117.         *(mapP - 1) = 5;
  118.     }
  119.     break;
  120.   case EDGE_135:               /*45 */
  121.     if (!Bcontour (iy + 1, ix - 1) && Bcontour (iy + 2, ix - 2))
  122.       goto L_EDGE_135;
  123.     else if (!(Bcontour (iy, ix - 1) || Bcontour (iy + 1, ix)) &&
  124.              (Bcontour (iy + 1, ix - 2) || Bcontour (iy + 2, ix - 1))) {
  125.     L_EDGE_135:if ((iy + 1 < ny) && (ix - 1 >= 0))
  126.         *(mapP + nx - 1) = 5;
  127.     }
  128.     break;
  129.   case EDGE_X:                 /*90 */
  130.     if (!Bcontour (iy + 1, ix) && Bcontour (iy + 2, ix))
  131.       goto L_EDGE_X;
  132.     else if (!(Bcontour (iy + 1, ix - 1) || Bcontour (iy + 1, ix + 1)) &&
  133.              (Bcontour (iy + 2, ix - 1) || Bcontour (iy + 2, ix + 1))) {
  134.     L_EDGE_X:if (iy + 1 < ny)
  135.         *(mapP + nx) = 5;
  136.     }
  137.     break;
  138.   case EDGE_45:                /*135 */
  139.     if (!Bcontour (iy - 1, ix - 1) && Bcontour (iy - 2, ix - 2))
  140.       goto L_EDGE_45;
  141.     else if (!(Bcontour (iy, ix - 1) || Bcontour (iy - 1, ix)) &&
  142.              (Bcontour (iy - 1, ix - 2) || Bcontour (iy - 2, ix - 1))) {
  143.     L_EDGE_45:if ((iy - 1 >= 0) && (ix - 1 >= 0))
  144.         *(mapP - nx - 1) = 5;
  145.     }
  146.     break;
  147.   default:
  148.     fprintf (stderr, "error in case statements\n");
  149.     fprintf (stderr, "x=%d y=%d\n", ix, iy);
  150.     exit (1);
  151.     break;
  152.   }
  153. }
  154.  
  155. int
  156. Fcontour (register int iy, register int ix)
  157. {
  158.   int edge_pt, index;
  159.   register unsigned char *mapP;
  160.  
  161.   /*if(ix<0||ix>=nx||iy<0||iy>=ny) return(0); */
  162.  
  163.   index = iy * nx + ix;
  164.   if (index < 0 || index >= nxXny)
  165.     return (0);
  166.  
  167.   mapP = &my_image->edge_map[index];
  168.   if (*mapP > 0)
  169.     return (1);
  170.   else if ((edge_pt = image_edge_map_lo (ix, iy, index)) != 0) {
  171.     *mapP = edge_pt;
  172.     image_neighbor_fwd (iy, ix, mapP);
  173.     return (1);
  174.   }
  175.   else
  176.     return (0);
  177. }
  178.  
  179. int
  180. Bcontour (register int iy, register int ix)
  181. {
  182.   register unsigned char *mapP;
  183.   int edge_pt, index;
  184.  
  185.   /*if(ix<0||ix>=nx||iy<0||iy>=ny) return(0); */
  186.  
  187.   index = iy * nx + ix;
  188.   if (index < 0 || index >= nxXny)
  189.     return (0);
  190.  
  191.   mapP = &my_image->edge_map[index];
  192.   if (*mapP > 0)
  193.     return (1);
  194.   else if ((edge_pt = image_edge_map_lo (ix, iy, index)) != 0) {
  195.     *mapP = edge_pt;
  196.     image_neighbor_bwd (iy, ix, mapP);
  197.     return (1);
  198.   }
  199.   else
  200.     return (0);
  201. }
  202.